Commit 448a4fd1 authored by unknown's avatar unknown

ndb - fix TUP filtering of LIKE / NOT_LIKE


ndb/include/util/NdbSqlUtil.hpp:
  1. fix wild_* chars 2. use correct wildcmp return value
ndb/src/common/util/NdbSqlUtil.cpp:
  1. fix wild_* chars 2. use correct wildcmp return value
ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp:
  1. fix wild_* chars 2. use correct wildcmp return value
parent e7038f43
...@@ -45,9 +45,9 @@ public: ...@@ -45,9 +45,9 @@ public:
typedef int Cmp(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full); typedef int Cmp(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full);
/** /**
* Prototype for "like" comparison. Defined for the 3 char string * Prototype for "like" comparison. Defined for string types. Second
* types. Second argument must have same type-specific format. * argument must have same type-specific format. Returns 0 on match,
* Returns >0 on match, 0 on no match, <0 on bad data. * +1 on no match, and -1 on bad data.
* *
* Uses default special chars ( \ % _ ). * Uses default special chars ( \ % _ ).
* *
......
...@@ -795,14 +795,18 @@ NdbSqlUtil::cmpTimestamp(const void* info, const void* p1, unsigned n1, const vo ...@@ -795,14 +795,18 @@ NdbSqlUtil::cmpTimestamp(const void* info, const void* p1, unsigned n1, const vo
// like // like
static const int ndb_wild_prefix = '\\';
static const int ndb_wild_one = '_';
static const int ndb_wild_many = '%';
int int
NdbSqlUtil::likeChar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2) NdbSqlUtil::likeChar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2)
{ {
const char* v1 = (const char*)p1; const char* v1 = (const char*)p1;
const char* v2 = (const char*)p2; const char* v2 = (const char*)p2;
CHARSET_INFO* cs = (CHARSET_INFO*)(info); CHARSET_INFO* cs = (CHARSET_INFO*)(info);
int k = (cs->coll->wildcmp)(cs, v1, v1 + n1, v2, v2 + n2, wild_prefix, wild_one, wild_many); int k = (cs->coll->wildcmp)(cs, v1, v1 + n1, v2, v2 + n2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many);
return k; return k == 0 ? 0 : +1;
} }
int int
...@@ -825,8 +829,8 @@ NdbSqlUtil::likeVarchar(const void* info, const void* p1, unsigned n1, const voi ...@@ -825,8 +829,8 @@ NdbSqlUtil::likeVarchar(const void* info, const void* p1, unsigned n1, const voi
const char* w1 = (const char*)v1 + lb; const char* w1 = (const char*)v1 + lb;
const char* w2 = (const char*)v2 + lb; const char* w2 = (const char*)v2 + lb;
CHARSET_INFO* cs = (CHARSET_INFO*)(info); CHARSET_INFO* cs = (CHARSET_INFO*)(info);
int k = (cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, wild_prefix, wild_one, wild_many); int k = (cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many);
return k; return k == 0 ? 0 : +1;
} }
} }
return -1; return -1;
...@@ -852,8 +856,8 @@ NdbSqlUtil::likeLongvarchar(const void* info, const void* p1, unsigned n1, const ...@@ -852,8 +856,8 @@ NdbSqlUtil::likeLongvarchar(const void* info, const void* p1, unsigned n1, const
const char* w1 = (const char*)v1 + lb; const char* w1 = (const char*)v1 + lb;
const char* w2 = (const char*)v2 + lb; const char* w2 = (const char*)v2 + lb;
CHARSET_INFO* cs = (CHARSET_INFO*)(info); CHARSET_INFO* cs = (CHARSET_INFO*)(info);
int k = (cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, wild_prefix, wild_one, wild_many); int k = (cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many);
return k; return k == 0 ? 0 : +1;
} }
} }
return -1; return -1;
......
...@@ -1861,56 +1861,57 @@ int Dbtup::interpreterNextLab(Signal* signal, ...@@ -1861,56 +1861,57 @@ int Dbtup::interpreterNextLab(Signal* signal,
bool r1_null = ah.isNULL(); bool r1_null = ah.isNULL();
bool r2_null = argLen == 0; bool r2_null = argLen == 0;
int res; int res1;
if (cond != Interpreter::LIKE && if (cond != Interpreter::LIKE &&
cond != Interpreter::NOT_LIKE) { cond != Interpreter::NOT_LIKE) {
if (r1_null || r2_null) { if (r1_null || r2_null) {
// NULL==NULL and NULL<not-NULL // NULL==NULL and NULL<not-NULL
res = r1_null && r2_null ? 0 : r1_null ? -1 : 1; res1 = r1_null && r2_null ? 0 : r1_null ? -1 : 1;
} else { } else {
res = (*sqlType.m_cmp)(cs, s1, attrLen, s2, argLen, true); res1 = (*sqlType.m_cmp)(cs, s1, attrLen, s2, argLen, true);
} }
} else { } else {
if (r1_null || r2_null) { if (r1_null || r2_null) {
// NULL like NULL is true (has no practical use) // NULL like NULL is true (has no practical use)
res = r1_null && r2_null ? 0 : -1; res1 = r1_null && r2_null ? 0 : -1;
} else { } else {
res = (*sqlType.m_like)(cs, s1, attrLen, s2, argLen); res1 = (*sqlType.m_like)(cs, s1, attrLen, s2, argLen);
} }
} }
int res = 0;
switch ((Interpreter::BinaryCondition)cond) { switch ((Interpreter::BinaryCondition)cond) {
case Interpreter::EQ: case Interpreter::EQ:
res = (res == 0); res = (res1 == 0);
break; break;
case Interpreter::NE: case Interpreter::NE:
res = (res != 0); res = (res1 != 0);
break; break;
// note the condition is backwards // note the condition is backwards
case Interpreter::LT: case Interpreter::LT:
res = (res > 0); res = (res1 > 0);
break; break;
case Interpreter::LE: case Interpreter::LE:
res = (res >= 0); res = (res1 >= 0);
break; break;
case Interpreter::GT: case Interpreter::GT:
res = (res < 0); res = (res1 < 0);
break; break;
case Interpreter::GE: case Interpreter::GE:
res = (res <= 0); res = (res1 <= 0);
break; break;
case Interpreter::LIKE: case Interpreter::LIKE:
res = (res > 0); res = (res1 == 0);
break; break;
case Interpreter::NOT_LIKE: case Interpreter::NOT_LIKE:
res = (res == 0); res = (res1 == 1);
break; break;
// XXX handle invalid value // XXX handle invalid value
} }
#ifdef TRACE_INTERPRETER #ifdef TRACE_INTERPRETER
ndbout_c("cond=%u diff=%d vc=%d nopad=%d attr(%d) = >%.*s<(%d) str=>%.*s<(%d) -> res = %d", ndbout_c("cond=%u attr(%d)='%.*s'(%d) str='%.*s'(%d) res1=%d res=%d",
cond, diff, vchr, nopad, cond, attrId >> 16,
attrId >> 16, attrLen, s1, attrLen, argLen, s2, argLen, res); attrLen, s1, attrLen, argLen, s2, argLen, res1, res);
#endif #endif
if (res) if (res)
TprogramCounter = brancher(theInstruction, TprogramCounter); TprogramCounter = brancher(theInstruction, TprogramCounter);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment