diff --git a/include/common/tvariant.h b/include/common/tvariant.h index 7143d7b8fdc8214bd40134805168606e985f92f6..552c7eaa3ffc7a01c2f3415653b12f39111879d5 100644 --- a/include/common/tvariant.h +++ b/include/common/tvariant.h @@ -27,8 +27,8 @@ typedef struct SVariant { uint32_t nType; int32_t nLen; // only used for string, for number, it is useless union { - int64_t i64; - uint64_t u64; + int64_t i; + uint64_t u; double d; char *pz; wchar_t *wpz; diff --git a/include/libs/function/function.h b/include/libs/function/function.h index fecb2e87fc18d355d8b62f6b6820091792bac9ff..1d1480606e593840c92e9ccc6cf6dbb096ed5413 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -186,7 +186,6 @@ typedef struct SResultDataInfo { int32_t intermediateBytes; } SResultDataInfo; - typedef struct SMultiFunctionsDesc { bool stableQuery; bool groupbyColumn; @@ -203,6 +202,8 @@ typedef struct SMultiFunctionsDesc { bool timewindow; bool topbotQuery; bool interpQuery; + bool distinct; + bool join; } SMultiFunctionsDesc; int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength, @@ -222,6 +223,8 @@ const char* qGetFunctionName(int32_t functionId); void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc); +tExprNode* exprdup(tExprNode* pTree); + #ifdef __cplusplus } #endif diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 262479ee4af8f46ad08a5cf17aa8cb037c882bf1..d9a7b0ea419dd1f02eec7813483b42b94732329f 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -163,7 +163,6 @@ typedef struct SQueryStmtInfo { int64_t vgroupLimit; // table limit in case of super table projection query + global order + limit int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX - bool distinct; // distinct tag or not int32_t bufLen; char* buf; SArray *pUdfInfo; @@ -231,6 +230,8 @@ SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SC int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy); STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex); +SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex); + int32_t getNewResColId(); #ifdef __cplusplus diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index be2179d76054a45add0d4d33cf6627657ad6d330..3ccc4bf4cd038a54430d633b48aec27ffbd41ecf 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -56,7 +56,7 @@ int32_t qOptimizeQueryPlan(struct SQueryPlanNode* pQueryNode); * @param pQueryNode * @return */ -int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode* pQueryNode); +int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode** pQueryNode); /** * Convert the query plan to string, in order to display it in the shell. diff --git a/source/common/src/tvariant.c b/source/common/src/tvariant.c index a218353ae3c4a51a7c2a1827bb5ba8116f8f6264..ed1f4d2bfd7826514a5d9a18665f33d8b01aed54 100644 --- a/source/common/src/tvariant.c +++ b/source/common/src/tvariant.c @@ -82,9 +82,9 @@ void taosVariantCreate(SVariant *pVar, char* z, int32_t n, int32_t type) { switch (type) { case TSDB_DATA_TYPE_BOOL: { if (strncasecmp(z, "true", 4) == 0) { - pVar->i64 = TSDB_TRUE; + pVar->i = TSDB_TRUE; } else if (strncasecmp(z, "false", 5) == 0) { - pVar->i64 = TSDB_FALSE; + pVar->i = TSDB_FALSE; } else { return; } @@ -106,7 +106,7 @@ void taosVariantCreate(SVariant *pVar, char* z, int32_t n, int32_t type) { base = 2; } - ret = toInteger(z, n, base, &pVar->i64, &sign); + ret = toInteger(z, n, base, &pVar->i, &sign); if (ret != 0) { pVar->nType = -1; // -1 means error type return; @@ -127,7 +127,7 @@ void taosVariantCreate(SVariant *pVar, char* z, int32_t n, int32_t type) { } case TSDB_DATA_TYPE_TIMESTAMP: { assert(0); - pVar->i64 = taosGetTimestamp(TSDB_TIME_PRECISION_NANO); + pVar->i = taosGetTimestamp(TSDB_TIME_PRECISION_NANO); break; } @@ -151,43 +151,43 @@ void taosVariantCreateFromBinary(SVariant *pVar, const char *pz, size_t len, uin case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT: { pVar->nLen = tDataTypes[type].bytes; - pVar->i64 = GET_INT8_VAL(pz); + pVar->i = GET_INT8_VAL(pz); break; } case TSDB_DATA_TYPE_UTINYINT: { pVar->nLen = tDataTypes[type].bytes; - pVar->u64 = GET_UINT8_VAL(pz); + pVar->u = GET_UINT8_VAL(pz); break; } case TSDB_DATA_TYPE_SMALLINT: { pVar->nLen = tDataTypes[type].bytes; - pVar->i64 = GET_INT16_VAL(pz); + pVar->i = GET_INT16_VAL(pz); break; } case TSDB_DATA_TYPE_USMALLINT: { pVar->nLen = tDataTypes[type].bytes; - pVar->u64 = GET_UINT16_VAL(pz); + pVar->u = GET_UINT16_VAL(pz); break; } case TSDB_DATA_TYPE_INT: { pVar->nLen = tDataTypes[type].bytes; - pVar->i64 = GET_INT32_VAL(pz); + pVar->i = GET_INT32_VAL(pz); break; } case TSDB_DATA_TYPE_UINT: { pVar->nLen = tDataTypes[type].bytes; - pVar->u64 = GET_UINT32_VAL(pz); + pVar->u = GET_UINT32_VAL(pz); break; } case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_TIMESTAMP: { pVar->nLen = tDataTypes[type].bytes; - pVar->i64 = GET_INT64_VAL(pz); + pVar->i = GET_INT64_VAL(pz); break; } case TSDB_DATA_TYPE_UBIGINT: { pVar->nLen = tDataTypes[type].bytes; - pVar->u64 = GET_UINT64_VAL(pz); + pVar->u = GET_UINT64_VAL(pz); break; } case TSDB_DATA_TYPE_DOUBLE: { @@ -217,7 +217,7 @@ void taosVariantCreateFromBinary(SVariant *pVar, const char *pz, size_t len, uin } default: - pVar->i64 = GET_INT32_VAL(pz); + pVar->i = GET_INT32_VAL(pz); pVar->nLen = tDataTypes[TSDB_DATA_TYPE_INT].bytes; } @@ -271,7 +271,7 @@ void taosVariantAssign(SVariant *pDst, const SVariant *pSrc) { } if (IS_NUMERIC_TYPE(pSrc->nType) || (pSrc->nType == TSDB_DATA_TYPE_BOOL)) { - pDst->i64 = pSrc->i64; + pDst->i = pSrc->i; } else if (pSrc->nType == TSDB_DATA_TYPE_POINTER_ARRAY) { // this is only for string array size_t num = taosArrayGetSize(pSrc->arr); pDst->arr = taosArrayInit(num, sizeof(char*)); @@ -322,16 +322,16 @@ int32_t taosVariantCompare(const SVariant* p1, const SVariant* p2) { return p1->d > p2->d? 1:-1; } } else if (IS_UNSIGNED_NUMERIC_TYPE(p1->nType)) { - if (p1->u64 == p2->u64) { + if (p1->u == p2->u) { return 0; } else { - return p1->u64 > p2->u64? 1:-1; + return p1->u > p2->u? 1:-1; } } else { - if (p1->i64 == p2->i64) { + if (p1->i == p2->i) { return 0; } else { - return p1->i64 > p2->i64? 1:-1; + return p1->i > p2->i? 1:-1; } } } @@ -362,12 +362,12 @@ int32_t taosVariantToString(SVariant *pVar, char *dst) { case TSDB_DATA_TYPE_UTINYINT: case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_UINT: - return sprintf(dst, "%d", (int32_t)pVar->i64); + return sprintf(dst, "%d", (int32_t)pVar->i); case TSDB_DATA_TYPE_BIGINT: - return sprintf(dst, "%" PRId64, pVar->i64); + return sprintf(dst, "%" PRId64, pVar->i); case TSDB_DATA_TYPE_UBIGINT: - return sprintf(dst, "%" PRIu64, pVar->u64); + return sprintf(dst, "%" PRIu64, pVar->u); case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_DOUBLE: return sprintf(dst, "%.9lf", pVar->d); @@ -426,11 +426,11 @@ static int32_t toBinary(SVariant *pVariant, char **pDest, int32_t *pDestSize) { } else { if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType)) { - sprintf(pBuf == NULL ? *pDest : pBuf, "%" PRId64, pVariant->i64); + sprintf(pBuf == NULL ? *pDest : pBuf, "%" PRId64, pVariant->i); } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { sprintf(pBuf == NULL ? *pDest : pBuf, "%lf", pVariant->d); } else if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { - sprintf(pBuf == NULL ? *pDest : pBuf, "%s", (pVariant->i64 == TSDB_TRUE) ? "TRUE" : "FALSE"); + sprintf(pBuf == NULL ? *pDest : pBuf, "%s", (pVariant->i == TSDB_TRUE) ? "TRUE" : "FALSE"); } else if (pVariant->nType == 0) { // null data setNull(pBuf == NULL ? *pDest : pBuf, TSDB_DATA_TYPE_BINARY, 0); } @@ -452,16 +452,16 @@ static int32_t toNchar(SVariant *pVariant, char **pDest, int32_t *pDestSize) { // convert the number to string, than convert it to wchar string. if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType)) { - nLen = sprintf(pDst, "%" PRId64, pVariant->i64); + nLen = sprintf(pDst, "%" PRId64, pVariant->i); } else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) { - nLen = sprintf(pDst, "%"PRIu64, pVariant->u64); + nLen = sprintf(pDst, "%"PRIu64, pVariant->u); } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { nLen = sprintf(pDst, "%lf", pVariant->d); } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { pDst = pVariant->pz; nLen = pVariant->nLen; } else if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { - nLen = sprintf(pDst, "%s", (pVariant->i64 == TSDB_TRUE) ? "TRUE" : "FALSE"); + nLen = sprintf(pDst, "%s", (pVariant->i == TSDB_TRUE) ? "TRUE" : "FALSE"); } if (*pDest == pVariant->pz) { @@ -519,9 +519,9 @@ static FORCE_INLINE int32_t convertToInteger(SVariant *pVariant, int64_t *result #if 0 errno = 0; if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType) || (pVariant->nType == TSDB_DATA_TYPE_BOOL)) { - *result = pVariant->i64; + *result = pVariant->i; } else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) { - *result = pVariant->u64; + *result = pVariant->u; } else if (IS_FLOAT_TYPE(pVariant->nType)) { *result = (int64_t) pVariant->d; } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { @@ -639,9 +639,9 @@ static FORCE_INLINE int32_t convertToInteger(SVariant *pVariant, int64_t *result static int32_t convertToBool(SVariant *pVariant, int64_t *pDest) { if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { - *pDest = pVariant->i64; // in order to be compatible to null of bool + *pDest = pVariant->i; // in order to be compatible to null of bool } else if (IS_NUMERIC_TYPE(pVariant->nType)) { - *pDest = ((pVariant->i64 != 0) ? TSDB_TRUE : TSDB_FALSE); + *pDest = ((pVariant->i != 0) ? TSDB_TRUE : TSDB_FALSE); } else if (pVariant->nType == TSDB_DATA_TYPE_FLOAT || pVariant->nType == TSDB_DATA_TYPE_DOUBLE) { *pDest = ((pVariant->d != 0) ? TSDB_TRUE : TSDB_FALSE); } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { @@ -791,12 +791,12 @@ int32_t tVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool inc *converted = true; } - if (pVariant->i64 > FLT_MAX || pVariant->i64 < -FLT_MAX) { - SET_EXT_INFO(converted, pVariant->i64, -FLT_MAX, FLT_MAX, extInfo); + if (pVariant->i > FLT_MAX || pVariant->i < -FLT_MAX) { + SET_EXT_INFO(converted, pVariant->i, -FLT_MAX, FLT_MAX, extInfo); return -1; } - SET_FLOAT_VAL(payload, pVariant->i64); + SET_FLOAT_VAL(payload, pVariant->i); } else if (IS_FLOAT_TYPE(pVariant->nType)) { if (converted) { *converted = true; @@ -836,7 +836,7 @@ int32_t tVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool inc SET_DOUBLE_VAL(payload, value); } } else if (pVariant->nType == TSDB_DATA_TYPE_BOOL || IS_SIGNED_NUMERIC_TYPE(pVariant->nType) || IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) { - SET_DOUBLE_VAL(payload, pVariant->i64); + SET_DOUBLE_VAL(payload, pVariant->i); } else if (IS_FLOAT_TYPE(pVariant->nType)) { SET_DOUBLE_VAL(payload, pVariant->d); } else if (pVariant->nType == TSDB_DATA_TYPE_NULL) { @@ -885,7 +885,7 @@ int32_t tVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool inc if (pVariant->nType == TSDB_DATA_TYPE_NULL) { *((int64_t *)payload) = TSDB_DATA_BIGINT_NULL; } else { - *((int64_t *)payload) = pVariant->i64; + *((int64_t *)payload) = pVariant->i; } break; } @@ -951,7 +951,7 @@ int32_t taosVariantTypeSetType(SVariant *pVariant, char type) { switch (type) { case TSDB_DATA_TYPE_BOOL: { // bool - if (convertToBool(pVariant, &pVariant->i64) < 0) { + if (convertToBool(pVariant, &pVariant->i) < 0) { return -1; } @@ -962,7 +962,7 @@ int32_t taosVariantTypeSetType(SVariant *pVariant, char type) { case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_SMALLINT: { - convertToInteger(pVariant, &(pVariant->i64), type, true, true, NULL); + convertToInteger(pVariant, &(pVariant->i), type, true, true, NULL); pVariant->nType = TSDB_DATA_TYPE_BIGINT; break; } @@ -989,7 +989,7 @@ int32_t taosVariantTypeSetType(SVariant *pVariant, char type) { free(pVariant->pz); pVariant->d = v; } else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { - double tmp = (double) pVariant->i64; + double tmp = (double) pVariant->i; pVariant->d = tmp; } diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index 21d46090e561dc5457cf3cd16f70d76b706b3665..08e2172adbff44f8cb2dfc6201f06855578c37e6 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -16,7 +16,7 @@ #include "catalogInt.h" struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) { - return NULL; + return (struct SCatalog*) 0x1; } int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData) { diff --git a/source/libs/function/inc/texpr.h b/source/libs/function/inc/texpr.h index fb4ddd476c17d87a02665c5e179751414317ccdd..33190954701c92e7d9fc646c7f300f9dd5de902e 100644 --- a/source/libs/function/inc/texpr.h +++ b/source/libs/function/inc/texpr.h @@ -62,7 +62,6 @@ typedef struct SExprTraverseSupp { tExprNode* exprTreeFromBinary(const void* data, size_t size); tExprNode* exprTreeFromTableName(const char* tbnameCond); -tExprNode* exprdup(tExprNode* pTree); bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); diff --git a/source/libs/function/inc/tscalarfunction.h b/source/libs/function/inc/tscalarfunction.h index 6959bc883d216d9eba2c435d72b707224a412b1f..9c87a42cfcf536d5ae77c53d3ff6cb3c17e5fcb3 100644 --- a/source/libs/function/inc/tscalarfunction.h +++ b/source/libs/function/inc/tscalarfunction.h @@ -28,6 +28,7 @@ extern struct SScalarFunctionInfo scalarFunc[1]; #define FUNCTION_ROUND 40 #define FUNCTION_MAVG 41 #define FUNCTION_CSUM 42 +#define FUNCCTION_CONCAT 43 #ifdef __cplusplus } diff --git a/source/libs/function/src/taggfunction.c b/source/libs/function/src/taggfunction.c index c8585a7b64746c34578ea29eea67fb9d787bd6a5..f35ffe2468a94575a924c0552fdac025b1fd046d 100644 --- a/source/libs/function/src/taggfunction.c +++ b/source/libs/function/src/taggfunction.c @@ -61,7 +61,7 @@ for (int32_t _i = 0; _i < (ctx)->tagInfo.numOfTagCols; ++_i) { \ SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[_i]; \ if (__ctx->functionId == FUNCTION_TS_DUMMY) { \ - __ctx->tag.i64 = (ts); \ + __ctx->tag.i = (ts); \ __ctx->tag.nType = TSDB_DATA_TYPE_BIGINT; \ } \ aggFunc[FUNCTION_TAG].exec(__ctx); \ @@ -722,7 +722,7 @@ static int32_t firstFuncRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t c } static int32_t lastFuncRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) { - if (pCtx->order != pCtx->param[0].i64) { + if (pCtx->order != pCtx->param[0].i) { return BLK_DATA_NO_NEEDED; } @@ -754,7 +754,7 @@ static int32_t firstDistFuncRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32 } static int32_t lastDistFuncRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) { - if (pCtx->order != pCtx->param[0].i64) { + if (pCtx->order != pCtx->param[0].i) { return BLK_DATA_NO_NEEDED; } @@ -953,7 +953,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, for (int32_t i = 0; i < (pCtx)->tagInfo.numOfTagCols; ++i) { SQLFunctionCtx *__ctx = pCtx->tagInfo.pTagCtxList[i]; if (__ctx->functionId == FUNCTION_TS_DUMMY) { - __ctx->tag.i64 = key; + __ctx->tag.i = key; __ctx->tag.nType = TSDB_DATA_TYPE_BIGINT; } @@ -1532,7 +1532,7 @@ static bool first_last_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* // used to keep the timestamp for comparison pCtx->param[1].nType = 0; - pCtx->param[1].i64 = 0; + pCtx->param[1].i = 0; return true; } @@ -1628,9 +1628,9 @@ static void first_dist_func_merge(SQLFunctionCtx *pCtx) { } // The param[1] is used to keep the initial value of max ts value - if (pCtx->param[1].nType != pCtx->outputType || pCtx->param[1].i64 > pInput->ts) { + if (pCtx->param[1].nType != pCtx->outputType || pCtx->param[1].i > pInput->ts) { memcpy(pCtx->pOutput, pData, pCtx->outputBytes); - pCtx->param[1].i64 = pInput->ts; + pCtx->param[1].i = pInput->ts; pCtx->param[1].nType = pCtx->outputType; DO_UPDATE_TAG_COLUMNS(pCtx, pInput->ts); @@ -1649,7 +1649,7 @@ static void first_dist_func_merge(SQLFunctionCtx *pCtx) { * least one data in this block that is not null.(TODO opt for this case) */ static void last_function(SQLFunctionCtx *pCtx) { - if (pCtx->order != pCtx->param[0].i64) { + if (pCtx->order != pCtx->param[0].i) { return; } @@ -1723,7 +1723,7 @@ static void last_dist_function(SQLFunctionCtx *pCtx) { * 1. for scan data is not the required order * 2. for data blocks that are not loaded, no need to check data */ - if (pCtx->order != pCtx->param[0].i64) { + if (pCtx->order != pCtx->param[0].i) { return; } @@ -1765,9 +1765,9 @@ static void last_dist_func_merge(SQLFunctionCtx *pCtx) { * param[1] used to keep the corresponding timestamp to decide if current result is * the true last result */ - if (pCtx->param[1].nType != pCtx->outputType || pCtx->param[1].i64 < pInput->ts) { + if (pCtx->param[1].nType != pCtx->outputType || pCtx->param[1].i < pInput->ts) { memcpy(pCtx->pOutput, pData, pCtx->outputBytes); - pCtx->param[1].i64 = pInput->ts; + pCtx->param[1].i = pInput->ts; pCtx->param[1].nType = pCtx->outputType; DO_UPDATE_TAG_COLUMNS(pCtx, pInput->ts); @@ -1822,7 +1822,7 @@ static void last_row_finalizer(SQLFunctionCtx *pCtx) { static void valuePairAssign(tValuePair *dst, int16_t type, const char *val, int64_t tsKey, char *pTags, SExtTagsInfo *pTagInfo, int16_t stage) { dst->v.nType = type; - dst->v.i64 = *(int64_t *)val; + dst->v.i = *(int64_t *)val; dst->timestamp = tsKey; int32_t size = 0; @@ -1833,7 +1833,7 @@ static void valuePairAssign(tValuePair *dst, int16_t type, const char *val, int6 SQLFunctionCtx* ctx = pTagInfo->pTagCtxList[i]; if (ctx->functionId == FUNCTION_TS_DUMMY) { ctx->tag.nType = TSDB_DATA_TYPE_BIGINT; - ctx->tag.i64 = tsKey; + ctx->tag.i = tsKey; } taosVariantDump(&ctx->tag, dst->pTags + size, ctx->tag.nType, true); @@ -1856,17 +1856,17 @@ static int32_t topBotComparFn(const void *p1, const void *p2, const void *param) tValuePair *val2 = *(tValuePair **) p2; if (IS_SIGNED_NUMERIC_TYPE(type)) { - if (val1->v.i64 == val2->v.i64) { + if (val1->v.i == val2->v.i) { return 0; } - return (val1->v.i64 > val2->v.i64) ? 1 : -1; + return (val1->v.i > val2->v.i) ? 1 : -1; } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - if (val1->v.u64 == val2->v.u64) { + if (val1->v.u == val2->v.u) { return 0; } - return (val1->v.u64 > val2->v.u64) ? 1 : -1; + return (val1->v.u > val2->v.u) ? 1 : -1; } if (val1->v.d == val2->v.d) { @@ -1901,16 +1901,16 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData, assert(pList != NULL); if (pInfo->num < maxLen) { - valuePairAssign(pList[pInfo->num], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage); + valuePairAssign(pList[pInfo->num], type, (const char *)&val.i, ts, pTags, pTagInfo, stage); taosheapsort((void *) pList, sizeof(tValuePair **), pInfo->num + 1, (const void *) &type, topBotComparFn, (const void *) &pTagInfo->tagsLen, topBotSwapFn, 0); pInfo->num++; } else { - if ((IS_SIGNED_NUMERIC_TYPE(type) && val.i64 > pList[0]->v.i64) || - (IS_UNSIGNED_NUMERIC_TYPE(type) && val.u64 > pList[0]->v.u64) || + if ((IS_SIGNED_NUMERIC_TYPE(type) && val.i > pList[0]->v.i) || + (IS_UNSIGNED_NUMERIC_TYPE(type) && val.u > pList[0]->v.u) || (IS_FLOAT_TYPE(type) && val.d > pList[0]->v.d)) { - valuePairAssign(pList[0], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage); + valuePairAssign(pList[0], type, (const char *)&val.i, ts, pTags, pTagInfo, stage); taosheapadjust((void *) pList, sizeof(tValuePair **), 0, maxLen - 1, (const void *) &type, topBotComparFn, (const void *) &pTagInfo->tagsLen, topBotSwapFn, 0); } } @@ -1925,16 +1925,16 @@ static void do_bottom_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pDa assert(pList != NULL); if (pInfo->num < maxLen) { - valuePairAssign(pList[pInfo->num], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage); + valuePairAssign(pList[pInfo->num], type, (const char *)&val.i, ts, pTags, pTagInfo, stage); taosheapsort((void *) pList, sizeof(tValuePair **), pInfo->num + 1, (const void *) &type, topBotComparFn, (const void *) &pTagInfo->tagsLen, topBotSwapFn, 1); pInfo->num++; } else { - if ((IS_SIGNED_NUMERIC_TYPE(type) && val.i64 < pList[0]->v.i64) || - (IS_UNSIGNED_NUMERIC_TYPE(type) && val.u64 < pList[0]->v.u64) || + if ((IS_SIGNED_NUMERIC_TYPE(type) && val.i < pList[0]->v.i) || + (IS_UNSIGNED_NUMERIC_TYPE(type) && val.u < pList[0]->v.u) || (IS_FLOAT_TYPE(type) && val.d < pList[0]->v.d)) { - valuePairAssign(pList[0], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage); + valuePairAssign(pList[0], type, (const char *)&val.i, ts, pTags, pTagInfo, stage); taosheapadjust((void *) pList, sizeof(tValuePair **), 0, maxLen - 1, (const void *) &type, topBotComparFn, (const void *) &pTagInfo->tagsLen, topBotSwapFn, 1); } } @@ -1964,16 +1964,16 @@ static int32_t resDataAscComparFn(const void *pLeft, const void *pRight) { return pLeftElem->v.d > pRightElem->v.d ? 1 : -1; } } else if (IS_SIGNED_NUMERIC_TYPE(pLeftElem->v.nType)){ - if (pLeftElem->v.i64 == pRightElem->v.i64) { + if (pLeftElem->v.i == pRightElem->v.i) { return 0; } else { - return pLeftElem->v.i64 > pRightElem->v.i64 ? 1 : -1; + return pLeftElem->v.i > pRightElem->v.i ? 1 : -1; } } else { - if (pLeftElem->v.u64 == pRightElem->v.u64) { + if (pLeftElem->v.u == pRightElem->v.u) { return 0; } else { - return pLeftElem->v.u64 > pRightElem->v.u64 ? 1 : -1; + return pLeftElem->v.u > pRightElem->v.u ? 1 : -1; } } } @@ -1994,7 +1994,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) { case TSDB_DATA_TYPE_INT: { int32_t *output = (int32_t *)pCtx->pOutput; for (int32_t i = 0; i < len; ++i, output += step) { - *output = (int32_t)tvp[i]->v.i64; + *output = (int32_t)tvp[i]->v.i; } break; } @@ -2002,7 +2002,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) { case TSDB_DATA_TYPE_BIGINT: { int64_t *output = (int64_t *)pCtx->pOutput; for (int32_t i = 0; i < len; ++i, output += step) { - *output = tvp[i]->v.i64; + *output = tvp[i]->v.i; } break; } @@ -2024,7 +2024,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) { case TSDB_DATA_TYPE_SMALLINT: { int16_t *output = (int16_t *)pCtx->pOutput; for (int32_t i = 0; i < len; ++i, output += step) { - *output = (int16_t)tvp[i]->v.i64; + *output = (int16_t)tvp[i]->v.i; } break; } @@ -2032,7 +2032,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) { case TSDB_DATA_TYPE_TINYINT: { int8_t *output = (int8_t *)pCtx->pOutput; for (int32_t i = 0; i < len; ++i, output += step) { - *output = (int8_t)tvp[i]->v.i64; + *output = (int8_t)tvp[i]->v.i; } break; } @@ -2096,11 +2096,11 @@ static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) { static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) { char *tmp = (char *)pTopBotInfo + sizeof(STopBotInfo); pTopBotInfo->res = (tValuePair**) tmp; - tmp += POINTER_BYTES * pCtx->param[0].i64; + tmp += POINTER_BYTES * pCtx->param[0].i; size_t size = sizeof(tValuePair) + pCtx->tagInfo.tagsLen; - for (int32_t i = 0; i < pCtx->param[0].i64; ++i) { + for (int32_t i = 0; i < pCtx->param[0].i; ++i) { pTopBotInfo->res[i] = (tValuePair*) tmp; pTopBotInfo->res[i]->pTags = tmp + sizeof(tValuePair); tmp += size; @@ -2116,11 +2116,11 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha STopBotInfo *pTopBotInfo = getTopBotOutputInfo(pCtx); // required number of results are not reached, continue load data block - if (pTopBotInfo->num < pCtx->param[0].i64) { + if (pTopBotInfo->num < pCtx->param[0].i) { return true; } - if ((void *)pTopBotInfo->res[0] != (void *)((char *)pTopBotInfo + sizeof(STopBotInfo) + POINTER_BYTES * pCtx->param[0].i64)) { + if ((void *)pTopBotInfo->res[0] != (void *)((char *)pTopBotInfo + sizeof(STopBotInfo) + POINTER_BYTES * pCtx->param[0].i)) { buildTopBotStruct(pTopBotInfo, pCtx); } @@ -2129,13 +2129,13 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha if (pCtx->functionId == FUNCTION_TOP) { switch (pCtx->inputType) { case TSDB_DATA_TYPE_TINYINT: - return GET_INT8_VAL(maxval) > pRes[0]->v.i64; + return GET_INT8_VAL(maxval) > pRes[0]->v.i; case TSDB_DATA_TYPE_SMALLINT: - return GET_INT16_VAL(maxval) > pRes[0]->v.i64; + return GET_INT16_VAL(maxval) > pRes[0]->v.i; case TSDB_DATA_TYPE_INT: - return GET_INT32_VAL(maxval) > pRes[0]->v.i64; + return GET_INT32_VAL(maxval) > pRes[0]->v.i; case TSDB_DATA_TYPE_BIGINT: - return GET_INT64_VAL(maxval) > pRes[0]->v.i64; + return GET_INT64_VAL(maxval) > pRes[0]->v.i; case TSDB_DATA_TYPE_FLOAT: return GET_FLOAT_VAL(maxval) > pRes[0]->v.d; case TSDB_DATA_TYPE_DOUBLE: @@ -2146,13 +2146,13 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha } else { switch (pCtx->inputType) { case TSDB_DATA_TYPE_TINYINT: - return GET_INT8_VAL(minval) < pRes[0]->v.i64; + return GET_INT8_VAL(minval) < pRes[0]->v.i; case TSDB_DATA_TYPE_SMALLINT: - return GET_INT16_VAL(minval) < pRes[0]->v.i64; + return GET_INT16_VAL(minval) < pRes[0]->v.i; case TSDB_DATA_TYPE_INT: - return GET_INT32_VAL(minval) < pRes[0]->v.i64; + return GET_INT32_VAL(minval) < pRes[0]->v.i; case TSDB_DATA_TYPE_BIGINT: - return GET_INT64_VAL(minval) < pRes[0]->v.i64; + return GET_INT64_VAL(minval) < pRes[0]->v.i; case TSDB_DATA_TYPE_FLOAT: return GET_FLOAT_VAL(minval) < pRes[0]->v.d; case TSDB_DATA_TYPE_DOUBLE: @@ -2179,7 +2179,7 @@ static void top_function(SQLFunctionCtx *pCtx) { STopBotInfo *pRes = getTopBotOutputInfo(pCtx); assert(pRes->num >= 0); - if ((void *)pRes->res[0] != (void *)((char *)pRes + sizeof(STopBotInfo) + POINTER_BYTES * pCtx->param[0].i64)) { + if ((void *)pRes->res[0] != (void *)((char *)pRes + sizeof(STopBotInfo) + POINTER_BYTES * pCtx->param[0].i)) { buildTopBotStruct(pRes, pCtx); } @@ -2193,7 +2193,7 @@ static void top_function(SQLFunctionCtx *pCtx) { // NOTE: Set the default timestamp if it is missing [todo refactor] TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0; - do_top_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0); + do_top_function_add(pRes, (int32_t)pCtx->param[0].i, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0); } if (!pCtx->hasNull) { @@ -2220,7 +2220,7 @@ static void top_func_merge(SQLFunctionCtx *pCtx) { // the intermediate result is binary, we only use the output data type for (int32_t i = 0; i < pInput->num; ++i) { int16_t type = (pCtx->outputType == TSDB_DATA_TYPE_FLOAT)? TSDB_DATA_TYPE_DOUBLE:pCtx->outputType; - do_top_function_add(pOutput, (int32_t)pCtx->param[0].i64, &pInput->res[i]->v.i64, pInput->res[i]->timestamp, + do_top_function_add(pOutput, (int32_t)pCtx->param[0].i, &pInput->res[i]->v.i, pInput->res[i]->timestamp, type, &pCtx->tagInfo, pInput->res[i]->pTags, pCtx->currentStage); } @@ -2237,7 +2237,7 @@ static void bottom_function(SQLFunctionCtx *pCtx) { STopBotInfo *pRes = getTopBotOutputInfo(pCtx); - if ((void *)pRes->res[0] != (void *)((char *)pRes + sizeof(STopBotInfo) + POINTER_BYTES * pCtx->param[0].i64)) { + if ((void *)pRes->res[0] != (void *)((char *)pRes + sizeof(STopBotInfo) + POINTER_BYTES * pCtx->param[0].i)) { buildTopBotStruct(pRes, pCtx); } @@ -2250,7 +2250,7 @@ static void bottom_function(SQLFunctionCtx *pCtx) { notNullElems++; // NOTE: Set the default timestamp if it is missing [todo refactor] TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0; - do_bottom_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0); + do_bottom_function_add(pRes, (int32_t)pCtx->param[0].i, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0); } if (!pCtx->hasNull) { @@ -2277,7 +2277,7 @@ static void bottom_func_merge(SQLFunctionCtx *pCtx) { // the intermediate result is binary, we only use the output data type for (int32_t i = 0; i < pInput->num; ++i) { int16_t type = (pCtx->outputType == TSDB_DATA_TYPE_FLOAT) ? TSDB_DATA_TYPE_DOUBLE : pCtx->outputType; - do_bottom_function_add(pOutput, (int32_t)pCtx->param[0].i64, &pInput->res[i]->v.i64, pInput->res[i]->timestamp, type, + do_bottom_function_add(pOutput, (int32_t)pCtx->param[0].i, &pInput->res[i]->v.i, pInput->res[i]->timestamp, type, &pCtx->tagInfo, pInput->res[i]->pTags, pCtx->currentStage); } @@ -2303,11 +2303,11 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) { tValuePair **tvp = pRes->res; // user specify the order of output by sort the result according to timestamp - if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_ID) { - __compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn; + if (pCtx->param[1].i == PRIMARYKEY_TIMESTAMP_COL_ID) { + __compar_fn_t comparator = (pCtx->param[2].i == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn; qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); - } else /*if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_ID)*/ { - __compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn; + } else /*if (pCtx->param[1].i > PRIMARYKEY_TIMESTAMP_COL_ID)*/ { + __compar_fn_t comparator = (pCtx->param[2].i == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn; qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); } @@ -2418,7 +2418,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) { } static void percentile_finalizer(SQLFunctionCtx *pCtx) { - double v = pCtx->param[0].nType == TSDB_DATA_TYPE_INT ? pCtx->param[0].i64 : pCtx->param[0].d; + double v = pCtx->param[0].nType == TSDB_DATA_TYPE_INT ? pCtx->param[0].i : pCtx->param[0].d; SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SPercentileInfo* ppInfo = (SPercentileInfo *) GET_ROWCELL_INTERBUF(pResInfo); @@ -2530,7 +2530,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) { } static void apercentile_finalizer(SQLFunctionCtx *pCtx) { - double v = (pCtx->param[0].nType == TSDB_DATA_TYPE_INT) ? pCtx->param[0].i64 : pCtx->param[0].d; + double v = (pCtx->param[0].nType == TSDB_DATA_TYPE_INT) ? pCtx->param[0].i : pCtx->param[0].d; SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SAPercentileInfo *pOutput = GET_ROWCELL_INTERBUF(pResInfo); @@ -2725,7 +2725,7 @@ static void col_project_function(SQLFunctionCtx *pCtx) { } // only one row is required. - if (pCtx->param[0].i64 == 1) { + if (pCtx->param[0].i == 1) { SET_VAL(pCtx, pCtx->size, 1); } else { INC_INIT_VAL(pCtx, pCtx->size); @@ -2733,7 +2733,7 @@ static void col_project_function(SQLFunctionCtx *pCtx) { char *pData = GET_INPUT_DATA_LIST(pCtx); if (pCtx->order == TSDB_ORDER_ASC) { - int32_t numOfRows = (pCtx->param[0].i64 == 1)? 1:pCtx->size; + int32_t numOfRows = (pCtx->param[0].i == 1)? 1:pCtx->size; memcpy(pCtx->pOutput, pData, (size_t) numOfRows * pCtx->inputBytes); } else { for(int32_t i = 0; i < pCtx->size; ++i) { @@ -2811,9 +2811,9 @@ static bool deriv_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResu // diff function require the value is set to -1 SDerivInfo* pDerivInfo = GET_ROWCELL_INTERBUF(pResultInfo); - pDerivInfo->ignoreNegative = pCtx->param[1].i64; + pDerivInfo->ignoreNegative = pCtx->param[1].i; pDerivInfo->prevTs = -1; - pDerivInfo->tsWindow = pCtx->param[0].i64; + pDerivInfo->tsWindow = pCtx->param[0].i; pDerivInfo->valueSet = false; return false; } @@ -3004,10 +3004,10 @@ static void deriv_function(SQLFunctionCtx *pCtx) { do { \ if ((ctx)->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { \ (ctx)->param[1].nType = (ctx)->inputType; \ - *(type *)&(ctx)->param[1].i64 = *(type *)(d); \ + *(type *)&(ctx)->param[1].i = *(type *)(d); \ } else { \ - *(type *)(ctx)->pOutput = *(type *)(d) - (*(type *)(&(ctx)->param[1].i64)); \ - *(type *)(&(ctx)->param[1].i64) = *(type *)(d); \ + *(type *)(ctx)->pOutput = *(type *)(d) - (*(type *)(&(ctx)->param[1].i)); \ + *(type *)(&(ctx)->param[1].i) = *(type *)(d); \ *(int64_t *)(ctx)->ptsOutputBuf = GET_TS_DATA(ctx, index); \ } \ } while (0); @@ -3036,13 +3036,13 @@ static void diff_function(SQLFunctionCtx *pCtx) { } if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet - *pOutput = (int32_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null + *pOutput = (int32_t)(pData[i] - pCtx->param[1].i); // direct previous may be null *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } - pCtx->param[1].i64 = pData[i]; + pCtx->param[1].i = pData[i]; pCtx->param[1].nType = pCtx->inputType; notNullElems++; } @@ -3058,13 +3058,13 @@ static void diff_function(SQLFunctionCtx *pCtx) { } if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet - *pOutput = pData[i] - pCtx->param[1].i64; // direct previous may be null + *pOutput = pData[i] - pCtx->param[1].i; // direct previous may be null *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } - pCtx->param[1].i64 = pData[i]; + pCtx->param[1].i = pData[i]; pCtx->param[1].nType = pCtx->inputType; notNullElems++; } @@ -3124,13 +3124,13 @@ static void diff_function(SQLFunctionCtx *pCtx) { } if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet - *pOutput = (int16_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null + *pOutput = (int16_t)(pData[i] - pCtx->param[1].i); // direct previous may be null *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } - pCtx->param[1].i64 = pData[i]; + pCtx->param[1].i = pData[i]; pCtx->param[1].nType = pCtx->inputType; notNullElems++; } @@ -3147,13 +3147,13 @@ static void diff_function(SQLFunctionCtx *pCtx) { } if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet - *pOutput = (int8_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null + *pOutput = (int8_t)(pData[i] - pCtx->param[1].i); // direct previous may be null *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } - pCtx->param[1].i64 = pData[i]; + pCtx->param[1].i = pData[i]; pCtx->param[1].nType = pCtx->inputType; notNullElems++; } @@ -3707,7 +3707,7 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) { */ static void interp_function_impl(SQLFunctionCtx *pCtx) { - int32_t type = (int32_t) pCtx->param[2].i64; + int32_t type = (int32_t) pCtx->param[2].i; if (type == TSDB_FILL_NONE) { return; } @@ -3891,11 +3891,11 @@ static void ts_comp_function(SQLFunctionCtx *pCtx) { // primary ts must be existed, so no need to check its existance if (pCtx->order == TSDB_ORDER_ASC) { - tsBufAppend(pTSbuf, (int32_t)pCtx->param[0].i64, &pCtx->tag, input, pCtx->size * TSDB_KEYSIZE); + tsBufAppend(pTSbuf, (int32_t)pCtx->param[0].i, &pCtx->tag, input, pCtx->size * TSDB_KEYSIZE); } else { for (int32_t i = pCtx->size - 1; i >= 0; --i) { char *d = GET_INPUT_DATA(pCtx, i); - tsBufAppend(pTSbuf, (int32_t)pCtx->param[0].i64, &pCtx->tag, d, (int32_t)TSDB_KEYSIZE); + tsBufAppend(pTSbuf, (int32_t)pCtx->param[0].i, &pCtx->tag, d, (int32_t)TSDB_KEYSIZE); } } @@ -4047,7 +4047,7 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) { return; } - SET_DOUBLE_VAL((double*) pCtx->pOutput, do_calc_rate(pRateInfo, (double) TSDB_TICK_PER_SECOND(pCtx->param[0].i64))); + SET_DOUBLE_VAL((double*) pCtx->pOutput, do_calc_rate(pRateInfo, (double) TSDB_TICK_PER_SECOND(pCtx->param[0].i))); // cannot set the numOfIteratedElems again since it is set during previous iteration pResInfo->numOfRes = 1; @@ -4144,7 +4144,7 @@ static void blockInfo_func(SQLFunctionCtx* pCtx) { int32_t len = *(int32_t*) pCtx->pInput; blockDistInfoFromBinary((char*)pCtx->pInput + sizeof(int32_t), len, pDist); - pDist->rowSize = (uint16_t)pCtx->param[0].i64; + pDist->rowSize = (uint16_t)pCtx->param[0].i; memcpy(pCtx->pOutput, pCtx->pInput, sizeof(int32_t) + len); @@ -4296,7 +4296,7 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) { SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo); - pDist->rowSize = (uint16_t)pCtx->param[0].i64; + pDist->rowSize = (uint16_t)pCtx->param[0].i; generateBlockDistResult(pDist, pCtx->pOutput); if (pDist->dataBlockInfos != NULL) { diff --git a/source/libs/function/src/texpr.c b/source/libs/function/src/texpr.c index cfddb81683adcb20c8e5c48bff3a7b88ace26a81..f02e5e77f5469219b669ec1fc5a3ed1f0ba68204 100644 --- a/source/libs/function/src/texpr.c +++ b/source/libs/function/src/texpr.c @@ -228,7 +228,7 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, } else if (pRight->nodeType == TEXPR_VALUE_NODE) { // exprLeft + 12 _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); - OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, &pRight->pVal->i64, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); + OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, &pRight->pVal->i, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); } } else if (pLeft->nodeType == TEXPR_COL_NODE) { // column data specified on left-hand-side @@ -255,16 +255,16 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, if (order == TSDB_ORDER_DESC) { reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows); - OperatorFn(pdata, numOfRows, pLeft->pSchema->type, &pRight->pVal->i64, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); + OperatorFn(pdata, numOfRows, pLeft->pSchema->type, &pRight->pVal->i, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); } else { - OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, &pRight->pVal->i64, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); + OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, &pRight->pVal->i, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); } } } else { // column data specified on left-hand-side if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) { // 12 + expr2 _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); - OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC); + OperatorFn(&pLeft->pVal->i, 1, pLeft->pVal->nType, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC); } else if (pRight->nodeType == TEXPR_COL_NODE) { // 12 + columnRight // column data specified on right-hand-side @@ -273,14 +273,14 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, if (order == TSDB_ORDER_DESC) { reverseCopy(pdata, pRightInputData, pRight->pSchema->type, numOfRows); - OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, pdata, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC); + OperatorFn(&pLeft->pVal->i, 1, pLeft->pVal->nType, pdata, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC); } else { - OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, pRightInputData, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC); + OperatorFn(&pLeft->pVal->i, 1, pLeft->pVal->nType, pRightInputData, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC); } } else if (pRight->nodeType == TEXPR_VALUE_NODE) { // 12 + 12 _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); - OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, &pRight->pVal->i64, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); + OperatorFn(&pLeft->pVal->i, 1, pLeft->pVal->nType, &pRight->pVal->i, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); } } @@ -302,7 +302,7 @@ static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) { tbufWriteInt32(bw, pVal->nLen); tbufWrite(bw, pVal->pz, pVal->nLen); } else { - tbufWriteInt64(bw, pVal->i64); + tbufWriteInt64(bw, pVal->i); } } else if (expr->nodeType == TEXPR_COL_NODE) { @@ -371,7 +371,7 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) { pVal->pz = calloc(1, pVal->nLen + 1); tbufReadToBuffer(br, pVal->pz, pVal->nLen); } else { - pVal->i64 = tbufReadInt64(br); + pVal->i = tbufReadInt64(br); } } else if (pExpr->nodeType == TEXPR_COL_NODE) { diff --git a/source/libs/function/src/ttszip.c b/source/libs/function/src/ttszip.c index fed857a8e7f72b389e16bce8ddd171d1e9f8ef0b..41eebc5da44c6114086a01a3560c3848968f4b00 100644 --- a/source/libs/function/src/ttszip.c +++ b/source/libs/function/src/ttszip.c @@ -276,7 +276,7 @@ static void writeDataToDisk(STSBuf* pTSBuf) { metaLen += (int32_t)fwrite(&tfloat, 1, (size_t) pBlock->tag.nLen, pTSBuf->f); } else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) { metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f); - metaLen += (int32_t)fwrite(&pBlock->tag.i64, 1, (size_t) pBlock->tag.nLen, pTSBuf->f); + metaLen += (int32_t)fwrite(&pBlock->tag.i, 1, (size_t) pBlock->tag.nLen, pTSBuf->f); } else { trueLen = 0; metaLen += (int32_t)fwrite(&trueLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f); @@ -364,7 +364,7 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) { pBlock->tag.d = (double)tfloat; UNUSED(sz); } else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) { //TODO check the return value - sz = fread(&pBlock->tag.i64, (size_t) pBlock->tag.nLen, 1, pTSBuf->f); + sz = fread(&pBlock->tag.i, (size_t) pBlock->tag.nLen, 1, pTSBuf->f); UNUSED(sz); } @@ -984,7 +984,7 @@ void tsBufDisplay(STSBuf* pTSBuf) { while (tsBufNextPos(pTSBuf)) { STSElem elem = tsBufGetElem(pTSBuf); if (elem.tag->nType == TSDB_DATA_TYPE_BIGINT) { - printf("%d-%" PRId64 "-%" PRId64 "\n", elem.id, elem.tag->i64, elem.ts); + printf("%d-%" PRId64 "-%" PRId64 "\n", elem.id, elem.tag->i, elem.ts); } } diff --git a/source/libs/parser/inc/queryInfoUtil.h b/source/libs/parser/inc/queryInfoUtil.h index fc892762cdbc292a0e5ef41ccf0e9f714b7c31ba..d75637e3c5c20f65e60185c5beca331c0b6cd690 100644 --- a/source/libs/parser/inc/queryInfoUtil.h +++ b/source/libs/parser/inc/queryInfoUtil.h @@ -27,7 +27,6 @@ int32_t getNumOfColumns(const STableMeta* pTableMeta); int32_t getNumOfTags(const STableMeta* pTableMeta); SSchema *getTableColumnSchema(const STableMeta *pTableMeta); SSchema *getTableTagSchema(const STableMeta* pTableMeta); -SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex); size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo); SExprInfo* createBinaryExprInfo(struct tExprNode* pNode, SSchema* pResSchema); diff --git a/source/libs/parser/src/astGenerator.c b/source/libs/parser/src/astGenerator.c index 6228212c4b5ae6f549b581b5a9404ef13e973c79..c574f75d070bc41b2a0e96734c806df5f823d3de 100644 --- a/source/libs/parser/src/astGenerator.c +++ b/source/libs/parser/src/astGenerator.c @@ -375,25 +375,25 @@ void tSqlExprEvaluate(tSqlExpr* pExpr) { switch (optrType) { case TK_PLUS: { - pExpr->value.i64 = pLeft->value.i64 + pRight->value.i64; + pExpr->value.i = pLeft->value.i + pRight->value.i; break; } case TK_MINUS: { - pExpr->value.i64 = pLeft->value.i64 - pRight->value.i64; + pExpr->value.i = pLeft->value.i - pRight->value.i; break; } case TK_STAR: { - pExpr->value.i64 = pLeft->value.i64 * pRight->value.i64; + pExpr->value.i = pLeft->value.i * pRight->value.i; break; } case TK_DIVIDE: { pExpr->tokenId = TK_FLOAT; pExpr->value.nType = TSDB_DATA_TYPE_DOUBLE; - pExpr->value.d = (double)pLeft->value.i64 / pRight->value.i64; + pExpr->value.d = (double)pLeft->value.i / pRight->value.i; break; } case TK_REM: { - pExpr->value.i64 = pLeft->value.i64 % pRight->value.i64; + pExpr->value.i = pLeft->value.i % pRight->value.i; break; } default: @@ -411,8 +411,8 @@ void tSqlExprEvaluate(tSqlExpr* pExpr) { pExpr->tokenId = TK_FLOAT; pExpr->type = SQL_NODE_VALUE; - double left = (pLeft->value.nType == TSDB_DATA_TYPE_DOUBLE) ? pLeft->value.d : pLeft->value.i64; - double right = (pRight->value.nType == TSDB_DATA_TYPE_DOUBLE) ? pRight->value.d : pRight->value.i64; + double left = (pLeft->value.nType == TSDB_DATA_TYPE_DOUBLE) ? pLeft->value.d : pLeft->value.i; + double right = (pRight->value.nType == TSDB_DATA_TYPE_DOUBLE) ? pRight->value.d : pRight->value.i; switch (optrType) { case TK_PLUS: { diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c index aaecf5c8a55b915acb08e217668c399b0c8e9b09..26ab04cb85469204501d741e52cc38198b423461 100644 --- a/source/libs/parser/src/astValidate.c +++ b/source/libs/parser/src/astValidate.c @@ -36,6 +36,8 @@ #define COLUMN_INDEX_INITIALIZER { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL } static int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, bool outerQuery, SMsgBuf* pMsgBuf); +static int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId, STableMetaInfo** pTableMetaInfo, SSchema* columnSchema, + tExprNode** pNode, SColumnIndex* pIndex, tSqlExprItem* pParamElem, SMsgBuf* pMsgBuf); void setTokenAndResColumnName(tSqlExprItem* pItem, char* resColumnName, char* rawName, int32_t nameLength) { memset(resColumnName, 0, nameLength); @@ -51,19 +53,15 @@ void setTokenAndResColumnName(tSqlExprItem* pItem, char* resColumnName, char* ra } } -size_t tscNumOfExprs(SQueryStmtInfo* pQueryInfo) { - return taosArrayGetSize(pQueryInfo->exprList); -} - -static int32_t evaluateImpl(tSqlExpr* pExpr, int32_t tsPrecision) { +static int32_t evaluateSqlNodeImpl(tSqlExpr* pExpr, int32_t tsPrecision) { int32_t code = 0; if (pExpr->type == SQL_NODE_EXPR) { - code = evaluateImpl(pExpr->pLeft, tsPrecision); + code = evaluateSqlNodeImpl(pExpr->pLeft, tsPrecision); if (code != TSDB_CODE_SUCCESS) { return code; } - code = evaluateImpl(pExpr->pRight, tsPrecision); + code = evaluateSqlNodeImpl(pExpr->pRight, tsPrecision); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -84,13 +82,13 @@ static int32_t evaluateImpl(tSqlExpr* pExpr, int32_t tsPrecision) { } } else if (pExpr->type == SQL_NODE_VALUE) { if (pExpr->tokenId == TK_NOW) { - pExpr->value.i64 = taosGetTimestamp(tsPrecision); + pExpr->value.i = taosGetTimestamp(tsPrecision); pExpr->value.nType = TSDB_DATA_TYPE_BIGINT; pExpr->tokenId = TK_TIMESTAMP; } else if (pExpr->tokenId == TK_VARIABLE) { char unit = 0; SToken* pToken = &pExpr->exprToken; - int32_t ret = parseAbsoluteDuration(pToken->z, pToken->n, &pExpr->value.i64, &unit, tsPrecision); + int32_t ret = parseAbsoluteDuration(pToken->z, pToken->n, &pExpr->value.i, &unit, tsPrecision); if (ret != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } @@ -109,28 +107,18 @@ static int32_t evaluateImpl(tSqlExpr* pExpr, int32_t tsPrecision) { return TSDB_CODE_SUCCESS; // other types of data are handled in the parent level. - } - - return TSDB_CODE_SUCCESS; -} - -typedef struct SVgroupTableInfo { - SVgroupMsg vgInfo; - SArray *itemList; // SArray -} SVgroupTableInfo; - -void freeVgroupTableInfo(SArray* pVgroupTables) { - if (pVgroupTables == NULL) { - return; - } + } else if (pExpr->type == SQL_NODE_SQLFUNCTION) { + SArray* pParam = pExpr->Expr.paramList; - size_t num = taosArrayGetSize(pVgroupTables); - for (size_t i = 0; i < num; i++) { - SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTables, i); - taosArrayDestroy(pInfo->itemList); + if (pParam != NULL) { + for (int32_t i = 0; i < taosArrayGetSize(pParam); ++i) { + tSqlExprItem* pItem = taosArrayGet(pParam, i); + evaluateSqlNodeImpl(pItem->pNode, tsPrecision); + } + } } - taosArrayDestroy(pVgroupTables); + return TSDB_CODE_SUCCESS; } void destroyFilterInfo(SColumnFilterList* pFilterList) { @@ -183,7 +171,7 @@ void clearTableMetaInfo(STableMetaInfo* pTableMetaInfo) { } static STableMeta* extractTempTableMetaFromSubquery(SQueryStmtInfo* pUpstream) { - STableMetaInfo* pUpstreamTableMetaInfo /*= getMetaInfo(pUpstream, 0)*/; + STableMetaInfo* pUpstreamTableMetaInfo = getMetaInfo(pUpstream, 0); int32_t numOfColumns = pUpstream->fieldsInfo.numOfOutput; STableMeta *meta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * numOfColumns); @@ -196,20 +184,14 @@ static STableMeta* extractTempTableMetaFromSubquery(SQueryStmtInfo* pUpstream) { int32_t n = 0; for(int32_t i = 0; i < numOfColumns; ++i) { -// SInternalField* pField = tscFieldInfoGetInternalField(&pUpstream->fieldsInfo, i); -// if (!pField->visible) { -// continue; -// } -// -// meta->schema[n].bytes = pField->field.bytes; -// meta->schema[n].type = pField->field.type; -// -// SExprInfo* pExpr = pField->pExpr; -// meta->schema[n].colId = pExpr->base.resColId; -// tstrncpy(meta->schema[n].name, pField->pExpr->base.aliasName, TSDB_COL_NAME_LEN); -// info->rowSize += meta->schema[n].bytes; -// -// n += 1; + SInternalField* pField = getInternalField(&pUpstream->fieldsInfo, i); + if (!pField->visible) { + continue; + } + + meta->schema[n] = pField->pExpr->base.resSchema; + info->rowSize += meta->schema[n].bytes; + n += 1; } info->numOfColumns = n; @@ -501,9 +483,15 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf* const char* msg4 = "join query does not support group by"; const char* msg5 = "not allowed column type for group by"; const char* msg6 = "tags not allowed for table query"; - const char* msg7 = "not support group by expression"; + const char* msg7 = "normal column and tags can not be mixed up in group by clause"; const char* msg8 = "normal column can only locate at the end of group by clause"; + SGroupbyExpr* pGroupExpr = &(pQueryInfo->groupbyExpr); + pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex)); + if (pGroupExpr->columnInfo == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + // todo : handle two tables situation STableMetaInfo* pTableMetaInfo = NULL; if (pList == NULL) { @@ -514,12 +502,6 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf* return buildInvalidOperationMsg(pMsgBuf, msg4); } - SGroupbyExpr* pGroupExpr = &(pQueryInfo->groupbyExpr); - pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex)); - if (pGroupExpr->columnInfo == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - size_t num = taosArrayGetSize(pList); if (num > TSDB_MAX_TAGS) { return buildInvalidOperationMsg(pMsgBuf, msg1); @@ -528,6 +510,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf* int32_t numOfGroupbyCols = 0; SSchema *pSchema = NULL; int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL; + bool groupbyTag = false; for (int32_t i = 0; i < num; ++i) { SListItem * pItem = taosArrayGet(pList, i); @@ -561,6 +544,8 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf* return buildInvalidOperationMsg(pMsgBuf, msg6); } + groupbyTag = true; + int32_t relIndex = index.columnIndex; if (index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) { relIndex -= getNumOfColumns(pTableMeta); @@ -590,12 +575,12 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf* } } - // 1. only one normal column allowed in the group by clause - // 2. the normal column in the group by clause can only located at the end position - if (numOfGroupbyCols > 1) { + if (numOfGroupbyCols > 0 && groupbyTag) { return buildInvalidOperationMsg(pMsgBuf, msg7); } + // todo ??? + // 1. the normal column in the group by clause can only located at the end position for(int32_t i = 0; i < num; ++i) { SColIndex* pIndex = taosArrayGet(pGroupExpr->columnInfo, i); if (TSDB_COL_IS_NORMAL_COL(pIndex->flag) && i != num - 1) { @@ -608,29 +593,30 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf* return TSDB_CODE_SUCCESS; } -int32_t filterUnsupportedQueryFunction(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) { - // todo NOT support yet - const char* msg6 = "not support stddev/percentile/interp in the outer query yet"; - const char* msg9 = "not support 3 level select"; +int32_t checkForUnsupportedQuery(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) { + const char* msg1 = "not support percentile/interp/block_dist in the outer query yet"; - for (int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) { + for (int32_t i = 0; i < getNumOfExprs(pQueryInfo); ++i) { SExprInfo* pExpr = getExprInfo(pQueryInfo, i); assert(pExpr->pExpr->nodeType == TEXPR_UNARYEXPR_NODE); - int32_t f = pExpr->pExpr->_node.functionId; - if (f == FUNCTION_STDDEV || f == FUNCTION_PERCT || f == FUNCTION_INTERP) { - return buildInvalidOperationMsg(pMsgBuf, msg6); + int32_t f = getExprFunctionId(pExpr); + if (f == FUNCTION_PERCT || f == FUNCTION_INTERP) { + return buildInvalidOperationMsg(pMsgBuf, msg1); } if (f == FUNCTION_BLKINFO && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { - return buildInvalidOperationMsg(pMsgBuf, msg9); + return buildInvalidOperationMsg(pMsgBuf, msg1); } +#if 0 + //todo planner handle this if (/*(timeWindowQuery || pQueryInfo->stateWindow) &&*/ f == FUNCTION_LAST) { pExpr->base.numOfParams = 1; - pExpr->base.param[0].i64 = TSDB_ORDER_ASC; + pExpr->base.param[0].i = TSDB_ORDER_ASC; pExpr->base.param[0].nType = TSDB_DATA_TYPE_INT; } +#endif } } @@ -644,34 +630,36 @@ static int32_t parseIntervalOffset(SQueryStmtInfo* pQueryInfo, SToken* offsetTok const char* msg3 = "cannot use 'year' as offset when interval is 'month'"; SToken* t = offsetToken; + SInterval* pInterval = &pQueryInfo->interval; + if (t->n == 0) { - pQueryInfo->interval.offsetUnit = pQueryInfo->interval.intervalUnit; - pQueryInfo->interval.offset = 0; + pInterval->offsetUnit = pInterval->intervalUnit; + pInterval->offset = 0; return TSDB_CODE_SUCCESS; } - if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.offset, &pQueryInfo->interval.offsetUnit, precision) != TSDB_CODE_SUCCESS) { + if (parseNatualDuration(t->z, t->n, &pInterval->offset, &pInterval->offsetUnit, precision) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } - if (pQueryInfo->interval.offset < 0) { + if (pInterval->offset < 0) { return buildInvalidOperationMsg(pMsgBuf, msg1); } - if (!TIME_IS_VAR_DURATION(pQueryInfo->interval.offsetUnit)) { - if (!TIME_IS_VAR_DURATION(pQueryInfo->interval.intervalUnit)) { - if (pQueryInfo->interval.offset > pQueryInfo->interval.interval) { + if (!TIME_IS_VAR_DURATION(pInterval->offsetUnit)) { + if (!TIME_IS_VAR_DURATION(pInterval->intervalUnit)) { + if (pInterval->offset > pInterval->interval) { return buildInvalidOperationMsg(pMsgBuf, msg2); } } - } else if (pQueryInfo->interval.offsetUnit == pQueryInfo->interval.intervalUnit) { - if (pQueryInfo->interval.offset >= pQueryInfo->interval.interval) { + } else if (pInterval->offsetUnit == pInterval->intervalUnit) { + if (pInterval->offset >= pInterval->interval) { return buildInvalidOperationMsg(pMsgBuf, msg2); } - } else if (pQueryInfo->interval.intervalUnit == 'n' && pQueryInfo->interval.offsetUnit == 'y') { + } else if (pInterval->intervalUnit == 'n' && pInterval->offsetUnit == 'y') { return buildInvalidOperationMsg(pMsgBuf, msg3); - } else if (pQueryInfo->interval.intervalUnit == 'y' && pQueryInfo->interval.offsetUnit == 'n') { - if (pQueryInfo->interval.interval * 12 <= pQueryInfo->interval.offset) { + } else if (pInterval->intervalUnit == 'y' && pInterval->offsetUnit == 'n') { + if (pInterval->interval * 12 <= pQueryInfo->interval.offset) { return buildInvalidOperationMsg(pMsgBuf, msg2); } } else { @@ -777,10 +765,6 @@ int32_t validateIntervalNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMs // if ((pSqlNode->interval.token == TK_EVERY && (!interpQuery)) || (pSqlNode->interval.token == TK_INTERVAL && interpQuery)) { // return buildInvalidOperationMsg(pMsgBuf, msg4); // } - - // The following part is used to check for the invalid query expression. -// return checkInvalidExprForTimeWindow(pCmd, pQueryInfo); - } int32_t validateSessionNode(SQueryStmtInfo *pQueryInfo, SSessionWindowVal* pSession, int32_t precision, SMsgBuf* pMsgBuf) { @@ -825,8 +809,6 @@ int32_t validateSessionNode(SQueryStmtInfo *pQueryInfo, SSessionWindowVal* pSess pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_ID; return TSDB_CODE_SUCCESS; - // The following part is used to check for the invalid query expression. -// return checkInvalidExprForTimeWindow(pCmd, pQueryInfo); } // parse the window_state @@ -948,7 +930,6 @@ int32_t validateLimitNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBu static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, int32_t outputIndex, int32_t tableIndex); - int32_t validateOrderbyNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) { const char* msg1 = "invalid column name in orderby clause"; const char* msg2 = "too many order by columns"; @@ -991,11 +972,11 @@ int32_t validateOrderbyNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsg s = *(SSchema*) getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); } else { // order by [1|2|3] - if (pVar->i64 > getNumOfExprs(pQueryInfo)) { + if (pVar->i > getNumOfFields(&pQueryInfo->fieldsInfo)) { return buildInvalidOperationMsg(pMsgBuf, msg4); } - SExprInfo* pExprInfo = getExprInfo(pQueryInfo, pVar->i64); + SExprInfo* pExprInfo = getExprInfo(pQueryInfo, pVar->i); s = pExprInfo->base.resSchema; } @@ -1150,7 +1131,7 @@ int32_t checkForInvalidOrderby(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, S // orderby ts query on super table if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { bool found = false; - for (int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) { + for (int32_t i = 0; i < getNumOfExprs(pQueryInfo); ++i) { SExprInfo* pExpr = getExprInfo(pQueryInfo, i); if (getExprFunctionId(pExpr) == FUNCTION_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_ID) { found = true; @@ -1266,7 +1247,7 @@ int32_t checkForInvalidOrderby(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, S } #endif -static int32_t checkQueryRangeForFill(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) { +static int32_t checkFillQueryRange(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) { const char* msg3 = "start(end) time of time range required or time range too large"; if (pQueryInfo->interval.interval == 0) { @@ -1305,20 +1286,14 @@ int32_t validateFillNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf const char* msg1 = "value is expected"; const char* msg2 = "invalid fill option"; - const char* msg3 = "top/bottom not support fill"; const char* msg4 = "illegal value or data overflow"; - const char* msg5 = "fill only available for interval query"; const char* msg6 = "not supported function now"; -// if ((!isTimeWindowQuery(pQueryInfo)) && (!tscIsPointInterpQuery(pQueryInfo))) { -// return buildInvalidOperationMsg(pMsgBuf, msg5); -// } - /* * fill options are set at the end position, when all columns are set properly * the columns may be increased due to group by operation */ - if (checkQueryRangeForFill(pQueryInfo, pMsgBuf) != TSDB_CODE_SUCCESS) { + if (checkFillQueryRange(pQueryInfo, pMsgBuf) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -1406,15 +1381,6 @@ int32_t validateFillNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf return buildInvalidOperationMsg(pMsgBuf, msg2); } -// for(int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) { -// SExprInfo* pExpr = getExprInfo(pQueryInfo, i); -// -// int32_t functionId = pExpr->pExpr->_node.functionId; -// if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM) { -// return buildInvalidOperationMsg(pMsgBuf, msg3); -// } -// } - return TSDB_CODE_SUCCESS; } @@ -1437,6 +1403,8 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* * select server_version(); * select client_version(); * select database(); + * select 1+2; + * select now(); */ if (pSqlNode->from == NULL) { assert(pSqlNode->fillType == NULL && pSqlNode->pGroupby == NULL && pSqlNode->pWhere == NULL && @@ -1458,28 +1426,24 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* } } - int32_t timeWindowQuery = - (TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)); -// TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY); - // parse the group by clause in the first place if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pMsgBuf) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } - if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, true, pMsgBuf) != - TSDB_CODE_SUCCESS) { + if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, true, pMsgBuf) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } - code = filterUnsupportedQueryFunction(pQueryInfo, pMsgBuf); + code = checkForUnsupportedQuery(pQueryInfo, pMsgBuf); STableMeta* pTableMeta = getMetaInfo(pQueryInfo, 0)->pTableMeta; SSchema* pSchema = getOneColumnSchema(pTableMeta, 0); int32_t precision = pTableMeta->tableInfo.precision; +#if 0 if (pSchema->type != TSDB_DATA_TYPE_TIMESTAMP) { - int32_t numOfExprs = (int32_t)tscNumOfExprs(pQueryInfo); + int32_t numOfExprs = (int32_t)getNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* pExpr = getExprInfo(pQueryInfo, i); @@ -1490,6 +1454,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* } } } +#endif // validate the query filter condition info if (pSqlNode->pWhere != NULL) { @@ -1536,19 +1501,14 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* } } else { pQueryInfo->command = TSDB_SQL_SELECT; - - size_t numOfTables = taosArrayGetSize(pSqlNode->from->list); - if (numOfTables > TSDB_MAX_JOIN_TABLE_NUM) { + if (taosArrayGetSize(pSqlNode->from->list) > TSDB_MAX_JOIN_TABLE_NUM) { return buildInvalidOperationMsg(pMsgBuf, msg2); } STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0); - int32_t precision = pTableMetaInfo->pTableMeta->tableInfo.precision; - - bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); + pQueryInfo->info.stableQuery = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); - int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY; - TSDB_QUERY_SET_TYPE(pQueryInfo->type, type); + int32_t precision = pTableMetaInfo->pTableMeta->tableInfo.precision; // parse the group by clause in the first place if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pMsgBuf) != TSDB_CODE_SUCCESS) { @@ -1566,8 +1526,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* } } - if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, false, pMsgBuf) != - TSDB_CODE_SUCCESS) { + if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, false, pMsgBuf) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -1599,10 +1558,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* return TSDB_CODE_TSC_INVALID_OPERATION; } -// if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) { -// return TSDB_CODE_TSC_INVALID_OPERATION; -// } - // no result due to invalid query time range if (pQueryInfo->window.skey > pQueryInfo->window.ekey) { pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; @@ -1623,27 +1578,96 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) { assert(pQueryInfo != NULL && pMsgBuf != NULL); - return 0; -} -static int32_t distinctCompatibleCheck(SQueryStmtInfo* pQueryInfo, bool joinQuery, SMsgBuf* pMsgBuf) { + const char* msg1 = "invalid query expression"; + const char* msg2 = "top/bottom query does not support order by value in time window query"; + const char* msg3 = "fill only available in time window query"; + const char* msg4 = "top/bottom not support fill"; + const char* msg5 = "scalar function can not be used in time window query"; const char* msg6 = "not support distinct mixed with join"; const char* msg7 = "not support distinct mixed with groupby"; - const char* msg8 = "not support distinct in nest query"; + const char* msg8 = "_block_dist not support subquery, only support stable/table"; + + if (pQueryInfo->info.topbotQuery) { + + // 1. invalid sql: + // select top(col, k) from table_name [interval(1d)|session(ts, 1d)|statewindow(col)] order by k asc + // order by normal column is not supported + int32_t colId = pQueryInfo->order.orderColId; + if (pQueryInfo->info.timewindow && colId != PRIMARYKEY_TIMESTAMP_COL_ID) { + return buildInvalidOperationMsg(pMsgBuf, msg2); + } + + // select top(col, k) from table_name interval(10s) fill(prev) + // not support fill in top/bottom query. + if (pQueryInfo->fillType != TSDB_FILL_NONE) { + return buildInvalidOperationMsg(pMsgBuf, msg4); + } + } + + /* + * 2. invalid sql: + * select count(tbname)/count(tag1)/count(tag2) from super_table_name [interval(1d)|session(ts, 1d)|statewindow(col)]; + */ + if (pQueryInfo->info.timewindow) { + size_t size = getNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < size; ++i) { + SExprInfo* pExpr = getExprInfo(pQueryInfo, i); + int32_t functionId = getExprFunctionId(pExpr); + if (functionId == FUNCTION_COUNT && TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { + return buildInvalidOperationMsg(pMsgBuf, msg1); + } + } + } + + /* + * 3. invalid sql: + * select tbname, tags_fields from super_table_name [interval(1s)|session(ts,1s)|statewindow(col)] + */ + if (pQueryInfo->info.onlyTagQuery && pQueryInfo->info.timewindow) { + return buildInvalidOperationMsg(pMsgBuf, msg1); + } + + /* + * 4. invalid sql: + * select * from table_name fill(prev|next|null|none) + */ + if (!pQueryInfo->info.timewindow && !pQueryInfo->info.interpQuery && pQueryInfo->fillType != TSDB_FILL_NONE) { + return buildInvalidOperationMsg(pMsgBuf, msg3); + } - if (pQueryInfo->distinct) { - if (joinQuery) { + /* + * 5. invalid sql: + * select diff(col)|derivative(col)|* from table_name interval(1s)|session(20s)|statewindow(col) + * projection query not compatible with the time window query + */ + if (pQueryInfo->info.timewindow && pQueryInfo->info.projectionQuery) { + return buildInvalidOperationMsg(pMsgBuf, msg5); + } + + /* + * 6. invalid sql: + * distinct + join not supported. + * select distinct a,b from table1, table2 where table1.ts=table2.ts + * + * distinct + group by not supported: + * select distinct count(a) from table_name group by col1; + */ + if (pQueryInfo->info.distinct) { + if (pQueryInfo->info.join) { return buildInvalidOperationMsg(pMsgBuf, msg6); } if (taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo) != 0) { return buildInvalidOperationMsg(pMsgBuf, msg7); } - - if (pQueryInfo->pDownstream != NULL) { - return buildInvalidOperationMsg(pMsgBuf, msg8); - } } + + /* + * 7. invalid sql: + * nested subquery not support block_dist query + * select block_dist() from (select * from table_name) + */ } static int32_t resColId = 5000; @@ -1684,42 +1708,32 @@ void setResultColName(char* name, tSqlExprItem* pItem, SToken* pToken, SToken* f } SExprInfo* doAddOneExprInfo(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex, - SSchema* pColSchema, SSchema* pResultSchema, tExprNode* pExprNode, int32_t interSize, const char* token) { + SSchema* pColSchema, SSchema* pResultSchema, tExprNode* pExprNode, int32_t interSize, const char* token, bool finalResult) { STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex); SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pIndex, pExprNode, pResultSchema, interSize); addExprInfo(pQueryInfo, outputColIndex, pExpr); tstrncpy(pExpr->base.token, token, sizeof(pExpr->base.token)); - - pExpr->base.colInfo.flag = pIndex->type; + uint64_t uid = pTableMetaInfo->pTableMeta->uid; SArray* p = TSDB_COL_IS_TAG(pIndex->type)?pTableMetaInfo->tagColList:pQueryInfo->colList; - columnListInsert(p, pIndex->columnIndex, pTableMetaInfo->pTableMeta->uid, pColSchema); - - addResColumnInfo(pQueryInfo, outputColIndex, pColSchema, pExpr); - return pExpr; -} + columnListInsert(p, pIndex->columnIndex, uid, pColSchema); -void doAddSourceColumnAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* index, int32_t outputIndex, SExprInfo* pExpr, SSchema* pColSchema, bool finalResult) { - columnListInsert(pQueryInfo->colList, index->columnIndex, pExpr->base.uid, pColSchema); + pExpr->base.colInfo.flag = pIndex->type; + if (TSDB_COL_IS_NORMAL_COL(pIndex->type)) { + insertPrimaryTsColumn(pQueryInfo->colList, uid); + } if (finalResult) { - addResColumnInfo(pQueryInfo, outputIndex, &pExpr->base.resSchema, pExpr); + addResColumnInfo(pQueryInfo, outputColIndex, pColSchema, pExpr); } - if (TSDB_COL_IS_NORMAL_COL(index->type)) { - insertPrimaryTsColumn(pQueryInfo->colList, pExpr->base.uid); - } + return pExpr; } -static int32_t addOneExprInfo(SQueryStmtInfo* pQueryInfo, tSqlExprItem* pItem, int32_t functionId, - int32_t outputColIndex, SColumnIndex* pColIndex, tExprNode* pNode, bool finalResult, SMsgBuf* pMsgBuf) { +static int32_t addOneExprInfo(SQueryStmtInfo* pQueryInfo, tSqlExprItem* pItem, int32_t functionId, int32_t outputIndex, SSchema* pSchema, SColumnIndex* pColIndex, tExprNode* pNode, bool finalResult, SMsgBuf* pMsgBuf) { const char* msg1 = "not support column types"; - - STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex); - SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex); - if (functionId == FUNCTION_SPREAD) { if (IS_VAR_DATA_TYPE(pSchema->type) || pSchema->type == TSDB_DATA_TYPE_BOOL) { return buildInvalidOperationMsg(pMsgBuf, msg1); @@ -1734,7 +1748,7 @@ static int32_t addOneExprInfo(SQueryStmtInfo* pQueryInfo, tSqlExprItem* pItem, i getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resInfo, 0, false); SSchema resultSchema = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), name); - doAddOneExprInfo(pQueryInfo, outputColIndex, functionId, pColIndex, pSchema, &resultSchema, pNode, resInfo.intermediateBytes, name); + doAddOneExprInfo(pQueryInfo, outputIndex, functionId, pColIndex, pSchema, &resultSchema, pNode, resInfo.intermediateBytes, name, finalResult); return TSDB_CODE_SUCCESS; } @@ -1776,6 +1790,8 @@ static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTab SSchema s = createSchema(TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts"); SExprInfo* pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS_DUMMY, &indexTS, NULL, &s, TSDB_KEYSIZE); + strncpy(pExpr->base.token, "ts", tListLen(pExpr->base.token)); + addExprInfo(pQueryInfo, outputIndex, pExpr); SSchema* pSourceSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, indexTS.columnIndex); @@ -1783,37 +1799,45 @@ static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTab addResColumnInfo(pQueryInfo, outputIndex, &pExpr->base.resSchema, pExpr); } -// todo handle count(a+b) -static int32_t setColumnIndex(SQueryStmtInfo* pQueryInfo, SArray* pParamList, SColumnIndex* index, SMsgBuf* pMsgBuf) { - const char* msg3 = "illegal column name"; - const char* msg4 = "invalid table name"; +static int32_t setColumnIndex(SQueryStmtInfo* pQueryInfo, SArray* pParamList, SColumnIndex* index, SSchema* columnSchema, tExprNode** pNode, SMsgBuf* pMsgBuf) { + const char* msg1 = "illegal column name"; + const char* msg2 = "invalid table name"; - if (pParamList != NULL) { + STableMeta* pTableMeta = getMetaInfo(pQueryInfo, 0)->pTableMeta; + if (pParamList == NULL) { + // count(*) is equalled to count(primary_timestamp_key) + *index = (SColumnIndex) {0, PRIMARYKEY_TIMESTAMP_COL_ID, false}; + *columnSchema = *(SSchema*) getOneColumnSchema(pTableMeta, index->columnIndex); + } else { tSqlExprItem* pParamElem = taosArrayGet(pParamList, 0); SToken* pToken = &pParamElem->pNode->columnName; int16_t tokenId = pParamElem->pNode->tokenId; - if ((pToken->z == NULL || pToken->n == 0) && (TK_INTEGER != tokenId)) { - return buildInvalidOperationMsg(pMsgBuf, msg3); - } // select count(table.*), select count(1), count(2) - if (tokenId == TK_ALL || tokenId == TK_INTEGER) { + if (tokenId == TK_ALL || tokenId == TK_INTEGER || tokenId == TK_FLOAT) { // check if the table name is valid or not SToken tmpToken = pParamElem->pNode->columnName; if (getTableIndexByName(&tmpToken, pQueryInfo, index) != TSDB_CODE_SUCCESS) { - return buildInvalidOperationMsg(pMsgBuf, msg4); + return buildInvalidOperationMsg(pMsgBuf, msg2); } - index->columnIndex = PRIMARYKEY_TIMESTAMP_COL_ID; - } else { + *index = (SColumnIndex) {0, PRIMARYKEY_TIMESTAMP_COL_ID, false}; + *columnSchema = *(SSchema*) getOneColumnSchema(pTableMeta, index->columnIndex); + } else if (pToken->z != NULL && pToken->n > 0) { // count the number of table created according to the super table if (getColumnIndexByName(pToken, pQueryInfo, index, pMsgBuf) != TSDB_CODE_SUCCESS) { - return buildInvalidOperationMsg(pMsgBuf, msg3); + return buildInvalidOperationMsg(pMsgBuf, msg1); + } + + *columnSchema = *(SSchema*) getOneColumnSchema(pTableMeta, index->columnIndex); + } else { + STableMetaInfo* pTableMetaInfo = NULL; + int32_t code = extractFunctionParameterInfo(pQueryInfo, tokenId, &pTableMetaInfo, columnSchema, pNode, index, pParamElem, pMsgBuf); + if (code != TSDB_CODE_SUCCESS) { + return buildInvalidOperationMsg(pMsgBuf, msg1); } } - } else { // count(*) is equalled to count(primary_timestamp_key) - *index = (SColumnIndex) {0, PRIMARYKEY_TIMESTAMP_COL_ID, false}; } return TSDB_CODE_SUCCESS; @@ -1821,10 +1845,12 @@ static int32_t setColumnIndex(SQueryStmtInfo* pQueryInfo, SArray* pParamList, SC static int32_t doAddAllColumnExprInSelectClause(SQueryStmtInfo *pQueryInfo, STableMetaInfo* pTableMetaInfo, tSqlExprItem* pItem, int32_t functionId, int32_t tableIndex, int32_t* colIndex, bool finalResult, SMsgBuf* pMsgBuf) { - for (int32_t i = 0; i < getNumOfColumns(pTableMetaInfo->pTableMeta); ++i) { + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + for (int32_t i = 0; i < getNumOfColumns(pTableMeta); ++i) { SColumnIndex index = {.tableIndex = tableIndex, .columnIndex = i, .type = TSDB_COL_NORMAL}; - if (addOneExprInfo(pQueryInfo, pItem, functionId, *colIndex, &index, NULL, finalResult, pMsgBuf) != 0) { + SSchema* pSchema = getOneColumnSchema(pTableMeta, i); + if (addOneExprInfo(pQueryInfo, pItem, functionId, *colIndex, pSchema, &index, NULL, finalResult, pMsgBuf) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -1832,9 +1858,6 @@ static int32_t doAddAllColumnExprInSelectClause(SQueryStmtInfo *pQueryInfo, STab } } -static int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId, STableMetaInfo** pTableMetaInfo, SSchema* columnSchema, - tExprNode** pNode, SColumnIndex* pIndex, tSqlExprItem* pParamElem, SMsgBuf* pMsgBuf); - static int32_t doHandleOneParam(SQueryStmtInfo *pQueryInfo, tSqlExprItem* pItem, tSqlExprItem* pParamElem, int32_t functionId, int32_t* outputIndex, bool finalResult, SMsgBuf* pMsgBuf) { const char* msg3 = "illegal column name"; @@ -1858,18 +1881,17 @@ static int32_t doHandleOneParam(SQueryStmtInfo *pQueryInfo, tSqlExprItem* pItem, SSchema columnSchema = {0}; STableMetaInfo* pTableMetaInfo = {0}; - extractFunctionParameterInfo(pQueryInfo, tokenId, &pTableMetaInfo, &columnSchema, &pNode, &index, pParamElem, pMsgBuf); - - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) { + int32_t code = extractFunctionParameterInfo(pQueryInfo, tokenId, &pTableMetaInfo, &columnSchema, &pNode, &index, pParamElem, pMsgBuf); + if (code != TSDB_CODE_SUCCESS) { return buildInvalidOperationMsg(pMsgBuf, msg3); } // functions can not be applied to tags - if (TSDB_COL_IS_TAG(index.type)) { + if (TSDB_COL_IS_TAG(index.type) && (functionId == FUNCTION_INTERP || functionId == FUNCTION_SPREAD)) { return buildInvalidOperationMsg(pMsgBuf, msg6); } - if (addOneExprInfo(pQueryInfo, pItem, functionId, (*outputIndex)++, &index, pNode, finalResult, pMsgBuf) != 0) { + if (addOneExprInfo(pQueryInfo, pItem, functionId, (*outputIndex)++, &columnSchema, &index, pNode, finalResult, pMsgBuf) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -1882,9 +1904,9 @@ int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId const char* msg1 = "not support column types"; const char* msg2 = "invalid parameters"; const char* msg3 = "illegal column name"; - const char* msg6 = "functions applied to tags are not allowed"; - const char* msg13 = "nested function is not supported"; - + const char* msg4 = "nested function is not supported"; + const char* msg5 = "functions applied to tags are not allowed"; + if (tokenId == TK_ALL || tokenId == TK_ID) { // simple parameter if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, pIndex, pMsgBuf) != TSDB_CODE_SUCCESS)) { return buildInvalidOperationMsg(pMsgBuf, msg3); @@ -1892,14 +1914,14 @@ int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId // functions can not be applied to tags if (TSDB_COL_IS_TAG(pIndex->type)) { - return buildInvalidOperationMsg(pMsgBuf, msg6); + return buildInvalidOperationMsg(pMsgBuf, msg5); } *pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex); // 2. check if sql function can be applied on this column data type *columnSchema = *(SSchema*) getOneColumnSchema((*pTableMetaInfo)->pTableMeta, pIndex->columnIndex); - } else if (tokenId == TK_PLUS || tokenId == TK_MINUS || tokenId == TK_STAR || tokenId == TK_REM || tokenId == TK_CONCAT) { + } else if (tokenId == TK_PLUS || tokenId == TK_MINUS || tokenId == TK_STAR || tokenId == TK_REM || tokenId == TK_DIVIDE || tokenId == TK_CONCAT) { int32_t arithmeticType = NON_ARITHMEIC_EXPR; SArray* pColumnList = taosArrayInit(4, sizeof(SColumnIndex)); if (validateComplexExpr(pParamElem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) { @@ -1907,12 +1929,16 @@ int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId } if (arithmeticType != NORMAL_ARITHMETIC) { - return buildInvalidOperationMsg(pMsgBuf, msg13); + return buildInvalidOperationMsg(pMsgBuf, msg4); } *pTableMetaInfo = getMetaInfo(pQueryInfo, 0); // todo get the first table meta. *columnSchema = createSchema(TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), ""); + SToken* pExprToken = &pParamElem->pNode->exprToken; + int32_t len = MIN(TSDB_COL_NAME_LEN, pExprToken->n + 1); + tstrncpy(columnSchema->name, pExprToken->z, len); + SArray* colList = taosArrayInit(10, sizeof(SColIndex)); int32_t ret = sqlExprToExprNode(pNode, pParamElem->pNode, pQueryInfo, colList, NULL, pMsgBuf); if (ret != TSDB_CODE_SUCCESS) { @@ -1978,8 +2004,11 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx return code; } + tExprNode* pNode = NULL; SColumnIndex index = COLUMN_INDEX_INITIALIZER; - code = setColumnIndex(pQueryInfo, pParamList, &index, pMsgBuf); + SSchema columnSchema = {0}; + + code = setColumnIndex(pQueryInfo, pParamList, &index, &columnSchema, &pNode, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -1990,11 +2019,8 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx char token[TSDB_COL_NAME_LEN] = {0}; setTokenAndResColumnName(pItem, s.name, token,sizeof(s.name) - 1); - STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta; int32_t outputIndex = getNumOfFields(&pQueryInfo->fieldsInfo); - SSchema* ps = getOneColumnSchema(pTableMeta, index.columnIndex); - - doAddOneExprInfo(pQueryInfo, outputIndex, functionId, &index, ps, &s, NULL, size, token); + doAddOneExprInfo(pQueryInfo, outputIndex, functionId, &index, &columnSchema, &s, pNode, size, token, finalResult); return TSDB_CODE_SUCCESS; } @@ -2058,7 +2084,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx char token[TSDB_COL_NAME_LEN] = {0}; setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1); - SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, numOfOutput, functionId, &index, &columnSchema, &s, pNode, resInfo.intermediateBytes, token); + SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, numOfOutput, functionId, &index, &columnSchema, &s, pNode, resInfo.intermediateBytes, token, finalResult); if (functionId == FUNCTION_LEASTSQR) { // set the leastsquares parameters char val[8] = {0}; @@ -2151,13 +2177,17 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx } tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0); - if (pParamElem->pNode->tokenId != TK_ID) { + if (pParamElem->pNode->tokenId == TK_ALL) { return buildInvalidOperationMsg(pMsgBuf, msg2); } + tExprNode* pNode = NULL; + int32_t tokenId = pParamElem->pNode->tokenId; SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) { - return buildInvalidOperationMsg(pMsgBuf, msg3); + SSchema columnSchema = {0}; + code = extractFunctionParameterInfo(pQueryInfo, tokenId, &pTableMetaInfo, &columnSchema, &pNode, &index, pParamElem,pMsgBuf); + if (code != TSDB_CODE_SUCCESS) { + return code; } // functions can not be applied to tags @@ -2166,10 +2196,9 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx } pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); // 2. valid the column type - if (!IS_NUMERIC_TYPE(pSchema->type)) { + if (!IS_NUMERIC_TYPE(columnSchema.type)) { return buildInvalidOperationMsg(pMsgBuf, msg1); } @@ -2178,50 +2207,42 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx return buildInvalidOperationMsg(pMsgBuf, msg2); } - SVariant* pVariant = &pParamElem[1].pNode->value; SResultDataInfo resInfo = {0}; - char val[8] = {0}; + getResultDataInfo(columnSchema.type, columnSchema.bytes, functionId, 0, &resInfo, 0, false); + if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM) { + // set the first column ts for top/bottom query + setTsOutputExprInfo(pQueryInfo, pTableMetaInfo, colIndex, index.tableIndex); + colIndex += 1; // the first column is ts + } - if (functionId == FUNCTION_PERCT || functionId == FUNCTION_APERCT) { - taosVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true); + SSchema s = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), ""); - double dp = GET_DOUBLE_VAL(val); - if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) { - return buildInvalidOperationMsg(pMsgBuf, msg5); - } + char token[TSDB_COL_NAME_LEN] = {0}; + setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1); + SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, &columnSchema, &s, pNode, resInfo.intermediateBytes, token, finalResult); + + SToken* pParamToken = &pParamElem[1].pNode->exprToken; + pExpr->base.numOfParams += 1; - getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resInfo, 0, false); + SVariant* pVar = &pExpr->base.param[0]; + if (functionId == FUNCTION_PERCT || functionId == FUNCTION_APERCT) { + taosVariantCreate(pVar, pParamToken->z, pParamToken->n, TSDB_DATA_TYPE_DOUBLE); /* * sql function transformation * for dp = 0, it is actually min, * for dp = 100, it is max, */ - colIndex += 1; // the first column is ts + if (pVar->d < 0 || pVar->d > TOP_BOTTOM_QUERY_LIMIT) { + return buildInvalidOperationMsg(pMsgBuf, msg5); + } } else { - taosVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true); - - int64_t nTop = GET_INT32_VAL(val); - if (nTop <= 0 || nTop > 100) { // todo use macro + taosVariantCreate(pVar, pParamToken->z, pParamToken->n, TSDB_DATA_TYPE_BIGINT); + if (pVar->i <= 0 || pVar->i > 100) { // todo use macro return buildInvalidOperationMsg(pMsgBuf, msg12); } - - // set the first column ts for top/bottom query - setTsOutputExprInfo(pQueryInfo, pTableMetaInfo, colIndex, index.tableIndex); - colIndex += 1; // the first column is ts } - SSchema s = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), ""); - - char token[TSDB_COL_NAME_LEN] = {0}; - setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1); - SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, pSchema, &s, NULL, resInfo.intermediateBytes, token); - - if (functionId == FUNCTION_PERCT || functionId == FUNCTION_APERCT) { - addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); - } else { - addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); - } return TSDB_CODE_SUCCESS; } @@ -2288,7 +2309,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx s.colId = getNewResColId(); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY); - doAddOneExprInfo(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s, &s, NULL, 0, s.name); + doAddOneExprInfo(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s, &s, NULL, 0, s.name, true); return TSDB_CODE_SUCCESS; } @@ -2309,7 +2330,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx char token[TSDB_COL_NAME_LEN] = {0}; setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1); - SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, &colSchema, &s, NULL, resInfo.intermediateBytes, token); + SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, &colSchema, &s, NULL, resInfo.intermediateBytes, token, finalResult); int64_t rowSize = pTableMetaInfo->pTableMeta->tableInfo.rowSize; addExprInfoParam(&pExpr->base, (char*) &rowSize, TSDB_DATA_TYPE_BIGINT, 8); @@ -2351,7 +2372,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx char token[TSDB_COL_NAME_LEN] = {0}; setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1); - doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, colSchema, &s, NULL, resInfo.intermediateBytes, token); + doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, colSchema, &s, NULL, resInfo.intermediateBytes, token, finalResult); return TSDB_CODE_SUCCESS; } } @@ -2377,7 +2398,7 @@ SExprInfo* doAddProjectCol(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, S const char* name = (aliasName == NULL)? pSchema->name:aliasName; SSchema s = createSchema(pSchema->type, pSchema->bytes, colId, name); - return doAddOneExprInfo(pQueryInfo, outputColIndex, functionId, &index, pSchema, &s, NULL, 0, pSchema->name); + return doAddOneExprInfo(pQueryInfo, outputColIndex, functionId, &index, pSchema, &s, NULL, 0, pSchema->name, true); } static int32_t doAddProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) { @@ -2440,7 +2461,7 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* return TSDB_CODE_TSC_INVALID_OPERATION; } - int32_t startPos = (int32_t)tscNumOfExprs(pQueryInfo); + int32_t startPos = (int32_t)getNumOfExprs(pQueryInfo); int32_t tokenId = pItem->pNode->tokenId; if (tokenId == TK_ALL) { // project on all fields TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY); @@ -2470,9 +2491,9 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* SColumnIndex index = createConstantColumnIndex(&pQueryInfo->udColumnId); SSchema colSchema = createConstantColumnSchema(&pItem->pNode->value, &pItem->pNode->exprToken, pItem->aliasName); - char rawName[TSDB_COL_NAME_LEN] = {0}; - tstrncpy(rawName, pItem->pNode->exprToken.z, MIN(TSDB_COL_NAME_LEN, TSDB_COL_NAME_LEN)); - SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema, &colSchema, NULL, 0, rawName); + char token[TSDB_COL_NAME_LEN] = {0}; + tstrncpy(token, pItem->pNode->exprToken.z, MIN(TSDB_COL_NAME_LEN, TSDB_COL_NAME_LEN)); + SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema, &colSchema, NULL, 0, token, true); // NOTE: the first parameter is reserved for the tag column id during join query process. pExpr->base.numOfParams = 2; @@ -2519,7 +2540,7 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* char rawName[TSDB_COL_NAME_LEN] = {0}; setTokenAndResColumnName(pItem, resultSchema.name, rawName, sizeof(colSchema.name) - 1); - doAddOneExprInfo(pQueryInfo, startPos, functionId, &index, &colSchema, &resultSchema, NULL, 0, rawName); + doAddOneExprInfo(pQueryInfo, startPos, functionId, &index, &colSchema, &resultSchema, NULL, 0, rawName, true); } else { STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); if (TSDB_COL_IS_TAG(index.type) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { @@ -2584,13 +2605,13 @@ static int32_t validateExprLeafNode(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, return TSDB_CODE_TSC_INVALID_OPERATION; } - int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo); + int32_t outputIndex = (int32_t)getNumOfExprs(pQueryInfo); if (addExprAndResColumn(pQueryInfo, outputIndex, &item, false, pMsgBuf) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } // It is invalid in case of more than one sqlExpr, such as first(ts, k) - last(ts, k) - int32_t inc = (int32_t) tscNumOfExprs(pQueryInfo) - outputIndex; + int32_t inc = (int32_t) getNumOfExprs(pQueryInfo) - outputIndex; if (inc > 1) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -2805,7 +2826,7 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt // check for dividing by 0 if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) { if (pRight->nodeType == TEXPR_VALUE_NODE) { - if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64 == 0) { + if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i == 0) { return buildInvalidOperationMsg(pMsgBuf, "invalid expr (divide by 0)"); } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->d == 0) { return buildInvalidOperationMsg(pMsgBuf, "invalid expr (divide by 0)"); @@ -2950,32 +2971,27 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, const char* msg1 = "too many items in selection clause"; const char* msg2 = "functions or others can not be mixed up"; const char* msg3 = "not support query expression"; - const char* msg4 = "not support distinct mixed with proj/agg func"; + const char* msg4 = "distinct should be in the first place in select clause"; const char* msg5 = "invalid function name"; - const char* msg6 = "_block_dist not support subquery, only support stable/table"; // too many result columns not support order by in query if (taosArrayGetSize(pSelNodeList) > TSDB_MAX_COLUMNS) { return buildInvalidOperationMsg(pMsgBuf, msg1); } - if (pQueryInfo->colList == NULL) { - pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); - } - size_t numOfExpr = taosArrayGetSize(pSelNodeList); for (int32_t i = 0; i < numOfExpr; ++i) { - int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo); + int32_t outputIndex = (int32_t)getNumOfExprs(pQueryInfo); tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i); int32_t type = pItem->pNode->type; if (pItem->distinct) { - if (i != 0 || type == SQL_NODE_SQLFUNCTION || type == SQL_NODE_EXPR) { + if (i != 0/* || type == SQL_NODE_SQLFUNCTION || type == SQL_NODE_EXPR*/) { return buildInvalidOperationMsg(pMsgBuf, msg4); } - pQueryInfo->distinct = true; + pQueryInfo->info.distinct = true; } if (type == SQL_NODE_SQLFUNCTION) { @@ -3010,39 +3026,32 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, } } - // there is only one user-defined column in the final result field, add the timestamp column. -// size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList); -// if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { -// addPrimaryTsColIntoResult(pQueryInfo, pCmd); -// } - return TSDB_CODE_SUCCESS; } int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf) { assert(pNode != NULL && pMsgBuf != NULL && pMsgBuf->len > 0); - if (pNode->pWhere == NULL) { - return TSDB_CODE_SUCCESS; - } // Evaluate expression in where clause - int32_t code = evaluateImpl(pNode->pWhere, tsPrecision); - if (code != TSDB_CODE_SUCCESS) { - strncpy(pMsgBuf->buf, "invalid time expression in sql", pMsgBuf->len); - return code; + if (pNode->pWhere != NULL) { + int32_t code = evaluateSqlNodeImpl(pNode->pWhere, tsPrecision); + if (code != TSDB_CODE_SUCCESS) { + strncpy(pMsgBuf->buf, "invalid time expression in sql", pMsgBuf->len); + return code; + } } // Evaluate the expression in select clause size_t size = taosArrayGetSize(pNode->pSelNodeList); for(int32_t i = 0; i < size; ++i) { tSqlExprItem* pItem = taosArrayGet(pNode->pSelNodeList, i); - code = evaluateImpl(pItem->pNode, tsPrecision); + int32_t code = evaluateSqlNodeImpl(pItem->pNode, tsPrecision); if (code != TSDB_CODE_SUCCESS) { return code; } } - return code; + return TSDB_CODE_SUCCESS; } int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQueryStmtInfo* pQueryInfo, int64_t id, char* msgBuf, int32_t msgBufLen) { diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index 051d19ccbfa9a41dc52320f6cfed960144b3a3bb..504971cc103ca2e667b354ed842a004807100354 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -177,7 +177,7 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet } // Let's assume that it is an UDF/UDAF, if it is not a built-in function. - if (!qIsBuiltinFunction(t->z, t->n)) { + if (qIsBuiltinFunction(t->z, t->n) < 0) { char* fname = strndup(t->z, t->n); taosArrayPush(pMetaInfo->pUdf, &fname); } diff --git a/source/libs/parser/src/queryInfoUtil.c b/source/libs/parser/src/queryInfoUtil.c index 8abbb14e78c035987231b12bd83ba9b313ab93d5..21ab193157f18968d38e1d0169d44151db691dd8 100644 --- a/source/libs/parser/src/queryInfoUtil.c +++ b/source/libs/parser/src/queryInfoUtil.c @@ -212,7 +212,7 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src) { } #endif -// dst->pExpr = exprdup(src->pExpr); + dst->pExpr = exprdup(src->pExpr); memset(dst->base.param, 0, sizeof(SVariant) * tListLen(dst->base.param)); for (int32_t j = 0; j < src->base.numOfParams; ++j) { taosVariantAssign(&dst->base.param[j], &src->base.param[j]); diff --git a/source/libs/parser/test/CMakeLists.txt b/source/libs/parser/test/CMakeLists.txt index 7c90cab6d92dac7365f3944321cd49b6955a3e5b..f7d71132434eeeb4cfb375eb959a694b43162b69 100644 --- a/source/libs/parser/test/CMakeLists.txt +++ b/source/libs/parser/test/CMakeLists.txt @@ -8,7 +8,7 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) ADD_EXECUTABLE(parserTest ${SOURCE_LIST}) TARGET_LINK_LIBRARIES( parserTest - PUBLIC os util common parser catalog transport gtest function + PUBLIC os util common parser catalog transport gtest function planner ) TARGET_INCLUDE_DIRECTORIES( diff --git a/source/libs/parser/test/parserTests.cpp b/source/libs/parser/test/parserTests.cpp index d02df6049888d43e3ef6a73f10bf029c18ebf2e5..9fb50e1006e950df54521cd0fe4f9d13686d87ab 100644 --- a/source/libs/parser/test/parserTests.cpp +++ b/source/libs/parser/test/parserTests.cpp @@ -13,7 +13,6 @@ * along with this program. If not, see . */ -#include #include #include #pragma GCC diagnostic ignored "-Wwrite-strings" @@ -124,287 +123,462 @@ TEST(testCase, validateAST_test) { destroySqlInfo(&info1); } -//TEST(testCase, function_Test) { -// SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`"); -// ASSERT_EQ(info1.valid, true); -// -// char msg[128] = {0}; -// SMsgBuf buf; -// buf.len = 128; -// buf.buf = msg; -// -// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); -// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); -// ASSERT_EQ(code, 0); -// -// SMetaReq req = {0}; -// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); -// ASSERT_EQ(ret, 0); -// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); -// -// SQueryStmtInfo* pQueryInfo = createQueryInfo(); -// setTableMetaInfo(pQueryInfo, &req); -// -// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); -// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); -// -// SArray* pExprList = pQueryInfo->exprList; -// ASSERT_EQ(taosArrayGetSize(pExprList), 1); -// -// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); -// ASSERT_EQ(p1->base.uid, 110); -// ASSERT_EQ(p1->base.numOfParams, 0); -// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT); -// ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a)"); -// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a"); -// ASSERT_EQ(p1->base.colInfo.colId, 1); -// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); -// ASSERT_STRCASEEQ(p1->base.token, "count(a)"); -// ASSERT_EQ(p1->base.interBytes, 8); -// -// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2); -// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); -// -// destroyQueryInfo(pQueryInfo); -// qParserClearupMetaRequestInfo(&req); -// destroySqlInfo(&info1); -//} -// -//TEST(testCase, function_Test2) { -// SSqlInfo info1 = doGenerateAST("select count(a) abc from `t.1abc`"); -// ASSERT_EQ(info1.valid, true); -// -// char msg[128] = {0}; -// SMsgBuf buf; -// buf.len = 128; -// buf.buf = msg; -// -// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); -// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); -// ASSERT_EQ(code, 0); -// -// SMetaReq req = {0}; -// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); -// ASSERT_EQ(ret, 0); -// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); -// -// SQueryStmtInfo* pQueryInfo = createQueryInfo(); -// setTableMetaInfo(pQueryInfo, &req); -// -// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); -// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); -// -// SArray* pExprList = pQueryInfo->exprList; -// ASSERT_EQ(taosArrayGetSize(pExprList), 1); -// -// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); -// ASSERT_EQ(p1->base.uid, 110); -// ASSERT_EQ(p1->base.numOfParams, 0); -// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT); -// ASSERT_STRCASEEQ(p1->base.resSchema.name, "abc"); -// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a"); -// ASSERT_EQ(p1->base.colInfo.colId, 1); -// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); -// ASSERT_STRCASEEQ(p1->base.token, "count(a)"); -// ASSERT_EQ(p1->base.interBytes, 8); -// -// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2); -// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); -// -// destroyQueryInfo(pQueryInfo); -// qParserClearupMetaRequestInfo(&req); -// destroySqlInfo(&info1); -//} -// -//TEST(testCase, function_Test3) { -// SSqlInfo info1 = doGenerateAST("select first(*) from `t.1abc`"); -// ASSERT_EQ(info1.valid, true); -// -// char msg[128] = {0}; -// SMsgBuf buf; -// buf.len = 128; -// buf.buf = msg; -// -// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); -// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); -// ASSERT_EQ(code, 0); -// -// SMetaReq req = {0}; -// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); -// ASSERT_EQ(ret, 0); -// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); -// -// SQueryStmtInfo* pQueryInfo = createQueryInfo(); -// setTableMetaInfo(pQueryInfo, &req); -// -// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); -// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); -// -// SArray* pExprList = pQueryInfo->exprList; -// ASSERT_EQ(taosArrayGetSize(pExprList), 4); -// -// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); -// ASSERT_EQ(p1->base.uid, 110); -// ASSERT_EQ(p1->base.numOfParams, 0); -// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_TIMESTAMP); -// ASSERT_STRCASEEQ(p1->base.resSchema.name, "first(ts)"); +TEST(testCase, function_Test) { + SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 1); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); + ASSERT_EQ(p1->base.uid, 110); + ASSERT_EQ(p1->base.numOfParams, 0); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a)"); + ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a"); + ASSERT_EQ(p1->base.colInfo.colId, 1); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "count(a)"); + ASSERT_EQ(p1->base.interBytes, 8); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, function_Test2) { + SSqlInfo info1 = doGenerateAST("select count(a) abc from `t.1abc`"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 1); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); + ASSERT_EQ(p1->base.uid, 110); + ASSERT_EQ(p1->base.numOfParams, 0); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "abc"); + ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a"); + ASSERT_EQ(p1->base.colInfo.colId, 1); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "count(a)"); + ASSERT_EQ(p1->base.interBytes, 8); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, function_Test3) { + SSqlInfo info1 = doGenerateAST("select first(*) from `t.1abc`"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 4); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); + ASSERT_EQ(p1->base.uid, 110); + ASSERT_EQ(p1->base.numOfParams, 0); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_TIMESTAMP); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "first(ts)"); + ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts"); + ASSERT_EQ(p1->base.colInfo.colId, 0); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "first(ts)"); + ASSERT_EQ(p1->base.interBytes, 24); + + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, function_Test4) { + SSqlInfo info1 = doGenerateAST("select _block_dist() as a1 from `t.1abc`"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 1); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); + ASSERT_EQ(p1->base.uid, 110); + ASSERT_EQ(p1->base.numOfParams, 1); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BINARY); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1"); // ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts"); // ASSERT_EQ(p1->base.colInfo.colId, 0); -// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); -// ASSERT_STRCASEEQ(p1->base.token, "first(ts)"); -// ASSERT_EQ(p1->base.interBytes, 24); -// -// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4); -// -// destroyQueryInfo(pQueryInfo); -// qParserClearupMetaRequestInfo(&req); -// destroySqlInfo(&info1); -//} -// -//TEST(testCase, function_Test4) { -// SSqlInfo info1 = doGenerateAST("select _block_dist() as a1 from `t.1abc`"); -// ASSERT_EQ(info1.valid, true); -// -// char msg[128] = {0}; -// SMsgBuf buf; -// buf.len = 128; -// buf.buf = msg; -// -// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); -// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); -// ASSERT_EQ(code, 0); -// -// SMetaReq req = {0}; -// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); -// ASSERT_EQ(ret, 0); -// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); -// -// SQueryStmtInfo* pQueryInfo = createQueryInfo(); -// setTableMetaInfo(pQueryInfo, &req); -// -// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); -// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); -// -// SArray* pExprList = pQueryInfo->exprList; -// ASSERT_EQ(taosArrayGetSize(pExprList), 1); -// -// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); -// ASSERT_EQ(p1->base.uid, 110); -// ASSERT_EQ(p1->base.numOfParams, 1); -// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BINARY); -// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1"); -//// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts"); -//// ASSERT_EQ(p1->base.colInfo.colId, 0); -// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); -// ASSERT_STRCASEEQ(p1->base.token, "_block_dist()"); -// ASSERT_EQ(p1->base.interBytes, 0); -// -// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1); -// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); -// -// destroyQueryInfo(pQueryInfo); -// qParserClearupMetaRequestInfo(&req); -// destroySqlInfo(&info1); -//} -// -//TEST(testCase, function_Test5) { -// SSqlInfo info1 = doGenerateAST("select sum(a) + avg(b) as a1 from `t.1abc`"); -// ASSERT_EQ(info1.valid, true); -// -// char msg[128] = {0}; -// SMsgBuf buf; -// buf.len = 128; -// buf.buf = msg; -// -// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); -// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); -// ASSERT_EQ(code, 0); -// -// SMetaReq req = {0}; -// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); -// ASSERT_EQ(ret, 0); -// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); -// -// SQueryStmtInfo* pQueryInfo = createQueryInfo(); -// setTableMetaInfo(pQueryInfo, &req); -// -// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); -// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); -// ASSERT_EQ(ret, 0); -// -// SArray* pExprList = pQueryInfo->exprList; -// ASSERT_EQ(taosArrayGetSize(pExprList), 3); -// -// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); -// ASSERT_EQ(p1->base.uid, 0); -// ASSERT_EQ(p1->base.numOfParams, 1); -// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); -// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1"); -//// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts"); -//// ASSERT_EQ(p1->base.colInfo.colId, 0); -// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); -// ASSERT_STRCASEEQ(p1->base.token, "sum(a) + avg(b)"); -// ASSERT_EQ(p1->base.interBytes, 0); -// -// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); -// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); -// -// destroyQueryInfo(pQueryInfo); -// qParserClearupMetaRequestInfo(&req); -// destroySqlInfo(&info1); -//} -// -//TEST(testCase, function_Test6) { -// SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1, first(b*a) from `t.1abc` interval(10s, 1s)"); -// ASSERT_EQ(info1.valid, true); -// -// char msg[128] = {0}; -// SMsgBuf buf; -// buf.len = 128; -// buf.buf = msg; -// -// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); -// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); -// ASSERT_EQ(code, 0); -// -// SMetaReq req = {0}; -// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); -// ASSERT_EQ(ret, 0); -// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); -// -// SQueryStmtInfo* pQueryInfo = createQueryInfo(); -// setTableMetaInfo(pQueryInfo, &req); -// -// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); -// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); -// ASSERT_EQ(ret, 0); -// -// SArray* pExprList = pQueryInfo->exprList; -// ASSERT_EQ(taosArrayGetSize(pExprList), 2); -// -// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); -// ASSERT_EQ(p1->base.uid, 110); -// ASSERT_EQ(p1->base.numOfParams, 0); -// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); -// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1"); -// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); -// ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)"); -// ASSERT_EQ(p1->base.interBytes, 16); -// ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE); -// ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_SUM); -// ASSERT_TRUE(p1->pExpr->_node.pRight == NULL); -// -// tExprNode* pParam = p1->pExpr->_node.pLeft; -// -// ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE); -// ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_ADD); -// ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_COL_NODE); -// ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_COL_NODE); -// -// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); -// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2); -// -// destroyQueryInfo(pQueryInfo); -// qParserClearupMetaRequestInfo(&req); -// destroySqlInfo(&info1); -//} \ No newline at end of file + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "_block_dist()"); + ASSERT_EQ(p1->base.interBytes, 0); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, function_Test5) { + SSqlInfo info1 = doGenerateAST("select sum(a) + avg(b) as a1 from `t.1abc`"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + ASSERT_EQ(ret, 0); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 3); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); + ASSERT_EQ(p1->base.uid, 0); + ASSERT_EQ(p1->base.numOfParams, 1); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1"); +// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts"); +// ASSERT_EQ(p1->base.colInfo.colId, 0); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "sum(a) + avg(b)"); + ASSERT_EQ(p1->base.interBytes, 0); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, function_Test6) { + SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1, first(b*a), count(b+b), count(1), count(42.1) from `t.1abc` interval(10s, 1s)"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + ASSERT_EQ(ret, 0); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 5); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); + ASSERT_EQ(p1->base.uid, 110); + ASSERT_EQ(p1->base.numOfParams, 0); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1"); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)"); + ASSERT_EQ(p1->base.interBytes, 16); + ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE); + ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_SUM); + ASSERT_TRUE(p1->pExpr->_node.pRight == NULL); + + tExprNode* pParam = p1->pExpr->_node.pLeft; + + ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE); + ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_ADD); + ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_COL_NODE); + ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_COL_NODE); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 5); + + SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1); + ASSERT_EQ(p2->base.uid, 110); + ASSERT_EQ(p2->base.numOfParams, 0); + ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); + ASSERT_STRCASEEQ(p2->base.resSchema.name, "first(b*a)"); + ASSERT_EQ(p2->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p2->base.token, "first(b*a)"); + ASSERT_EQ(p2->base.interBytes, 24); + ASSERT_EQ(p2->pExpr->nodeType, TEXPR_UNARYEXPR_NODE); + ASSERT_EQ(p2->pExpr->_node.functionId, FUNCTION_FIRST); + ASSERT_TRUE(p2->pExpr->_node.pRight == NULL); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, function_Test7) { + SSqlInfo info1 = doGenerateAST("select count(a+b),count(1) from `t.1abc` interval(10s, 1s)"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + ASSERT_EQ(ret, 0); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 2); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); + ASSERT_EQ(p1->base.uid, 110); + ASSERT_EQ(p1->base.numOfParams, 0); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a+b)"); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "count(a+b)"); + ASSERT_EQ(p1->base.interBytes, 8); + ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE); + ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_COUNT); + ASSERT_TRUE(p1->pExpr->_node.pRight == NULL); + + tExprNode* pParam = p1->pExpr->_node.pLeft; + + ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE); + ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_ADD); + ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_COL_NODE); + ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_COL_NODE); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, function_Test8) { + SSqlInfo info1 = doGenerateAST("select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + ASSERT_EQ(ret, 0); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 2); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 1); + ASSERT_EQ(p1->base.uid, 110); + ASSERT_EQ(p1->base.numOfParams, 1); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)"); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)"); + ASSERT_EQ(p1->base.interBytes, 16); + + ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE); + ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_TOP); + ASSERT_TRUE(p1->pExpr->_node.pRight == NULL); + + tExprNode* pParam = p1->pExpr->_node.pLeft; + + ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE); + ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_DIVIDE); + ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_BINARYEXPR_NODE); + ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_VALUE_NODE); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, invalid_sql_Test) { + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlInfo info1 = doGenerateAST("select count(k) from `t.1abc` interval(10s, 1s)"); + ASSERT_EQ(info1.valid, true); + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + ASSERT_NE(ret, 0); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +//=============================================================================================================== + info1 = doGenerateAST("select top(a*b, ABC) from `t.1abc` interval(10s, 1s)"); + ASSERT_EQ(info1.valid, true); + + pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + ASSERT_NE(ret, 0); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} \ No newline at end of file diff --git a/source/libs/parser/test/plannerTest.cpp b/source/libs/parser/test/plannerTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..528116fc32932d56c860369cfb5b139f37ee48d3 --- /dev/null +++ b/source/libs/parser/test/plannerTest.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#pragma GCC diagnostic ignored "-Wwrite-strings" + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wsign-compare" +#include "os.h" + +#include "astGenerator.h" +#include "parserInt.h" +#include "taos.h" +#include "tdef.h" +#include "tvariant.h" +#include "planner.h" + +namespace { +void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_t colId) { + p->colId = colId; + p->bytes = bytes; + p->type = type; + strcpy(p->name, name); +} + +void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) { + pQueryInfo->numOfTables = 1; + + pQueryInfo->pTableMetaInfo = (STableMetaInfo**)calloc(1, POINTER_BYTES); + STableMetaInfo* pTableMetaInfo = (STableMetaInfo*)calloc(1, sizeof(STableMetaInfo)); + pQueryInfo->pTableMetaInfo[0] = pTableMetaInfo; + + SName* name = (SName*)taosArrayGet(req->pTableName, 0); + + memcpy(&pTableMetaInfo->name, taosArrayGet(req->pTableName, 0), sizeof(SName)); + pTableMetaInfo->pTableMeta = (STableMeta*)calloc(1, sizeof(STableMeta) + 4 * sizeof(SSchema)); + strcpy(pTableMetaInfo->aliasName, name->tname); + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + pTableMeta->tableType = TSDB_NORMAL_TABLE; + pTableMeta->tableInfo.numOfColumns = 4; + pTableMeta->tableInfo.rowSize = 28; + pTableMeta->uid = 110; + + pTableMetaInfo->tagColList = (SArray*) taosArrayInit(4, POINTER_BYTES); + + SSchema* pSchema = pTableMetaInfo->pTableMeta->schema; + setSchema(&pSchema[0], TSDB_DATA_TYPE_TIMESTAMP, 8, "ts", 0); + setSchema(&pSchema[1], TSDB_DATA_TYPE_INT, 4, "a", 1); + setSchema(&pSchema[2], TSDB_DATA_TYPE_DOUBLE, 8, "b", 2); + setSchema(&pSchema[3], TSDB_DATA_TYPE_DOUBLE, 8, "col", 3); + +} +} + +TEST(testCase, planner_test) { + SSqlInfo info1 = doGenerateAST("select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SMetaReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + ASSERT_EQ(ret, 0); + + SArray* pExprList = pQueryInfo->exprList; + ASSERT_EQ(taosArrayGetSize(pExprList), 2); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 1); + ASSERT_EQ(p1->base.uid, 110); + ASSERT_EQ(p1->base.numOfParams, 1); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)"); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)"); + ASSERT_EQ(p1->base.interBytes, 16); + + ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE); + ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_TOP); + ASSERT_TRUE(p1->pExpr->_node.pRight == NULL); + + tExprNode* pParam = p1->pExpr->_node.pLeft; + + ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE); + ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_DIVIDE); + ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_BINARYEXPR_NODE); + ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_VALUE_NODE); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2); + + struct SQueryPlanNode* n = nullptr; + code = qCreateQueryPlan(pQueryInfo, &n); + + char* str = NULL; + qQueryPlanToString(n, &str); + printf("%s\n", str); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} \ No newline at end of file diff --git a/source/libs/parser/test/tokenizerTest.cpp b/source/libs/parser/test/tokenizerTest.cpp index 2296ede80be17b4cd0c94c2602f049f04f916173..7d6f55692d4517911702c963875259a8dfe189e6 100644 --- a/source/libs/parser/test/tokenizerTest.cpp +++ b/source/libs/parser/test/tokenizerTest.cpp @@ -37,22 +37,22 @@ SToken createToken(char* s) { } // namespace static void _init_tvariant_bool(SVariant* t) { - t->i64 = TSDB_FALSE; + t->i = TSDB_FALSE; t->nType = TSDB_DATA_TYPE_BOOL; } static void _init_tvariant_tinyint(SVariant* t) { - t->i64 = -27; + t->i = -27; t->nType = TSDB_DATA_TYPE_TINYINT; } static void _init_tvariant_int(SVariant* t) { - t->i64 = -23997659; + t->i = -23997659; t->nType = TSDB_DATA_TYPE_INT; } static void _init_tvariant_bigint(SVariant* t) { - t->i64 = -3333333333333; + t->i = -3333333333333; t->nType = TSDB_DATA_TYPE_BIGINT; } @@ -359,19 +359,19 @@ TEST(testCase, tvariant_convert) { _init_tvariant_bool(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), 0); - EXPECT_EQ(t.i64, 0); + EXPECT_EQ(t.i, 0); _init_tvariant_bool(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_TINYINT), 0); - EXPECT_EQ(t.i64, 0); + EXPECT_EQ(t.i, 0); _init_tvariant_bool(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_SMALLINT), 0); - EXPECT_EQ(t.i64, 0); + EXPECT_EQ(t.i, 0); _init_tvariant_bool(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BIGINT), 0); - EXPECT_EQ(t.i64, 0); + EXPECT_EQ(t.i, 0); _init_tvariant_bool(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_FLOAT), 0); @@ -394,23 +394,23 @@ TEST(testCase, tvariant_convert) { // 2. tinyint to other data types _init_tvariant_tinyint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), 0); - EXPECT_EQ(t.i64, 1); + EXPECT_EQ(t.i, 1); _init_tvariant_tinyint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_TINYINT), 0); - EXPECT_EQ(t.i64, -27); + EXPECT_EQ(t.i, -27); _init_tvariant_tinyint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_SMALLINT), 0); - EXPECT_EQ(t.i64, -27); + EXPECT_EQ(t.i, -27); _init_tvariant_tinyint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_INT), 0); - EXPECT_EQ(t.i64, -27); + EXPECT_EQ(t.i, -27); _init_tvariant_tinyint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BIGINT), 0); - EXPECT_EQ(t.i64, -27); + EXPECT_EQ(t.i, -27); _init_tvariant_tinyint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_FLOAT), 0); @@ -434,7 +434,7 @@ TEST(testCase, tvariant_convert) { // types////////////////////////////////////////////////////////////////// _init_tvariant_int(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), 0); - EXPECT_EQ(t.i64, 1); + EXPECT_EQ(t.i, 1); _init_tvariant_int(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_TINYINT), 0); @@ -444,11 +444,11 @@ TEST(testCase, tvariant_convert) { _init_tvariant_int(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_INT), 0); - EXPECT_EQ(t.i64, -23997659); + EXPECT_EQ(t.i, -23997659); _init_tvariant_int(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BIGINT), 0); - EXPECT_EQ(t.i64, -23997659); + EXPECT_EQ(t.i, -23997659); _init_tvariant_int(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_FLOAT), 0); @@ -472,7 +472,7 @@ TEST(testCase, tvariant_convert) { // type////////////////////////////////////////////////////////////////////////////// _init_tvariant_bigint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), 0); - EXPECT_EQ(t.i64, 1); + EXPECT_EQ(t.i, 1); _init_tvariant_bigint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_TINYINT), 0); @@ -485,7 +485,7 @@ TEST(testCase, tvariant_convert) { _init_tvariant_bigint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BIGINT), 0); - EXPECT_EQ(t.i64, -3333333333333); + EXPECT_EQ(t.i, -3333333333333); _init_tvariant_bigint(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_FLOAT), 0); @@ -509,11 +509,11 @@ TEST(testCase, tvariant_convert) { // types//////////////////////////////////////////////////////////////////////// _init_tvariant_float(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), 0); - EXPECT_EQ(t.i64, 1); + EXPECT_EQ(t.i, 1); _init_tvariant_float(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BIGINT), 0); - EXPECT_EQ(t.i64, -8991212199); + EXPECT_EQ(t.i, -8991212199); _init_tvariant_float(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_FLOAT), 0); @@ -539,14 +539,14 @@ TEST(testCase, tvariant_convert) { t.nLen = strlen(t.pz); t.nType = TSDB_DATA_TYPE_BINARY; EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), 0); - EXPECT_EQ(t.i64, 1); + EXPECT_EQ(t.i, 1); _init_tvariant_binary(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), -1); _init_tvariant_binary(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BIGINT), 0); - EXPECT_EQ(t.i64, 200000); + EXPECT_EQ(t.i, 200000); _init_tvariant_binary(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_FLOAT), 0); @@ -572,14 +572,14 @@ TEST(testCase, tvariant_convert) { t.nLen = wcslen(t.wpz); t.nType = TSDB_DATA_TYPE_NCHAR; EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), 0); - EXPECT_EQ(t.i64, 0); + EXPECT_EQ(t.i, 0); _init_tvariant_nchar(&t); EXPECT_LE(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BOOL), 0); _init_tvariant_nchar(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_BIGINT), 0); - EXPECT_EQ(t.i64, -2000000); + EXPECT_EQ(t.i, -2000000); _init_tvariant_nchar(&t); EXPECT_EQ(taosVariantTypeSetType(&t, TSDB_DATA_TYPE_FLOAT), 0); @@ -667,59 +667,59 @@ TEST(testCase, isValidNumber_test) { EXPECT_EQ(tGetNumericStringType(&t1), TK_FLOAT); } -//TEST(testCase, generateAST_test) { -// SSqlInfo info = doGenerateAST("select * from t1 where ts < now"); -// ASSERT_EQ(info.valid, true); -// -// SSqlInfo info1 = doGenerateAST("select * from `t.1abc` where ts + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef TDENGINE_PLANNERUTIL_H +#define TDENGINE_PLANNERUTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "parser.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#endif // TDENGINE_PLANNERUTIL_H diff --git a/source/libs/planner/src/planner.c b/source/libs/planner/src/planner.c index 5ff1fe08d629be510854e7aedf3115c61ac6bbe6..1a6c496cd0eb39ac0104d8c5b9cd43a448d0211e 100644 --- a/source/libs/planner/src/planner.c +++ b/source/libs/planner/src/planner.c @@ -46,23 +46,20 @@ typedef struct SJoinCond { static SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo); static void doDestroyQueryNode(SQueryPlanNode* pQueryNode); - int32_t qOptimizeQueryPlan(struct SQueryPlanNode* pQueryNode) { +int32_t qOptimizeQueryPlan(struct SQueryPlanNode* pQueryNode) { return 0; } -int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode* pQueryNode) { +int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode** pQueryNode) { SArray* upstream = createQueryPlanImpl((struct SQueryStmtInfo*) pQueryInfo); assert(taosArrayGetSize(upstream) == 1); - /*SQueryPlanNode* p = */taosArrayGetP(upstream, 0); + *pQueryNode = taosArrayGetP(upstream, 0); + taosArrayDestroy(upstream); return TSDB_CODE_SUCCESS; } -int32_t qQueryPlanToString(struct SQueryPlanNode* pQueryNode, char** str) { - return 0; -} - int32_t qQueryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql) { return 0; } @@ -108,10 +105,10 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla } pNode->numOfOutput = numOfOutput; - pNode->pExpr = calloc(numOfOutput, sizeof(SExprInfo)); + pNode->pExpr = taosArrayInit(numOfOutput, POINTER_BYTES); + for(int32_t i = 0; i < numOfOutput; ++i) { - SExprInfo* pExprInfo = taosArrayGet(pNode->pExpr, i); - assignExprInfo(pExprInfo, pExpr[i]); + taosArrayPush(pNode->pExpr, &pExpr[i]); } pNode->pPrevNodes = taosArrayInit(4, POINTER_BYTES); @@ -167,7 +164,7 @@ static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMe int32_t num = (int32_t) taosArrayGetSize(pExprs); SQueryPlanNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info, NULL); - if (pQueryInfo->distinct) { + if (pQueryInfo->info.distinct) { pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, info, NULL); } @@ -184,22 +181,21 @@ static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMe // table source column projection, generate the projection expr int32_t numOfCols = (int32_t) taosArrayGetSize(tableCols); SExprInfo** pExpr = calloc(numOfCols, POINTER_BYTES); - SSchema* pSchema = pTableMetaInfo->pTableMeta->schema; STableMetaInfo* pTableMetaInfo1 = getMetaInfo(pQueryInfo, 0); - SSchema resultSchema = *pSchema; - resultSchema.colId = getNewResColId(); for (int32_t i = 0; i < numOfCols; ++i) { SColumn* pCol = taosArrayGetP(tableCols, i); SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex}; + SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, i); + SSchema resultSchema = *pSchema; + SExprInfo* p = createExprInfo(pTableMetaInfo1, FUNCTION_PRJ, &index, NULL, &resultSchema, 0); pExpr[i] = p; } pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExpr, numOfCols, info, NULL); -// dropAllExprInfo(pExpr); tfree(pExpr); } @@ -254,7 +250,7 @@ static SQueryPlanNode* doCreateQueryPlanForOneTableImpl(SQueryStmtInfo* pQueryIn static SQueryPlanNode* doCreateQueryPlanForOneTable(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs, SArray* tableCols) { char name[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, name); + tstrncpy(name, pTableMetaInfo->name.tname, TSDB_TABLE_FNAME_LEN); SQueryTableInfo info = {.tableName = strdup(name), .uid = pTableMetaInfo->pTableMeta->uid,}; @@ -357,12 +353,6 @@ static void doDestroyQueryNode(SQueryPlanNode* pQueryNode) { tfree(pQueryNode); } -bool hasAliasName(SExprInfo* pExpr) { - assert(pExpr != NULL); - return true; -// return strncmp(pExpr->base.token, pExpr->base., tListLen(pExpr->base.aliasName)) != 0; -} - static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, int32_t totalLen) { if (level > 0) { sprintf(buf + totalLen, "%*c", level, ' '); @@ -412,13 +402,7 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i); SSqlExpr* pExpr = &pExprInfo->base; -// if (hasAliasName(&pQueryNode->pExpr[i])) { - len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->resSchema.name); -// } else { -// len1 = sprintf(buf + len,"[%s]", pExpr->token); -// } - - len += len1; + len += sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId); if (i < pQueryNode->numOfOutput - 1) { len1 = sprintf(buf + len, ", "); len += len1; @@ -435,13 +419,7 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i); SSqlExpr* pExpr = &pExprInfo->base; - if (hasAliasName(pExprInfo)) { - len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->resSchema.name); - } else { - len1 = sprintf(buf + len,"[%s]", pExpr->token); - } - - len += len1; + len += sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId); if (i < pQueryNode->numOfOutput - 1) { len1 = sprintf(buf + len,", "); len += len1; @@ -452,9 +430,11 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, len += len1; SInterval* pInterval = pQueryNode->pExtInfo; - len1 = sprintf(buf + len, "interval:%" PRId64 "(%s), sliding:%" PRId64 "(%s), offset:%" PRId64 "\n", + + // todo dynamic return the time precision + len1 = sprintf(buf + len, "interval:%" PRId64 "(%s), sliding:%" PRId64 "(%s), offset:%" PRId64 "(%s)\n", pInterval->interval, TSDB_TIME_PRECISION_MILLI_STR, pInterval->sliding, TSDB_TIME_PRECISION_MILLI_STR, - pInterval->offset); + pInterval->offset, TSDB_TIME_PRECISION_MILLI_STR); len += len1; break; @@ -465,12 +445,7 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i); SSqlExpr* pExpr = &pExprInfo->base; - - if (hasAliasName(pExprInfo)) { - len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->resSchema.name); - } else { - len1 = sprintf(buf + len,"[%s]", pExpr->token); - } + len1 = sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId); len += len1; if (i < pQueryNode->numOfOutput - 1) { @@ -568,14 +543,15 @@ int32_t queryPlanToStringImpl(char* buf, SQueryPlanNode* pQueryNode, int32_t lev return len; } -char* queryPlanToString(SQueryPlanNode* pQueryNode) { +int32_t qQueryPlanToString(struct SQueryPlanNode* pQueryNode, char** str) { assert(pQueryNode); - char* buf = calloc(1, 4096); + *str = calloc(1, 4096); - int32_t len = sprintf(buf, "===== logic plan =====\n"); - queryPlanToStringImpl(buf, pQueryNode, 0, len); - return buf; + int32_t len = sprintf(*str, "===== logic plan =====\n"); + queryPlanToStringImpl(*str, pQueryNode, 0, len); + + return TSDB_CODE_SUCCESS; } SQueryPlanNode* queryPlanFromString() { diff --git a/source/libs/planner/src/plannerUtil.c b/source/libs/planner/src/plannerUtil.c new file mode 100644 index 0000000000000000000000000000000000000000..b692fc67c2e04e5eaac600eca8c3fc8168593a39 --- /dev/null +++ b/source/libs/planner/src/plannerUtil.c @@ -0,0 +1,6 @@ +#include "tvariant.h" +#include "plannerUtil.h" + + + + diff --git a/source/libs/planner/test/CMakeLists.txt b/source/libs/planner/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a83d7a39d99a36fa1869dbc6874024155ef308f4 --- /dev/null +++ b/source/libs/planner/test/CMakeLists.txt @@ -0,0 +1,18 @@ + +MESSAGE(STATUS "build planner unit test") + +# GoogleTest requires at least C++11 +SET(CMAKE_CXX_STANDARD 11) +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) + +ADD_EXECUTABLE(plannerTest ${SOURCE_LIST}) +TARGET_LINK_LIBRARIES( + plannerTest + PUBLIC os util common planner parser catalog transport gtest function +) + +TARGET_INCLUDE_DIRECTORIES( + plannerTest + PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/planner/" + PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/planner/inc" +) diff --git a/source/libs/planner/test/plannerTests.cpp b/source/libs/planner/test/plannerTests.cpp index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5ede8dd15578b353953488a3104460bfd63d6cd8 100644 --- a/source/libs/planner/test/plannerTests.cpp +++ b/source/libs/planner/test/plannerTests.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "os.h" + +#include "taos.h" +#include "parser.h" + +#pragma GCC diagnostic ignored "-Wwrite-strings" + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wsign-compare" + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +TEST(testCase, planner_test) { + char msg[128] = {0}; + const char* sql = "select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)"; + + SQueryStmtInfo* pQueryInfo = nullptr; +// int32_t code = qParseQuerySql(sql, strlen(sql), &pQueryInfo, 0, msg, sizeof(msg)); +// ASSERT_EQ(code, 0); + +// SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.list), 0); +// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); +// ASSERT_EQ(code, 0); +// +// SMetaReq req = {0}; +// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); +// ASSERT_EQ(ret, 0); +// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); +// +// SQueryStmtInfo* pQueryInfo = createQueryInfo(); +// setTableMetaInfo(pQueryInfo, &req); +// +// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); +// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); +// ASSERT_EQ(ret, 0); +// +// SArray* pExprList = pQueryInfo->exprList; +// ASSERT_EQ(taosArrayGetSize(pExprList), 2); +// +// SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 1); +// ASSERT_EQ(p1->base.uid, 110); +// ASSERT_EQ(p1->base.numOfParams, 1); +// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); +// ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)"); +// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); +// ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)"); +// ASSERT_EQ(p1->base.interBytes, 16); +// +// ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE); +// ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_TOP); +// ASSERT_TRUE(p1->pExpr->_node.pRight == NULL); +// +// tExprNode* pParam = p1->pExpr->_node.pLeft; +// +// ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE); +// ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_DIVIDE); +// ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_BINARYEXPR_NODE); +// ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_VALUE_NODE); +// +// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); +// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2); +// +// destroyQueryInfo(pQueryInfo); +// qParserClearupMetaRequestInfo(&req); +// destroySqlInfo(&info1); +} \ No newline at end of file