未验证 提交 9a59e944 编写于 作者: X Xiaoyu Wang 提交者: GitHub

Merge pull request #11490 from taosdata/feature/3.0_wxy

enh(query): improve the validity check of function parameters
......@@ -181,49 +181,50 @@
#define TK_NULL 163
#define TK_FIRST 164
#define TK_LAST 165
#define TK_NOW 166
#define TK_TODAY 167
#define TK_ROWTS 168
#define TK_TBNAME 169
#define TK_QSTARTTS 170
#define TK_QENDTS 171
#define TK_WSTARTTS 172
#define TK_WENDTS 173
#define TK_WDURATION 174
#define TK_BETWEEN 175
#define TK_IS 176
#define TK_NK_LT 177
#define TK_NK_GT 178
#define TK_NK_LE 179
#define TK_NK_GE 180
#define TK_NK_NE 181
#define TK_MATCH 182
#define TK_NMATCH 183
#define TK_JOIN 184
#define TK_INNER 185
#define TK_SELECT 186
#define TK_DISTINCT 187
#define TK_WHERE 188
#define TK_PARTITION 189
#define TK_BY 190
#define TK_SESSION 191
#define TK_STATE_WINDOW 192
#define TK_SLIDING 193
#define TK_FILL 194
#define TK_VALUE 195
#define TK_NONE 196
#define TK_PREV 197
#define TK_LINEAR 198
#define TK_NEXT 199
#define TK_GROUP 200
#define TK_HAVING 201
#define TK_ORDER 202
#define TK_SLIMIT 203
#define TK_SOFFSET 204
#define TK_LIMIT 205
#define TK_OFFSET 206
#define TK_ASC 207
#define TK_NULLS 208
#define TK_CAST 166
#define TK_NOW 167
#define TK_TODAY 168
#define TK_ROWTS 169
#define TK_TBNAME 170
#define TK_QSTARTTS 171
#define TK_QENDTS 172
#define TK_WSTARTTS 173
#define TK_WENDTS 174
#define TK_WDURATION 175
#define TK_BETWEEN 176
#define TK_IS 177
#define TK_NK_LT 178
#define TK_NK_GT 179
#define TK_NK_LE 180
#define TK_NK_GE 181
#define TK_NK_NE 182
#define TK_MATCH 183
#define TK_NMATCH 184
#define TK_JOIN 185
#define TK_INNER 186
#define TK_SELECT 187
#define TK_DISTINCT 188
#define TK_WHERE 189
#define TK_PARTITION 190
#define TK_BY 191
#define TK_SESSION 192
#define TK_STATE_WINDOW 193
#define TK_SLIDING 194
#define TK_FILL 195
#define TK_VALUE 196
#define TK_NONE 197
#define TK_PREV 198
#define TK_LINEAR 199
#define TK_NEXT 200
#define TK_GROUP 201
#define TK_HAVING 202
#define TK_ORDER 203
#define TK_SLIMIT 204
#define TK_SOFFSET 205
#define TK_LIMIT 206
#define TK_OFFSET 207
#define TK_ASC 208
#define TK_NULLS 209
#define TK_NK_SPACE 300
#define TK_NK_COMMENT 301
......
......@@ -181,6 +181,7 @@ typedef struct {
#define IS_SIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_TINYINT && (_t) <= TSDB_DATA_TYPE_BIGINT)
#define IS_UNSIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_UTINYINT && (_t) <= TSDB_DATA_TYPE_UBIGINT)
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
#define IS_INTEGER_TYPE(_t) ((IS_SIGNED_NUMERIC_TYPE(_t)) || (IS_UNSIGNED_NUMERIC_TYPE(_t)))
#define IS_NUMERIC_TYPE(_t) ((IS_SIGNED_NUMERIC_TYPE(_t)) || (IS_UNSIGNED_NUMERIC_TYPE(_t)) || (IS_FLOAT_TYPE(_t)))
#define IS_MATHABLE_TYPE(_t) (IS_NUMERIC_TYPE(_t) || (_t) == (TSDB_DATA_TYPE_BOOL) || (_t) == (TSDB_DATA_TYPE_TIMESTAMP))
......
......@@ -123,7 +123,7 @@ void fmFuncMgtDestroy();
int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType);
int32_t fmGetFuncResultType(SFunctionNode* pFunc);
int32_t fmGetFuncResultType(SFunctionNode* pFunc, char* pErrBuf, int32_t len);
bool fmIsAggFunc(int32_t funcId);
bool fmIsScalarFunc(int32_t funcId);
......
......@@ -566,8 +566,6 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_AMBIGUOUS_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2603)
#define TSDB_CODE_PAR_WRONG_VALUE_TYPE TAOS_DEF_ERROR_CODE(0, 0x2604)
#define TSDB_CODE_PAR_INVALID_FUNTION TAOS_DEF_ERROR_CODE(0, 0x2605)
#define TSDB_CODE_PAR_FUNTION_PARA_NUM TAOS_DEF_ERROR_CODE(0, 0x2606)
#define TSDB_CODE_PAR_FUNTION_PARA_TYPE TAOS_DEF_ERROR_CODE(0, 0x2607)
#define TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION TAOS_DEF_ERROR_CODE(0, 0x2608)
#define TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT TAOS_DEF_ERROR_CODE(0, 0x2609)
#define TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION TAOS_DEF_ERROR_CODE(0, 0x260A)
......@@ -601,7 +599,12 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_INVALID_KEEP_UNIT TAOS_DEF_ERROR_CODE(0, 0x2626)
//planner
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
//function
#define TSDB_CODE_FUNC_FUNTION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2800)
#define TSDB_CODE_FUNC_FUNTION_PARA_NUM TAOS_DEF_ERROR_CODE(0, 0x2801)
#define TSDB_CODE_FUNC_FUNTION_PARA_TYPE TAOS_DEF_ERROR_CODE(0, 0x2802)
#ifdef __cplusplus
}
......
......@@ -40,14 +40,14 @@ extern "C" {
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
typedef int32_t (*FCheckAndGetResultType)(SFunctionNode* pFunc);
typedef int32_t (*FTranslateFunc)(SFunctionNode* pFunc, char* pErrBuf, int32_t len);
typedef EFuncDataRequired (*FFuncDataRequired)(SFunctionNode* pFunc, STimeWindow* pTimeWindow);
typedef struct SBuiltinFuncDefinition {
char name[FUNCTION_NAME_MAX_LENGTH];
EFunctionType type;
uint64_t classification;
FCheckAndGetResultType checkFunc;
FTranslateFunc translateFunc;
FFuncDataRequired dataRequiredFunc;
FExecGetEnv getEnvFunc;
FExecInit initFunc;
......
此差异已折叠。
......@@ -69,11 +69,11 @@ int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncTyp
return TSDB_CODE_SUCCESS;
}
int32_t fmGetFuncResultType(SFunctionNode* pFunc) {
int32_t fmGetFuncResultType(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (pFunc->funcId < 0 || pFunc->funcId >= funcMgtBuiltinsNum) {
return TSDB_CODE_FAILED;
}
return funcMgtBuiltins[pFunc->funcId].checkFunc(pFunc);
return funcMgtBuiltins[pFunc->funcId].translateFunc(pFunc, pErrBuf, len);
}
EFuncDataRequired fmFuncDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWindow) {
......
......@@ -81,7 +81,6 @@ SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode);
SNodeList* createNodeList(SAstCreateContext* pCxt, SNode* pNode);
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode);
SNodeList* addValueNodeFromTypeToList(SAstCreateContext* pCxt, SDataType dataType, SNodeList* pList);
SNode* createColumnNode(SAstCreateContext* pCxt, SToken* pTableAlias, SToken* pColumnName);
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral);
......@@ -93,6 +92,7 @@ SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pL
SNode* createBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList);
SNode* createCastFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SDataType dt);
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList);
SNode* createNodeListNodeEx(SAstCreateContext* pCxt, SNode* p1, SNode* p2);
SNode* createRealTableNode(SAstCreateContext* pCxt, SToken* pDbName, SToken* pTableName, SToken* pTableAlias);
......
......@@ -535,13 +535,7 @@ expression(A) ::= pseudo_column(B).
expression(A) ::= column_reference(B). { A = B; }
expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
expression(A) ::= function_name(B) NK_LP NK_STAR(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, createNodeList(pCxt, createColumnNode(pCxt, NULL, &C)))); }
//for CAST function CAST(expr AS type_name)
expression(A) ::= function_name(B) NK_LP expression(C) AS type_name(D) NK_RP(E). {
SNodeList *p = createNodeList(pCxt, releaseRawExprNode(pCxt, C));
p = addValueNodeFromTypeToList(pCxt, D, p);
A = createRawExprNodeExt(pCxt, &B, &E, createFunctionNode(pCxt, &B, p));
}
//expression(A) ::= cast_expression(B). { A = B; }
expression(A) ::= CAST(B) NK_LP expression(C) AS type_name(D) NK_RP(E). { A = createRawExprNodeExt(pCxt, &B, &E, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, C), D)); }
//expression(A) ::= case_expression(B). { A = B; }
expression(A) ::= subquery(B). { A = B; }
expression(A) ::= NK_LP(B) expression(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, releaseRawExprNode(pCxt, C)); }
......
......@@ -208,7 +208,9 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
SRawExprNode* pRawExpr = (SRawExprNode*)pNode;
SNode* pExpr = pRawExpr->pNode;
if (nodesIsExprNode(pExpr)) {
strncpy(((SExprNode*)pExpr)->aliasName, pRawExpr->p, pRawExpr->n);
int32_t len = TMIN(sizeof(((SExprNode*)pExpr)->aliasName) - 1, pRawExpr->n);
strncpy(((SExprNode*)pExpr)->aliasName, pRawExpr->p, len);
((SExprNode*)pExpr)->aliasName[len] = '\0';
}
taosMemoryFreeClear(pNode);
return pExpr;
......@@ -253,33 +255,6 @@ SNode* createColumnNode(SAstCreateContext* pCxt, SToken* pTableAlias, SToken* pC
return (SNode*)col;
}
SNodeList* addValueNodeFromTypeToList(SAstCreateContext* pCxt, SDataType dataType, SNodeList* pList) {
char buf[64] = {0};
//add value node for type
snprintf(buf, sizeof(buf), "%u", dataType.type);
SToken token = {.type = TSDB_DATA_TYPE_SMALLINT, .n = strlen(buf), .z = buf};
SNode* pNode = createValueNode(pCxt, token.type, &token);
addNodeToList(pCxt, pList, pNode);
//add value node for bytes
memset(buf, 0, sizeof(buf));
int32_t bytes;
if (IS_VAR_DATA_TYPE(dataType.type)) {
bytes = (dataType.type == TSDB_DATA_TYPE_NCHAR) ? dataType.bytes * TSDB_NCHAR_SIZE : dataType.bytes;
bytes += VARSTR_HEADER_SIZE;
} else {
bytes = dataType.bytes;
}
snprintf(buf, sizeof(buf), "%d", bytes);
token.type = TSDB_DATA_TYPE_BIGINT;
token.n = strlen(buf);
token.z = buf;
pNode = createValueNode(pCxt, token.type, &token);
addNodeToList(pCxt, pList, pNode);
return pList;
}
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral) {
SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
CHECK_OUT_OF_MEM(val);
......@@ -385,6 +360,15 @@ SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNod
return (SNode*)func;
}
SNode* createCastFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SDataType dt) {
SFunctionNode* func = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
CHECK_OUT_OF_MEM(func);
strcpy(func->functionName, "cast");
func->node.resType = dt;
nodesListMakeAppend(&func->pParameterList, pExpr);
return (SNode*)func;
}
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList) {
SNodeListNode* list = (SNodeListNode*)nodesMakeNode(QUERY_NODE_NODE_LIST);
CHECK_OUT_OF_MEM(list);
......
......@@ -415,7 +415,6 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
pVal->datum.d = strtold(pVal->literal, &endPtr);
break;
}
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY: {
pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
......@@ -433,6 +432,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
}
break;
}
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_JSON:
case TSDB_DATA_TYPE_DECIMAL:
case TSDB_DATA_TYPE_BLOB:
......@@ -485,9 +485,9 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
if (TSDB_CODE_SUCCESS != fmGetFuncInfo(pFunc->functionName, &pFunc->funcId, &pFunc->funcType)) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_FUNTION, pFunc->functionName);
}
int32_t code = fmGetFuncResultType(pFunc);
if (TSDB_CODE_SUCCESS != code) {
return generateDealNodeErrMsg(pCxt, code, pFunc->functionName);
pCxt->errCode = fmGetFuncResultType(pFunc, pCxt->msgBuf.buf, pCxt->msgBuf.len);
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
return DEAL_RES_ERROR;
}
if (fmIsAggFunc(pFunc->funcId) && beforeHaving(pCxt->currClause)) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION);
......
......@@ -31,10 +31,6 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "Invalid value type : %s";
case TSDB_CODE_PAR_INVALID_FUNTION:
return "Invalid function name : %s";
case TSDB_CODE_PAR_FUNTION_PARA_NUM:
return "Invalid number of arguments : %s";
case TSDB_CODE_PAR_FUNTION_PARA_TYPE:
return "Inconsistent datatypes : %s";
case TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION:
return "There mustn't be aggregation";
case TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT:
......
此差异已折叠。
......@@ -31,7 +31,7 @@
./test.sh -f tsim/query/interval.sim
./test.sh -f tsim/query/interval-offset.sim
./test.sh -f tsim/query/scalarFunction.sim
./test.sh -f tsim/query/charScalarFunction.sim
#./test.sh -f tsim/query/charScalarFunction.sim
./test.sh -f tsim/query/explain.sim
./test.sh -f tsim/query/session.sim
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册