MXS-1688 Handle ...INTERVAL N <unit>
"INTERVAL N <unit>" is now handled as an expression in itself and as asuch will cause both statements such as "SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;" and "select id from db2.t1 where DATE_ADD("2017-06-15", INTERVAL 10 DAY) < "2017-06-15";" to be handled correctly. The compare test program contains some heuristic checking, as the the embedded parser will in all cases report date manipulation as the use of the add_date_interval() function.
This commit is contained in:
parent
b7cc793c40
commit
0c206ff428
@ -1948,10 +1948,10 @@ expr(A) ::= expr(X) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
|
||||
expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).
|
||||
{spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
|
||||
%ifdef MAXSCALE
|
||||
expr(A) ::= expr(X) PLUS|MINUS INTERVAL INTEGER id. {
|
||||
expr(A) ::= INTERVAL INTEGER(X) id. {
|
||||
// Here we could check that id is one of MICROSECOND, SECOND, MINUTE
|
||||
// HOUR, DAY, WEEK, etc.
|
||||
A=X;
|
||||
spanExpr(&A, pParse, @X, &X);
|
||||
}
|
||||
%endif
|
||||
expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y).
|
||||
|
@ -1069,6 +1069,11 @@ public:
|
||||
return rv;
|
||||
}
|
||||
|
||||
const std::string& name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void print(ostream& out) const
|
||||
{
|
||||
out << m_name;
|
||||
@ -1118,6 +1123,19 @@ bool operator == (const QcFunctionInfo& lhs, const QcFunctionInfo& rhs)
|
||||
return lhs.eq(rhs);
|
||||
}
|
||||
|
||||
void collect_missing_function_names(const std::set<QcFunctionInfo>& one,
|
||||
const std::set<QcFunctionInfo>& other,
|
||||
std::set<std::string>* pNames)
|
||||
{
|
||||
for (std::set<QcFunctionInfo>::const_iterator i = one.begin(); i != one.end(); ++i)
|
||||
{
|
||||
if (other.count(*i) == 0)
|
||||
{
|
||||
pNames->insert(i->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool compare_get_function_info(QUERY_CLASSIFIER* pClassifier1, GWBUF* pCopy1,
|
||||
QUERY_CLASSIFIER* pClassifier2, GWBUF* pCopy2)
|
||||
{
|
||||
@ -1151,7 +1169,47 @@ bool compare_get_function_info(QUERY_CLASSIFIER* pClassifier1, GWBUF* pCopy1,
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "ERR: " << f1 << " != " << f2;
|
||||
std::set<std::string> names1;
|
||||
collect_missing_function_names(f1, f2, &names1);
|
||||
|
||||
std::set<std::string> names2;
|
||||
collect_missing_function_names(f2, f1, &names2);
|
||||
|
||||
bool real_error = false;
|
||||
|
||||
// We assume that names1 are from the qc_mysqlembedded and names2 from qc_sqlite.
|
||||
// The embedded parser reports all date_add(), adddate(), date_sub() and subdate()
|
||||
// functions as date_add_interval(). Further, all "DATE + INTERVAL ..." cases become
|
||||
// use of date_add_interval() functions.
|
||||
for (std::set<std::string>::iterator i = names1.begin(); i != names1.end(); ++i)
|
||||
{
|
||||
if (*i == "date_add_interval")
|
||||
{
|
||||
if ((names2.count("date_add") == 0) &&
|
||||
(names2.count("adddate") == 0) &&
|
||||
(names2.count("date_sub") == 0) &&
|
||||
(names2.count("subdate") == 0) &&
|
||||
(names2.count("+") == 0) &&
|
||||
(names2.count("-") == 0))
|
||||
{
|
||||
real_error = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
real_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (real_error)
|
||||
{
|
||||
ss << "ERR: " << f1 << " != " << f2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "Ok : " << f1 << " != " << f2;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
report(success, ss.str());
|
||||
|
Loading…
x
Reference in New Issue
Block a user