提交 3c7927d2 编写于 作者: X Xiaoyu Wang

normal table rollup translate, and condition rewrite

上级 709dda39
...@@ -94,6 +94,7 @@ typedef struct SColumnDefNode { ...@@ -94,6 +94,7 @@ typedef struct SColumnDefNode {
char colName[TSDB_COL_NAME_LEN]; char colName[TSDB_COL_NAME_LEN];
SDataType dataType; SDataType dataType;
char comments[TSDB_STB_COMMENT_LEN]; char comments[TSDB_STB_COMMENT_LEN];
bool sma;
} SColumnDefNode; } SColumnDefNode;
typedef struct SCreateTableStmt { typedef struct SCreateTableStmt {
......
...@@ -1050,6 +1050,7 @@ SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDat ...@@ -1050,6 +1050,7 @@ SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDat
if (NULL != pComment) { if (NULL != pComment) {
trimString(pComment->z, pComment->n, pCol->comments, sizeof(pCol->comments)); trimString(pComment->z, pComment->n, pCol->comments, sizeof(pCol->comments));
} }
pCol->sma = true;
return (SNode*)pCol; return (SNode*)pCol;
} }
......
...@@ -65,7 +65,7 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) { ...@@ -65,7 +65,7 @@ int32_t parse(SParseContext* pParseCxt, SQuery** pQuery) {
} }
default: default:
Parse(pParser, t0.type, t0, &cxt); Parse(pParser, t0.type, t0, &cxt);
// ParseTrace(stdout, ""); ParseTrace(stdout, "");
if (!cxt.valid) { if (!cxt.valid) {
goto abort_parse; goto abort_parse;
} }
......
...@@ -90,14 +90,91 @@ static EDealRes calcConst(SNode** pNode, void* pContext) { ...@@ -90,14 +90,91 @@ static EDealRes calcConst(SNode** pNode, void* pContext) {
return DEAL_RES_CONTINUE; return DEAL_RES_CONTINUE;
} }
static bool isCondition(const SNode* pNode) {
if (QUERY_NODE_OPERATOR == nodeType(pNode)) {
return nodesIsComparisonOp((const SOperatorNode*)pNode);
}
return (QUERY_NODE_LOGIC_CONDITION == nodeType(pNode));
}
static int32_t rewriteIsTrue(SNode* pSrc, SNode** pIsTrue) {
SOperatorNode* pOp = nodesMakeNode(QUERY_NODE_OPERATOR);
if (NULL == pOp) {
return TSDB_CODE_OUT_OF_MEMORY;
}
pOp->opType = OP_TYPE_IS_TRUE;
pOp->pLeft = pSrc;
*pIsTrue = (SNode*)pOp;
return TSDB_CODE_SUCCESS;
}
static EDealRes doRewriteCondition(SNode** pNode, void* pContext) {
if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pNode)) {
SNode* pParam = NULL;
FOREACH(pParam, ((SLogicConditionNode*)*pNode)->pParameterList) {
if (!isCondition(pParam)) {
SNode* pIsTrue = NULL;
if (TSDB_CODE_SUCCESS != rewriteIsTrue(pParam, &pIsTrue)) {
((SCalcConstContext*)pContext)->code = TSDB_CODE_OUT_OF_MEMORY;
return DEAL_RES_ERROR;
}
REPLACE_NODE(pIsTrue);
}
}
}
return DEAL_RES_CONTINUE;
}
static int32_t rewriteCondition(SCalcConstContext* pCxt, SNode** pNode) {
if (!isCondition(*pNode)) {
return rewriteIsTrue(*pNode, pNode);
}
nodesRewriteExprPostOrder(pNode, doRewriteCondition, pCxt);
return pCxt->code;
}
static int32_t rewriteConditionForFromTable(SCalcConstContext* pCxt, SNode* pTable) {
if (QUERY_NODE_JOIN_TABLE == nodeType(pTable)) {
SJoinTableNode* pJoin = (SJoinTableNode*)pTable;
pCxt->code = rewriteConditionForFromTable(pCxt, pJoin->pLeft);
if (TSDB_CODE_SUCCESS == pCxt->code) {
pCxt->code = rewriteConditionForFromTable(pCxt, pJoin->pRight);
}
if (TSDB_CODE_SUCCESS == pCxt->code) {
pCxt->code = rewriteCondition(pCxt, &pJoin->pOnCond);
}
}
return pCxt->code;
}
static int32_t calcConstFromTable(SCalcConstContext* pCxt, SSelectStmt* pSelect) {
nodesRewriteExprPostOrder(&pSelect->pFromTable, calcConst, pCxt);
if (TSDB_CODE_SUCCESS == pCxt->code) {
pCxt->code = rewriteConditionForFromTable(pCxt, pSelect->pFromTable);
}
return pCxt->code;
}
static int32_t calcConstCondition(SCalcConstContext* pCxt, SNode** pCond) {
if (NULL == *pCond) {
return TSDB_CODE_SUCCESS;
}
nodesRewriteExprPostOrder(pCond, calcConst, pCxt);
if (TSDB_CODE_SUCCESS == pCxt->code) {
pCxt->code = rewriteCondition(pCxt, pCond);
}
return pCxt->code;
}
static int32_t calcConstSelect(SSelectStmt* pSelect) { static int32_t calcConstSelect(SSelectStmt* pSelect) {
SCalcConstContext cxt = { .code = TSDB_CODE_SUCCESS }; SCalcConstContext cxt = { .code = TSDB_CODE_SUCCESS };
nodesRewriteExprsPostOrder(pSelect->pProjectionList, calcConst, &cxt); nodesRewriteExprsPostOrder(pSelect->pProjectionList, calcConst, &cxt);
if (TSDB_CODE_SUCCESS == cxt.code) { if (TSDB_CODE_SUCCESS == cxt.code) {
nodesRewriteExprPostOrder(&pSelect->pFromTable, calcConst, &cxt); cxt.code = calcConstFromTable(&cxt, pSelect);
} }
if (TSDB_CODE_SUCCESS == cxt.code) { if (TSDB_CODE_SUCCESS == cxt.code) {
nodesRewriteExprPostOrder(&pSelect->pWhere, calcConst, &cxt); cxt.code = calcConstCondition(&cxt, &pSelect->pWhere);
} }
if (TSDB_CODE_SUCCESS == cxt.code) { if (TSDB_CODE_SUCCESS == cxt.code) {
nodesRewriteExprsPostOrder(pSelect->pPartitionByList, calcConst, &cxt); nodesRewriteExprsPostOrder(pSelect->pPartitionByList, calcConst, &cxt);
...@@ -109,7 +186,7 @@ static int32_t calcConstSelect(SSelectStmt* pSelect) { ...@@ -109,7 +186,7 @@ static int32_t calcConstSelect(SSelectStmt* pSelect) {
nodesRewriteExprsPostOrder(pSelect->pGroupByList, calcConst, &cxt); nodesRewriteExprsPostOrder(pSelect->pGroupByList, calcConst, &cxt);
} }
if (TSDB_CODE_SUCCESS == cxt.code) { if (TSDB_CODE_SUCCESS == cxt.code) {
nodesRewriteExprPostOrder(&pSelect->pHaving, calcConst, &cxt); cxt.code = calcConstCondition(&cxt, &pSelect->pHaving);
} }
if (TSDB_CODE_SUCCESS == cxt.code) { if (TSDB_CODE_SUCCESS == cxt.code) {
nodesRewriteExprsPostOrder(pSelect->pOrderByList, calcConst, &cxt); nodesRewriteExprsPostOrder(pSelect->pOrderByList, calcConst, &cxt);
......
...@@ -1115,7 +1115,7 @@ static int32_t columnNodeToField(SNodeList* pList, SArray** pArray) { ...@@ -1115,7 +1115,7 @@ static int32_t columnNodeToField(SNodeList* pList, SArray** pArray) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static const SColumnDefNode* findColDef(const SNodeList* pCols, const SColumnNode* pCol) { static SColumnDefNode* findColDef(SNodeList* pCols, const SColumnNode* pCol) {
SNode* pColDef = NULL; SNode* pColDef = NULL;
FOREACH(pColDef, pCols) { FOREACH(pColDef, pCols) {
if (0 == strcmp(pCol->colName, ((SColumnDefNode*)pColDef)->colName)) { if (0 == strcmp(pCol->colName, ((SColumnDefNode*)pColDef)->colName)) {
...@@ -1125,16 +1125,20 @@ static const SColumnDefNode* findColDef(const SNodeList* pCols, const SColumnNod ...@@ -1125,16 +1125,20 @@ static const SColumnDefNode* findColDef(const SNodeList* pCols, const SColumnNod
return NULL; return NULL;
} }
static int32_t checkCreateSuperTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) { static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
if (NULL != pStmt->pOptions->pSma) { if (NULL != pStmt->pOptions->pSma) {
SNode* pNode = NULL; SNode* pNode = NULL;
FOREACH(pNode, pStmt->pCols) {
((SColumnDefNode*)pNode)->sma = false;
}
FOREACH(pNode, pStmt->pOptions->pSma) { FOREACH(pNode, pStmt->pOptions->pSma) {
SColumnNode* pSmaCol = (SColumnNode*)pNode; SColumnNode* pSmaCol = (SColumnNode*)pNode;
const SColumnDefNode* pColDef = findColDef(pStmt->pCols, pSmaCol); SColumnDefNode* pColDef = findColDef(pStmt->pCols, pSmaCol);
if (NULL == pColDef) { if (NULL == pColDef) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pSmaCol->colName); return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pSmaCol->colName);
} }
pSmaCol->node.resType = pColDef->dataType; pSmaCol->node.resType = pColDef->dataType;
pColDef->sma = true;
} }
} }
if (NULL != pStmt->pOptions->pFuncs) { if (NULL != pStmt->pOptions->pFuncs) {
...@@ -1154,7 +1158,7 @@ static int32_t getAggregationMethod(SNodeList* pFuncs) { ...@@ -1154,7 +1158,7 @@ static int32_t getAggregationMethod(SNodeList* pFuncs) {
} }
static int32_t translateCreateSuperTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) { static int32_t translateCreateSuperTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
int32_t code = checkCreateSuperTable(pCxt, pStmt); int32_t code = checkCreateTable(pCxt, pStmt);
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS != code) {
return code; return code;
} }
...@@ -1485,7 +1489,7 @@ static int32_t nodeTypeToShowType(ENodeType nt) { ...@@ -1485,7 +1489,7 @@ static int32_t nodeTypeToShowType(ENodeType nt) {
case QUERY_NODE_SHOW_CONNECTIONS_STMT: case QUERY_NODE_SHOW_CONNECTIONS_STMT:
return TSDB_MGMT_TABLE_CONNS; return TSDB_MGMT_TABLE_CONNS;
case QUERY_NODE_SHOW_LICENCE_STMT: case QUERY_NODE_SHOW_LICENCE_STMT:
return 0; // todo return TSDB_MGMT_TABLE_GRANTS;
case QUERY_NODE_SHOW_QUERIES_STMT: case QUERY_NODE_SHOW_QUERIES_STMT:
return TSDB_MGMT_TABLE_QUERIES; return TSDB_MGMT_TABLE_QUERIES;
case QUERY_NODE_SHOW_SCORES_STMT: case QUERY_NODE_SHOW_SCORES_STMT:
...@@ -2157,11 +2161,11 @@ typedef struct SVgroupTablesBatch { ...@@ -2157,11 +2161,11 @@ typedef struct SVgroupTablesBatch {
char dbName[TSDB_DB_NAME_LEN]; char dbName[TSDB_DB_NAME_LEN];
} SVgroupTablesBatch; } SVgroupTablesBatch;
static void toSchema(const SColumnDefNode* pCol, col_id_t colId, SSchemaEx* pSchema) { static void toSchemaEx(const SColumnDefNode* pCol, col_id_t colId, SSchemaEx* pSchema) {
pSchema->colId = colId; pSchema->colId = colId;
pSchema->type = pCol->dataType.type; pSchema->type = pCol->dataType.type;
pSchema->bytes = calcTypeBytes(pCol->dataType); pSchema->bytes = calcTypeBytes(pCol->dataType);
pSchema->sma = TSDB_BSMA_TYPE_LATEST; // TODO: use default value currently, and use the real value later. pSchema->sma = pCol->sma ? TSDB_BSMA_TYPE_LATEST : TSDB_BSMA_TYPE_NONE;
strcpy(pSchema->name, pCol->colName); strcpy(pSchema->name, pCol->colName);
} }
...@@ -2171,33 +2175,60 @@ static void destroyCreateTbReq(SVCreateTbReq* pReq) { ...@@ -2171,33 +2175,60 @@ static void destroyCreateTbReq(SVCreateTbReq* pReq) {
taosMemoryFreeClear(pReq->ntbCfg.pSchema); taosMemoryFreeClear(pReq->ntbCfg.pSchema);
} }
static int32_t buildNormalTableBatchReq(int32_t acctId, const char* pDbName, const char* pTableName, static int32_t buildSmaParam(STableOptions* pOptions, SVCreateTbReq* pReq) {
const SNodeList* pColumns, const SVgroupInfo* pVgroupInfo, SVgroupTablesBatch* pBatch) { if (0 == LIST_LENGTH(pOptions->pFuncs)) {
return TSDB_CODE_SUCCESS;
}
pReq->ntbCfg.pRSmaParam = taosMemoryCalloc(1, sizeof(SRSmaParam));
if (NULL == pReq->ntbCfg.pRSmaParam) {
return TSDB_CODE_OUT_OF_MEMORY;
}
pReq->ntbCfg.pRSmaParam->delay = pOptions->delay;
pReq->ntbCfg.pRSmaParam->xFilesFactor = pOptions->filesFactor;
pReq->ntbCfg.pRSmaParam->nFuncIds = LIST_LENGTH(pOptions->pFuncs);
pReq->ntbCfg.pRSmaParam->pFuncIds = taosMemoryCalloc(pReq->ntbCfg.pRSmaParam->nFuncIds, sizeof(func_id_t));
if (NULL == pReq->ntbCfg.pRSmaParam->pFuncIds) {
return TSDB_CODE_OUT_OF_MEMORY;
}
int32_t index = 0;
SNode* pFunc = NULL;
FOREACH(pFunc, pOptions->pFuncs) {
pReq->ntbCfg.pRSmaParam->pFuncIds[index++] = ((SFunctionNode*)pFunc)->funcId;
}
return TSDB_CODE_SUCCESS;
}
static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt* pStmt, const SVgroupInfo* pVgroupInfo, SVgroupTablesBatch* pBatch) {
char dbFName[TSDB_DB_FNAME_LEN] = {0}; char dbFName[TSDB_DB_FNAME_LEN] = {0};
SName name = { .type = TSDB_DB_NAME_T, .acctId = acctId }; SName name = { .type = TSDB_DB_NAME_T, .acctId = acctId };
strcpy(name.dbname, pDbName); strcpy(name.dbname, pStmt->dbName);
tNameGetFullDbName(&name, dbFName); tNameGetFullDbName(&name, dbFName);
SVCreateTbReq req = {0}; SVCreateTbReq req = {0};
req.type = TD_NORMAL_TABLE; req.type = TD_NORMAL_TABLE;
req.dbFName = strdup(dbFName); req.dbFName = strdup(dbFName);
req.name = strdup(pTableName); req.name = strdup(pStmt->tableName);
req.ntbCfg.nCols = LIST_LENGTH(pColumns); req.ntbCfg.nCols = LIST_LENGTH(pStmt->pCols);
req.ntbCfg.pSchema = taosMemoryCalloc(req.ntbCfg.nCols, sizeof(SSchemaEx)); req.ntbCfg.pSchema = taosMemoryCalloc(req.ntbCfg.nCols, sizeof(SSchemaEx));
if (NULL == req.name || NULL == req.ntbCfg.pSchema) { if (NULL == req.name || NULL == req.ntbCfg.pSchema) {
destroyCreateTbReq(&req); destroyCreateTbReq(&req);
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
SNode* pCol; SNode* pCol;
int32_t index = 0; col_id_t index = 0;
FOREACH(pCol, pColumns) { FOREACH(pCol, pStmt->pCols) {
toSchema((SColumnDefNode*)pCol, index + 1, req.ntbCfg.pSchema + index); toSchemaEx((SColumnDefNode*)pCol, index + 1, req.ntbCfg.pSchema + index);
++index; ++index;
} }
// TODO: use the real sma for normal table. if (TSDB_CODE_SUCCESS != buildSmaParam(pStmt->pOptions, &req)) {
destroyCreateTbReq(&req);
return TSDB_CODE_OUT_OF_MEMORY;
}
pBatch->info = *pVgroupInfo; pBatch->info = *pVgroupInfo;
strcpy(pBatch->dbName, pDbName); strcpy(pBatch->dbName, pStmt->dbName);
pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq)); pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
if (NULL == pBatch->req.pArray) { if (NULL == pBatch->req.pArray) {
destroyCreateTbReq(&req); destroyCreateTbReq(&req);
...@@ -2278,7 +2309,7 @@ static int32_t buildCreateTableDataBlock(int32_t acctId, const SCreateTableStmt* ...@@ -2278,7 +2309,7 @@ static int32_t buildCreateTableDataBlock(int32_t acctId, const SCreateTableStmt*
} }
SVgroupTablesBatch tbatch = {0}; SVgroupTablesBatch tbatch = {0};
int32_t code = buildNormalTableBatchReq(acctId, pStmt->dbName, pStmt->tableName, pStmt->pCols, pInfo, &tbatch); int32_t code = buildNormalTableBatchReq(acctId, pStmt, pInfo, &tbatch);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = serializeVgroupTablesBatch(&tbatch, *pBufArray); code = serializeVgroupTablesBatch(&tbatch, *pBufArray);
} }
...@@ -2293,8 +2324,11 @@ static int32_t buildCreateTableDataBlock(int32_t acctId, const SCreateTableStmt* ...@@ -2293,8 +2324,11 @@ static int32_t buildCreateTableDataBlock(int32_t acctId, const SCreateTableStmt*
static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) { static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) {
SCreateTableStmt* pStmt = (SCreateTableStmt*)pQuery->pRoot; SCreateTableStmt* pStmt = (SCreateTableStmt*)pQuery->pRoot;
int32_t code = checkCreateTable(pCxt, pStmt);
SVgroupInfo info = {0}; SVgroupInfo info = {0};
int32_t code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &info); if (TSDB_CODE_SUCCESS == code) {
code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &info);
}
SArray* pBufArray = NULL; SArray* pBufArray = NULL;
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = buildCreateTableDataBlock(pCxt->pParseCxt->acctId, pStmt, &info, &pBufArray); code = buildCreateTableDataBlock(pCxt->pParseCxt->acctId, pStmt, &info, &pBufArray);
......
...@@ -44,7 +44,7 @@ protected: ...@@ -44,7 +44,7 @@ protected:
query_ = nullptr; query_ = nullptr;
bool res = runImpl(parseCode, translateCode); bool res = runImpl(parseCode, translateCode);
qDestroyQuery(query_); qDestroyQuery(query_);
if (!res) { if (1/*!res*/) {
dump(); dump();
} }
return res; return res;
...@@ -69,6 +69,12 @@ private: ...@@ -69,6 +69,12 @@ private:
return (terrno == translateCode); return (terrno == translateCode);
} }
translatedAstStr_ = toString(query_->pRoot); translatedAstStr_ = toString(query_->pRoot);
code = calculateConstant(&cxt_, query_);
if (code != TSDB_CODE_SUCCESS) {
calcConstErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
return false;
}
calcConstAstStr_ = toString(query_->pRoot);
return (TSDB_CODE_SUCCESS == translateCode); return (TSDB_CODE_SUCCESS == translateCode);
} }
...@@ -88,6 +94,13 @@ private: ...@@ -88,6 +94,13 @@ private:
cout << "translate output: " << endl; cout << "translate output: " << endl;
cout << translatedAstStr_ << endl; cout << translatedAstStr_ << endl;
} }
if (!calcConstErrStr_.empty()) {
cout << "calculateConstant error: " << calcConstErrStr_ << endl;
}
if (!calcConstAstStr_.empty()) {
cout << "calculateConstant output: " << endl;
cout << calcConstAstStr_ << endl;
}
} }
string toString(const SNode* pRoot, bool format = false) { string toString(const SNode* pRoot, bool format = false) {
...@@ -112,6 +125,8 @@ private: ...@@ -112,6 +125,8 @@ private:
parsedAstStr_.clear(); parsedAstStr_.clear();
translateErrStr_.clear(); translateErrStr_.clear();
translatedAstStr_.clear(); translatedAstStr_.clear();
calcConstErrStr_.clear();
calcConstAstStr_.clear();
} }
string acctId_; string acctId_;
...@@ -124,6 +139,8 @@ private: ...@@ -124,6 +139,8 @@ private:
string parsedAstStr_; string parsedAstStr_;
string translateErrStr_; string translateErrStr_;
string translatedAstStr_; string translatedAstStr_;
string calcConstErrStr_;
string calcConstAstStr_;
}; };
TEST_F(ParserTest, createAccount) { TEST_F(ParserTest, createAccount) {
...@@ -191,6 +208,9 @@ TEST_F(ParserTest, selectConstant) { ...@@ -191,6 +208,9 @@ TEST_F(ParserTest, selectConstant) {
bind("SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", TIMESTAMP '2022-02-09 17:30:20', true, false, 15s FROM t1"); bind("SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", TIMESTAMP '2022-02-09 17:30:20', true, false, 15s FROM t1");
ASSERT_TRUE(run()); ASSERT_TRUE(run());
bind("SELECT 123 + 45 FROM t1 where 2 - 1");
ASSERT_TRUE(run());
} }
TEST_F(ParserTest, selectExpression) { TEST_F(ParserTest, selectExpression) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册