From cc1d37cfe5881e38a85841a893f8d1746e518a27 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Mon, 29 Aug 2022 17:23:29 +0800 Subject: [PATCH] fix: some problems of parser --- source/common/src/tvariant.c | 8 ++-- source/libs/parser/src/parInsert.c | 4 ++ source/libs/parser/src/parTranslater.c | 53 +++++++++++++++++++++++++- source/util/src/terror.c | 2 +- 4 files changed, 60 insertions(+), 7 deletions(-) diff --git a/source/common/src/tvariant.c b/source/common/src/tvariant.c index 0810be1497..a01c393441 100644 --- a/source/common/src/tvariant.c +++ b/source/common/src/tvariant.c @@ -155,8 +155,8 @@ void taosVariantCreateFromBinary(SVariant *pVar, const char *pz, size_t len, uin void taosVariantDestroy(SVariant *pVar) { if (pVar == NULL) return; - if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR - || pVar->nType == TSDB_DATA_TYPE_JSON) { + if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR || + pVar->nType == TSDB_DATA_TYPE_JSON) { taosMemoryFreeClear(pVar->pz); pVar->nLen = 0; } @@ -185,8 +185,8 @@ void taosVariantAssign(SVariant *pDst, const SVariant *pSrc) { if (pSrc == NULL || pDst == NULL) return; pDst->nType = pSrc->nType; - if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR - || pSrc->nType == TSDB_DATA_TYPE_JSON) { + if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR || + pSrc->nType == TSDB_DATA_TYPE_JSON) { int32_t len = pSrc->nLen + TSDB_NCHAR_SIZE; char *p = taosMemoryRealloc(pDst->pz, len); assert(p); diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index c9115d90e1..56fbafe76d 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -502,6 +502,10 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int return func(pMsgBuf, NULL, 0, param); } + if (IS_NUMERIC_TYPE(pSchema->type) && pToken->n == 0) { + return buildSyntaxErrMsg(pMsgBuf, "invalid numeric data", pToken->z); + } + switch (pSchema->type) { case TSDB_DATA_TYPE_BOOL: { if ((pToken->type == TK_NK_BOOL || pToken->type == TK_NK_STRING) && (pToken->n != 0)) { diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 5a32c87fc3..fbffaba3f0 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -2475,13 +2475,62 @@ static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) { return code; } +static EDealRes needFillImpl(SNode* pNode, void* pContext) { + if (isAggFunc(pNode)) { + *(bool*)pContext = true; + return DEAL_RES_END; + } + return DEAL_RES_CONTINUE; +} + +static bool needFill(SNode* pNode) { + bool hasFillFunc = false; + nodesWalkExpr(pNode, needFillImpl, &hasFillFunc); + return hasFillFunc; +} + +static bool mismatchFillDataType(SDataType origDt, SDataType fillDt) { + if (IS_NUMERIC_TYPE(origDt.type) && !IS_NUMERIC_TYPE(fillDt.type)) { + return true; + } + if (IS_VAR_DATA_TYPE(origDt.type) && !IS_VAR_DATA_TYPE(fillDt.type)) { + return true; + } + return false; +} + +static int32_t checkFillValues(STranslateContext* pCxt, SFillNode* pFill, SNodeList* pProjectionList) { + if (FILL_MODE_VALUE != pFill->mode) { + return TSDB_CODE_SUCCESS; + } + + int32_t fillNo = 0; + SNodeListNode* pFillValues = (SNodeListNode*)pFill->pValues; + SNode* pProject = NULL; + FOREACH(pProject, pProjectionList) { + if (needFill(pProject)) { + if (fillNo >= LIST_LENGTH(pFillValues->pNodeList)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled values number mismatch"); + } + if (mismatchFillDataType(((SExprNode*)pProject)->resType, + ((SExprNode*)nodesListGetNode(pFillValues->pNodeList, fillNo))->resType)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled data type mismatch"); + } + ++fillNo; + } + } + if (fillNo != LIST_LENGTH(pFillValues->pNodeList)) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled values number mismatch"); + } + return TSDB_CODE_SUCCESS; +} + static int32_t translateFillValues(STranslateContext* pCxt, SSelectStmt* pSelect) { if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow) || NULL == ((SIntervalWindowNode*)pSelect->pWindow)->pFill) { return TSDB_CODE_SUCCESS; } - SFillNode* pFill = (SFillNode*)((SIntervalWindowNode*)pSelect->pWindow)->pFill; - return TSDB_CODE_SUCCESS; + return checkFillValues(pCxt, (SFillNode*)((SIntervalWindowNode*)pSelect->pWindow)->pFill, pSelect->pProjectionList); } static int32_t rewriteProjectAlias(SNodeList* pProjectionList) { diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 662a3f0c88..f99d126892 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -121,7 +121,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_CONN_KILLED, "Connection killed") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR, "Syntax error in SQL") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DB_NOT_SELECTED, "Database not specified or available") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME, "Table does not exist") -TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, "SQL statement too long, check maxSQLLength config") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, "SQL statement too long") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_FILE_EMPTY, "File is empty") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_LINE_SYNTAX_ERROR, "Syntax error in Line") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_NO_META_CACHED, "No table meta cached")