fix: like wildcard match

This commit is contained in:
factosea 2023-12-26 14:48:05 +08:00
parent 68795ecf35
commit 1aae0e52e3
5 changed files with 221 additions and 4 deletions

View File

@ -1070,6 +1070,11 @@ int32_t patternMatch(const char *pattern, size_t psize, const char *str, size_t
return TSDB_PATTERN_MATCH; /* "*" at the end of the pattern matches */
}
if (c == '\\' && (pattern[i] == '_' || pattern[i] == '%')) {
c = pattern[i];
i++;
}
char rejectList[2] = {toupper(c), tolower(c)};
str += nMatchChar;
@ -1139,6 +1144,11 @@ int32_t wcsPatternMatch(const TdUcs4 *pattern, size_t psize, const TdUcs4 *str,
return TSDB_PATTERN_MATCH;
}
if (c == '\\' && (pattern[i] == '_' || pattern[i] == '%')) {
c = pattern[i];
i++;
}
TdUcs4 rejectList[2] = {towupper(c), towlower(c)};
str += nMatchChar;
@ -1166,7 +1176,8 @@ int32_t wcsPatternMatch(const TdUcs4 *pattern, size_t psize, const TdUcs4 *str,
c1 = str[j++];
nMatchChar++;
if (c == L'\\' && pattern[i] == L'_' && c1 == L'_') {
if (c == '\\' && pattern[i] == c1 &&
(c1 == '_' || c1 == '%')) {
i++;
continue;
}

View File

@ -76,6 +76,16 @@ TEST(utilTest, wchar_pattern_match_test) {
const TdWchar* str12 = L"";
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern12), 4, reinterpret_cast<const TdUcs4*>(str12), 0, &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_NOMATCH);
const TdWchar* pattern13 = L"%\\_6 ";
const TdWchar* str13 = L"6a6 ";
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern13), 6, reinterpret_cast<const TdUcs4*>(str13), 4, &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
const TdWchar* pattern14 = L"%\\%6 ";
const TdWchar* str14 = L"6a6 ";
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern14), 6, reinterpret_cast<const TdUcs4*>(str14), 4, &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
}
TEST(utilTest, wchar_pattern_match_no_terminated) {
@ -128,12 +138,22 @@ TEST(utilTest, wchar_pattern_match_no_terminated) {
const TdWchar* pattern9 = L"6\\_6 ";
const TdWchar* str9 = L"6_6 ";
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern9), 4, reinterpret_cast<const TdUcs4*>(str9), 3, &pInfo);
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern9), 6, reinterpret_cast<const TdUcs4*>(str9), 4, &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
const TdWchar* pattern10 = L"% ";
const TdWchar* str10 = L"6_6 ";
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern10), 1, reinterpret_cast<const TdUcs4*>(str10), 3, &pInfo);
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern10), 2, reinterpret_cast<const TdUcs4*>(str10), 4, &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
const TdWchar* pattern11 = L"%\\_6 ";
const TdWchar* str11 = L"6_6 ";
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern11), 6, reinterpret_cast<const TdUcs4*>(str11), 4, &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
const TdWchar* pattern12 = L"%\\%6 ";
const TdWchar* str12 = L"6%6 ";
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern12), 6, reinterpret_cast<const TdUcs4*>(str12), 4, &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
}
@ -209,6 +229,36 @@ TEST(utilTest, char_pattern_match_test) {
const char* str13 = "a%c";
ret = patternMatch(pattern13, 5, str13, strlen(str13), &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
const char* pattern14 = "%a\\%c";
const char* str14 = "a%c";
ret = patternMatch(pattern14, strlen(pattern14), str14, strlen(str14), &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
const char* pattern15 = "_a\\%c";
const char* str15 = "ba%c";
ret = patternMatch(pattern15, strlen(pattern15), str15, strlen(str15), &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
const char* pattern16 = "_\\%c";
const char* str16 = "a%c";
ret = patternMatch(pattern16, strlen(pattern16), str16, strlen(str16), &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
const char* pattern17 = "_\\%c";
const char* str17 = "ba%c";
ret = patternMatch(pattern17, strlen(pattern17), str17, strlen(str17), &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_NOMATCH);
const char* pattern18 = "%\\%c";
const char* str18 = "abc";
ret = patternMatch(pattern18, strlen(pattern18), str18, strlen(str18), &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
const char* pattern19 = "%\\_c";
const char* str19 = "abc";
ret = patternMatch(pattern19, strlen(pattern19), str19, strlen(str19), &pInfo);
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
}
TEST(utilTest, char_pattern_match_no_terminated) {

View File

@ -131,6 +131,10 @@
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 2
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 3
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 4
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 2
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 3
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 4
,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreDnode.py -N 5 -M 3 -i False
,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreVnode.py -N 5 -M 3 -i False

View File

@ -0,0 +1,148 @@
import taos
import sys
import datetime
import inspect
from util.log import *
from util.sql import *
from util.cases import *
from util.common import tdCom
class TDTestCase:
def init(self, conn, logSql, replicaVar=1):
self.replicaVar = int(replicaVar)
tdLog.debug(f"start to excute {__file__}")
tdSql.init(conn.cursor(), False)
def initDB(self):
tdSql.execute("drop database if exists db")
tdSql.execute("create database if not exists db")
def stopTest(self):
tdSql.execute("drop database if exists db")
def like_wildcard_test(self):
tdSql.execute("create table db.t1x (ts timestamp, c1 varchar(100))")
tdSql.execute("create table db.t_1x (ts timestamp, c1 varchar(100))")
tdSql.query("select * from information_schema.ins_columns where table_name like '%1x'")
tdSql.checkRows(4)
tdSql.query("select * from information_schema.ins_columns where table_name like '%\_1x'")
tdSql.checkRows(2)
tdSql.query("insert into db.t1x values(now, 'abc'), (now+1s, 'a%c'),(now+2s, 'a_c'),(now+3s, '_c'),(now+4s, '%c')")
tdSql.query("select * from db.t1x")
tdSql.checkRows(5)
tdSql.query("select * from db.t1x where c1 like '%_c'")
tdSql.checkRows(5)
tdSql.query("select * from db.t1x where c1 like '%__c'")
tdSql.checkRows(3)
tdSql.query("select * from db.t1x where c1 like '%\_c'")
tdSql.checkRows(2)
tdSql.query("select * from db.t1x where c1 like '%\%c'")
tdSql.checkRows(2)
tdSql.query("select * from db.t1x where c1 like '_\%c'")
tdSql.checkRows(1)
tdSql.checkData(0, 1, "a%c")
tdSql.query("select * from db.t1x where c1 like '_\_c'")
tdSql.checkRows(1)
tdSql.checkData(0, 1, "a_c")
tdSql.query("select * from db.t1x where c1 like '%%_c'")
tdSql.checkRows(5)
tdSql.query("select * from db.t1x where c1 like '%_%c'")
tdSql.checkRows(5)
tdSql.query("select * from db.t1x where c1 like '__%c'")
tdSql.checkRows(3)
tdSql.query("select * from db.t1x where c1 not like '__%c'")
tdSql.checkRows(2)
def like_cnc_wildcard_test(self):
tdSql.execute("create table db.t3x (ts timestamp, c1 varchar(100))")
tdSql.execute("insert into db.t3x values(now, '我是中文'), (now+1s, '我是_中文'), (now+2s, '我是%中文'), (now+3s, '%中文'),(now+4s, '_中文')")
tdSql.query("select * from db.t3x")
tdSql.checkRows(5)
tdSql.query("select * from db.t3x where c1 like '%中文'")
tdSql.checkRows(5)
tdSql.query("select * from db.t3x where c1 like '%中_文'")
tdSql.checkRows(0)
tdSql.query("select * from db.t3x where c1 like '%\%中文'")
tdSql.checkRows(2)
tdSql.query("select * from db.t3x where c1 like '%\_中文'")
tdSql.checkRows(2)
tdSql.query("select * from db.t3x where c1 like '_中文'")
tdSql.checkRows(2)
tdSql.query("select * from db.t3x where c1 like '\_中文'")
tdSql.checkRows(1)
def like_multi_wildcard_test(self):
tdSql.execute("create table db.t4x (ts timestamp, c1 varchar(100))")
# 插入测试数据
tdSql.execute("insert into db.t4x values(now, 'abc'), (now+1s, 'a%c'),(now+2s, 'a_c'),(now+3s, '_c'),(now+4s, '%c')")
tdSql.execute("insert into db.t4x values(now+5s, '%%%c'),(now+6s, '___c'),(now+7s, '%_%c'),(now+8s, '%\\c')")
tdSql.query("select * from db.t4x where c1 like '%%%_'")
tdSql.checkRows(9)
tdSql.query("select * from db.t4x where c1 like '\%\%\%_'")
tdSql.checkRows(1)
tdSql.query("select * from db.t4x where c1 like '%\_%%'")
tdSql.checkRows(4)
tdSql.query("select * from db.t4x where c1 like '_\%\%'")
tdSql.checkRows(0)
tdSql.query("select * from db.t4x where c1 like '%abc%'")
tdSql.checkRows(1)
tdSql.query("select * from db.t4x where c1 like '_%abc%'")
tdSql.checkRows(0)
tdSql.query("select * from db.t4x where c1 like '\%%\%%'")
tdSql.checkRows(2)
tdSql.query("select * from db.t4x where c1 like '\%\_%\%%'")
tdSql.checkRows(1)
def run(self):
tdLog.printNoPrefix("==========start like_wildcard_test run ...............")
tdSql.prepare(replica = self.replicaVar)
self.initDB()
self.like_wildcard_test()
self.like_cnc_wildcard_test()
self.like_multi_wildcard_test()
tdLog.printNoPrefix("==========end like_wildcard_test run ...............")
self.stopTest()
def stop(self):
tdSql.close()
tdLog.success(f"{__file__} successfully executed")
tdCases.addLinux(__file__, TDTestCase())
tdCases.addWindows(__file__, TDTestCase())

View File

@ -99,6 +99,10 @@ python3 ./test.py -f 2-query/ts-4233.py
python3 ./test.py -f 2-query/ts-4233.py -Q 2
python3 ./test.py -f 2-query/ts-4233.py -Q 3
python3 ./test.py -f 2-query/ts-4233.py -Q 4
python3 ./test.py -f 2-query/like.py
python3 ./test.py -f 2-query/like.py -Q 2
python3 ./test.py -f 2-query/like.py -Q 3
python3 ./test.py -f 2-query/like.py -Q 4
python3 ./test.py -f 3-enterprise/restore/restoreDnode.py -N 5 -M 3 -i False
python3 ./test.py -f 3-enterprise/restore/restoreVnode.py -N 5 -M 3 -i False
python3 ./test.py -f 3-enterprise/restore/restoreMnode.py -N 5 -M 3 -i False