fix: some problem of parser and planner
This commit is contained in:
parent
a64a0320a0
commit
72738040a9
|
@ -543,11 +543,40 @@ static int32_t jsonToLogicPlanNode(const SJson* pJson, void* pObj) {
|
|||
|
||||
static const char* jkScanLogicPlanScanCols = "ScanCols";
|
||||
static const char* jkScanLogicPlanScanPseudoCols = "ScanPseudoCols";
|
||||
static const char* jkScanLogicPlanTableId = "TableId";
|
||||
static const char* jkScanLogicPlanTableType = "TableType";
|
||||
static const char* jkScanLogicPlanTableId = "TableId";
|
||||
static const char* jkScanLogicPlanStableId = "StableId";
|
||||
static const char* jkScanLogicPlanScanCount = "ScanCount";
|
||||
static const char* jkScanLogicPlanReverseScanCount = "ReverseScanCount";
|
||||
static const char* jkScanLogicPlanTagCond = "TagCond";
|
||||
static const char* jkScanLogicPlanGroupTags = "GroupTags";
|
||||
|
||||
// typedef struct SScanLogicNode {
|
||||
// uint64_t stableId;
|
||||
// SVgroupsInfo* pVgroupList;
|
||||
// EScanType scanType;
|
||||
// uint8_t scanSeq[2]; // first is scan count, and second is reverse scan count
|
||||
// STimeWindow scanRange;
|
||||
// SName tableName;
|
||||
// bool showRewrite;
|
||||
// double ratio;
|
||||
// SNodeList* pDynamicScanFuncs;
|
||||
// int32_t dataRequired;
|
||||
// int64_t interval;
|
||||
// int64_t offset;
|
||||
// int64_t sliding;
|
||||
// int8_t intervalUnit;
|
||||
// int8_t slidingUnit;
|
||||
// SNode* pTagCond;
|
||||
// SNode* pTagIndexCond;
|
||||
// int8_t triggerType;
|
||||
// int64_t watermark;
|
||||
// int8_t igExpired;
|
||||
// SArray* pSmaIndexes;
|
||||
// SNodeList* pGroupTags;
|
||||
// bool groupSort;
|
||||
// } SScanLogicNode;
|
||||
|
||||
static int32_t logicScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SScanLogicNode* pNode = (const SScanLogicNode*)pObj;
|
||||
|
||||
|
@ -558,11 +587,20 @@ static int32_t logicScanNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkScanLogicPlanScanPseudoCols, pNode->pScanPseudoCols);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanLogicPlanTableType, pNode->tableType);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanLogicPlanTableId, pNode->tableId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanLogicPlanTableType, pNode->tableType);
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanLogicPlanStableId, pNode->stableId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanLogicPlanScanCount, pNode->scanSeq[0]);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanLogicPlanReverseScanCount, pNode->scanSeq[1]);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkScanLogicPlanTagCond, nodeToJson, pNode->pTagCond);
|
||||
|
@ -585,11 +623,20 @@ static int32_t jsonToLogicScanNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkScanLogicPlanScanPseudoCols, &pNode->pScanPseudoCols);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetTinyIntValue(pJson, jkScanLogicPlanTableType, &pNode->tableType);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetUBigIntValue(pJson, jkScanLogicPlanTableId, &pNode->tableId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetTinyIntValue(pJson, jkScanLogicPlanTableType, &pNode->tableType);
|
||||
code = tjsonGetUBigIntValue(pJson, jkScanLogicPlanStableId, &pNode->stableId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetUTinyIntValue(pJson, jkScanLogicPlanScanCount, &pNode->scanSeq[0]);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetUTinyIntValue(pJson, jkScanLogicPlanReverseScanCount, &pNode->scanSeq[1]);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkScanLogicPlanTagCond, &pNode->pTagCond);
|
||||
|
|
|
@ -120,86 +120,6 @@ static int32_t skipInsertInto(char** pSql, SMsgBuf* pMsg) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t parserValidateIdToken(SToken* pToken) {
|
||||
if (pToken == NULL || pToken->z == NULL || pToken->type != TK_NK_ID) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
// it is a token quoted with escape char '`'
|
||||
if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
|
||||
if (sep == NULL) { // It is a single part token, not a complex type
|
||||
if (isNumber(pToken)) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
strntolower(pToken->z, pToken->z, pToken->n);
|
||||
} else { // two part
|
||||
int32_t oldLen = pToken->n;
|
||||
char* pStr = pToken->z;
|
||||
|
||||
if (pToken->type == TK_NK_SPACE) {
|
||||
pToken->n = (uint32_t)strtrim(pToken->z);
|
||||
}
|
||||
|
||||
pToken->n = tGetToken(pToken->z, &pToken->type);
|
||||
if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (pToken->type != TK_NK_ID) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
int32_t firstPartLen = pToken->n;
|
||||
|
||||
pToken->z = sep + 1;
|
||||
pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1);
|
||||
int32_t len = tGetToken(pToken->z, &pToken->type);
|
||||
if (len != pToken->n || pToken->type != TK_NK_ID) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
// re-build the whole name string
|
||||
if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) {
|
||||
// first part do not have quote do nothing
|
||||
} else {
|
||||
pStr[firstPartLen] = TS_PATH_DELIMITER[0];
|
||||
memmove(&pStr[firstPartLen + 1], pToken->z, pToken->n);
|
||||
uint32_t offset = (uint32_t)(pToken->z - (pStr + firstPartLen + 1));
|
||||
memset(pToken->z + pToken->n - offset, ' ', offset);
|
||||
}
|
||||
|
||||
pToken->n += (firstPartLen + sizeof(TS_PATH_DELIMITER[0]));
|
||||
pToken->z = pStr;
|
||||
|
||||
strntolower(pToken->z, pToken->z, pToken->n);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullDbName, char* tableName) {
|
||||
if (parserValidateIdToken(pStname) != TSDB_CODE_SUCCESS) {
|
||||
return buildSyntaxErrMsg(&pCxt->msg, "invalid table name", pStname->z);
|
||||
}
|
||||
|
||||
char* p = strnchr(pStname->z, TS_PATH_DELIMITER[0], pStname->n, false);
|
||||
if (NULL != p) { // db.table
|
||||
int32_t n = sprintf(fullDbName, "%d.", pCxt->pComCxt->acctId);
|
||||
strncpy(fullDbName + n, pStname->z, p - pStname->z);
|
||||
strncpy(tableName, p + 1, pStname->n - (p - pStname->z) - 1);
|
||||
} else {
|
||||
snprintf(fullDbName, TSDB_DB_FNAME_LEN, "%d.%s", pCxt->pComCxt->acctId, pCxt->pComCxt->db);
|
||||
strncpy(tableName, pStname->z, pStname->n);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t createSName(SName* pName, SToken* pTableName, int32_t acctId, const char* dbName, SMsgBuf* pMsgBuf) {
|
||||
const char* msg1 = "name too long";
|
||||
const char* msg2 = "invalid database name";
|
||||
|
@ -978,11 +898,11 @@ static int32_t parseTagToken(char** end, SToken* pToken, SSchema* pSchema, int16
|
|||
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
int32_t output = 0;
|
||||
void* p = taosMemoryCalloc(1, pToken->n * TSDB_NCHAR_SIZE);
|
||||
void* p = taosMemoryCalloc(1, pSchema->bytes - VARSTR_HEADER_SIZE);
|
||||
if (p == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
if (!taosMbsToUcs4(pToken->z, pToken->n, (TdUcs4*)(p), pToken->n * TSDB_NCHAR_SIZE, &output)) {
|
||||
if (!taosMbsToUcs4(pToken->z, pToken->n, (TdUcs4*)(p), pSchema->bytes - VARSTR_HEADER_SIZE, &output)) {
|
||||
if (errno == E2BIG) {
|
||||
taosMemoryFree(p);
|
||||
return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
|
||||
|
|
|
@ -38,6 +38,8 @@ bool qIsInsertValuesSql(const char* pStr, size_t length) {
|
|||
t = tStrGetToken((char*)pStr, &index, false);
|
||||
if (TK_USING == t.type || TK_VALUES == t.type) {
|
||||
return true;
|
||||
} else if (TK_SELECT == t.type) {
|
||||
return false;
|
||||
}
|
||||
if (0 == t.type) {
|
||||
break;
|
||||
|
|
|
@ -1010,8 +1010,13 @@ static int32_t sortPriKeyOptApply(SOptimizeContext* pCxt, SLogicSubplan* pLogicS
|
|||
SNodeList* pScanNodes) {
|
||||
EOrder order = sortPriKeyOptGetPriKeyOrder(pSort);
|
||||
if (ORDER_DESC == order) {
|
||||
SNode* pScan = NULL;
|
||||
FOREACH(pScan, pScanNodes) { TSWAP(((SScanLogicNode*)pScan)->scanSeq[0], ((SScanLogicNode*)pScan)->scanSeq[1]); }
|
||||
SNode* pScanNode = NULL;
|
||||
FOREACH(pScanNode, pScanNodes) {
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)pScanNode;
|
||||
if (pScan->scanSeq[0] > 0) {
|
||||
TSWAP(pScan->scanSeq[0], pScan->scanSeq[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t code =
|
||||
|
@ -1020,6 +1025,7 @@ static int32_t sortPriKeyOptApply(SOptimizeContext* pCxt, SLogicSubplan* pLogicS
|
|||
NODES_CLEAR_LIST(pSort->node.pChildren);
|
||||
nodesDestroyNode((SNode*)pSort);
|
||||
}
|
||||
pCxt->optimized = true;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -945,6 +945,7 @@ static int32_t stbSplSplitPartitionNode(SSplitContext* pCxt, SStableSplitInfo* p
|
|||
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
|
||||
(SNode*)splCreateScanSubplan(pCxt, pInfo->pSplitNode, SPLIT_FLAG_STABLE_SPLIT));
|
||||
}
|
||||
pInfo->pSubplan->subplanType = SUBPLAN_TYPE_MERGE;
|
||||
++(pCxt->groupId);
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,12 @@ TEST_F(PlanOrderByTest, withGroupBy) {
|
|||
run("SELECT SUM(c1) AS a FROM t1 GROUP BY c2 ORDER BY a");
|
||||
}
|
||||
|
||||
TEST_F(PlanOrderByTest, withSubquery) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT ts FROM (SELECT * FROM t1 ORDER BY ts DESC) ORDER BY ts DESC");
|
||||
}
|
||||
|
||||
TEST_F(PlanOrderByTest, stable) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ TEST_F(PlanPartitionByTest, withAggFunc) {
|
|||
|
||||
run("select count(*) from st1 partition by c1");
|
||||
|
||||
run("select sample(c1, 2) from st1 partition by c1");
|
||||
|
||||
run("select count(*), c1 from t1 partition by c1");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue