MXS-1475 Allow the setting on N vars with one stmt
With this change, the following will be possible. SET @maxscale.cache.populate=false, @maxscale.cache.use=true;
This commit is contained in:
@ -21,6 +21,7 @@
|
|||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <maxscale/alloc.h>
|
#include <maxscale/alloc.h>
|
||||||
#include <maxscale/authenticator.h>
|
#include <maxscale/authenticator.h>
|
||||||
@ -899,7 +900,13 @@ char* handle_variables(MXS_SESSION* session, GWBUF** read_buffer)
|
|||||||
{
|
{
|
||||||
SqlModeParser sql_mode_parser;
|
SqlModeParser sql_mode_parser;
|
||||||
|
|
||||||
switch (sql_mode_parser.get_sql_mode(result.value_begin(), result.value_end()))
|
const SetParser::Result::Items& values = result.values();
|
||||||
|
|
||||||
|
for (SetParser::Result::Items::const_iterator i = values.begin(); i != values.end(); ++i)
|
||||||
|
{
|
||||||
|
const SetParser::Result::Item& value = *i;
|
||||||
|
|
||||||
|
switch (sql_mode_parser.get_sql_mode(value.first, value.second))
|
||||||
{
|
{
|
||||||
case SqlModeParser::ORACLE:
|
case SqlModeParser::ORACLE:
|
||||||
session_set_autocommit(session, false);
|
session_set_autocommit(session, false);
|
||||||
@ -918,12 +925,30 @@ char* handle_variables(MXS_SESSION* session, GWBUF** read_buffer)
|
|||||||
ss_dassert(!true);
|
ss_dassert(!true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SetParser::IS_SET_MAXSCALE:
|
case SetParser::IS_SET_MAXSCALE:
|
||||||
|
{
|
||||||
|
const SetParser::Result::Items& variables = result.variables();
|
||||||
|
const SetParser::Result::Items& values = result.values();
|
||||||
|
|
||||||
|
SetParser::Result::Items::const_iterator i = variables.begin();
|
||||||
|
SetParser::Result::Items::const_iterator j = values.begin();
|
||||||
|
|
||||||
|
while (!message && (i != variables.end()))
|
||||||
|
{
|
||||||
|
const SetParser::Result::Item& variable = *i;
|
||||||
|
const SetParser::Result::Item& value = *j;
|
||||||
|
|
||||||
message = session_set_variable_value(session,
|
message = session_set_variable_value(session,
|
||||||
result.variable_begin(), result.variable_end(),
|
variable.first, variable.second,
|
||||||
result.value_begin(), result.value_end());
|
value.first, value.second);
|
||||||
|
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SetParser::NOT_RELEVANT:
|
case SetParser::NOT_RELEVANT:
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <maxscale/cppdefs.hh>
|
#include <maxscale/cppdefs.hh>
|
||||||
|
#include <vector>
|
||||||
#include <maxscale/customparser.hh>
|
#include <maxscale/customparser.hh>
|
||||||
#include <maxscale/protocol/mysql.h>
|
#include <maxscale/protocol/mysql.h>
|
||||||
|
|
||||||
@ -47,28 +48,28 @@ public:
|
|||||||
class Result
|
class Result
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef std::pair<const char*, const char*> Item;
|
||||||
|
typedef std::vector<Item> Items;
|
||||||
|
|
||||||
Result()
|
Result()
|
||||||
: m_pVariable_begin(NULL)
|
|
||||||
, m_pVariable_end(NULL)
|
|
||||||
, m_pValue_begin(NULL)
|
|
||||||
, m_pValue_end(NULL)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const char* variable_begin() const { return m_pVariable_begin; }
|
const Items& variables() const { return m_variables; }
|
||||||
const char* variable_end() const { return m_pVariable_end; }
|
const Items& values() const { return m_values; }
|
||||||
const char* value_begin() const { return m_pValue_begin; }
|
|
||||||
const char* value_end() const { return m_pValue_end; }
|
|
||||||
|
|
||||||
void set_variable_begin(const char* pVariable_begin) { m_pVariable_begin = pVariable_begin; }
|
void add_variable(const char *begin, const char* end)
|
||||||
void set_variable_end(const char* pVariable_end) { m_pVariable_end = pVariable_end; }
|
{
|
||||||
void set_value_begin(const char* pValue_begin) { m_pValue_begin = pValue_begin; }
|
m_variables.push_back(Item(begin, end));
|
||||||
void set_value_end(const char* pValue_end) { m_pValue_end = pValue_end; }
|
}
|
||||||
|
|
||||||
|
void add_value(const char* begin, const char* end)
|
||||||
|
{
|
||||||
|
m_values.push_back(Item(begin, end));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* m_pVariable_begin;
|
std::vector<Item> m_variables;
|
||||||
const char* m_pVariable_end;
|
std::vector<Item> m_values;
|
||||||
const char* m_pValue_begin;
|
|
||||||
const char* m_pValue_end;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -270,7 +271,8 @@ private:
|
|||||||
|
|
||||||
++m_pI;
|
++m_pI;
|
||||||
|
|
||||||
while ((m_pI < m_pEnd) && (is_alpha(*m_pI) || is_number(*m_pI) || (*m_pI == '.') || (*m_pI == '_')))
|
while ((m_pI < m_pEnd) &&
|
||||||
|
(is_alpha(*m_pI) || is_number(*m_pI) || (*m_pI == '.') || (*m_pI == '_')))
|
||||||
{
|
{
|
||||||
++m_pI;
|
++m_pI;
|
||||||
}
|
}
|
||||||
@ -385,8 +387,7 @@ private:
|
|||||||
|
|
||||||
if (next_token() == '=')
|
if (next_token() == '=')
|
||||||
{
|
{
|
||||||
pResult->set_variable_begin(pVariable_begin);
|
pResult->add_variable(pVariable_begin, pVariable_end);
|
||||||
pResult->set_variable_end(pVariable_end);
|
|
||||||
|
|
||||||
bypass_whitespace();
|
bypass_whitespace();
|
||||||
|
|
||||||
@ -395,8 +396,7 @@ private:
|
|||||||
|
|
||||||
consume_value(&pValue_end);
|
consume_value(&pValue_end);
|
||||||
|
|
||||||
pResult->set_value_begin(pValue_begin);
|
pResult->add_value(pValue_begin, pValue_end);
|
||||||
pResult->set_value_end(pValue_end);
|
|
||||||
|
|
||||||
rv = IS_SET_SQL_MODE;
|
rv = IS_SET_SQL_MODE;
|
||||||
}
|
}
|
||||||
@ -417,8 +417,7 @@ private:
|
|||||||
|
|
||||||
if (next_token() == '=')
|
if (next_token() == '=')
|
||||||
{
|
{
|
||||||
pResult->set_variable_begin(pVariable_begin);
|
pResult->add_variable(pVariable_begin, pVariable_end);
|
||||||
pResult->set_variable_end(pVariable_end);
|
|
||||||
|
|
||||||
bypass_whitespace();
|
bypass_whitespace();
|
||||||
|
|
||||||
@ -427,8 +426,7 @@ private:
|
|||||||
|
|
||||||
consume_value(&pValue_end);
|
consume_value(&pValue_end);
|
||||||
|
|
||||||
pResult->set_value_begin(pValue_begin);
|
pResult->add_value(pValue_begin, pValue_end);
|
||||||
pResult->set_value_end(pValue_end);
|
|
||||||
|
|
||||||
rv = IS_SET_MAXSCALE;
|
rv = IS_SET_MAXSCALE;
|
||||||
}
|
}
|
||||||
|
@ -52,183 +52,328 @@ struct TEST_CASE
|
|||||||
{
|
{
|
||||||
const char* zStmt;
|
const char* zStmt;
|
||||||
SetParser::status_t status;
|
SetParser::status_t status;
|
||||||
|
struct EXPECTATION
|
||||||
|
{
|
||||||
const char* zVariable;
|
const char* zVariable;
|
||||||
const char* zValue;
|
const char* zValue;
|
||||||
|
} expectations[10];
|
||||||
} test_cases[] =
|
} test_cases[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"SET SQL_MODE=DEFAULT",
|
"SET SQL_MODE=DEFAULT",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"DEFAULT"
|
"DEFAULT"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE=DEFAULT;",
|
"SET SQL_MODE=DEFAULT;",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"DEFAULT"
|
"DEFAULT"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE=DEFAULT; ",
|
"SET SQL_MODE=DEFAULT; ",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"DEFAULT"
|
"DEFAULT"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"-- This is a comment\nSET SQL_MODE=DEFAULT",
|
"-- This is a comment\nSET SQL_MODE=DEFAULT",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"DEFAULT"
|
"DEFAULT"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"#This is a comment\nSET SQL_MODE=DEFAULT",
|
"#This is a comment\nSET SQL_MODE=DEFAULT",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"DEFAULT"
|
"DEFAULT"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"/*blah*/ SET /*blah*/ SQL_MODE /*blah*/ = /*blah*/ DEFAULT /*blah*/ ",
|
"/*blah*/ SET /*blah*/ SQL_MODE /*blah*/ = /*blah*/ DEFAULT /*blah*/ ",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"DEFAULT"
|
"DEFAULT"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE=ORACLE",
|
"SET SQL_MODE=ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE=BLAH", // So short that it cannot be DEFAULT|ORACLE
|
"SET SQL_MODE=BLAH", // So short that it cannot be DEFAULT|ORACLE
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"BLAH"
|
"BLAH"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE='BLAH'",
|
"SET SQL_MODE='BLAH'",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"'BLAH'"
|
"'BLAH'"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE=BLAHBLAH",
|
"SET SQL_MODE=BLAHBLAH",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"BLAHBLAH"
|
"BLAHBLAH"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE='ORACLE'",
|
"SET SQL_MODE='ORACLE'",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"'ORACLE'"
|
"'ORACLE'"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE='BLAH, A, B, ORACLE'",
|
"SET SQL_MODE='BLAH, A, B, ORACLE'",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"'BLAH, A, B, ORACLE'"
|
"'BLAH, A, B, ORACLE'"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE='BLAH, A, B, XYZ_123'",
|
"SET SQL_MODE='BLAH, A, B, XYZ_123'",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"'BLAH, A, B, XYZ_123'"
|
"'BLAH, A, B, XYZ_123'"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET VAR1=1234, VAR2=3456, SQL_MODE='A,B, ORACLE'",
|
"SET VAR1=1234, VAR2=3456, SQL_MODE='A,B, ORACLE'",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"'A,B, ORACLE'"
|
"'A,B, ORACLE'"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SQL_MODE=ORACLE, VAR1=3456, VAR2='A=b, c=d', SQL_MODE='A,B, ORACLE'",
|
"SET SQL_MODE=ORACLE, VAR1=3456, VAR2='A=b, c=d', SQL_MODE='A,B, ORACLE'",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET GLOBAL SQL_MODE=ORACLE",
|
"SET GLOBAL SQL_MODE=ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET SESSION SQL_MODE=ORACLE",
|
"SET SESSION SQL_MODE=ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET LOCAL SQL_MODE=ORACLE",
|
"SET LOCAL SQL_MODE=ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET @@GLOBAL.SQL_MODE=ORACLE",
|
"SET @@GLOBAL.SQL_MODE=ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET @@SESSION.SQL_MODE=ORACLE",
|
"SET @@SESSION.SQL_MODE=ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET @@LOCAL.SQL_MODE=ORACLE",
|
"SET @@LOCAL.SQL_MODE=ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET @@LOCAL . SQL_MODE = ORACLE",
|
"SET @@LOCAL . SQL_MODE = ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"SQL_MODE",
|
"SQL_MODE",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET @@SESSION.blah = 1234, @@GLOBAL.blahblah = something, sql_mode=ORACLE",
|
"SET @@SESSION.blah = 1234, @@GLOBAL.blahblah = something, sql_mode=ORACLE",
|
||||||
P::IS_SET_SQL_MODE,
|
P::IS_SET_SQL_MODE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"sql_mode",
|
"sql_mode",
|
||||||
"ORACLE"
|
"ORACLE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET MAXSCALE=",
|
"SET MAXSCALE=",
|
||||||
P::NOT_RELEVANT,
|
P::NOT_RELEVANT,
|
||||||
NULL,
|
{
|
||||||
NULL
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"SET MAXSCALE.CACHE.ENABLED=TRUE",
|
"SET MAXSCALE.CACHE.ENABLED=TRUE",
|
||||||
P::NOT_RELEVANT,
|
P::NOT_RELEVANT,
|
||||||
NULL,
|
{
|
||||||
NULL
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"SET @MAXSCALE.CACHE.ENABLED=TRUE",
|
"SET @MAXSCALE.CACHE.ENABLED=TRUE",
|
||||||
P::IS_SET_MAXSCALE,
|
P::IS_SET_MAXSCALE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"@MAXSCALE.CACHE.ENABLED",
|
"@MAXSCALE.CACHE.ENABLED",
|
||||||
"TRUE"
|
"TRUE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET @MAXSCALE.CACHE.ENABLED = TRUE /*blah*/",
|
"SET @MAXSCALE.CACHE.ENABLED = TRUE /*blah*/",
|
||||||
P::IS_SET_MAXSCALE,
|
P::IS_SET_MAXSCALE,
|
||||||
|
{
|
||||||
|
{
|
||||||
"@MAXSCALE.CACHE.ENABLED",
|
"@MAXSCALE.CACHE.ENABLED",
|
||||||
"TRUE"
|
"TRUE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"SET @MAXSCALE.CACHE.ENABLED = TRUE, @maxscale.cache.enabled = FALSE",
|
"SET @MAXSCALE.CACHE.ENABLED = TRUE, @maxscale.cache.enabled = FALSE",
|
||||||
P::IS_SET_MAXSCALE,
|
P::IS_SET_MAXSCALE,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"@MAXSCALE.CACHE.ENABLED",
|
||||||
|
"TRUE"
|
||||||
|
},
|
||||||
|
{
|
||||||
"@maxscale.cache.enabled",
|
"@maxscale.cache.enabled",
|
||||||
"FALSE"
|
"FALSE"
|
||||||
},
|
},
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const int N_TEST_CASES = sizeof(test_cases) / sizeof(test_cases[0]);
|
const int N_TEST_CASES = sizeof(test_cases) / sizeof(test_cases[0]);
|
||||||
|
|
||||||
int test(GWBUF** ppStmt, SetParser::status_t expected_status, const char* zVariable, const char* zValue)
|
int test(GWBUF** ppStmt, SetParser::status_t expected_status, const TEST_CASE::EXPECTATION expectations[])
|
||||||
{
|
{
|
||||||
int rv = EXIT_SUCCESS;
|
int rv = EXIT_SUCCESS;
|
||||||
|
|
||||||
@ -241,22 +386,40 @@ int test(GWBUF** ppStmt, SetParser::status_t expected_status, const char* zVaria
|
|||||||
{
|
{
|
||||||
if ((status != SetParser::ERROR) && (status != SetParser::NOT_RELEVANT))
|
if ((status != SetParser::ERROR) && (status != SetParser::NOT_RELEVANT))
|
||||||
{
|
{
|
||||||
size_t l1 = result.variable_end() - result.variable_begin();
|
const SetParser::Result::Items& variables = result.variables();
|
||||||
|
const SetParser::Result::Items& values = result.values();
|
||||||
|
ss_dassert(variables.size() == values.size());
|
||||||
|
|
||||||
if ((l1 == strlen(zVariable)) && (memcmp(result.variable_begin(), zVariable, l1) == 0))
|
SetParser::Result::Items::const_iterator i = variables.begin();
|
||||||
|
SetParser::Result::Items::const_iterator j = values.begin();
|
||||||
|
int k = 0;
|
||||||
|
|
||||||
|
while (i != variables.end())
|
||||||
{
|
{
|
||||||
size_t l2 = result.value_end() - result.value_begin();
|
const SetParser::Result::Item& variable = *i;
|
||||||
|
const SetParser::Result::Item& value = *j;
|
||||||
|
const TEST_CASE::EXPECTATION& expectation = expectations[k];
|
||||||
|
|
||||||
if ((l2 == strlen(zValue)) && (memcmp(result.value_begin(), zValue, l2) == 0))
|
if (expectation.zVariable)
|
||||||
|
{
|
||||||
|
size_t l1 = variable.second - variable.first;
|
||||||
|
|
||||||
|
if ((l1 == strlen(expectation.zVariable)) &&
|
||||||
|
(memcmp(variable.first, expectation.zVariable, l1) == 0))
|
||||||
|
{
|
||||||
|
size_t l2 = value.second - value.first;
|
||||||
|
|
||||||
|
if ((l2 == strlen(expectation.zValue)) &&
|
||||||
|
(memcmp(value.first, expectation.zValue, l2) == 0))
|
||||||
{
|
{
|
||||||
cout << "OK";
|
cout << "OK";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "ERROR: Expected value "
|
cout << "ERROR: Expected value "
|
||||||
<< "'" << zValue << "'"
|
<< "'" << expectation.zValue << "'"
|
||||||
<< ", got '";
|
<< ", got '";
|
||||||
cout.write(result.value_begin(), l2);
|
cout.write(value.first, l2);
|
||||||
cout << "'.";
|
cout << "'.";
|
||||||
rv = EXIT_FAILURE;
|
rv = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -264,14 +427,35 @@ int test(GWBUF** ppStmt, SetParser::status_t expected_status, const char* zVaria
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "ERROR: Expected variable "
|
cout << "ERROR: Expected variable "
|
||||||
<< "'" << zVariable << "'"
|
<< "'" << expectation.zVariable << "'"
|
||||||
<< ", got '";
|
<< ", got '";
|
||||||
cout.write(result.variable_begin(), l1);
|
cout.write(variable.first, l1);
|
||||||
cout << "'.";
|
cout << "'.";
|
||||||
rv = EXIT_FAILURE;
|
rv = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
cout << "ERROR: Nothing expected for variable '";
|
||||||
|
cout.write(variable.first, variable.second - variable.first);
|
||||||
|
cout << "'";
|
||||||
|
rv = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
++j;
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectations[k].zVariable)
|
||||||
|
{
|
||||||
|
cout << "ERROR: "
|
||||||
|
<< expectations[k].zVariable << " = " << expectations[k].zValue
|
||||||
|
<< " not reported.";
|
||||||
|
rv = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
cout << "OK";
|
cout << "OK";
|
||||||
}
|
}
|
||||||
@ -300,7 +484,7 @@ int test(const TEST_CASE& test_case)
|
|||||||
GWBUF* pStmt = gwbuf_create_com_query(test_case.zStmt);
|
GWBUF* pStmt = gwbuf_create_com_query(test_case.zStmt);
|
||||||
ss_dassert(pStmt);
|
ss_dassert(pStmt);
|
||||||
|
|
||||||
rv = test(&pStmt, test_case.status, test_case.zVariable, test_case.zValue);
|
rv = test(&pStmt, test_case.status, test_case.expectations);
|
||||||
|
|
||||||
gwbuf_free(pStmt);
|
gwbuf_free(pStmt);
|
||||||
|
|
||||||
@ -362,7 +546,7 @@ int test_non_contiguous()
|
|||||||
|
|
||||||
cout << "): " << flush;
|
cout << "): " << flush;
|
||||||
|
|
||||||
if (test(&pStmt, test_case.status, test_case.zVariable, test_case.zValue) == EXIT_FAILURE)
|
if (test(&pStmt, test_case.status, test_case.expectations) == EXIT_FAILURE)
|
||||||
{
|
{
|
||||||
rv = EXIT_FAILURE;
|
rv = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -191,8 +191,14 @@ int test(GWBUF** ppStmt,
|
|||||||
{
|
{
|
||||||
if (status == SetParser::IS_SET_SQL_MODE)
|
if (status == SetParser::IS_SET_SQL_MODE)
|
||||||
{
|
{
|
||||||
|
const SetParser::Result::Items& values = result.values();
|
||||||
|
|
||||||
|
for (SetParser::Result::Items::const_iterator i = values.begin(); i != values.end(); ++i)
|
||||||
|
{
|
||||||
|
const SetParser::Result::Item& item = *i;
|
||||||
|
|
||||||
SqlModeParser sql_mode_parser;
|
SqlModeParser sql_mode_parser;
|
||||||
SqlModeParser::sql_mode_t sql_mode = sql_mode_parser.get_sql_mode(result.value_begin(), result.value_end());
|
SqlModeParser::sql_mode_t sql_mode = sql_mode_parser.get_sql_mode(item.first, item.second);
|
||||||
|
|
||||||
if (sql_mode == expected_sql_mode)
|
if (sql_mode == expected_sql_mode)
|
||||||
{
|
{
|
||||||
@ -208,6 +214,7 @@ int test(GWBUF** ppStmt,
|
|||||||
rv = EXIT_FAILURE;
|
rv = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "OK";
|
cout << "OK";
|
||||||
|
Reference in New Issue
Block a user