diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 539cdb1077a33331c32987e5226f9fc8bc2f18c7..56796089c916e49fc3ec4f59ff7382b175160662 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -4656,7 +4656,7 @@ static int32_t validateSQLExprItemSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr, return TSDB_CODE_SUCCESS; } -static int32_t validateSQLExprItemArithmeticExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, +static int32_t validateSQLExprItemOperatorExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type, uint64_t* uid, int32_t* height) { uint64_t uidLeft = 0; uint64_t uidRight = 0; @@ -4685,7 +4685,9 @@ static int32_t validateSQLExprItemArithmeticExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, *height = (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight+1; { - assert(leftType != SQLEXPR_TYPE_UNASSIGNED && rightType != SQLEXPR_TYPE_UNASSIGNED); + if (leftType == SQLEXPR_TYPE_UNASSIGNED || rightType == SQLEXPR_TYPE_UNASSIGNED) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "invalid operand expression"); + } // return invalid operation when one child aggregate and the other child scalar or column if ((leftType == SQLEXPR_TYPE_AGG && rightType == SQLEXPR_TYPE_SCALAR) || (rightType == SQLEXPR_TYPE_AGG && leftType == SQLEXPR_TYPE_SCALAR)) { @@ -4713,6 +4715,11 @@ static int32_t validateSQLExprItemArithmeticExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, rightType == SQLEXPR_TYPE_AGG || rightType == SQLEXPR_TYPE_SCALAR) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } + } else if (pExpr->tokenId == TK_ISNULL || pExpr->tokenId == TK_NOTNULL || + pExpr->tokenId == TK_IS || pExpr->tokenId == TK_LIKE || + pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_NMATCH || + pExpr->tokenId == TK_CONTAINS || pExpr->tokenId == TK_IN) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "unsupported filtering operations"); } } return TSDB_CODE_SUCCESS; @@ -4728,7 +4735,7 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr, return TSDB_CODE_SUCCESS; } if (pExpr->type == SQL_NODE_EXPR) { - int32_t ret = validateSQLExprItemArithmeticExpr(pCmd, pExpr, pQueryInfo, pList, type, uid, height); + int32_t ret = validateSQLExprItemOperatorExpr(pCmd, pExpr, pQueryInfo, pList, type, uid, height); if (ret != TSDB_CODE_SUCCESS) { return ret; } diff --git a/tests/develop-test/2-query/constant_compare.py b/tests/develop-test/2-query/constant_compare.py index a8ca27e63ce0db8e3bd05009e1d9aab4e7995981..21beddc51303a73b0c5eb4cf2f21a5b2e6735c9c 100644 --- a/tests/develop-test/2-query/constant_compare.py +++ b/tests/develop-test/2-query/constant_compare.py @@ -1129,6 +1129,56 @@ class TDTestCase: tdSql.error('select 1 != 2 and 1 < 2 or \'abc123\' or 2 between \'abc123\' and 5 and false or "abc123" from tb;') tdSql.error('select \'1234\' or 1 < 2 or \'aace\' and "cde" between 4 and "def" and "ckas" or 10.1 from tb;') + #operator: is NULL + tdSql.error('select 1 is NULL from tb;') + tdSql.error('select 1.0 is NULL from tb;') + tdSql.error('select true is NULL from tb;') + tdSql.error('select \'a\' is NULL from tb;') + tdSql.error('select "abc" is NULL from tb;') + tdSql.error('select 1 is NULL and 1.0 is NULL or "abc" is NULL from tb;') + + #operator: is not NULL + tdSql.error('select 1 is not NULL from tb;') + tdSql.error('select 1.0 is not NULL from tb;') + tdSql.error('select true is not NULL from tb;') + tdSql.error('select \'a\' is not NULL from tb;') + tdSql.error('select "abc" is not NULL from tb;') + tdSql.error('select 1 is not NULL and 1.0 is not NULL or "abc" is not NULL from tb;') + + #operator: like + tdSql.error('select 1 like 1 from tb;') + tdSql.error('select 1.0 like 1.0 from tb;') + tdSql.error('select true like true from tb;') + tdSql.error('select \'abc\' like \'a_\' from tb;') + tdSql.error('select "abc" like "ab__%" from tb;') + tdSql.error('select 1 like 1 and 1.0 like 1.0 or "abc" like "a%" from tb;') + + #operator: match + tdSql.error('select 1 match 1 from tb;') + tdSql.error('select 1.0 match 1.0 from tb;') + tdSql.error('select true match true from tb;') + tdSql.error('select \'abc\' match \'a_\' from tb;') + tdSql.error('select "abc" match "ab__%" from tb;') + tdSql.error('select 1 match 1 and 1.0 match 1.0 or "abc" match "a%" from tb;') + + #operator: nmatch + tdSql.error('select 1 nmatch 1 from tb;') + tdSql.error('select 1.0 nmatch 1.0 from tb;') + tdSql.error('select true nmatch true from tb;') + tdSql.error('select \'abc\' nmatch \'a_\' from tb;') + tdSql.error('select "abc" nmatch "ab__%" from tb;') + tdSql.error('select 1 nmatch 1 and 1.0 nmatch 1.0 or "abc" nmatch "a%" from tb;') + + #operator: in + tdSql.error('select 1 in 1 from tb;') + tdSql.error('select 1 in (1, 2, 3) from tb;') + tdSql.error('select 1.0 in 1.0 from tb;') + tdSql.error('select 1.0 in (1.0, 2.0, 3.0) from tb;') + tdSql.error('select true in (true, false, true) from tb;') + tdSql.error('select \'abc\' in (\'acd\', \'bce\') from tb;') + tdSql.error('select "abc" in ("acd", "bce") from tb;') + tdSql.error('select 1 in (1,2,3) and 1.0 in (1.0,2.0,3.0) or "abc" in ("abc","cde") from tb;') + tdSql.execute('drop database db') def stop(self): tdSql.close() diff --git a/tests/develop-test/2-query/func_compare.py b/tests/develop-test/2-query/func_compare.py index 80894b9e0872a2d08e14e7e04dbafbf0f0f88f1c..6a5b4c7e975e04a982984671b39650a957ef4754 100644 --- a/tests/develop-test/2-query/func_compare.py +++ b/tests/develop-test/2-query/func_compare.py @@ -297,6 +297,91 @@ class TDTestCase: tdSql.error('select percentile(value, 50) or diff(value) = ceil(value) and apercentile(value, 50) from tb') tdSql.error('select floor(3.5) or round(3.5) and ceil(3.5) > true and round(3.5) or 3 from tb') + #operator: is NULL + tdSql.error('select count(*) is NULL from tb;') + tdSql.error('select avg(value) is NULL from tb;') + tdSql.error('select twa(value) is NULL from tb;') + tdSql.error('select sum(value) is NULL from tb;') + tdSql.error('select stddev(value) is NULL from tb;') + tdSql.error('select min(value) is NULL from tb;') + tdSql.error('select max(value) is NULL from tb;') + tdSql.error('select first(*) is NULL from tb;') + tdSql.error('select last(*) is NULL from tb;') + tdSql.error('select top(value, 3) is NULL or bottom(value,3) is NULL from tb;') + tdSql.error('select percentile(value, 50) is NULL or apercentile(value, 50) is NULL from tb') + tdSql.error('select diff(value) is NULL or ceil(value) is NULL from tb') + tdSql.error('select floor(3.5) is NULL or round(3.5) is NULL or ceil(3.5) is NULL from tb') + + #operator: is not NULL + tdSql.error('select count(*) is not NULL from tb;') + tdSql.error('select avg(value) is not NULL from tb;') + tdSql.error('select twa(value) is not NULL from tb;') + tdSql.error('select sum(value) is not NULL from tb;') + tdSql.error('select stddev(value) is not NULL from tb;') + tdSql.error('select min(value) is not NULL from tb;') + tdSql.error('select max(value) is not NULL from tb;') + tdSql.error('select first(*) is not NULL from tb;') + tdSql.error('select last(*) is not NULL from tb;') + tdSql.error('select top(value, 3) is not NULL or bottom(value,3) is not NULL from tb;') + tdSql.error('select percentile(value, 50) is not NULL or apercentile(value, 50) is not NULL from tb') + tdSql.error('select diff(value) is not NULL or ceil(value) is not NULL from tb') + tdSql.error('select floor(3.5) is not NULL or round(3.5) is not NULL or ceil(3.5) is not NULL from tb') + + #operator: like + tdSql.error('select count(*) like "abc" from tb;') + tdSql.error('select avg(value) like "abc" from tb;') + tdSql.error('select twa(value) like "abc" from tb;') + tdSql.error('select sum(value) like "abc" from tb;') + tdSql.error('select stddev(value) like "abc" from tb;') + tdSql.error('select min(value) like "abc" from tb;') + tdSql.error('select max(value) like "abc" from tb;') + tdSql.error('select first(*) like "abc" from tb;') + tdSql.error('select last(*) like "abc" from tb;') + tdSql.error('select top(value, 3) like "abc" or bottom(value,3) like "abc" from tb;') + tdSql.error('select percentile(value, 50) like "abc" or apercentile(value, 50) like "abc" from tb') + tdSql.error('select diff(value) like "abc" or ceil(value) like "abc" from tb') + tdSql.error('select floor(3.5) like "abc" or round(3.5) like "abc" or ceil(3.5) like "abc" from tb') + + #operator: match + tdSql.error('select count(*) match "abc" from tb;') + tdSql.error('select avg(value) match "abc" from tb;') + tdSql.error('select twa(value) match "abc" from tb;') + tdSql.error('select sum(value) match "abc" from tb;') + tdSql.error('select stddev(value) match "abc" from tb;') + tdSql.error('select min(value) match "abc" from tb;') + tdSql.error('select max(value) match "abc" from tb;') + tdSql.error('select first(*) match "abc" from tb;') + tdSql.error('select last(*) match "abc" from tb;') + tdSql.error('select top(value, 3) match "abc" or bottom(value,3) match "abc" from tb;') + tdSql.error('select percentile(value, 50) match "abc" or apercentile(value, 50) match "abc" from tb') + tdSql.error('select diff(value) match "abc" or ceil(value) match "abc" from tb') + tdSql.error('select floor(3.5) match "abc" or round(3.5) match "abc" or ceil(3.5) match "abc" from tb') + + #operator: nmatch + tdSql.error('select count(*) nmatch "abc" from tb;') + tdSql.error('select avg(value) nmatch "abc" from tb;') + tdSql.error('select twa(value) nmatch "abc" from tb;') + tdSql.error('select sum(value) nmatch "abc" from tb;') + tdSql.error('select stddev(value) nmatch "abc" from tb;') + tdSql.error('select min(value) nmatch "abc" from tb;') + tdSql.error('select max(value) nmatch "abc" from tb;') + tdSql.error('select first(*) nmatch "abc" from tb;') + tdSql.error('select last(*) nmatch "abc" from tb;') + tdSql.error('select top(value, 3) nmatch "abc" or bottom(value,3) nmatch "abc" from tb;') + tdSql.error('select percentile(value, 50) nmatch "abc" or apercentile(value, 50) nmatch "abc" from tb') + tdSql.error('select diff(value) nmatch "abc" or ceil(value) nmatch "abc" from tb') + tdSql.error('select floor(3.5) nmatch "abc" or round(3.5) nmatch "abc" or ceil(3.5) nmatch "abc" from tb') + + #operator: in + tdSql.error('select count(*) in 1 from tb;') + tdSql.error('select avg(value) in (1, 2, 3) from tb;') + tdSql.error('select twa(value) in 1.0 from tb;') + tdSql.error('select sum(value) in (1.0, 2.0, 3.0) from tb;') + tdSql.error('select min(value) in (true, false, true) from tb;') + tdSql.error('select tbname in (\'acd\', \'bce\') from tb;') + tdSql.error('select t in ("acd", "bce") from tb;') + tdSql.error('select top(value, 3) in (1,2,3) and ceil(value) in (1.0,2.0,3.0) or last(*) in ("abc","cde") from tb;') + tdSql.execute('drop database db') def stop(self):