TD-14383 limit/slimit plan implement, and sort plan bugfix
This commit is contained in:
parent
a5af4547d9
commit
0f60e644e9
|
@ -121,6 +121,7 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_LOGIC_PLAN_EXCHANGE,
|
QUERY_NODE_LOGIC_PLAN_EXCHANGE,
|
||||||
QUERY_NODE_LOGIC_PLAN_WINDOW,
|
QUERY_NODE_LOGIC_PLAN_WINDOW,
|
||||||
QUERY_NODE_LOGIC_PLAN_SORT,
|
QUERY_NODE_LOGIC_PLAN_SORT,
|
||||||
|
QUERY_NODE_LOGIC_PLAN_PARTITION,
|
||||||
QUERY_NODE_LOGIC_SUBPLAN,
|
QUERY_NODE_LOGIC_SUBPLAN,
|
||||||
QUERY_NODE_LOGIC_PLAN,
|
QUERY_NODE_LOGIC_PLAN,
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,11 @@ typedef struct SAggLogicNode {
|
||||||
typedef struct SProjectLogicNode {
|
typedef struct SProjectLogicNode {
|
||||||
SLogicNode node;
|
SLogicNode node;
|
||||||
SNodeList* pProjections;
|
SNodeList* pProjections;
|
||||||
char stmtName[TSDB_TABLE_NAME_LEN];
|
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||||
|
int64_t limit;
|
||||||
|
int64_t offset;
|
||||||
|
int64_t slimit;
|
||||||
|
int64_t soffset;
|
||||||
} SProjectLogicNode;
|
} SProjectLogicNode;
|
||||||
|
|
||||||
typedef struct SVnodeModifLogicNode {
|
typedef struct SVnodeModifLogicNode {
|
||||||
|
@ -106,6 +110,11 @@ typedef struct SSortLogicNode {
|
||||||
SNodeList* pSortKeys;
|
SNodeList* pSortKeys;
|
||||||
} SSortLogicNode;
|
} SSortLogicNode;
|
||||||
|
|
||||||
|
typedef struct SPartitionLogicNode {
|
||||||
|
SLogicNode node;
|
||||||
|
SNodeList* pPartitionKeys;
|
||||||
|
} SPartitionLogicNode;
|
||||||
|
|
||||||
typedef enum ESubplanType {
|
typedef enum ESubplanType {
|
||||||
SUBPLAN_TYPE_MERGE = 1,
|
SUBPLAN_TYPE_MERGE = 1,
|
||||||
SUBPLAN_TYPE_PARTIAL,
|
SUBPLAN_TYPE_PARTIAL,
|
||||||
|
@ -150,7 +159,8 @@ typedef struct SDataBlockDescNode {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
int16_t dataBlockId;
|
int16_t dataBlockId;
|
||||||
SNodeList* pSlots;
|
SNodeList* pSlots;
|
||||||
int32_t resultRowSize;
|
int32_t totalRowSize;
|
||||||
|
int32_t outputRowSize;
|
||||||
int16_t precision;
|
int16_t precision;
|
||||||
} SDataBlockDescNode;
|
} SDataBlockDescNode;
|
||||||
|
|
||||||
|
@ -195,6 +205,10 @@ typedef STableScanPhysiNode STableSeqScanPhysiNode;
|
||||||
typedef struct SProjectPhysiNode {
|
typedef struct SProjectPhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
SNodeList* pProjections;
|
SNodeList* pProjections;
|
||||||
|
int64_t limit;
|
||||||
|
int64_t offset;
|
||||||
|
int64_t slimit;
|
||||||
|
int64_t soffset;
|
||||||
} SProjectPhysiNode;
|
} SProjectPhysiNode;
|
||||||
|
|
||||||
typedef struct SJoinPhysiNode {
|
typedef struct SJoinPhysiNode {
|
||||||
|
@ -283,10 +297,17 @@ typedef struct SSubplan {
|
||||||
SDataSinkNode* pDataSink; // data of the subplan flow into the datasink
|
SDataSinkNode* pDataSink; // data of the subplan flow into the datasink
|
||||||
} SSubplan;
|
} SSubplan;
|
||||||
|
|
||||||
|
typedef enum EQueryMode {
|
||||||
|
QUERY_MODE_NORMAL = 1,
|
||||||
|
QUERY_MODE_EXPLAIN,
|
||||||
|
QUERY_MODE_EXPLAIN_AN
|
||||||
|
} EQueryMode;
|
||||||
|
|
||||||
typedef struct SQueryPlan {
|
typedef struct SQueryPlan {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
uint64_t queryId;
|
uint64_t queryId;
|
||||||
int32_t numOfSubplans;
|
int32_t numOfSubplans;
|
||||||
|
|
||||||
SNodeList* pSubplans; // Element is SNodeListNode. The execution level of subplan, starting from 0.
|
SNodeList* pSubplans; // Element is SNodeListNode. The execution level of subplan, starting from 0.
|
||||||
} SQueryPlan;
|
} SQueryPlan;
|
||||||
|
|
||||||
|
|
|
@ -180,8 +180,8 @@ typedef struct SOrderByExprNode {
|
||||||
|
|
||||||
typedef struct SLimitNode {
|
typedef struct SLimitNode {
|
||||||
ENodeType type; // QUERY_NODE_LIMIT
|
ENodeType type; // QUERY_NODE_LIMIT
|
||||||
uint64_t limit;
|
int64_t limit;
|
||||||
uint64_t offset;
|
int64_t offset;
|
||||||
} SLimitNode;
|
} SLimitNode;
|
||||||
|
|
||||||
typedef struct SStateWindowNode {
|
typedef struct SStateWindowNode {
|
||||||
|
|
|
@ -350,7 +350,7 @@ SSDataBlock* createOutputBuf_rv1(SDataBlockDescNode* pNode) {
|
||||||
pBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
|
pBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
|
||||||
|
|
||||||
pBlock->info.blockId = pNode->dataBlockId;
|
pBlock->info.blockId = pNode->dataBlockId;
|
||||||
pBlock->info.rowSize = pNode->resultRowSize;
|
pBlock->info.rowSize = pNode->totalRowSize;
|
||||||
|
|
||||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||||
SColumnInfoData idata = {{0}};
|
SColumnInfoData idata = {{0}};
|
||||||
|
|
|
@ -260,9 +260,9 @@ static SNode* logicAggCopy(const SAggLogicNode* pSrc, SAggLogicNode* pDst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static SNode* logicProjectCopy(const SProjectLogicNode* pSrc, SProjectLogicNode* pDst) {
|
static SNode* logicProjectCopy(const SProjectLogicNode* pSrc, SProjectLogicNode* pDst) {
|
||||||
|
COPY_ALL_SCALAR_FIELDS;
|
||||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||||
CLONE_NODE_LIST_FIELD(pProjections);
|
CLONE_NODE_LIST_FIELD(pProjections);
|
||||||
COPY_CHAR_ARRAY_FIELD(stmtName);
|
|
||||||
return (SNode*)pDst;
|
return (SNode*)pDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,10 +307,8 @@ static SNode* logicSubplanCopy(const SLogicSubplan* pSrc, SLogicSubplan* pDst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static SNode* dataBlockDescCopy(const SDataBlockDescNode* pSrc, SDataBlockDescNode* pDst) {
|
static SNode* dataBlockDescCopy(const SDataBlockDescNode* pSrc, SDataBlockDescNode* pDst) {
|
||||||
COPY_SCALAR_FIELD(dataBlockId);
|
COPY_ALL_SCALAR_FIELDS;
|
||||||
CLONE_NODE_LIST_FIELD(pSlots);
|
CLONE_NODE_LIST_FIELD(pSlots);
|
||||||
COPY_SCALAR_FIELD(resultRowSize);
|
|
||||||
COPY_SCALAR_FIELD(precision);
|
|
||||||
return (SNode*)pDst;
|
return (SNode*)pDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -475,6 +475,10 @@ static int32_t jsonToLogicScanNode(const SJson* pJson, void* pObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* jkProjectLogicPlanProjections = "Projections";
|
static const char* jkProjectLogicPlanProjections = "Projections";
|
||||||
|
static const char* jkProjectLogicPlanLimit = "Limit";
|
||||||
|
static const char* jkProjectLogicPlanOffset = "Offset";
|
||||||
|
static const char* jkProjectLogicPlanSlimit = "SLimit";
|
||||||
|
static const char* jkProjectLogicPlanSoffset = "SOffset";
|
||||||
|
|
||||||
static int32_t logicProjectNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t logicProjectNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SProjectLogicNode* pNode = (const SProjectLogicNode*)pObj;
|
const SProjectLogicNode* pNode = (const SProjectLogicNode*)pObj;
|
||||||
|
@ -483,6 +487,18 @@ static int32_t logicProjectNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkProjectLogicPlanProjections, pNode->pProjections);
|
code = nodeListToJson(pJson, jkProjectLogicPlanProjections, pNode->pProjections);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkProjectLogicPlanLimit, pNode->limit);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkProjectLogicPlanOffset, pNode->offset);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkProjectLogicPlanSlimit, pNode->slimit);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkScanLogicPlanTableMetaSize, pNode->soffset);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -494,6 +510,18 @@ static int32_t jsonToLogicProjectNode(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeList(pJson, jkProjectLogicPlanProjections, &pNode->pProjections);
|
code = jsonToNodeList(pJson, jkProjectLogicPlanProjections, &pNode->pProjections);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkProjectLogicPlanLimit, &pNode->limit);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkProjectLogicPlanOffset, &pNode->offset);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkProjectLogicPlanSlimit, &pNode->slimit);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkScanLogicPlanTableMetaSize, &pNode->soffset);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -802,6 +830,10 @@ static int32_t jsonToPhysiSysTableScanNode(const SJson* pJson, void* pObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* jkProjectPhysiPlanProjections = "Projections";
|
static const char* jkProjectPhysiPlanProjections = "Projections";
|
||||||
|
static const char* jkProjectPhysiPlanLimit = "Limit";
|
||||||
|
static const char* jkProjectPhysiPlanOffset = "Offset";
|
||||||
|
static const char* jkProjectPhysiPlanSlimit = "SLimit";
|
||||||
|
static const char* jkProjectPhysiPlanSoffset = "SOffset";
|
||||||
|
|
||||||
static int32_t physiProjectNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t physiProjectNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SProjectPhysiNode* pNode = (const SProjectPhysiNode*)pObj;
|
const SProjectPhysiNode* pNode = (const SProjectPhysiNode*)pObj;
|
||||||
|
@ -810,6 +842,18 @@ static int32_t physiProjectNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkProjectPhysiPlanProjections, pNode->pProjections);
|
code = nodeListToJson(pJson, jkProjectPhysiPlanProjections, pNode->pProjections);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkProjectPhysiPlanLimit, pNode->limit);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkProjectPhysiPlanOffset, pNode->offset);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkProjectPhysiPlanSlimit, pNode->slimit);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkProjectPhysiPlanSoffset, pNode->soffset);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -821,6 +865,18 @@ static int32_t jsonToPhysiProjectNode(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeList(pJson, jkProjectPhysiPlanProjections, &pNode->pProjections);
|
code = jsonToNodeList(pJson, jkProjectPhysiPlanProjections, &pNode->pProjections);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkProjectPhysiPlanLimit, &pNode->limit);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkProjectPhysiPlanOffset, &pNode->offset);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkProjectPhysiPlanSlimit, &pNode->slimit);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBigIntValue(pJson, jkProjectPhysiPlanSoffset, &pNode->soffset);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2057,19 +2113,26 @@ static int32_t jsonToDownstreamSourceNode(const SJson* pJson, void* pObj) {
|
||||||
|
|
||||||
static const char* jkDataBlockDescDataBlockId = "DataBlockId";
|
static const char* jkDataBlockDescDataBlockId = "DataBlockId";
|
||||||
static const char* jkDataBlockDescSlots = "Slots";
|
static const char* jkDataBlockDescSlots = "Slots";
|
||||||
static const char* jkDataBlockResultRowSize = "ResultRowSize";
|
static const char* jkDataBlockTotalRowSize = "TotalRowSize";
|
||||||
|
static const char* jkDataBlockOutputRowSize = "OutputRowSize";
|
||||||
|
static const char* jkDataBlockPrecision = "Precision";
|
||||||
|
|
||||||
static int32_t dataBlockDescNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t dataBlockDescNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SDataBlockDescNode* pNode = (const SDataBlockDescNode*)pObj;
|
const SDataBlockDescNode* pNode = (const SDataBlockDescNode*)pObj;
|
||||||
|
|
||||||
int32_t code = tjsonAddIntegerToObject(pJson, jkDataBlockDescDataBlockId, pNode->dataBlockId);
|
int32_t code = tjsonAddIntegerToObject(pJson, jkDataBlockDescDataBlockId, pNode->dataBlockId);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddIntegerToObject(pJson, jkDataBlockResultRowSize, pNode->resultRowSize);
|
code = tjsonAddIntegerToObject(pJson, jkDataBlockTotalRowSize, pNode->totalRowSize);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkDataBlockOutputRowSize, pNode->outputRowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkDataBlockDescSlots, pNode->pSlots);
|
code = nodeListToJson(pJson, jkDataBlockDescSlots, pNode->pSlots);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkDataBlockPrecision, pNode->precision);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2079,12 +2142,17 @@ static int32_t jsonToDataBlockDescNode(const SJson* pJson, void* pObj) {
|
||||||
|
|
||||||
int32_t code = tjsonGetSmallIntValue(pJson, jkDataBlockDescDataBlockId, &pNode->dataBlockId);
|
int32_t code = tjsonGetSmallIntValue(pJson, jkDataBlockDescDataBlockId, &pNode->dataBlockId);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonGetIntValue(pJson, jkDataBlockResultRowSize, &pNode->resultRowSize);
|
code = tjsonGetIntValue(pJson, jkDataBlockTotalRowSize, &pNode->totalRowSize);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetIntValue(pJson, jkDataBlockOutputRowSize, &pNode->outputRowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeList(pJson, jkDataBlockDescSlots, &pNode->pSlots);
|
code = jsonToNodeList(pJson, jkDataBlockDescSlots, &pNode->pSlots);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetSmallIntValue(pJson, jkDataBlockPrecision, &pNode->precision);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,11 +582,11 @@ int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char*
|
||||||
nodesWalkSelectStmt(pSelect, clause, collectColumns, &cxt);
|
nodesWalkSelectStmt(pSelect, clause, collectColumns, &cxt);
|
||||||
taosHashCleanup(cxt.pColIdHash);
|
taosHashCleanup(cxt.pColIdHash);
|
||||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||||
nodesDestroyList(cxt.pCols);
|
nodesClearList(cxt.pCols);
|
||||||
return cxt.errCode;
|
return cxt.errCode;
|
||||||
}
|
}
|
||||||
if (0 == LIST_LENGTH(cxt.pCols)) {
|
if (0 == LIST_LENGTH(cxt.pCols)) {
|
||||||
nodesDestroyList(cxt.pCols);
|
nodesClearList(cxt.pCols);
|
||||||
cxt.pCols = NULL;
|
cxt.pCols = NULL;
|
||||||
}
|
}
|
||||||
*pCols = cxt.pCols;
|
*pCols = cxt.pCols;
|
||||||
|
|
|
@ -717,8 +717,10 @@ SNode* createJoinTableNode(SAstCreateContext* pCxt, EJoinType type, SNode* pLeft
|
||||||
SNode* createLimitNode(SAstCreateContext* pCxt, const SToken* pLimit, const SToken* pOffset) {
|
SNode* createLimitNode(SAstCreateContext* pCxt, const SToken* pLimit, const SToken* pOffset) {
|
||||||
SLimitNode* limitNode = (SLimitNode*)nodesMakeNode(QUERY_NODE_LIMIT);
|
SLimitNode* limitNode = (SLimitNode*)nodesMakeNode(QUERY_NODE_LIMIT);
|
||||||
CHECK_OUT_OF_MEM(limitNode);
|
CHECK_OUT_OF_MEM(limitNode);
|
||||||
// limitNode->limit = limit;
|
limitNode->limit = strtol(pLimit->z, NULL, 10);
|
||||||
// limitNode->offset = offset;
|
if (NULL != pOffset) {
|
||||||
|
limitNode->offset = strtol(pOffset->z, NULL, 10);
|
||||||
|
}
|
||||||
return (SNode*)limitNode;
|
return (SNode*)limitNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ static SKeyword keywordTable[] = {
|
||||||
{"ON", TK_ON},
|
{"ON", TK_ON},
|
||||||
{"OR", TK_OR},
|
{"OR", TK_OR},
|
||||||
{"ORDER", TK_ORDER},
|
{"ORDER", TK_ORDER},
|
||||||
|
{"PARTITION", TK_PARTITION},
|
||||||
{"PASS", TK_PASS},
|
{"PASS", TK_PASS},
|
||||||
{"PORT", TK_PORT},
|
{"PORT", TK_PORT},
|
||||||
{"PRECISION", TK_PRECISION},
|
{"PRECISION", TK_PRECISION},
|
||||||
|
|
|
@ -235,6 +235,8 @@ static void setColumnInfoByExpr(const STableNode* pTable, SExprNode* pExpr, SCol
|
||||||
nodesListAppend(pExpr->pAssociationList, (SNode*)pCol);
|
nodesListAppend(pExpr->pAssociationList, (SNode*)pCol);
|
||||||
if (NULL != pTable) {
|
if (NULL != pTable) {
|
||||||
strcpy(pCol->tableAlias, pTable->tableAlias);
|
strcpy(pCol->tableAlias, pTable->tableAlias);
|
||||||
|
} else if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
|
||||||
|
strcpy(pCol->tableAlias, ((SColumnNode*)pExpr)->tableAlias);
|
||||||
}
|
}
|
||||||
strcpy(pCol->colName, pExpr->aliasName);
|
strcpy(pCol->colName, pExpr->aliasName);
|
||||||
pCol->node.resType = pExpr->resType;
|
pCol->node.resType = pExpr->resType;
|
||||||
|
@ -617,7 +619,6 @@ static int32_t toVgroupsInfo(SArray* pVgs, SVgroupsInfo** pVgsInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t setSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) {
|
static int32_t setSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) {
|
||||||
// todo release
|
|
||||||
if (0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_USER_TABLES)) {
|
if (0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_USER_TABLES)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -631,11 +632,6 @@ static int32_t setSysTableVgroupList(STranslateContext* pCxt, SName* pName, SRea
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
// todo remove
|
|
||||||
//if (NULL != vgroupList && taosArrayGetSize(vgroupList) > 0 && 0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_USER_TABLES)) {
|
|
||||||
// taosArrayPopTailBatch(vgroupList, taosArrayGetSize(vgroupList) - 1);
|
|
||||||
//}
|
|
||||||
|
|
||||||
code = toVgroupsInfo(vgroupList, &pRealTable->pVgroupList);
|
code = toVgroupsInfo(vgroupList, &pRealTable->pVgroupList);
|
||||||
}
|
}
|
||||||
taosArrayDestroy(vgroupList);
|
taosArrayDestroy(vgroupList);
|
||||||
|
@ -1488,12 +1484,6 @@ static int32_t nodeTypeToShowType(ENodeType nt) {
|
||||||
|
|
||||||
static int32_t translateShow(STranslateContext* pCxt, SShowStmt* pStmt) {
|
static int32_t translateShow(STranslateContext* pCxt, SShowStmt* pStmt) {
|
||||||
SShowReq showReq = { .type = nodeTypeToShowType(nodeType(pStmt)) };
|
SShowReq showReq = { .type = nodeTypeToShowType(nodeType(pStmt)) };
|
||||||
// if ('\0' != pStmt->dbName[0]) {
|
|
||||||
// SName name = {0};
|
|
||||||
// tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
|
|
||||||
// char dbFname[TSDB_DB_FNAME_LEN] = {0};
|
|
||||||
// tNameGetFullDbName(&name, showReq.db);
|
|
||||||
// }
|
|
||||||
|
|
||||||
pCxt->pCmdMsg = taosMemoryMalloc(sizeof(SCmdMsgInfo));
|
pCxt->pCmdMsg = taosMemoryMalloc(sizeof(SCmdMsgInfo));
|
||||||
if (NULL == pCxt->pCmdMsg) {
|
if (NULL == pCxt->pCmdMsg) {
|
||||||
|
|
|
@ -142,6 +142,46 @@ static EScanType getScanType(SLogicPlanContext* pCxt, SNodeList* pScanCols, STab
|
||||||
return SCAN_TYPE_TAG;
|
return SCAN_TYPE_TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SNodeptr createPrimaryKeyCol(uint64_t tableId) {
|
||||||
|
SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
||||||
|
if (NULL == pCol) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pCol->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
|
pCol->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
|
||||||
|
pCol->tableId = tableId;
|
||||||
|
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||||
|
pCol->colType = COLUMN_TYPE_COLUMN;
|
||||||
|
strcpy(pCol->colName, "#primarykey");
|
||||||
|
return pCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t addPrimaryKeyCol(uint64_t tableId, SNodeList** pCols) {
|
||||||
|
if (NULL == *pCols) {
|
||||||
|
*pCols = nodesMakeList();
|
||||||
|
if (NULL == *pCols) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
SNode* pCol = NULL;
|
||||||
|
FOREACH(pCol, *pCols) {
|
||||||
|
if (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pCol)->colId) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
if (TSDB_CODE_SUCCESS != nodesListStrictAppend(*pCols, createPrimaryKeyCol(tableId))) {
|
||||||
|
nodesDestroyList(*pCols);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable, SLogicNode** pLogicNode) {
|
static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable, SLogicNode** pLogicNode) {
|
||||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN);
|
SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN);
|
||||||
if (NULL == pScan) {
|
if (NULL == pScan) {
|
||||||
|
@ -161,7 +201,11 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
||||||
// set columns to scan
|
// set columns to scan
|
||||||
SNodeList* pCols = NULL;
|
SNodeList* pCols = NULL;
|
||||||
int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, &pCols);
|
int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, &pCols);
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pCols) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = addPrimaryKeyCol(pScan->pMeta->uid, &pCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pScan->pScanCols = nodesCloneList(pCols);
|
pScan->pScanCols = nodesCloneList(pCols);
|
||||||
if (NULL == pScan) {
|
if (NULL == pScan) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
@ -171,13 +215,15 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
||||||
pScan->scanType = getScanType(pCxt, pCols, pScan->pMeta);
|
pScan->scanType = getScanType(pCxt, pCols, pScan->pMeta);
|
||||||
|
|
||||||
// set output
|
// set output
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pCols) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pScan->node.pTargets = nodesCloneList(pCols);
|
pScan->node.pTargets = nodesCloneList(pCols);
|
||||||
if (NULL == pScan) {
|
if (NULL == pScan) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodesClearList(pCols);
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
*pLogicNode = (SLogicNode*)pScan;
|
*pLogicNode = (SLogicNode*)pScan;
|
||||||
} else {
|
} else {
|
||||||
|
@ -548,6 +594,22 @@ static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSel
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NULL != pSelect->pLimit) {
|
||||||
|
pProject->limit = ((SLimitNode*)pSelect->pLimit)->limit;
|
||||||
|
pProject->offset = ((SLimitNode*)pSelect->pLimit)->offset;
|
||||||
|
} else {
|
||||||
|
pProject->limit = -1;
|
||||||
|
pProject->offset = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != pSelect->pSlimit) {
|
||||||
|
pProject->slimit = ((SLimitNode*)pSelect->pSlimit)->limit;
|
||||||
|
pProject->soffset = ((SLimitNode*)pSelect->pSlimit)->offset;
|
||||||
|
} else {
|
||||||
|
pProject->slimit = -1;
|
||||||
|
pProject->soffset = -1;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
pProject->pProjections = nodesCloneList(pSelect->pProjectionList);
|
pProject->pProjections = nodesCloneList(pSelect->pProjectionList);
|
||||||
|
@ -569,15 +631,42 @@ static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSel
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t createPartitionLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
|
if (NULL == pSelect->pPartitionByList) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPartitionLogicNode* pPartition = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_PARTITION);
|
||||||
|
if (NULL == pPartition) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t createDistinctLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
|
if (!pSelect->isDistinct) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
SLogicNode* pRoot = NULL;
|
SLogicNode* pRoot = NULL;
|
||||||
int32_t code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot);
|
int32_t code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
|
code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createChildLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
|
code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = createChildLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createChildLogicNode(pCxt, pSelect, createSortLogicNode, &pRoot);
|
code = createChildLogicNode(pCxt, pSelect, createSortLogicNode, &pRoot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,8 @@ static int32_t buildDataBlockSlots(SPhysiPlanContext* pCxt, SNodeList* pList, SD
|
||||||
code = putSlotToHash(pDataBlockDesc->dataBlockId, slotId, pNode, pHash);
|
code = putSlotToHash(pDataBlockDesc->dataBlockId, slotId, pNode, pHash);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pDataBlockDesc->resultRowSize += ((SExprNode*)pNode)->resType.bytes;
|
pDataBlockDesc->totalRowSize += ((SExprNode*)pNode)->resType.bytes;
|
||||||
|
pDataBlockDesc->outputRowSize += ((SExprNode*)pNode)->resType.bytes;
|
||||||
++slotId;
|
++slotId;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -189,7 +190,10 @@ static int32_t addDataBlockSlotsImpl(SPhysiPlanContext* pCxt, SNodeList* pList,
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = putSlotToHashImpl(pDataBlockDesc->dataBlockId, nextSlotId, name, len, pHash);
|
code = putSlotToHashImpl(pDataBlockDesc->dataBlockId, nextSlotId, name, len, pHash);
|
||||||
}
|
}
|
||||||
pDataBlockDesc->resultRowSize += ((SExprNode*)pExpr)->resType.bytes;
|
pDataBlockDesc->totalRowSize += ((SExprNode*)pExpr)->resType.bytes;
|
||||||
|
if (output) {
|
||||||
|
pDataBlockDesc->outputRowSize += ((SExprNode*)pExpr)->resType.bytes;
|
||||||
|
}
|
||||||
slotId = nextSlotId;
|
slotId = nextSlotId;
|
||||||
++nextSlotId;
|
++nextSlotId;
|
||||||
} else {
|
} else {
|
||||||
|
@ -311,20 +315,6 @@ static int32_t setConditionsSlotId(SPhysiPlanContext* pCxt, const SLogicNode* pL
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SNodeptr createPrimaryKeyCol(SPhysiPlanContext* pCxt, uint64_t tableId) {
|
|
||||||
SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
|
||||||
if (NULL == pCol) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
pCol->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP;
|
|
||||||
pCol->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
|
|
||||||
pCol->tableId = tableId;
|
|
||||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
|
||||||
pCol->colType = COLUMN_TYPE_COLUMN;
|
|
||||||
strcpy(pCol->colName, "#primarykey");
|
|
||||||
return pCol;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t colIdCompare(const void* pLeft, const void* pRight) {
|
static int32_t colIdCompare(const void* pLeft, const void* pRight) {
|
||||||
SColumnNode* pLeftCol = *(SColumnNode**)pLeft;
|
SColumnNode* pLeftCol = *(SColumnNode**)pLeft;
|
||||||
SColumnNode* pRightCol = *(SColumnNode**)pRight;
|
SColumnNode* pRightCol = *(SColumnNode**)pRight;
|
||||||
|
@ -353,35 +343,10 @@ static int32_t sortScanCols(SNodeList* pScanCols) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createScanCols(SPhysiPlanContext* pCxt, SScanPhysiNode* pScanPhysiNode, SNodeList* pScanCols) {
|
static int32_t createScanCols(SPhysiPlanContext* pCxt, SScanPhysiNode* pScanPhysiNode, SNodeList* pScanCols) {
|
||||||
if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == nodeType(pScanPhysiNode)
|
pScanPhysiNode->pScanCols = nodesCloneList(pScanCols);
|
||||||
|| QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN == nodeType(pScanPhysiNode)) {
|
if (NULL == pScanPhysiNode->pScanCols) {
|
||||||
pScanPhysiNode->pScanCols = nodesMakeList();
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
if (NULL == pScanPhysiNode->pScanCols) {
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS != nodesListStrictAppend(pScanPhysiNode->pScanCols, createPrimaryKeyCol(pCxt, pScanPhysiNode->uid))) {
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
SNode* pNode;
|
|
||||||
FOREACH(pNode, pScanCols) {
|
|
||||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pNode)->colId) {
|
|
||||||
SColumnNode* pCol = nodesListGetNode(pScanPhysiNode->pScanCols, 0);
|
|
||||||
strcpy(pCol->tableAlias, ((SColumnNode*)pNode)->tableAlias);
|
|
||||||
strcpy(pCol->colName, ((SColumnNode*)pNode)->colName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS != nodesListStrictAppend(pScanPhysiNode->pScanCols, nodesCloneNode(pNode))) {
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pScanPhysiNode->pScanCols = nodesCloneList(pScanCols);
|
|
||||||
if (NULL == pScanPhysiNode->pScanCols) {
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sortScanCols(pScanPhysiNode->pScanCols);
|
return sortScanCols(pScanPhysiNode->pScanCols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,6 +673,11 @@ static int32_t createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChild
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pProject->limit = pProjectLogicNode->limit;
|
||||||
|
pProject->offset = pProjectLogicNode->offset;
|
||||||
|
pProject->slimit = pProjectLogicNode->slimit;
|
||||||
|
pProject->soffset = pProjectLogicNode->soffset;
|
||||||
|
|
||||||
int32_t code = setListSlotId(pCxt, ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc->dataBlockId, -1, pProjectLogicNode->pProjections, &pProject->pProjections);
|
int32_t code = setListSlotId(pCxt, ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc->dataBlockId, -1, pProjectLogicNode->pProjections, &pProject->pProjections);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = addDataBlockSlotsForProject(pCxt, pProjectLogicNode->stmtName, pProject->pProjections, pProject->node.pOutputDataBlockDesc);
|
code = addDataBlockSlotsForProject(pCxt, pProjectLogicNode->stmtName, pProject->pProjections, pProject->node.pOutputDataBlockDesc);
|
||||||
|
|
|
@ -207,7 +207,7 @@ TEST_F(PlannerTest, sessionWindow) {
|
||||||
TEST_F(PlannerTest, orderBy) {
|
TEST_F(PlannerTest, orderBy) {
|
||||||
setDatabase("root", "test");
|
setDatabase("root", "test");
|
||||||
|
|
||||||
bind("SELECT * FROM t1 order by c1");
|
bind("SELECT c1 FROM t1 order by c1");
|
||||||
ASSERT_TRUE(run());
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
bind("SELECT c1 FROM t1 order by c2");
|
bind("SELECT c1 FROM t1 order by c2");
|
||||||
|
@ -217,6 +217,32 @@ TEST_F(PlannerTest, orderBy) {
|
||||||
ASSERT_TRUE(run());
|
ASSERT_TRUE(run());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PlannerTest, limit) {
|
||||||
|
setDatabase("root", "test");
|
||||||
|
|
||||||
|
bind("SELECT * FROM t1 limit 2");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("SELECT * FROM t1 limit 5 offset 2");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("SELECT * FROM t1 limit 2, 5");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PlannerTest, slimit) {
|
||||||
|
setDatabase("root", "test");
|
||||||
|
|
||||||
|
bind("SELECT * FROM t1 partition by c1 slimit 2");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("SELECT * FROM t1 partition by c1 slimit 5 soffset 2");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("SELECT * FROM t1 partition by c1 slimit 2, 5");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(PlannerTest, showTables) {
|
TEST_F(PlannerTest, showTables) {
|
||||||
setDatabase("root", "test");
|
setDatabase("root", "test");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue