fix: problem of parser and planner
This commit is contained in:
parent
1088e463a4
commit
4c914c2960
|
@ -154,6 +154,7 @@ bool fmIsWindowClauseFunc(int32_t funcId);
|
|||
bool fmIsSpecialDataRequiredFunc(int32_t funcId);
|
||||
bool fmIsDynamicScanOptimizedFunc(int32_t funcId);
|
||||
bool fmIsMultiResFunc(int32_t funcId);
|
||||
bool fmIsRepeatScanFunc(int32_t funcId);
|
||||
bool fmIsUserDefinedFunc(int32_t funcId);
|
||||
|
||||
typedef enum EFuncDataRequired {
|
||||
|
@ -170,7 +171,7 @@ int32_t fmGetScalarFuncExecFuncs(int32_t funcId, SScalarFuncExecFuncs* pFpSet);
|
|||
int32_t fmGetUdafExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
int32_t fmSetInvertFunc(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
int32_t fmSetNormalFunc(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
bool fmIsInvertible(int32_t funcId);
|
||||
bool fmIsInvertible(int32_t funcId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE,
|
||||
QUERY_NODE_PHYSICAL_PLAN_SORT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_FILL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW,
|
||||
QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW,
|
||||
|
|
|
@ -274,6 +274,8 @@ typedef struct SIntervalPhysiNode {
|
|||
int8_t slidingUnit;
|
||||
} SIntervalPhysiNode;
|
||||
|
||||
typedef SIntervalPhysiNode SStreamIntervalPhysiNode;
|
||||
|
||||
typedef struct SFillPhysiNode {
|
||||
SPhysiNode node;
|
||||
EFillMode mode;
|
||||
|
|
|
@ -233,6 +233,7 @@ typedef struct SSelectStmt {
|
|||
uint8_t precision;
|
||||
bool isEmptyResult;
|
||||
bool hasAggFuncs;
|
||||
bool hasRepeatScanFuncs;
|
||||
bool isTimeOrderQuery;
|
||||
} SSelectStmt;
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ extern "C" {
|
|||
#define FUNC_MGT_MULTI_RES_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(11)
|
||||
#define FUNC_MGT_SCAN_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(12)
|
||||
#define FUNC_MGT_SELECT_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(13)
|
||||
#define FUNC_MGT_REPEAT_SCAN_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(14)
|
||||
|
||||
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType) { .bytes = 512, .type = TSDB_DATA_TYPE_BINARY };
|
||||
pFunc->node.resType = (SDataType){.bytes = 512, .type = TSDB_DATA_TYPE_BINARY};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,8 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
}
|
||||
|
||||
SExprNode* p1 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (!IS_NUMERIC_TYPE(p1->resType.type)) {
|
||||
if (!IS_SIGNED_NUMERIC_TYPE(p1->resType.type) && !IS_FLOAT_TYPE(p1->resType.type) &&
|
||||
TSDB_DATA_TYPE_BOOL != p1->resType.type) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
pFunc->node.resType = p1->resType;
|
||||
|
@ -549,7 +550,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
{
|
||||
.name = "percentile",
|
||||
.type = FUNCTION_TYPE_PERCENTILE,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_REPEAT_SCAN_FUNC,
|
||||
.translateFunc = translatePercentile,
|
||||
.getEnvFunc = getPercentileFuncEnv,
|
||||
.initFunc = percentileFunctionSetup,
|
||||
|
|
|
@ -169,6 +169,8 @@ bool fmIsDynamicScanOptimizedFunc(int32_t funcId) {
|
|||
|
||||
bool fmIsMultiResFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_MULTI_RES_FUNC); }
|
||||
|
||||
bool fmIsRepeatScanFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_REPEAT_SCAN_FUNC); }
|
||||
|
||||
bool fmIsUserDefinedFunc(int32_t funcId) { return funcId > FUNC_UDF_ID_START; }
|
||||
|
||||
void fmFuncMgtDestroy() {
|
||||
|
@ -197,15 +199,14 @@ int32_t fmSetNormalFunc(int32_t funcId, SFuncExecFuncs* pFpSet) {
|
|||
bool fmIsInvertible(int32_t funcId) {
|
||||
bool res = false;
|
||||
switch (funcMgtBuiltins[funcId].type) {
|
||||
case FUNCTION_TYPE_COUNT:
|
||||
case FUNCTION_TYPE_SUM:
|
||||
case FUNCTION_TYPE_STDDEV:
|
||||
case FUNCTION_TYPE_AVG:
|
||||
res = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case FUNCTION_TYPE_COUNT:
|
||||
case FUNCTION_TYPE_SUM:
|
||||
case FUNCTION_TYPE_STDDEV:
|
||||
case FUNCTION_TYPE_AVG:
|
||||
res = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,8 @@ const char* nodesNodeName(ENodeType type) {
|
|||
return "PhysiSort";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return "PhysiInterval";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
return "PhysiStreamInterval";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
return "PhysiFill";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
|
@ -2893,6 +2895,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
||||
return physiSortNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
return physiIntervalNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
return physiFillNodeToJson(pObj, pJson);
|
||||
|
@ -2983,6 +2986,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
|||
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
||||
return jsonToPhysiSortNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
return jsonToPhysiIntervalNode(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
return jsonToPhysiFillNode(pJson, pObj);
|
||||
|
@ -3099,6 +3103,7 @@ int32_t nodesStringToNode(const char* pStr, SNode** pNode) {
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
int32_t code = makeNodeByJson(pJson, pNode);
|
||||
tjsonDelete(pJson);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = NULL;
|
||||
|
|
|
@ -513,6 +513,7 @@ static EDealRes dispatchPhysiPlan(SNode* pNode, ETraversalOrder order, FNodeWalk
|
|||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
|
|
|
@ -252,6 +252,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SSortPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return makeNode(type, sizeof(SIntervalPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
return makeNode(type, sizeof(SStreamIntervalPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_FILL:
|
||||
return makeNode(type, sizeof(SFillPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
|
@ -644,6 +646,7 @@ void nodesDestroyNode(SNodeptr pNode) {
|
|||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL:
|
||||
destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
|
||||
|
|
|
@ -64,8 +64,8 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) {
|
|||
goto abort_parse;
|
||||
}
|
||||
default:
|
||||
Parse(pParser, t0.type, t0, &cxt);
|
||||
// ParseTrace(stdout, "");
|
||||
Parse(pParser, t0.type, t0, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
goto abort_parse;
|
||||
}
|
||||
|
|
|
@ -590,6 +590,8 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
|||
if (seg == 4) { // ip address
|
||||
*tokenId = TK_NK_IPTOKEN;
|
||||
return i;
|
||||
} else if (seg > 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((z[i] == 'e' || z[i] == 'E') &&
|
||||
|
|
|
@ -699,6 +699,10 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
|||
if (isCountStar(pFunc)) {
|
||||
pCxt->errCode = rewriteCountStar(pCxt, pFunc);
|
||||
}
|
||||
|
||||
if (fmIsRepeatScanFunc(pFunc->funcId)) {
|
||||
pCxt->pCurrStmt->hasRepeatScanFuncs = true;
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
|
||||
}
|
||||
|
@ -2255,8 +2259,8 @@ static int32_t checkTableColsSchema(STranslateContext* pCxt, SHashObj* pHash, SN
|
|||
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if ((TSDB_DATA_TYPE_VARCHAR == pCol->dataType.type && pCol->dataType.bytes > TSDB_MAX_BINARY_LEN) ||
|
||||
(TSDB_DATA_TYPE_NCHAR == pCol->dataType.type && pCol->dataType.bytes > TSDB_MAX_NCHAR_LEN)) {
|
||||
if ((TSDB_DATA_TYPE_VARCHAR == pCol->dataType.type && calcTypeBytes(pCol->dataType) > TSDB_MAX_BINARY_LEN) ||
|
||||
(TSDB_DATA_TYPE_NCHAR == pCol->dataType.type && calcTypeBytes(pCol->dataType) > TSDB_MAX_NCHAR_LEN)) {
|
||||
code = code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,13 +37,15 @@ TEST_F(ParserSelectTest, basic) {
|
|||
|
||||
TEST_F(ParserSelectTest, constant) {
|
||||
useDb("root", "test");
|
||||
|
||||
#if 0
|
||||
run("SELECT 123, 20.4, 'abc', \"wxy\", timestamp '2022-02-09 17:30:20', true, false, 10s FROM t1");
|
||||
|
||||
run("SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", "
|
||||
"timestamp '2022-02-09 17:30:20', true, false, 15s FROM t1");
|
||||
|
||||
run("SELECT 123 + 45 FROM t1 WHERE 2 - 1");
|
||||
#endif
|
||||
run("SELECT 1.1.1 FROM t1");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, expression) {
|
||||
|
|
|
@ -54,6 +54,9 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
|
|||
pCol->node.resType = pToBeRewrittenExpr->resType;
|
||||
strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
|
||||
strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName);
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pExpr) && FUNCTION_TYPE_WSTARTTS == ((SFunctionNode*)pExpr)->funcType) {
|
||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
}
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = (SNode*)pCol;
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
|
@ -253,7 +256,7 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
|||
|
||||
TSWAP(pScan->pMeta, pRealTable->pMeta);
|
||||
TSWAP(pScan->pVgroupList, pRealTable->pVgroupList);
|
||||
pScan->scanSeq[0] = 1;
|
||||
pScan->scanSeq[0] = pSelect->hasRepeatScanFuncs ? 2 : 1;
|
||||
pScan->scanSeq[1] = 0;
|
||||
pScan->scanRange = TSWINDOW_INITIALIZER;
|
||||
pScan->tableName.type = TSDB_TABLE_NAME_T;
|
||||
|
|
|
@ -754,10 +754,7 @@ static int32_t opkDoOptimized(SOptimizeContext* pCxt, SSortLogicNode* pSort, SNo
|
|||
EOrder order = opkGetPrimaryKeyOrder(pSort);
|
||||
if (ORDER_DESC == order) {
|
||||
SNode* pScan = NULL;
|
||||
FOREACH(pScan, pScanNodes) {
|
||||
((SScanLogicNode*)pScan)->scanSeq[0] = 0;
|
||||
((SScanLogicNode*)pScan)->scanSeq[1] = 1;
|
||||
}
|
||||
FOREACH(pScan, pScanNodes) { TSWAP(((SScanLogicNode*)pScan)->scanSeq[0], ((SScanLogicNode*)pScan)->scanSeq[1]); }
|
||||
}
|
||||
|
||||
if (NULL == pSort->node.pParent) {
|
||||
|
|
|
@ -869,7 +869,8 @@ static int32_t createWindowPhysiNodeFinalize(SPhysiPlanContext* pCxt, SNodeList*
|
|||
static int32_t createIntervalPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
|
||||
SWindowLogicNode* pWindowLogicNode, SPhysiNode** pPhyNode) {
|
||||
SIntervalPhysiNode* pInterval = (SIntervalPhysiNode*)makePhysiNode(
|
||||
pCxt, getPrecision(pChildren), (SLogicNode*)pWindowLogicNode, QUERY_NODE_PHYSICAL_PLAN_INTERVAL);
|
||||
pCxt, getPrecision(pChildren), (SLogicNode*)pWindowLogicNode,
|
||||
(pCxt->pPlanCxt->streamQuery ? QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL : QUERY_NODE_PHYSICAL_PLAN_INTERVAL));
|
||||
if (NULL == pInterval) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -48,4 +48,6 @@ TEST_F(PlanBasicTest, func) {
|
|||
useDb("root", "test");
|
||||
|
||||
run("SELECT DIFF(c1) FROM t1");
|
||||
|
||||
run("SELECT PERCENTILE(c1, 60) FROM t1");
|
||||
}
|
||||
|
|
|
@ -37,4 +37,6 @@ TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
|
|||
run("SELECT * FROM t1 ORDER BY ts DESC");
|
||||
run("SELECT c1 FROM t1 ORDER BY ts");
|
||||
run("SELECT c1 FROM t1 ORDER BY ts DESC");
|
||||
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10S) ORDER BY _WSTARTTS DESC");
|
||||
}
|
||||
|
|
|
@ -101,8 +101,8 @@ if [ "$EXEC_OPTON" = "start" ]; then
|
|||
if [ "$VALGRIND_OPTION" = "true" ]; then
|
||||
TT=`date +%s`
|
||||
#mkdir ${LOG_DIR}/${TT}
|
||||
echo "nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &"
|
||||
nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &
|
||||
echo "nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &"
|
||||
nohup valgrind --log-file=${LOG_DIR}/valgrind-taosd-${NODE_NAME}-${TT}.log --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v -v --workaround-gcc296-bugs=yes $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &
|
||||
else
|
||||
echo "nohup $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &"
|
||||
nohup $EXE_DIR/taosd -c $CFG_DIR > /dev/null 2>&1 &
|
||||
|
|
|
@ -131,8 +131,8 @@ if [ -n "$FILE_NAME" ]; then
|
|||
FLAG="-v"
|
||||
fi
|
||||
|
||||
echo valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --child-silent-after-fork=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes --log-file=${LOG_DIR}/valgrind-tsim.log $PROGRAM -c $CFG_DIR -f $FILE_NAME $FLAG
|
||||
valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --child-silent-after-fork=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes --log-file=${LOG_DIR}/valgrind-tsim.log $PROGRAM -c $CFG_DIR -f $FILE_NAME $FLAG
|
||||
echo valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --child-silent-after-fork=yes --show-leak-kinds=all --num-callers=20 -v --workaround-gcc296-bugs=yes --log-file=${LOG_DIR}/valgrind-tsim.log $PROGRAM -c $CFG_DIR -f $FILE_NAME $FLAG
|
||||
valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --child-silent-after-fork=yes --show-leak-kinds=all --num-callers=20 -v --workaround-gcc296-bugs=yes --log-file=${LOG_DIR}/valgrind-tsim.log $PROGRAM -c $CFG_DIR -f $FILE_NAME $FLAG
|
||||
else
|
||||
if [[ $MULTIPROCESS -eq 1 ]];then
|
||||
echo "ExcuteCmd(multiprocess):" $PROGRAM -m -c $CFG_DIR -f $FILE_NAME
|
||||
|
|
Loading…
Reference in New Issue