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:
@ -1948,10 +1948,10 @@ expr(A) ::= expr(X) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
|
|||||||
expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).
|
expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).
|
||||||
{spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
|
{spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
|
||||||
%ifdef MAXSCALE
|
%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
|
// Here we could check that id is one of MICROSECOND, SECOND, MINUTE
|
||||||
// HOUR, DAY, WEEK, etc.
|
// HOUR, DAY, WEEK, etc.
|
||||||
A=X;
|
spanExpr(&A, pParse, @X, &X);
|
||||||
}
|
}
|
||||||
%endif
|
%endif
|
||||||
expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y).
|
expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y).
|
||||||
|
|||||||
@ -1069,6 +1069,11 @@ public:
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
void print(ostream& out) const
|
void print(ostream& out) const
|
||||||
{
|
{
|
||||||
out << m_name;
|
out << m_name;
|
||||||
@ -1118,6 +1123,19 @@ bool operator == (const QcFunctionInfo& lhs, const QcFunctionInfo& rhs)
|
|||||||
return lhs.eq(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,
|
bool compare_get_function_info(QUERY_CLASSIFIER* pClassifier1, GWBUF* pCopy1,
|
||||||
QUERY_CLASSIFIER* pClassifier2, GWBUF* pCopy2)
|
QUERY_CLASSIFIER* pClassifier2, GWBUF* pCopy2)
|
||||||
{
|
{
|
||||||
@ -1150,9 +1168,49 @@ bool compare_get_function_info(QUERY_CLASSIFIER* pClassifier1, GWBUF* pCopy1,
|
|||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
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;
|
ss << "ERR: " << f1 << " != " << f2;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "Ok : " << f1 << " != " << f2;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
report(success, ss.str());
|
report(success, ss.str());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user