diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index f987afd878f4a6e276b8031508bc5a58f92d3c75..6b6d11c2fef7b89ed16cfb5c4aef569a99b76af3 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -124,6 +124,7 @@ typedef struct STableNode { char dbName[TSDB_DB_NAME_LEN]; char tableName[TSDB_TABLE_NAME_LEN]; char tableAlias[TSDB_TABLE_NAME_LEN]; + uint8_t precision; } STableNode; struct STableMeta; @@ -236,6 +237,7 @@ typedef struct SSelectStmt { SNode* pLimit; SNode* pSlimit; char stmtName[TSDB_TABLE_NAME_LEN]; + uint8_t precision; } SSelectStmt; typedef enum ESetOperatorType { diff --git a/include/util/taoserror.h b/include/util/taoserror.h index ed90628bda4ee2a0e1c6982e37a0a5c32855c72c..37e05bf3d37c9dfd42d279e0dfa27f348f675dfe 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -483,16 +483,17 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME TAOS_DEF_ERROR_CODE(0, 0x2617) #define TSDB_CODE_PAR_CORRESPONDING_STABLE_ERR TAOS_DEF_ERROR_CODE(0, 0x2618) #define TSDB_CODE_PAR_INVALID_RANGE_OPTION TAOS_DEF_ERROR_CODE(0, 0x2619) -#define TSDB_CODE_PAR_INVALID_STR_OPTION TAOS_DEF_ERROR_CODE(0, 0x2620) -#define TSDB_CODE_PAR_INVALID_ENUM_OPTION TAOS_DEF_ERROR_CODE(0, 0x2621) -#define TSDB_CODE_PAR_INVALID_TTL_OPTION TAOS_DEF_ERROR_CODE(0, 0x2622) -#define TSDB_CODE_PAR_INVALID_KEEP_NUM TAOS_DEF_ERROR_CODE(0, 0x2623) -#define TSDB_CODE_PAR_INVALID_KEEP_ORDER TAOS_DEF_ERROR_CODE(0, 0x2624) -#define TSDB_CODE_PAR_INVALID_KEEP_VALUE TAOS_DEF_ERROR_CODE(0, 0x2625) -#define TSDB_CODE_PAR_INVALID_COMMENT_OPTION TAOS_DEF_ERROR_CODE(0, 0x2626) -#define TSDB_CODE_PAR_INVALID_F_RANGE_OPTION TAOS_DEF_ERROR_CODE(0, 0x2627) -#define TSDB_CODE_PAR_INVALID_ROLLUP_OPTION TAOS_DEF_ERROR_CODE(0, 0x2628) -#define TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION TAOS_DEF_ERROR_CODE(0, 0x2629) +#define TSDB_CODE_PAR_INVALID_STR_OPTION TAOS_DEF_ERROR_CODE(0, 0x261A) +#define TSDB_CODE_PAR_INVALID_ENUM_OPTION TAOS_DEF_ERROR_CODE(0, 0x261B) +#define TSDB_CODE_PAR_INVALID_TTL_OPTION TAOS_DEF_ERROR_CODE(0, 0x261C) +#define TSDB_CODE_PAR_INVALID_KEEP_NUM TAOS_DEF_ERROR_CODE(0, 0x261D) +#define TSDB_CODE_PAR_INVALID_KEEP_ORDER TAOS_DEF_ERROR_CODE(0, 0x261E) +#define TSDB_CODE_PAR_INVALID_KEEP_VALUE TAOS_DEF_ERROR_CODE(0, 0x261F) +#define TSDB_CODE_PAR_INVALID_COMMENT_OPTION TAOS_DEF_ERROR_CODE(0, 0x2620) +#define TSDB_CODE_PAR_INVALID_F_RANGE_OPTION TAOS_DEF_ERROR_CODE(0, 0x2621) +#define TSDB_CODE_PAR_INVALID_ROLLUP_OPTION TAOS_DEF_ERROR_CODE(0, 0x2622) +#define TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION TAOS_DEF_ERROR_CODE(0, 0x2623) +#define TSDB_CODE_PAR_GROUPBY_WINDOW_COEXIST TAOS_DEF_ERROR_CODE(0, 0x2624) //planner #define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700) diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index c3bc696a534cdc84a6dfc0314fd70ab3b59cc6ac..8f90670d13f48656f0a24c3f68300e55063aa5de 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -1578,7 +1578,7 @@ static int32_t datumToJson(const void* pObj, SJson* pJson) { case TSDB_DATA_TYPE_NULL: break; case TSDB_DATA_TYPE_BOOL: - code = tjsonAddIntegerToObject(pJson, jkValueDatum, pNode->datum.b); + code = tjsonAddBoolToObject(pJson, jkValueDatum, pNode->datum.b); break; case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_SMALLINT: diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 3491974eab965968099d9d59ecae2c092d112a5c..88c3d5b5497ca3fe03ad6a44abe0eb33dddf4447 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -376,8 +376,9 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) { } static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { + uint8_t precision = (NULL != pCxt->pCurrStmt ? pCxt->pCurrStmt->precision : pVal->node.resType.precision); if (pVal->isDuration) { - if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit, pVal->node.resType.precision) != TSDB_CODE_SUCCESS) { + if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit, precision) != TSDB_CODE_SUCCESS) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); } } else { @@ -421,7 +422,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { break; } case TSDB_DATA_TYPE_TIMESTAMP: { - if (taosParseTime(pVal->literal, &pVal->datum.i, pVal->node.resType.bytes, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) { + if (taosParseTime(pVal->literal, &pVal->datum.i, pVal->node.resType.bytes, precision, tsDaylight) != TSDB_CODE_SUCCESS) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); } break; @@ -683,6 +684,19 @@ static int32_t setTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTa return code; } +static uint8_t getStmtPrecision(SNode* pStmt) { + if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) { + return ((SSelectStmt*)pStmt)->precision; + } + return 0; +} + +static uint8_t getJoinTablePrecision(SJoinTableNode* pJoinTable) { + uint8_t lp = ((STableNode*)pJoinTable->pLeft)->precision; + uint8_t rp = ((STableNode*)pJoinTable->pRight)->precision; + return (lp > rp ? rp : lp); +} + static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) { int32_t code = TSDB_CODE_SUCCESS; switch (nodeType(pTable)) { @@ -695,6 +709,7 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) { if (TSDB_CODE_SUCCESS != code) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TABLE_NOT_EXIST, pRealTable->table.tableName); } + pRealTable->table.precision = pRealTable->pMeta->tableInfo.precision; code = setTableVgroupList(pCxt, &name, pRealTable); if (TSDB_CODE_SUCCESS == code) { code = addNamespace(pCxt, pRealTable); @@ -705,6 +720,7 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) { STempTableNode* pTempTable = (STempTableNode*)pTable; code = translateSubquery(pCxt, pTempTable->pSubquery); if (TSDB_CODE_SUCCESS == code) { + pTempTable->table.precision = getStmtPrecision(pTempTable->pSubquery); code = addNamespace(pCxt, pTempTable); } break; @@ -716,6 +732,7 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) { code = translateTable(pCxt, pJoinTable->pRight); } if (TSDB_CODE_SUCCESS == code) { + pJoinTable->table.precision = getJoinTablePrecision(pJoinTable); code = translateExpr(pCxt, pJoinTable->pOnCond); } break; @@ -852,9 +869,12 @@ static int32_t translateHaving(STranslateContext* pCxt, SSelectStmt* pSelect) { return code; } -static int32_t translateGroupBy(STranslateContext* pCxt, SNodeList* pGroupByList) { +static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) { + if (NULL != pSelect->pGroupByList && NULL != pSelect->pWindow) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_WINDOW_COEXIST); + } pCxt->currClause = SQL_CLAUSE_GROUP_BY; - return translateExprList(pCxt, pGroupByList); + return translateExprList(pCxt, pSelect->pGroupByList); } static int32_t translateIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode* pInterval) { @@ -899,14 +919,18 @@ static int32_t translateWhere(STranslateContext* pCxt, SNode* pWhere) { return translateExpr(pCxt, pWhere); } -static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) { +static int32_t translateFrom(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->currClause = SQL_CLAUSE_FROM; - return translateTable(pCxt, pTable); + int32_t code = translateTable(pCxt, pSelect->pFromTable); + if (TSDB_CODE_SUCCESS == code) { + pSelect->precision = ((STableNode*)pSelect->pFromTable)->precision; + } + return code; } static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->pCurrStmt = pSelect; - int32_t code = translateFrom(pCxt, pSelect->pFromTable); + int32_t code = translateFrom(pCxt, pSelect); if (TSDB_CODE_SUCCESS == code) { code = translateWhere(pCxt, pSelect->pWhere); } @@ -917,7 +941,7 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) { code = translateWindow(pCxt, pSelect->pWindow); } if (TSDB_CODE_SUCCESS == code) { - code = translateGroupBy(pCxt, pSelect->pGroupByList); + code = translateGroupBy(pCxt, pSelect); } if (TSDB_CODE_SUCCESS == code) { code = translateHaving(pCxt, pSelect); diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 5206e0f8a52ca410b991dcaf2f7894fc163d5616..171324aa99680b2daa6456af8e66a0204d405aeb 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -89,6 +89,8 @@ static char* getSyntaxErrFormat(int32_t errCode) { return "invalid option rollup: only one function is allowed"; case TSDB_CODE_PAR_INVALID_RETENTIONS_OPTION: return "invalid option retentions"; + case TSDB_CODE_PAR_GROUPBY_WINDOW_COEXIST: + return "GROUP BY and WINDOW-clause can't be used together"; case TSDB_CODE_OUT_OF_MEMORY: return "Out of memory"; default: