Merge pull request #14450 from taosdata/feature/3.0_debug_wxy
fix: some problems of parser and planner
This commit is contained in:
commit
2450d5982b
|
@ -22,8 +22,8 @@ extern "C" {
|
|||
|
||||
#include "tdef.h"
|
||||
|
||||
#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type)
|
||||
#define setNodeType(nodeptr, type) (((SNode*)(nodeptr))->type = (type))
|
||||
#define nodeType(nodeptr) (((const SNode*)(nodeptr))->type)
|
||||
#define setNodeType(nodeptr, nodetype) (((SNode*)(nodeptr))->type = (nodetype))
|
||||
|
||||
#define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0)
|
||||
|
||||
|
@ -118,6 +118,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_DROP_TABLE_STMT,
|
||||
QUERY_NODE_DROP_SUPER_TABLE_STMT,
|
||||
QUERY_NODE_ALTER_TABLE_STMT,
|
||||
QUERY_NODE_ALTER_SUPER_TABLE_STMT,
|
||||
QUERY_NODE_CREATE_USER_STMT,
|
||||
QUERY_NODE_ALTER_USER_STMT,
|
||||
QUERY_NODE_DROP_USER_STMT,
|
||||
|
|
|
@ -25,6 +25,8 @@ extern "C" {
|
|||
|
||||
typedef struct SFilterInfo SFilterInfo;
|
||||
|
||||
int32_t scalarGetOperatorResultType(SDataType left, SDataType right, EOperatorType op, SDataType* pRes);
|
||||
|
||||
/*
|
||||
pNode will be freed in API;
|
||||
*pRes need to freed in caller
|
||||
|
|
|
@ -578,6 +578,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_INVALID_TABLE_OPTION TAOS_DEF_ERROR_CODE(0, 0x265C)
|
||||
#define TSDB_CODE_PAR_INVALID_INTERP_CLAUSE TAOS_DEF_ERROR_CODE(0, 0x265D)
|
||||
#define TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN TAOS_DEF_ERROR_CODE(0, 0x265E)
|
||||
#define TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE TAOS_DEF_ERROR_CODE(0, 0x265F)
|
||||
|
||||
//planner
|
||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
#include "querynodes.h"
|
||||
#include "taos.h"
|
||||
#include "taoserror.h"
|
||||
#include "thash.h"
|
||||
#include "tdatablock.h"
|
||||
#include "thash.h"
|
||||
|
||||
static SNode* makeNode(ENodeType type, size_t size) {
|
||||
SNode* p = taosMemoryCalloc(1, size);
|
||||
|
@ -1497,13 +1497,18 @@ typedef struct SCollectFuncsCxt {
|
|||
int32_t errCode;
|
||||
FFuncClassifier classifier;
|
||||
SNodeList* pFuncs;
|
||||
SHashObj* pAliasName;
|
||||
} SCollectFuncsCxt;
|
||||
|
||||
static EDealRes collectFuncs(SNode* pNode, void* pContext) {
|
||||
SCollectFuncsCxt* pCxt = (SCollectFuncsCxt*)pContext;
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode) && pCxt->classifier(((SFunctionNode*)pNode)->funcId) &&
|
||||
!(((SExprNode*)pNode)->orderAlias)) {
|
||||
pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode));
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
if (NULL == taosHashGet(pCxt->pAliasName, pExpr->aliasName, strlen(pExpr->aliasName))) {
|
||||
pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode));
|
||||
taosHashPut(pCxt->pAliasName, pExpr->aliasName, strlen(pExpr->aliasName), &pExpr, POINTER_BYTES);
|
||||
}
|
||||
return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
|
@ -1515,23 +1520,27 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, FFuncClassifi
|
|||
}
|
||||
|
||||
SCollectFuncsCxt cxt = {
|
||||
.errCode = TSDB_CODE_SUCCESS, .classifier = classifier, .pFuncs = (NULL == *pFuncs ? nodesMakeList() : *pFuncs)};
|
||||
.errCode = TSDB_CODE_SUCCESS,
|
||||
.classifier = classifier,
|
||||
.pFuncs = (NULL == *pFuncs ? nodesMakeList() : *pFuncs),
|
||||
.pAliasName = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, false)};
|
||||
if (NULL == cxt.pFuncs) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
*pFuncs = NULL;
|
||||
nodesWalkSelectStmt(pSelect, clause, collectFuncs, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyList(cxt.pFuncs);
|
||||
return cxt.errCode;
|
||||
}
|
||||
if (LIST_LENGTH(cxt.pFuncs) > 0) {
|
||||
*pFuncs = cxt.pFuncs;
|
||||
if (TSDB_CODE_SUCCESS == cxt.errCode) {
|
||||
if (LIST_LENGTH(cxt.pFuncs) > 0) {
|
||||
*pFuncs = cxt.pFuncs;
|
||||
} else {
|
||||
nodesDestroyList(cxt.pFuncs);
|
||||
}
|
||||
} else {
|
||||
nodesDestroyList(cxt.pFuncs);
|
||||
}
|
||||
taosHashCleanup(cxt.pAliasName);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
||||
typedef struct SCollectSpecialNodesCxt {
|
||||
|
|
|
@ -154,6 +154,7 @@ SNode* createAlterTableDropCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_
|
|||
SNode* createAlterTableRenameCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pOldColName,
|
||||
SToken* pNewColName);
|
||||
SNode* createAlterTableSetTag(SAstCreateContext* pCxt, SNode* pRealTable, SToken* pTagName, SNode* pVal);
|
||||
SNode* setAlterSuperTableType(SNode* pStmt);
|
||||
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName);
|
||||
SNode* createShowStmt(SAstCreateContext* pCxt, ENodeType type);
|
||||
SNode* createShowStmtWithCond(SAstCreateContext* pCxt, ENodeType type, SNode* pDbName, SNode* pTbName,
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef struct SParseMetaCache {
|
|||
} SParseMetaCache;
|
||||
|
||||
int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...);
|
||||
int32_t generateSyntaxErrMsgExt(SMsgBuf* pBuf, int32_t errCode, const char* pFormat, ...);
|
||||
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
|
||||
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr);
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ cmd ::= DROP TABLE multi_drop_clause(A).
|
|||
cmd ::= DROP STABLE exists_opt(A) full_table_name(B). { pCxt->pRootNode = createDropSuperTableStmt(pCxt, A, B); }
|
||||
|
||||
cmd ::= ALTER TABLE alter_table_clause(A). { pCxt->pRootNode = A; }
|
||||
cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode = A; }
|
||||
cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode = setAlterSuperTableType(A); }
|
||||
|
||||
alter_table_clause(A) ::= full_table_name(B) alter_table_options(C). { A = createAlterTableModifyOptions(pCxt, B, C); }
|
||||
alter_table_clause(A) ::=
|
||||
|
@ -259,7 +259,7 @@ multi_create_clause(A) ::= multi_create_clause(B) create_subtable_clause(C).
|
|||
|
||||
create_subtable_clause(A) ::=
|
||||
not_exists_opt(B) full_table_name(C) USING full_table_name(D)
|
||||
specific_tags_opt(E) TAGS NK_LP literal_list(F) NK_RP table_options(G). { A = createCreateSubTableClause(pCxt, B, C, D, E, F, G); }
|
||||
specific_tags_opt(E) TAGS NK_LP expression_list(F) NK_RP table_options(G). { A = createCreateSubTableClause(pCxt, B, C, D, E, F, G); }
|
||||
|
||||
%type multi_drop_clause { SNodeList* }
|
||||
%destructor multi_drop_clause { nodesDestroyList($$); }
|
||||
|
|
|
@ -1127,6 +1127,11 @@ SNode* createAlterTableSetTag(SAstCreateContext* pCxt, SNode* pRealTable, SToken
|
|||
return createAlterTableStmtFinalize(pRealTable, pStmt);
|
||||
}
|
||||
|
||||
SNode* setAlterSuperTableType(SNode* pStmt) {
|
||||
setNodeType(pStmt, QUERY_NODE_ALTER_SUPER_TABLE_STMT);
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
if (!checkDbName(pCxt, pDbName, false)) {
|
||||
|
|
|
@ -247,6 +247,10 @@ static int32_t collectMetaKeyFromAlterTable(SCollectMetaKeyCxt* pCxt, SAlterTabl
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromAlterStable(SCollectMetaKeyCxt* pCxt, SAlterTableStmt* pStmt) {
|
||||
return reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromUseDatabase(SCollectMetaKeyCxt* pCxt, SUseDatabaseStmt* pStmt) {
|
||||
return reserveDbVgVersionInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
|
||||
}
|
||||
|
@ -483,6 +487,8 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
|
|||
return collectMetaKeyFromDropTable(pCxt, (SDropTableStmt*)pStmt);
|
||||
case QUERY_NODE_ALTER_TABLE_STMT:
|
||||
return collectMetaKeyFromAlterTable(pCxt, (SAlterTableStmt*)pStmt);
|
||||
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
|
||||
return collectMetaKeyFromAlterStable(pCxt, (SAlterTableStmt*)pStmt);
|
||||
case QUERY_NODE_USE_DATABASE_STMT:
|
||||
return collectMetaKeyFromUseDatabase(pCxt, (SUseDatabaseStmt*)pStmt);
|
||||
case QUERY_NODE_CREATE_INDEX_STMT:
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
pSql += sToken.n; \
|
||||
} while (TK_NK_SPACE == sToken.type)
|
||||
|
||||
typedef struct SInsertParseBaseContext {
|
||||
SParseContext* pComCxt;
|
||||
char* pSql;
|
||||
SMsgBuf msg;
|
||||
} SInsertParseBaseContext;
|
||||
|
||||
typedef struct SInsertParseContext {
|
||||
SParseContext* pComCxt; // input
|
||||
char* pSql; // input
|
||||
|
@ -1105,6 +1111,32 @@ static int32_t storeTableMeta(SInsertParseContext* pCxt, SHashObj* pHash, SName*
|
|||
return taosHashPut(pHash, pName, len, &pBackup, POINTER_BYTES);
|
||||
}
|
||||
|
||||
static int32_t skipParentheses(SInsertParseSyntaxCxt* pCxt) {
|
||||
SToken sToken;
|
||||
int32_t expectRightParenthesis = 1;
|
||||
while (1) {
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
if (TK_NK_LP == sToken.type) {
|
||||
++expectRightParenthesis;
|
||||
} else if (TK_NK_RP == sToken.type && 0 == --expectRightParenthesis) {
|
||||
break;
|
||||
}
|
||||
if (0 == sToken.n) {
|
||||
return buildSyntaxErrMsg(&pCxt->msg, ") expected", NULL);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t skipBoundColumns(SInsertParseSyntaxCxt* pCxt) { return skipParentheses(pCxt); }
|
||||
|
||||
static int32_t ignoreBoundColumns(SInsertParseContext* pCxt) {
|
||||
SInsertParseSyntaxCxt cxt = {.pComCxt = pCxt->pComCxt, .pSql = pCxt->pSql, .msg = pCxt->msg, .pMetaCache = NULL};
|
||||
int32_t code = skipBoundColumns(&cxt);
|
||||
pCxt->pSql = cxt.pSql;
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t skipUsingClause(SInsertParseSyntaxCxt* pCxt);
|
||||
|
||||
// pSql -> stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)
|
||||
|
@ -1453,12 +1485,29 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|||
tNameGetFullDbName(&name, dbFName);
|
||||
CHECK_CODE(taosHashPut(pCxt->pDbFNameHashObj, dbFName, strlen(dbFName), dbFName, sizeof(dbFName)));
|
||||
|
||||
bool existedUsing = false;
|
||||
// USING clause
|
||||
if (TK_USING == sToken.type) {
|
||||
existedUsing = true;
|
||||
CHECK_CODE(parseUsingClause(pCxt, &name, tbFName));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
autoCreateTbl = true;
|
||||
}
|
||||
|
||||
char* pBoundColsStart = NULL;
|
||||
if (TK_NK_LP == sToken.type) {
|
||||
// pSql -> field1_name, ...)
|
||||
pBoundColsStart = pCxt->pSql;
|
||||
CHECK_CODE(ignoreBoundColumns(pCxt));
|
||||
// CHECK_CODE(parseBoundColumns(pCxt, &dataBuf->boundColumnInfo, getTableColumnSchema(pCxt->pTableMeta)));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
}
|
||||
|
||||
if (TK_USING == sToken.type) {
|
||||
CHECK_CODE(parseUsingClause(pCxt, &name, tbFName));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
autoCreateTbl = true;
|
||||
} else {
|
||||
} else if (!existedUsing) {
|
||||
CHECK_CODE(getTableMeta(pCxt, &name, dbFName));
|
||||
}
|
||||
|
||||
|
@ -1467,10 +1516,11 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|||
sizeof(SSubmitBlk), getTableInfo(pCxt->pTableMeta).rowSize, pCxt->pTableMeta,
|
||||
&dataBuf, NULL, &pCxt->createTblReq));
|
||||
|
||||
if (TK_NK_LP == sToken.type) {
|
||||
// pSql -> field1_name, ...)
|
||||
if (NULL != pBoundColsStart) {
|
||||
char* pCurrPos = pCxt->pSql;
|
||||
pCxt->pSql = pBoundColsStart;
|
||||
CHECK_CODE(parseBoundColumns(pCxt, &dataBuf->boundColumnInfo, getTableColumnSchema(pCxt->pTableMeta)));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
pCxt->pSql = pCurrPos;
|
||||
}
|
||||
|
||||
if (TK_VALUES == sToken.type) {
|
||||
|
@ -1610,25 +1660,6 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery, SParseMetaCache
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t skipParentheses(SInsertParseSyntaxCxt* pCxt) {
|
||||
SToken sToken;
|
||||
int32_t expectRightParenthesis = 1;
|
||||
while (1) {
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
if (TK_NK_LP == sToken.type) {
|
||||
++expectRightParenthesis;
|
||||
} else if (TK_NK_RP == sToken.type && 0 == --expectRightParenthesis) {
|
||||
break;
|
||||
}
|
||||
if (0 == sToken.n) {
|
||||
return buildSyntaxErrMsg(&pCxt->msg, ") expected", NULL);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t skipBoundColumns(SInsertParseSyntaxCxt* pCxt) { return skipParentheses(pCxt); }
|
||||
|
||||
// pSql -> (field1_value, ...) [(field1_value2, ...) ...]
|
||||
static int32_t skipValuesClause(SInsertParseSyntaxCxt* pCxt) {
|
||||
int32_t numOfRows = 0;
|
||||
|
@ -1717,8 +1748,25 @@ static int32_t parseInsertBodySyntax(SInsertParseSyntaxCxt* pCxt) {
|
|||
SToken tbnameToken = sToken;
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
|
||||
bool existedUsing = false;
|
||||
// USING clause
|
||||
if (TK_USING == sToken.type) {
|
||||
existedUsing = true;
|
||||
CHECK_CODE(collectAutoCreateTableMetaKey(pCxt, &tbnameToken));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
CHECK_CODE(collectTableMetaKey(pCxt, &sToken));
|
||||
CHECK_CODE(skipUsingClause(pCxt));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
}
|
||||
|
||||
if (TK_NK_LP == sToken.type) {
|
||||
// pSql -> field1_name, ...)
|
||||
CHECK_CODE(skipBoundColumns(pCxt));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
}
|
||||
|
||||
if (TK_USING == sToken.type && !existedUsing) {
|
||||
existedUsing = true;
|
||||
CHECK_CODE(collectAutoCreateTableMetaKey(pCxt, &tbnameToken));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
CHECK_CODE(collectTableMetaKey(pCxt, &sToken));
|
||||
|
@ -1728,12 +1776,6 @@ static int32_t parseInsertBodySyntax(SInsertParseSyntaxCxt* pCxt) {
|
|||
CHECK_CODE(collectTableMetaKey(pCxt, &tbnameToken));
|
||||
}
|
||||
|
||||
if (TK_NK_LP == sToken.type) {
|
||||
// pSql -> field1_name, ...)
|
||||
CHECK_CODE(skipBoundColumns(pCxt));
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
}
|
||||
|
||||
if (TK_VALUES == sToken.type) {
|
||||
// pSql -> (field1_value, ...) [(field1_value2, ...) ...]
|
||||
CHECK_CODE(skipValuesClause(pCxt));
|
||||
|
|
|
@ -121,8 +121,8 @@ static int32_t getTableMetaImpl(STranslateContext* pCxt, const SName* pName, STa
|
|||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("catalogGetTableMeta error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname,
|
||||
pName->tname);
|
||||
parserError("0x%" PRIx64 " catalogGetTableMeta error, code:%s, dbName:%s, tbName:%s", pCxt->pParseCxt->requestId,
|
||||
tstrerror(code), pName->dbname, pName->tname);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -150,8 +150,8 @@ static int32_t getTableCfg(STranslateContext* pCxt, const SName* pName, STableCf
|
|||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("catalogRefreshGetTableCfg error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname,
|
||||
pName->tname);
|
||||
parserError("0x%" PRIx64 " catalogRefreshGetTableCfg error, code:%s, dbName:%s, tbName:%s",
|
||||
pCxt->pParseCxt->requestId, tstrerror(code), pName->dbname, pName->tname);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -173,8 +173,8 @@ static int32_t refreshGetTableMeta(STranslateContext* pCxt, const char* pDbName,
|
|||
code = catalogRefreshGetTableMeta(pParCxt->pCatalog, &conn, &name, pMeta, false);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("catalogRefreshGetTableMeta error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pDbName,
|
||||
pTableName);
|
||||
parserError("0x%" PRIx64 " catalogRefreshGetTableMeta error, code:%s, dbName:%s, tbName:%s",
|
||||
pCxt->pParseCxt->requestId, tstrerror(code), pDbName, pTableName);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -196,7 +196,8 @@ static int32_t getDBVgInfoImpl(STranslateContext* pCxt, const SName* pName, SArr
|
|||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("catalogGetDBVgInfo error, code:%s, dbFName:%s", tstrerror(code), fullDbName);
|
||||
parserError("0x%" PRIx64 " catalogGetDBVgInfo error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId,
|
||||
tstrerror(code), fullDbName);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -227,8 +228,8 @@ static int32_t getTableHashVgroupImpl(STranslateContext* pCxt, const SName* pNam
|
|||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("catalogGetTableHashVgroup error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname,
|
||||
pName->tname);
|
||||
parserError("0x%" PRIx64 " catalogGetTableHashVgroup error, code:%s, dbName:%s, tbName:%s",
|
||||
pCxt->pParseCxt->requestId, tstrerror(code), pName->dbname, pName->tname);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -251,7 +252,8 @@ static int32_t getDBVgVersion(STranslateContext* pCxt, const char* pDbFName, int
|
|||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("catalogGetDBVgVersion error, code:%s, dbFName:%s", tstrerror(code), pDbFName);
|
||||
parserError("0x%" PRIx64 " catalogGetDBVgVersion error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId,
|
||||
tstrerror(code), pDbFName);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -276,7 +278,8 @@ static int32_t getDBCfg(STranslateContext* pCxt, const char* pDbName, SDbCfgInfo
|
|||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("catalogGetDBCfg error, code:%s, dbFName:%s", tstrerror(code), dbFname);
|
||||
parserError("0x%" PRIx64 " catalogGetDBCfg error, code:%s, dbFName:%s", pCxt->pParseCxt->requestId, tstrerror(code),
|
||||
dbFname);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -303,6 +306,10 @@ static int32_t getUdfInfo(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
|||
pFunc->udfBufSize = funcInfo.bufSize;
|
||||
tFreeSFuncInfo(&funcInfo);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("0x%" PRIx64 " catalogGetUdfInfo error, code:%s, funcName:%s", pCxt->pParseCxt->requestId,
|
||||
tstrerror(code), pFunc->functionName);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -323,7 +330,8 @@ static int32_t getTableIndex(STranslateContext* pCxt, const SName* pName, SArray
|
|||
code = catalogGetTableIndex(pParCxt->pCatalog, &conn, pName, pIndexes);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("getTableIndex error, code:%s, dbName:%s, tbName:%s", tstrerror(code), pName->dbname, pName->tname);
|
||||
parserError("0x%" PRIx64 " getTableIndex error, code:%s, dbName:%s, tbName:%s", pCxt->pParseCxt->requestId,
|
||||
tstrerror(code), pName->dbname, pName->tname);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -341,7 +349,7 @@ static int32_t getDnodeList(STranslateContext* pCxt, SArray** pDnodes) {
|
|||
code = catalogGetDnodeList(pParCxt->pCatalog, &conn, pDnodes);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
parserError("getDnodeList error, code:%s", tstrerror(code));
|
||||
parserError("0x%" PRIx64 " getDnodeList error, code:%s", pCxt->pParseCxt->requestId, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -707,7 +715,7 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p
|
|||
}
|
||||
|
||||
static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) {
|
||||
if (isSelectStmt(pCxt->pCurrStmt) && NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) {
|
||||
if (NULL == pCxt->pCurrStmt || isSelectStmt(pCxt->pCurrStmt) && NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, (*pCol)->colName);
|
||||
}
|
||||
|
||||
|
@ -1248,6 +1256,22 @@ static int32_t translateForbidGroupByFunc(STranslateContext* pCxt, SFunctionNode
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateRepeatScanFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||
if (!fmIsRepeatScanFunc(pFunc->funcId)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
if (isSelectStmt(pCxt->pCurrStmt) && NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) {
|
||||
SNode* pTable = ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable;
|
||||
if (QUERY_NODE_REAL_TABLE == nodeType(pTable) &&
|
||||
(TSDB_CHILD_TABLE == ((SRealTableNode*)pTable)->pMeta->tableType ||
|
||||
TSDB_NORMAL_TABLE == ((SRealTableNode*)pTable)->pMeta->tableType)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE,
|
||||
"%s is only supported in single table query", pFunc->functionName);
|
||||
}
|
||||
|
||||
static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) {
|
||||
if (NULL != pCurrStmt && QUERY_NODE_SELECT_STMT == nodeType(pCurrStmt)) {
|
||||
SSelectStmt* pSelect = (SSelectStmt*)pCurrStmt;
|
||||
|
@ -1370,6 +1394,9 @@ static int32_t translateNoramlFunction(STranslateContext* pCxt, SFunctionNode* p
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateForbidGroupByFunc(pCxt, pFunc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateRepeatScanFunc(pCxt, pFunc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
setFuncClassification(pCxt->pCurrStmt, pFunc);
|
||||
}
|
||||
|
@ -2760,6 +2787,7 @@ static int32_t translateDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelet
|
|||
}
|
||||
|
||||
static int32_t translateDelete(STranslateContext* pCxt, SDeleteStmt* pDelete) {
|
||||
pCxt->pCurrStmt = (SNode*)pDelete;
|
||||
int32_t code = translateFrom(pCxt, pDelete->pFromTable);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateDeleteWhere(pCxt, pDelete);
|
||||
|
@ -3743,12 +3771,24 @@ static int32_t buildAlterSuperTableReq(STranslateContext* pCxt, SAlterTableStmt*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static SSchema* getColSchema(STableMeta* pTableMeta, const char* pTagName) {
|
||||
static SSchema* getColSchema(STableMeta* pTableMeta, const char* pColName) {
|
||||
int32_t numOfFields = getNumOfTags(pTableMeta) + getNumOfColumns(pTableMeta);
|
||||
for (int32_t i = 0; i < numOfFields; ++i) {
|
||||
SSchema* pTagSchema = pTableMeta->schema + i;
|
||||
if (0 == strcmp(pTagName, pTagSchema->name)) {
|
||||
return pTagSchema;
|
||||
SSchema* pSchema = pTableMeta->schema + i;
|
||||
if (0 == strcmp(pColName, pSchema->name)) {
|
||||
return pSchema;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SSchema* getTagSchema(STableMeta* pTableMeta, const char* pTagName) {
|
||||
int32_t numOfTags = getNumOfTags(pTableMeta);
|
||||
SSchema* pTagsSchema = getTableTagSchema(pTableMeta);
|
||||
for (int32_t i = 0; i < numOfTags; ++i) {
|
||||
SSchema* pSchema = pTagsSchema + i;
|
||||
if (0 == strcmp(pTagName, pSchema->name)) {
|
||||
return pSchema;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
@ -3756,22 +3796,48 @@ static SSchema* getColSchema(STableMeta* pTableMeta, const char* pTagName) {
|
|||
|
||||
static int32_t checkAlterSuperTable(STranslateContext* pCxt, SAlterTableStmt* pStmt) {
|
||||
if (TSDB_ALTER_TABLE_UPDATE_TAG_VAL == pStmt->alterType || TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME == pStmt->alterType) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE,
|
||||
"Set tag value only available for child table");
|
||||
}
|
||||
|
||||
if (pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_OPTIONS && -1 != pStmt->pOptions->ttl) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE);
|
||||
}
|
||||
|
||||
if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
|
||||
}
|
||||
|
||||
if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON);
|
||||
}
|
||||
|
||||
STableMeta* pTableMeta = NULL;
|
||||
int32_t code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
SSchema* pTagsSchema = getTableTagSchema(pTableMeta);
|
||||
if (getNumOfTags(pTableMeta) == 1 && pTagsSchema->type == TSDB_DATA_TYPE_JSON &&
|
||||
(pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG || pStmt->alterType == TSDB_ALTER_TABLE_DROP_TAG ||
|
||||
pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_TAG_BYTES)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
|
||||
}
|
||||
|
||||
if (TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES == pStmt->alterType ||
|
||||
TSDB_ALTER_TABLE_UPDATE_TAG_BYTES == pStmt->alterType) {
|
||||
STableMeta* pTableMeta = NULL;
|
||||
int32_t code = getTableMeta(pCxt, pStmt->dbName, pStmt->tableName, &pTableMeta);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
SSchema* pSchema = getColSchema(pTableMeta, pStmt->colName);
|
||||
if (NULL == pSchema) {
|
||||
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pStmt->colName);
|
||||
} else if (!IS_VAR_DATA_TYPE(pSchema->type) || pSchema->type != pStmt->dataType.type ||
|
||||
pSchema->bytes >= calcTypeBytes(pStmt->dataType)) {
|
||||
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL);
|
||||
}
|
||||
if (TSDB_SUPER_TABLE != pTableMeta->tableType) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE, "Table is not super table");
|
||||
}
|
||||
|
||||
SSchema* pSchema = getColSchema(pTableMeta, pStmt->colName);
|
||||
if (NULL == pSchema) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pStmt->colName);
|
||||
} else if (!IS_VAR_DATA_TYPE(pSchema->type) || pSchema->type != pStmt->dataType.type ||
|
||||
pSchema->bytes >= calcTypeBytes(pStmt->dataType)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_MODIFY_COL);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -4455,6 +4521,7 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
|
|||
code = translateDropSuperTable(pCxt, (SDropSuperTableStmt*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_ALTER_TABLE_STMT:
|
||||
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
|
||||
code = translateAlterSuperTable(pCxt, (SAlterTableStmt*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_CREATE_USER_STMT:
|
||||
|
@ -5222,30 +5289,62 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, S
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t createValueFromFunction(STranslateContext* pCxt, SFunctionNode* pFunc, SValueNode** pVal) {
|
||||
int32_t code = getFuncInfo(pCxt, pFunc);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = scalarCalculateConstants((SNode*)pFunc, (SNode**)pVal);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static SDataType schemaToDataType(uint8_t precision, SSchema* pSchema) {
|
||||
SDataType dt = {.type = pSchema->type, .bytes = pSchema->bytes, .precision = precision, .scale = 0};
|
||||
return dt;
|
||||
}
|
||||
|
||||
static int32_t translateTagVal(STranslateContext* pCxt, uint8_t precision, SSchema* pSchema, SNode* pNode,
|
||||
SValueNode** pVal) {
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
||||
return createValueFromFunction(pCxt, (SFunctionNode*)pNode, pVal);
|
||||
} else if (QUERY_NODE_VALUE == nodeType(pNode)) {
|
||||
return (DEAL_RES_ERROR == translateValueImpl(pCxt, (SValueNode*)pNode, schemaToDataType(precision, pSchema))
|
||||
? pCxt->errCode
|
||||
: TSDB_CODE_SUCCESS);
|
||||
static int32_t createCastFuncForTag(STranslateContext* pCxt, SNode* pNode, SDataType dt, SNode** pCast) {
|
||||
SNode* pExpr = nodesCloneNode(pNode);
|
||||
if (NULL == pExpr) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
int32_t code = translateExpr(pCxt, &pExpr);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createCastFunc(pCxt, pExpr, dt, pCast);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyNode(pExpr);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t createTagValFromExpr(STranslateContext* pCxt, SDataType targetDt, SNode* pNode, SValueNode** pVal) {
|
||||
SNode* pCast = NULL;
|
||||
int32_t code = createCastFuncForTag(pCxt, pNode, targetDt, &pCast);
|
||||
SNode* pNew = NULL;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = scalarCalculateConstants(pCast, &pNew);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pCast = pNew;
|
||||
if (QUERY_NODE_VALUE != nodeType(pCast)) {
|
||||
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pNode)->aliasName);
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pVal = (SValueNode*)pCast;
|
||||
} else {
|
||||
// return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pNode)->aliasName);
|
||||
return TSDB_CODE_FAILED;
|
||||
nodesDestroyNode(pCast);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t createTagValFromVal(STranslateContext* pCxt, SDataType targetDt, SNode* pNode, SValueNode** pVal) {
|
||||
*pVal = (SValueNode*)nodesCloneNode(pNode);
|
||||
if (NULL == *pVal) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
return DEAL_RES_ERROR == translateValueImpl(pCxt, *pVal, targetDt) ? pCxt->errCode : TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t createTagVal(STranslateContext* pCxt, uint8_t precision, SSchema* pSchema, SNode* pNode,
|
||||
SValueNode** pVal) {
|
||||
if (QUERY_NODE_VALUE == nodeType(pNode)) {
|
||||
return createTagValFromVal(pCxt, schemaToDataType(precision, pSchema), pNode, pVal);
|
||||
} else {
|
||||
return createTagValFromExpr(pCxt, schemaToDataType(precision, pSchema), pNode, pVal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5285,56 +5384,45 @@ static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableCla
|
|||
if (NULL == pTagArray) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SSchema* pTagSchema = getTableTagSchema(pSuperTableMeta);
|
||||
SNode * pTag = NULL, *pNode = NULL;
|
||||
bool isJson = false;
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
bool isJson = false;
|
||||
SNodeList* pVals = NULL;
|
||||
SNode * pTag = NULL, *pNode = NULL;
|
||||
FORBOTH(pTag, pStmt->pSpecificTags, pNode, pStmt->pValsOfTags) {
|
||||
SColumnNode* pCol = (SColumnNode*)pTag;
|
||||
SSchema* pSchema = NULL;
|
||||
for (int32_t i = 0; i < numOfTags; ++i) {
|
||||
if (0 == strcmp(pCol->colName, pTagSchema[i].name)) {
|
||||
pSchema = pTagSchema + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SSchema* pSchema = getTagSchema(pSuperTableMeta, pCol->colName);
|
||||
if (NULL == pSchema) {
|
||||
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAG_NAME, pCol->colName);
|
||||
goto end;
|
||||
}
|
||||
SValueNode* pVal = NULL;
|
||||
code = translateTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pSchema, pNode, &pVal);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
goto end;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pSchema, pNode, &pVal);
|
||||
}
|
||||
|
||||
if (NULL == pVal) {
|
||||
pVal = (SValueNode*)pNode;
|
||||
} else {
|
||||
REPLACE_LIST2_NODE(pVal);
|
||||
}
|
||||
|
||||
if (pSchema->type == TSDB_DATA_TYPE_JSON) {
|
||||
isJson = true;
|
||||
code = buildJsonTagVal(pCxt, pSchema, pVal, pTagArray, ppTag);
|
||||
} else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) {
|
||||
code = buildNormalTagVal(pCxt, pSchema, pVal, pTagArray);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isJson) code = tTagNew(pTagArray, 1, false, ppTag);
|
||||
|
||||
end:
|
||||
if (isJson) {
|
||||
for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) {
|
||||
STagVal* p = (STagVal*)taosArrayGet(pTagArray, i);
|
||||
if (IS_VAR_DATA_TYPE(p->type)) {
|
||||
taosMemoryFree(p->pData);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pSchema->type == TSDB_DATA_TYPE_JSON) {
|
||||
isJson = true;
|
||||
code = buildJsonTagVal(pCxt, pSchema, pVal, pTagArray, ppTag);
|
||||
} else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) {
|
||||
code = buildNormalTagVal(pCxt, pSchema, pVal, pTagArray);
|
||||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListMakeAppend(&pVals, (SNode*)pVal);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && !isJson) {
|
||||
code = tTagNew(pTagArray, 1, false, ppTag);
|
||||
}
|
||||
|
||||
nodesDestroyList(pVals);
|
||||
taosArrayDestroy(pTagArray);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClause* pStmt, STableMeta* pSuperTableMeta,
|
||||
|
@ -5343,64 +5431,52 @@ static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClau
|
|||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TAGS_NOT_MATCHED);
|
||||
}
|
||||
|
||||
SSchema* pTagSchemas = getTableTagSchema(pSuperTableMeta);
|
||||
SNode* pNode;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t index = 0;
|
||||
SArray* pTagArray = taosArrayInit(LIST_LENGTH(pStmt->pValsOfTags), sizeof(STagVal));
|
||||
if (!pTagArray) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_TSC_OUT_OF_MEMORY);
|
||||
SArray* pTagArray = taosArrayInit(LIST_LENGTH(pStmt->pValsOfTags), sizeof(STagVal));
|
||||
if (NULL == pTagArray) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
bool isJson = false;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
bool isJson = false;
|
||||
int32_t index = 0;
|
||||
SSchema* pTagSchemas = getTableTagSchema(pSuperTableMeta);
|
||||
SNodeList* pVals = NULL;
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pStmt->pValsOfTags) {
|
||||
SValueNode* pVal = NULL;
|
||||
SSchema* pTagSchema = pTagSchemas + index;
|
||||
code = translateTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pTagSchema, pNode, &pVal);
|
||||
code = createTagVal(pCxt, pSuperTableMeta->tableInfo.precision, pTagSchema, pNode, &pVal);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
|
||||
isJson = true;
|
||||
code = buildJsonTagVal(pCxt, pTagSchema, pVal, pTagArray, ppTag);
|
||||
} else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL && !pVal->isNull) {
|
||||
char* tmpVal = nodesGetValueFromNode(pVal);
|
||||
STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
|
||||
if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
|
||||
val.pData = varDataVal(tmpVal);
|
||||
val.nData = varDataLen(tmpVal);
|
||||
} else {
|
||||
memcpy(&val.i64, tmpVal, pTagSchema->bytes);
|
||||
}
|
||||
taosArrayPush(pTagArray, &val);
|
||||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListMakeAppend(&pVals, (SNode*)pVal);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
goto end;
|
||||
}
|
||||
if (NULL == pVal) {
|
||||
pVal = (SValueNode*)pNode;
|
||||
} else {
|
||||
REPLACE_NODE(pVal);
|
||||
}
|
||||
if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
|
||||
if (pVal->literal && strlen(pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
|
||||
code = buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pVal->literal);
|
||||
goto end;
|
||||
}
|
||||
|
||||
isJson = true;
|
||||
code = parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto end;
|
||||
}
|
||||
} else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL && !pVal->isNull) {
|
||||
char* tmpVal = nodesGetValueFromNode(pVal);
|
||||
STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
|
||||
if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
|
||||
val.pData = varDataVal(tmpVal);
|
||||
val.nData = varDataLen(tmpVal);
|
||||
} else {
|
||||
memcpy(&val.i64, tmpVal, pTagSchema->bytes);
|
||||
}
|
||||
taosArrayPush(pTagArray, &val);
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
if (!isJson) code = tTagNew(pTagArray, 1, false, ppTag);
|
||||
|
||||
end:
|
||||
if (isJson) {
|
||||
for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) {
|
||||
STagVal* p = (STagVal*)taosArrayGet(pTagArray, i);
|
||||
if (IS_VAR_DATA_TYPE(p->type)) {
|
||||
taosMemoryFree(p->pData);
|
||||
}
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && !isJson) {
|
||||
code = tTagNew(pTagArray, 1, false, ppTag);
|
||||
}
|
||||
|
||||
nodesDestroyList(pVals);
|
||||
taosArrayDestroy(pTagArray);
|
||||
return code;
|
||||
}
|
||||
|
@ -5898,15 +5974,6 @@ static int32_t rewriteAlterTableImpl(STranslateContext* pCxt, SAlterTableStmt* p
|
|||
}
|
||||
|
||||
if (TSDB_SUPER_TABLE == pTableMeta->tableType) {
|
||||
SSchema* pTagsSchema = getTableTagSchema(pTableMeta);
|
||||
if (getNumOfTags(pTableMeta) == 1 && pTagsSchema->type == TSDB_DATA_TYPE_JSON &&
|
||||
(pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG || pStmt->alterType == TSDB_ALTER_TABLE_DROP_TAG ||
|
||||
pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_TAG_BYTES)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
|
||||
}
|
||||
if (pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_OPTIONS && -1 != pStmt->pOptions->ttl) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (TSDB_CHILD_TABLE != pTableMeta->tableType && TSDB_NORMAL_TABLE != pTableMeta->tableType) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE);
|
||||
|
@ -5929,10 +5996,6 @@ static int32_t rewriteAlterTableImpl(STranslateContext* pCxt, SAlterTableStmt* p
|
|||
static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) {
|
||||
SAlterTableStmt* pStmt = (SAlterTableStmt*)pQuery->pRoot;
|
||||
|
||||
if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
|
||||
}
|
||||
|
||||
if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON);
|
||||
}
|
||||
|
|
|
@ -215,13 +215,21 @@ int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...) {
|
|||
return errCode;
|
||||
}
|
||||
|
||||
int32_t generateSyntaxErrMsgExt(SMsgBuf* pBuf, int32_t errCode, const char* pFormat, ...) {
|
||||
va_list vArgList;
|
||||
va_start(vArgList, pFormat);
|
||||
vsnprintf(pBuf->buf, pBuf->len, pFormat, vArgList);
|
||||
va_end(vArgList);
|
||||
return errCode;
|
||||
}
|
||||
|
||||
int32_t buildInvalidOperationMsg(SMsgBuf* pBuf, const char* msg) {
|
||||
strncpy(pBuf->buf, msg, pBuf->len);
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr) {
|
||||
if(pBuf == NULL) return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||
if (pBuf == NULL) return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||
const char* msgFormat1 = "syntax error near \'%s\'";
|
||||
const char* msgFormat2 = "syntax error near \'%s\' (%s)";
|
||||
const char* msgFormat3 = "%s";
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -77,8 +77,6 @@ TEST_F(ParserInitialATest, alterLocal) {
|
|||
clearAlterLocal();
|
||||
}
|
||||
|
||||
// todo ALTER stable
|
||||
|
||||
/*
|
||||
* ALTER TABLE [db_name.]tb_name alter_table_clause
|
||||
*
|
||||
|
@ -157,7 +155,7 @@ TEST_F(ParserInitialATest, alterSTable) {
|
|||
};
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_TABLE_STMT);
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_SUPER_TABLE_STMT);
|
||||
SMAlterStbReq req = {0};
|
||||
ASSERT_EQ(tDeserializeSMAlterStbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
|
||||
ASSERT_EQ(std::string(req.name), std::string(expect.name));
|
||||
|
@ -181,44 +179,44 @@ TEST_F(ParserInitialATest, alterSTable) {
|
|||
});
|
||||
|
||||
// setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, nullptr, 10);
|
||||
// run("ALTER TABLE st1 TTL 10");
|
||||
// run("ALTER STABLE st1 TTL 10");
|
||||
// clearAlterStbReq();
|
||||
|
||||
setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_OPTIONS, 0, nullptr, 0, 0, nullptr, "test");
|
||||
run("ALTER TABLE st1 COMMENT 'test'");
|
||||
run("ALTER STABLE st1 COMMENT 'test'");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_COLUMN, 1, "cc1", TSDB_DATA_TYPE_BIGINT);
|
||||
run("ALTER TABLE st1 ADD COLUMN cc1 BIGINT");
|
||||
run("ALTER STABLE st1 ADD COLUMN cc1 BIGINT");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_DROP_COLUMN, 1, "c1");
|
||||
run("ALTER TABLE st1 DROP COLUMN c1");
|
||||
run("ALTER STABLE st1 DROP COLUMN c1");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, 1, "c2", TSDB_DATA_TYPE_VARCHAR,
|
||||
30 + VARSTR_HEADER_SIZE);
|
||||
run("ALTER TABLE st1 MODIFY COLUMN c2 VARCHAR(30)");
|
||||
run("ALTER STABLE st1 MODIFY COLUMN c2 VARCHAR(30)");
|
||||
clearAlterStbReq();
|
||||
|
||||
// setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, 2, "c1", 0, 0, "cc1");
|
||||
// run("ALTER TABLE st1 RENAME COLUMN c1 cc1");
|
||||
// run("ALTER STABLE st1 RENAME COLUMN c1 cc1");
|
||||
|
||||
setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_ADD_TAG, 1, "tag11", TSDB_DATA_TYPE_BIGINT);
|
||||
run("ALTER TABLE st1 ADD TAG tag11 BIGINT");
|
||||
run("ALTER STABLE st1 ADD TAG tag11 BIGINT");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_DROP_TAG, 1, "tag1");
|
||||
run("ALTER TABLE st1 DROP TAG tag1");
|
||||
run("ALTER STABLE st1 DROP TAG tag1");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, 1, "tag2", TSDB_DATA_TYPE_VARCHAR,
|
||||
30 + VARSTR_HEADER_SIZE);
|
||||
run("ALTER TABLE st1 MODIFY TAG tag2 VARCHAR(30)");
|
||||
run("ALTER STABLE st1 MODIFY TAG tag2 VARCHAR(30)");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReqFunc("st1", TSDB_ALTER_TABLE_UPDATE_TAG_NAME, 2, "tag1", 0, 0, "tag11");
|
||||
run("ALTER TABLE st1 RENAME TAG tag1 tag11");
|
||||
run("ALTER STABLE st1 RENAME TAG tag1 tag11");
|
||||
clearAlterStbReq();
|
||||
|
||||
// todo
|
||||
|
@ -228,11 +226,11 @@ TEST_F(ParserInitialATest, alterSTable) {
|
|||
TEST_F(ParserInitialATest, alterSTableSemanticCheck) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("ALTER TABLE st1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE);
|
||||
run("ALTER STABLE st1 RENAME COLUMN c1 cc1", TSDB_CODE_PAR_INVALID_ALTER_TABLE);
|
||||
|
||||
run("ALTER TABLE st1 MODIFY COLUMN c2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL);
|
||||
run("ALTER STABLE st1 MODIFY COLUMN c2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL);
|
||||
|
||||
run("ALTER TABLE st1 MODIFY TAG tag2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL);
|
||||
run("ALTER STABLE st1 MODIFY TAG tag2 NCHAR(10)", TSDB_CODE_PAR_INVALID_MODIFY_COL);
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialATest, alterTable) {
|
||||
|
|
|
@ -720,7 +720,7 @@ static int32_t pushDownCondOptDealAgg(SOptimizeContext* pCxt, SAggLogicNode* pAg
|
|||
// TODO: remove it after full implementation of pushing down to child
|
||||
if (1 != LIST_LENGTH(pAgg->node.pChildren) ||
|
||||
QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pAgg->node.pChildren, 0)) &&
|
||||
QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(nodesListGetNode(pAgg->node.pChildren, 0))) {
|
||||
QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(nodesListGetNode(pAgg->node.pChildren, 0))) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1251,7 +1251,7 @@ static SNode* partTagsCreateWrapperFunc(const char* pFuncName, SNode* pNode) {
|
|||
}
|
||||
|
||||
strcpy(pFunc->functionName, pFuncName);
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode) && COLUMN_TYPE_TBNAME != ((SColumnNode*)pNode)->colType) {
|
||||
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||
partTagsSetAlias(pFunc->node.aliasName, sizeof(pFunc->node.aliasName), pCol->tableAlias, pCol->colName);
|
||||
} else {
|
||||
|
@ -1868,6 +1868,8 @@ static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) {
|
|||
pCxt->errCode = terrno;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
snprintf(((SExprNode*)pExpr)->aliasName, sizeof(((SExprNode*)pExpr)->aliasName), "%s",
|
||||
((SExprNode*)*pNode)->aliasName);
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = pExpr;
|
||||
}
|
||||
|
|
|
@ -986,6 +986,10 @@ static bool unionIsChildSubplan(SLogicNode* pLogicNode, int32_t groupId) {
|
|||
return ((SExchangeLogicNode*)pLogicNode)->srcGroupId == groupId;
|
||||
}
|
||||
|
||||
if (QUERY_NODE_LOGIC_PLAN_MERGE == nodeType(pLogicNode)) {
|
||||
return ((SMergeLogicNode*)pLogicNode)->srcGroupId == groupId;
|
||||
}
|
||||
|
||||
SNode* pChild;
|
||||
FOREACH(pChild, pLogicNode->pChildren) {
|
||||
bool isChild = unionIsChildSubplan((SLogicNode*)pChild, groupId);
|
||||
|
|
|
@ -68,6 +68,8 @@ TEST_F(PlanOptimizeTest, PartitionTags) {
|
|||
run("SELECT SUM(c1), tag1 FROM st1 GROUP BY tag1");
|
||||
|
||||
run("SELECT SUM(c1), tag1 + 10 FROM st1 GROUP BY tag1 + 10");
|
||||
|
||||
run("SELECT SUM(c1), tbname FROM st1 GROUP BY tbname");
|
||||
}
|
||||
|
||||
TEST_F(PlanOptimizeTest, eliminateProjection) {
|
||||
|
|
|
@ -97,7 +97,15 @@ TEST_F(PlanSetOpTest, unionSubquery) {
|
|||
run("SELECT * FROM (SELECT c1, c2 FROM t1 UNION SELECT c1, c2 FROM t1)");
|
||||
}
|
||||
|
||||
TEST_F(PlanSetOpTest, bug001) {
|
||||
TEST_F(PlanSetOpTest, unionWithSubquery) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT c1 FROM (SELECT c1 FROM st1) UNION SELECT c2 FROM (SELECT c1 AS c2 FROM st2)");
|
||||
|
||||
run("SELECT c1 FROM (SELECT c1 FROM st1 ORDER BY c2) UNION SELECT c1 FROM (SELECT c1 FROM st2)");
|
||||
}
|
||||
|
||||
TEST_F(PlanSetOpTest, unionDataTypeConversion) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT c2 FROM t1 WHERE c1 IS NOT NULL GROUP BY c2 "
|
||||
|
|
|
@ -566,7 +566,7 @@ class TDTestCase:
|
|||
tdSql.checkRows(3)
|
||||
tdSql.query("select bottom(dataint,100) from jsons1 where jtag->'tag1'>1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select percentile(dataint,20) from jsons1 where jtag->'tag1'>1")
|
||||
#tdSql.query("select percentile(dataint,20) from jsons1 where jtag->'tag1'>1")
|
||||
tdSql.query("select apercentile(dataint, 50) from jsons1 where jtag->'tag1'>1")
|
||||
tdSql.checkData(0, 0, 1.5)
|
||||
# tdSql.query("select last_row(dataint) from jsons1 where jtag->'tag1'>1")
|
||||
|
|
Loading…
Reference in New Issue