Merge pull request #13467 from taosdata/feature/3.0_wxy
feat: sql command 'delete from'
This commit is contained in:
commit
7fa2d3d0d0
|
@ -193,65 +193,66 @@
|
|||
#define TK_REDISTRIBUTE 175
|
||||
#define TK_SPLIT 176
|
||||
#define TK_SYNCDB 177
|
||||
#define TK_NULL 178
|
||||
#define TK_NK_QUESTION 179
|
||||
#define TK_NK_ARROW 180
|
||||
#define TK_ROWTS 181
|
||||
#define TK_TBNAME 182
|
||||
#define TK_QSTARTTS 183
|
||||
#define TK_QENDTS 184
|
||||
#define TK_WSTARTTS 185
|
||||
#define TK_WENDTS 186
|
||||
#define TK_WDURATION 187
|
||||
#define TK_CAST 188
|
||||
#define TK_NOW 189
|
||||
#define TK_TODAY 190
|
||||
#define TK_TIMEZONE 191
|
||||
#define TK_COUNT 192
|
||||
#define TK_FIRST 193
|
||||
#define TK_LAST 194
|
||||
#define TK_LAST_ROW 195
|
||||
#define TK_BETWEEN 196
|
||||
#define TK_IS 197
|
||||
#define TK_NK_LT 198
|
||||
#define TK_NK_GT 199
|
||||
#define TK_NK_LE 200
|
||||
#define TK_NK_GE 201
|
||||
#define TK_NK_NE 202
|
||||
#define TK_MATCH 203
|
||||
#define TK_NMATCH 204
|
||||
#define TK_CONTAINS 205
|
||||
#define TK_JOIN 206
|
||||
#define TK_INNER 207
|
||||
#define TK_SELECT 208
|
||||
#define TK_DISTINCT 209
|
||||
#define TK_WHERE 210
|
||||
#define TK_PARTITION 211
|
||||
#define TK_BY 212
|
||||
#define TK_SESSION 213
|
||||
#define TK_STATE_WINDOW 214
|
||||
#define TK_SLIDING 215
|
||||
#define TK_FILL 216
|
||||
#define TK_VALUE 217
|
||||
#define TK_NONE 218
|
||||
#define TK_PREV 219
|
||||
#define TK_LINEAR 220
|
||||
#define TK_NEXT 221
|
||||
#define TK_HAVING 222
|
||||
#define TK_ORDER 223
|
||||
#define TK_SLIMIT 224
|
||||
#define TK_SOFFSET 225
|
||||
#define TK_LIMIT 226
|
||||
#define TK_OFFSET 227
|
||||
#define TK_ASC 228
|
||||
#define TK_NULLS 229
|
||||
#define TK_ID 230
|
||||
#define TK_NK_BITNOT 231
|
||||
#define TK_INSERT 232
|
||||
#define TK_VALUES 233
|
||||
#define TK_IMPORT 234
|
||||
#define TK_NK_SEMI 235
|
||||
#define TK_FILE 236
|
||||
#define TK_DELETE 178
|
||||
#define TK_NULL 179
|
||||
#define TK_NK_QUESTION 180
|
||||
#define TK_NK_ARROW 181
|
||||
#define TK_ROWTS 182
|
||||
#define TK_TBNAME 183
|
||||
#define TK_QSTARTTS 184
|
||||
#define TK_QENDTS 185
|
||||
#define TK_WSTARTTS 186
|
||||
#define TK_WENDTS 187
|
||||
#define TK_WDURATION 188
|
||||
#define TK_CAST 189
|
||||
#define TK_NOW 190
|
||||
#define TK_TODAY 191
|
||||
#define TK_TIMEZONE 192
|
||||
#define TK_COUNT 193
|
||||
#define TK_FIRST 194
|
||||
#define TK_LAST 195
|
||||
#define TK_LAST_ROW 196
|
||||
#define TK_BETWEEN 197
|
||||
#define TK_IS 198
|
||||
#define TK_NK_LT 199
|
||||
#define TK_NK_GT 200
|
||||
#define TK_NK_LE 201
|
||||
#define TK_NK_GE 202
|
||||
#define TK_NK_NE 203
|
||||
#define TK_MATCH 204
|
||||
#define TK_NMATCH 205
|
||||
#define TK_CONTAINS 206
|
||||
#define TK_JOIN 207
|
||||
#define TK_INNER 208
|
||||
#define TK_SELECT 209
|
||||
#define TK_DISTINCT 210
|
||||
#define TK_WHERE 211
|
||||
#define TK_PARTITION 212
|
||||
#define TK_BY 213
|
||||
#define TK_SESSION 214
|
||||
#define TK_STATE_WINDOW 215
|
||||
#define TK_SLIDING 216
|
||||
#define TK_FILL 217
|
||||
#define TK_VALUE 218
|
||||
#define TK_NONE 219
|
||||
#define TK_PREV 220
|
||||
#define TK_LINEAR 221
|
||||
#define TK_NEXT 222
|
||||
#define TK_HAVING 223
|
||||
#define TK_ORDER 224
|
||||
#define TK_SLIMIT 225
|
||||
#define TK_SOFFSET 226
|
||||
#define TK_LIMIT 227
|
||||
#define TK_OFFSET 228
|
||||
#define TK_ASC 229
|
||||
#define TK_NULLS 230
|
||||
#define TK_ID 231
|
||||
#define TK_NK_BITNOT 232
|
||||
#define TK_INSERT 233
|
||||
#define TK_VALUES 234
|
||||
#define TK_IMPORT 235
|
||||
#define TK_NK_SEMI 236
|
||||
#define TK_FILE 237
|
||||
|
||||
#define TK_NK_SPACE 300
|
||||
#define TK_NK_COMMENT 301
|
||||
|
|
|
@ -180,6 +180,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_KILL_CONNECTION_STMT,
|
||||
QUERY_NODE_KILL_QUERY_STMT,
|
||||
QUERY_NODE_KILL_TRANSACTION_STMT,
|
||||
QUERY_NODE_DELETE_STMT,
|
||||
QUERY_NODE_QUERY,
|
||||
|
||||
// logic plan node
|
||||
|
|
|
@ -60,6 +60,7 @@ typedef struct SColumnNode {
|
|||
int8_t tableType;
|
||||
col_id_t colId;
|
||||
EColumnType colType; // column or tag
|
||||
bool hasIndex;
|
||||
char dbName[TSDB_DB_NAME_LEN];
|
||||
char tableName[TSDB_TABLE_NAME_LEN];
|
||||
char tableAlias[TSDB_TABLE_NAME_LEN];
|
||||
|
@ -258,6 +259,7 @@ typedef struct SSetOperator {
|
|||
SNodeList* pOrderByList; // SOrderByExprNode
|
||||
SNode* pLimit;
|
||||
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||
uint8_t precision;
|
||||
} SSetOperator;
|
||||
|
||||
typedef enum ESqlClause {
|
||||
|
@ -272,6 +274,17 @@ typedef enum ESqlClause {
|
|||
SQL_CLAUSE_ORDER_BY
|
||||
} ESqlClause;
|
||||
|
||||
typedef struct SDeleteStmt {
|
||||
ENodeType type; // QUERY_NODE_DELETE_STMT
|
||||
SNode* pFromTable; // FROM clause
|
||||
SNode* pWhere; // WHERE clause
|
||||
SNode* pCountFunc; // count the number of rows affected
|
||||
SNode* pTagIndexCond; // pWhere divided into pTagIndexCond and timeRange
|
||||
STimeWindow timeRange;
|
||||
uint8_t precision;
|
||||
bool deleteZeroRows;
|
||||
} SDeleteStmt;
|
||||
|
||||
typedef enum {
|
||||
PAYLOAD_TYPE_KV = 0,
|
||||
PAYLOAD_TYPE_RAW = 1,
|
||||
|
@ -363,8 +376,11 @@ bool nodesIsRegularOp(const SOperatorNode* pOp);
|
|||
void* nodesGetValueFromNode(SValueNode* pNode);
|
||||
int32_t nodesSetValueNodeValue(SValueNode* pNode, void* value);
|
||||
char* nodesGetStrValueFromNode(SValueNode* pNode);
|
||||
char* getFillModeString(EFillMode mode);
|
||||
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
|
||||
void nodesValueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
|
||||
|
||||
char* nodesGetFillModeString(EFillMode mode);
|
||||
int32_t nodesMergeConds(SNode** pDst, SNodeList** pSrc);
|
||||
int32_t nodesPartitionCond(SNode** pCondition, SNode** pPrimaryKeyCond, SNode** pTagCond, SNode** pOtherCond);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -649,6 +649,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_INVALID_COL_JSON TAOS_DEF_ERROR_CODE(0, 0x2652)
|
||||
#define TSDB_CODE_PAR_VALUE_TOO_LONG TAOS_DEF_ERROR_CODE(0, 0x2653)
|
||||
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2654)
|
||||
#define TSDB_CODE_PAR_INVALID_DELETE_WHERE TAOS_DEF_ERROR_CODE(0, 0x2655)
|
||||
|
||||
//planner
|
||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||
|
|
|
@ -345,7 +345,6 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
|||
// In case of group by column query, the required SResultRow object must be existInCurrentResusltRowInfo in the
|
||||
// pResultRowInfo object.
|
||||
if (p1 != NULL) {
|
||||
|
||||
// todo
|
||||
pResult = getResultRowByPos(pResultBuf, p1);
|
||||
ASSERT(pResult->pageId == p1->pageId && pResult->offset == p1->offset);
|
||||
|
@ -369,7 +368,8 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
|||
|
||||
// add a new result set for a new group
|
||||
SResultRowPosition pos = {.pageId = pResult->pageId, .offset = pResult->offset};
|
||||
taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos, sizeof(SResultRowPosition));
|
||||
taosHashPut(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), &pos,
|
||||
sizeof(SResultRowPosition));
|
||||
}
|
||||
|
||||
// 2. set the new time window to be the new active time window
|
||||
|
@ -551,7 +551,6 @@ void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow
|
|||
colDataAppendInt64(pColData, 4, &pQueryWindow->ekey);
|
||||
}
|
||||
|
||||
|
||||
void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow* pWin,
|
||||
SColumnInfoData* pTimeWindowData, int32_t offset, int32_t forwardStep, TSKEY* tsCol,
|
||||
int32_t numOfTotal, int32_t numOfOutput, int32_t order) {
|
||||
|
@ -1283,7 +1282,6 @@ static int32_t updateBlockLoadStatus(STaskAttr* pQuery, int32_t status) {
|
|||
hasOtherFunc = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (hasFirstLastFunc && status == BLK_DATA_NOT_LOAD) {
|
||||
|
@ -1765,7 +1763,6 @@ void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t* bufCapacity, int32_t numOf
|
|||
// if (i > 0) pBInfo->pCtx[i].pTsOutput = pBInfo->pCtx[i - 1].pOutput;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4262,7 +4259,7 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t*
|
|||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||
pType->precision, pValNode->node.aliasName);
|
||||
pExp->base.pParam[0].type = FUNC_PARAM_TYPE_VALUE;
|
||||
valueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
|
||||
nodesValueNodeToVariant(pValNode, &pExp->base.pParam[0].param);
|
||||
} else if (type == QUERY_NODE_FUNCTION) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_FUNCTION;
|
||||
SFunctionNode* pFuncNode = (SFunctionNode*)pTargetNode->pExpr;
|
||||
|
@ -4305,7 +4302,7 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t*
|
|||
} else if (p1->type == QUERY_NODE_VALUE) {
|
||||
SValueNode* pvn = (SValueNode*)p1;
|
||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
|
||||
valueNodeToVariant(pvn, &pExp->base.pParam[j].param);
|
||||
nodesValueNodeToVariant(pvn, &pExp->base.pParam[j].param);
|
||||
}
|
||||
}
|
||||
} else if (type == QUERY_NODE_OPERATOR) {
|
||||
|
@ -4392,7 +4389,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
}
|
||||
SArray* groupKyes = extractPartitionColInfo(pTableScanNode->pPartitionKeys);
|
||||
extractTableSchemaVersion(pHandle, pTableScanNode->scan.uid, pTaskInfo);
|
||||
SOperatorInfo* pOperator = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, groupKyes, pTaskInfo);
|
||||
SOperatorInfo* pOperator =
|
||||
createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, groupKyes, pTaskInfo);
|
||||
|
||||
STableScanInfo* pScanInfo = pOperator->info;
|
||||
pTaskInfo->cost.pRecoder = &pScanInfo->readRecorder;
|
||||
|
@ -4422,8 +4420,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
}
|
||||
SArray* tableIdList = extractTableIdList(pTableListInfo);
|
||||
|
||||
SOperatorInfo* pOperator = createStreamScanOperatorInfo(pDataReader, pHandle,
|
||||
tableIdList, pTableScanNode, pTaskInfo, &twSup);
|
||||
SOperatorInfo* pOperator =
|
||||
createStreamScanOperatorInfo(pDataReader, pHandle, tableIdList, pTableScanNode, pTaskInfo, &twSup);
|
||||
|
||||
taosArrayDestroy(tableIdList);
|
||||
return pOperator;
|
||||
|
@ -4522,18 +4520,19 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
.offset = pIntervalPhyNode->offset,
|
||||
.precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision};
|
||||
|
||||
STimeWindowAggSupp as = {.waterMark = pIntervalPhyNode->window.watermark,
|
||||
STimeWindowAggSupp as = {
|
||||
.waterMark = pIntervalPhyNode->window.watermark,
|
||||
.calTrigger = pIntervalPhyNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.winMap = NULL,};
|
||||
.winMap = NULL,
|
||||
};
|
||||
if (isSmaStream(pIntervalPhyNode->window.triggerType)) {
|
||||
if (FLT_LESS(pIntervalPhyNode->window.filesFactor, 1.000000)) {
|
||||
as.calTrigger = STREAM_TRIGGER_AT_ONCE_SMA;
|
||||
} else {
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_TIMESTAMP);
|
||||
as.winMap = taosHashInit(64, hashFn, true, HASH_NO_LOCK);
|
||||
as.waterMark = getSmaWaterMark(interval.interval,
|
||||
pIntervalPhyNode->window.filesFactor);
|
||||
as.waterMark = getSmaWaterMark(interval.interval, pIntervalPhyNode->window.filesFactor);
|
||||
as.calTrigger = STREAM_TRIGGER_WINDOW_CLOSE_SMA;
|
||||
}
|
||||
}
|
||||
|
@ -5214,8 +5213,7 @@ int64_t getSmaWaterMark(int64_t interval, double filesFactor) {
|
|||
}
|
||||
|
||||
bool isSmaStream(int8_t triggerType) {
|
||||
if (triggerType == STREAM_TRIGGER_AT_ONCE ||
|
||||
triggerType == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
if (triggerType == STREAM_TRIGGER_AT_ONCE || triggerType == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -22,14 +22,15 @@
|
|||
#include "thash.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#include "function.h"
|
||||
#include "tdatablock.h"
|
||||
#include "executorInt.h"
|
||||
#include "function.h"
|
||||
#include "querynodes.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tfill.h"
|
||||
|
||||
#define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC)
|
||||
#define DO_INTERPOLATION(_v1, _v2, _k1, _k2, _k) ((_v1) + ((_v2) - (_v1)) * (((double)(_k)) - ((double)(_k1))) / (((double)(_k2)) - ((double)(_k1))))
|
||||
#define DO_INTERPOLATION(_v1, _v2, _k1, _k2, _k) \
|
||||
((_v1) + ((_v2) - (_v1)) * (((double)(_k)) - ((double)(_k1))) / (((double)(_k2)) - ((double)(_k1))))
|
||||
|
||||
static void setTagsValue(SFillInfo* pFillInfo, void** data, int32_t genRows) {
|
||||
for (int32_t j = 0; j < pFillInfo->numOfCols; ++j) {
|
||||
|
@ -60,7 +61,8 @@ static void setNullRow(SSDataBlock* pBlock, int32_t numOfCol, int32_t rowIndex)
|
|||
|
||||
static void doSetVal(SColumnInfoData* pDstColInfoData, int32_t rowIndex, const SGroupKeys* pKey);
|
||||
|
||||
static void doFillOneRowResult(SFillInfo* pFillInfo, SSDataBlock *pBlock, SSDataBlock* pSrcBlock, int64_t ts, bool outOfBound) {
|
||||
static void doFillOneRowResult(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* pSrcBlock, int64_t ts,
|
||||
bool outOfBound) {
|
||||
SPoint point1, point2, point;
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pFillInfo->order);
|
||||
|
||||
|
@ -167,7 +169,8 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, SSDataBlock *pBlock, SSData
|
|||
|
||||
// setTagsValue(pFillInfo, data, index);
|
||||
SInterval* pInterval = &pFillInfo->interval;
|
||||
pFillInfo->currentKey = taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision);
|
||||
pFillInfo->currentKey =
|
||||
taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision);
|
||||
pFillInfo->numOfCurrent++;
|
||||
}
|
||||
|
||||
|
@ -236,9 +239,11 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t
|
|||
copyCurrentRowIntoBuf(pFillInfo, pFillInfo->index, pFillInfo->next);
|
||||
}
|
||||
|
||||
if (((pFillInfo->currentKey < ts && ascFill) || (pFillInfo->currentKey > ts && !ascFill)) && pFillInfo->numOfCurrent < outputRows) {
|
||||
if (((pFillInfo->currentKey < ts && ascFill) || (pFillInfo->currentKey > ts && !ascFill)) &&
|
||||
pFillInfo->numOfCurrent < outputRows) {
|
||||
// fill the gap between two input rows
|
||||
while (((pFillInfo->currentKey < ts && ascFill) || (pFillInfo->currentKey > ts && !ascFill)) && pFillInfo->numOfCurrent < outputRows) {
|
||||
while (((pFillInfo->currentKey < ts && ascFill) || (pFillInfo->currentKey > ts && !ascFill)) &&
|
||||
pFillInfo->numOfCurrent < outputRows) {
|
||||
doFillOneRowResult(pFillInfo, pBlock, pFillInfo->pSrcBlock, ts, false);
|
||||
}
|
||||
|
||||
|
@ -298,7 +303,8 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t
|
|||
// set the tag value for final result
|
||||
// setTagsValue(pFillInfo, data, pFillInfo->numOfCurrent);
|
||||
SInterval* pInterval = &pFillInfo->interval;
|
||||
pFillInfo->currentKey = taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision);
|
||||
pFillInfo->currentKey =
|
||||
taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision);
|
||||
|
||||
pFillInfo->index += 1;
|
||||
pFillInfo->numOfCurrent += 1;
|
||||
|
@ -399,7 +405,8 @@ static int32_t taosNumOfRemainRows(SFillInfo* pFillInfo) {
|
|||
}
|
||||
|
||||
struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
|
||||
SInterval* pInterval, int32_t fillType, struct SFillColInfo* pCol, const char* id) {
|
||||
SInterval* pInterval, int32_t fillType, struct SFillColInfo* pCol,
|
||||
const char* id) {
|
||||
if (fillType == TSDB_FILL_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -414,12 +421,24 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
|
|||
pFillInfo->order = order;
|
||||
|
||||
switch (fillType) {
|
||||
case FILL_MODE_NONE: pFillInfo->type = TSDB_FILL_NONE; break;
|
||||
case FILL_MODE_PREV: pFillInfo->type = TSDB_FILL_PREV; break;
|
||||
case FILL_MODE_NULL: pFillInfo->type = TSDB_FILL_NULL; break;
|
||||
case FILL_MODE_LINEAR: pFillInfo->type = TSDB_FILL_LINEAR;break;
|
||||
case FILL_MODE_NEXT: pFillInfo->type = TSDB_FILL_NEXT; break;
|
||||
case FILL_MODE_VALUE: pFillInfo->type = TSDB_FILL_SET_VALUE; break;
|
||||
case FILL_MODE_NONE:
|
||||
pFillInfo->type = TSDB_FILL_NONE;
|
||||
break;
|
||||
case FILL_MODE_PREV:
|
||||
pFillInfo->type = TSDB_FILL_PREV;
|
||||
break;
|
||||
case FILL_MODE_NULL:
|
||||
pFillInfo->type = TSDB_FILL_NULL;
|
||||
break;
|
||||
case FILL_MODE_LINEAR:
|
||||
pFillInfo->type = TSDB_FILL_LINEAR;
|
||||
break;
|
||||
case FILL_MODE_NEXT:
|
||||
pFillInfo->type = TSDB_FILL_NEXT;
|
||||
break;
|
||||
case FILL_MODE_VALUE:
|
||||
pFillInfo->type = TSDB_FILL_SET_VALUE;
|
||||
break;
|
||||
default:
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return NULL;
|
||||
|
@ -524,12 +543,8 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma
|
|||
int64_t numOfRes = -1;
|
||||
if (numOfRows > 0) { // still fill gap within current data block, not generating data after the result set.
|
||||
TSKEY lastKey = tsList[pFillInfo->numOfRows - 1];
|
||||
numOfRes = taosTimeCountInterval(
|
||||
lastKey,
|
||||
pFillInfo->currentKey,
|
||||
pFillInfo->interval.sliding,
|
||||
pFillInfo->interval.slidingUnit,
|
||||
pFillInfo->interval.precision);
|
||||
numOfRes = taosTimeCountInterval(lastKey, pFillInfo->currentKey, pFillInfo->interval.sliding,
|
||||
pFillInfo->interval.slidingUnit, pFillInfo->interval.precision);
|
||||
numOfRes += 1;
|
||||
assert(numOfRes >= numOfRows);
|
||||
} else { // reach the end of data
|
||||
|
@ -537,19 +552,16 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma
|
|||
(ekey1 > pFillInfo->currentKey && !FILL_IS_ASC_FILL(pFillInfo))) {
|
||||
return 0;
|
||||
}
|
||||
numOfRes = taosTimeCountInterval(
|
||||
ekey1,
|
||||
pFillInfo->currentKey,
|
||||
pFillInfo->interval.sliding,
|
||||
pFillInfo->interval.slidingUnit,
|
||||
pFillInfo->interval.precision);
|
||||
numOfRes = taosTimeCountInterval(ekey1, pFillInfo->currentKey, pFillInfo->interval.sliding,
|
||||
pFillInfo->interval.slidingUnit, pFillInfo->interval.precision);
|
||||
numOfRes += 1;
|
||||
}
|
||||
|
||||
return (numOfRes > maxNumOfRows) ? maxNumOfRows : numOfRes;
|
||||
}
|
||||
|
||||
int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint* point1, SPoint* point2, int32_t inputType) {
|
||||
int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint* point1, SPoint* point2,
|
||||
int32_t inputType) {
|
||||
double v1 = -1, v2 = -1;
|
||||
GET_TYPED_DATA(v1, double, inputType, point1->val);
|
||||
GET_TYPED_DATA(v2, double, inputType, point2->val);
|
||||
|
@ -574,16 +586,16 @@ int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, SSDataBlock* p, int32_t ca
|
|||
assert(numOfRes == pFillInfo->numOfCurrent);
|
||||
}
|
||||
|
||||
// qDebug("fill:%p, generated fill result, src block:%d, index:%d, brange:%"PRId64"-%"PRId64", currentKey:%"PRId64", current:%d, total:%d, %p",
|
||||
// pFillInfo, pFillInfo->numOfRows, pFillInfo->index, pFillInfo->start, pFillInfo->end, pFillInfo->currentKey, pFillInfo->numOfCurrent,
|
||||
// qDebug("fill:%p, generated fill result, src block:%d, index:%d, brange:%"PRId64"-%"PRId64", currentKey:%"PRId64",
|
||||
// current:%d, total:%d, %p",
|
||||
// pFillInfo, pFillInfo->numOfRows, pFillInfo->index, pFillInfo->start, pFillInfo->end, pFillInfo->currentKey,
|
||||
// pFillInfo->numOfCurrent,
|
||||
// pFillInfo->numOfTotal, pFillInfo->handle);
|
||||
|
||||
return numOfRes;
|
||||
}
|
||||
|
||||
int64_t getFillInfoStart(struct SFillInfo *pFillInfo) {
|
||||
return pFillInfo->start;
|
||||
}
|
||||
int64_t getFillInfoStart(struct SFillInfo* pFillInfo) { return pFillInfo->start; }
|
||||
|
||||
SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, const struct SNodeListNode* pValNode) {
|
||||
SFillColInfo* pFillCol = taosMemoryCalloc(numOfOutput, sizeof(SFillColInfo));
|
||||
|
@ -603,7 +615,7 @@ SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, const str
|
|||
int32_t index = (i >= len) ? (len - 1) : i;
|
||||
|
||||
SValueNode* pv = (SValueNode*)nodesListGetNode(pValNode->pNodeList, index);
|
||||
valueNodeToVariant(pv, &pFillCol[i].fillVal);
|
||||
nodesValueNodeToVariant(pv, &pFillCol[i].fillVal);
|
||||
}
|
||||
|
||||
if (pExprInfo->base.numOfParams > 0) {
|
||||
|
|
|
@ -486,7 +486,7 @@ static int32_t sifExecLogic(SLogicConditionNode *node, SIFCtx *ctx, SIFParam *ou
|
|||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
int32_t code;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SIFParam *params = NULL;
|
||||
SIF_ERR_RET(sifInitParamList(¶ms, node->pParameterList, ctx));
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
|||
COPY_SCALAR_FIELD(tableType);
|
||||
COPY_SCALAR_FIELD(colId);
|
||||
COPY_SCALAR_FIELD(colType);
|
||||
COPY_SCALAR_FIELD(hasIndex);
|
||||
COPY_CHAR_ARRAY_FIELD(dbName);
|
||||
COPY_CHAR_ARRAY_FIELD(tableName);
|
||||
COPY_CHAR_ARRAY_FIELD(tableAlias);
|
||||
|
|
|
@ -178,6 +178,8 @@ const char* nodesNodeName(ENodeType type) {
|
|||
return "ShowQueriesStmt";
|
||||
case QUERY_NODE_SHOW_VNODES_STMT:
|
||||
return "ShowVnodeStmt";
|
||||
case QUERY_NODE_DELETE_STMT:
|
||||
return "DeleteStmt";
|
||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||
return "LogicScan";
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||
|
|
|
@ -208,6 +208,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
case QUERY_NODE_KILL_QUERY_STMT:
|
||||
case QUERY_NODE_KILL_TRANSACTION_STMT:
|
||||
return makeNode(type, sizeof(SKillStmt));
|
||||
case QUERY_NODE_DELETE_STMT:
|
||||
return makeNode(type, sizeof(SDeleteStmt));
|
||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||
return makeNode(type, sizeof(SScanLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||
|
@ -1305,7 +1307,7 @@ int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeT
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
char* getFillModeString(EFillMode mode) {
|
||||
char* nodesGetFillModeString(EFillMode mode) {
|
||||
switch (mode) {
|
||||
case FILL_MODE_NONE:
|
||||
return "none";
|
||||
|
@ -1353,7 +1355,7 @@ int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots) {
|
|||
return num;
|
||||
}
|
||||
|
||||
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal) {
|
||||
void nodesValueNodeToVariant(const SValueNode* pNode, SVariant* pVal) {
|
||||
pVal->nType = pNode->node.resType.type;
|
||||
pVal->nLen = pNode->node.resType.bytes;
|
||||
switch (pNode->node.resType.type) {
|
||||
|
@ -1394,3 +1396,159 @@ void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t nodesMergeConds(SNode** pDst, SNodeList** pSrc) {
|
||||
if (NULL == *pSrc) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (1 == LIST_LENGTH(*pSrc)) {
|
||||
*pDst = nodesListGetNode(*pSrc, 0);
|
||||
nodesClearList(*pSrc);
|
||||
} else {
|
||||
SLogicConditionNode* pLogicCond = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||
if (NULL == pLogicCond) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL;
|
||||
pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
|
||||
pLogicCond->condType = LOGIC_COND_TYPE_AND;
|
||||
pLogicCond->pParameterList = *pSrc;
|
||||
*pDst = (SNode*)pLogicCond;
|
||||
}
|
||||
*pSrc = NULL;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct SClassifyConditionCxt {
|
||||
bool hasPrimaryKey;
|
||||
bool hasTagIndexCol;
|
||||
bool hasOtherCol;
|
||||
} SClassifyConditionCxt;
|
||||
|
||||
static EDealRes classifyConditionImpl(SNode* pNode, void* pContext) {
|
||||
SClassifyConditionCxt* pCxt = (SClassifyConditionCxt*)pContext;
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||
if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) {
|
||||
pCxt->hasPrimaryKey = true;
|
||||
} else if (pCol->hasIndex) {
|
||||
pCxt->hasTagIndexCol = true;
|
||||
} else {
|
||||
pCxt->hasOtherCol = true;
|
||||
}
|
||||
return *((bool*)pContext) ? DEAL_RES_CONTINUE : DEAL_RES_END;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
typedef enum EConditionType { COND_TYPE_PRIMARY_KEY = 1, COND_TYPE_TAG_INDEX, COND_TYPE_NORMAL } EConditionType;
|
||||
|
||||
static EConditionType classifyCondition(SNode* pNode) {
|
||||
SClassifyConditionCxt cxt = {.hasPrimaryKey = false, .hasTagIndexCol = false, .hasOtherCol = false};
|
||||
nodesWalkExpr(pNode, classifyConditionImpl, &cxt);
|
||||
return cxt.hasOtherCol ? COND_TYPE_NORMAL
|
||||
: (cxt.hasPrimaryKey && cxt.hasTagIndexCol
|
||||
? COND_TYPE_NORMAL
|
||||
: (cxt.hasPrimaryKey ? COND_TYPE_PRIMARY_KEY : COND_TYPE_TAG_INDEX));
|
||||
}
|
||||
|
||||
static int32_t partitionLogicCond(SNode** pCondition, SNode** pPrimaryKeyCond, SNode** pTagCond, SNode** pOtherCond) {
|
||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(*pCondition);
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
SNodeList* pPrimaryKeyConds = NULL;
|
||||
SNodeList* pTagConds = NULL;
|
||||
SNodeList* pOtherConds = NULL;
|
||||
SNode* pCond = NULL;
|
||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||
switch (classifyCondition(pCond)) {
|
||||
case COND_TYPE_PRIMARY_KEY:
|
||||
if (NULL != pPrimaryKeyCond) {
|
||||
code = nodesListMakeAppend(&pPrimaryKeyConds, nodesCloneNode(pCond));
|
||||
}
|
||||
break;
|
||||
case COND_TYPE_TAG_INDEX:
|
||||
if (NULL != pTagCond) {
|
||||
code = nodesListMakeAppend(&pTagConds, nodesCloneNode(pCond));
|
||||
}
|
||||
break;
|
||||
case COND_TYPE_NORMAL:
|
||||
default:
|
||||
if (NULL != pOtherCond) {
|
||||
code = nodesListMakeAppend(&pOtherConds, nodesCloneNode(pCond));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SNode* pTempPrimaryKeyCond = NULL;
|
||||
SNode* pTempTagCond = NULL;
|
||||
SNode* pTempOtherCond = NULL;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesMergeConds(&pTempPrimaryKeyCond, &pPrimaryKeyConds);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesMergeConds(&pTempTagCond, &pTagConds);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesMergeConds(&pTempOtherCond, &pOtherConds);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (NULL != pPrimaryKeyCond) {
|
||||
*pPrimaryKeyCond = pTempPrimaryKeyCond;
|
||||
}
|
||||
if (NULL != pTagCond) {
|
||||
*pTagCond = pTempTagCond;
|
||||
}
|
||||
if (NULL != pOtherCond) {
|
||||
*pOtherCond = pTempOtherCond;
|
||||
}
|
||||
nodesDestroyNode(*pCondition);
|
||||
*pCondition = NULL;
|
||||
} else {
|
||||
nodesDestroyList(pPrimaryKeyConds);
|
||||
nodesDestroyList(pTagConds);
|
||||
nodesDestroyList(pOtherConds);
|
||||
nodesDestroyNode(pTempPrimaryKeyCond);
|
||||
nodesDestroyNode(pTempTagCond);
|
||||
nodesDestroyNode(pTempOtherCond);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t nodesPartitionCond(SNode** pCondition, SNode** pPrimaryKeyCond, SNode** pTagCond, SNode** pOtherCond) {
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pCondition) &&
|
||||
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)*pCondition)->condType) {
|
||||
return partitionLogicCond(pCondition, pPrimaryKeyCond, pTagCond, pOtherCond);
|
||||
}
|
||||
|
||||
switch (classifyCondition(*pCondition)) {
|
||||
case COND_TYPE_PRIMARY_KEY:
|
||||
if (NULL != pPrimaryKeyCond) {
|
||||
*pPrimaryKeyCond = *pCondition;
|
||||
}
|
||||
break;
|
||||
case COND_TYPE_TAG_INDEX:
|
||||
if (NULL != pTagCond) {
|
||||
*pTagCond = *pCondition;
|
||||
}
|
||||
break;
|
||||
case COND_TYPE_NORMAL:
|
||||
default:
|
||||
if (NULL != pOtherCond) {
|
||||
*pOtherCond = *pCondition;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*pCondition = NULL;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -193,6 +193,7 @@ SNode* createSplitVgroupStmt(SAstCreateContext* pCxt, const SToken* pVgId);
|
|||
SNode* createSyncdbStmt(SAstCreateContext* pCxt, const SToken* pDbName);
|
||||
SNode* createGrantStmt(SAstCreateContext* pCxt, int64_t privileges, SToken* pDbName, SToken* pUserName);
|
||||
SNode* createRevokeStmt(SAstCreateContext* pCxt, int64_t privileges, SToken* pDbName, SToken* pUserName);
|
||||
SNode* createDeleteStmt(SAstCreateContext* pCxt, SNode* pTable, SNode* pWhere);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -481,6 +481,9 @@ dnode_list(A) ::= dnode_list(B) DNODE NK_INTEGER(C).
|
|||
/************************************************ syncdb **************************************************************/
|
||||
cmd ::= SYNCDB db_name(A) REPLICA. { pCxt->pRootNode = createSyncdbStmt(pCxt, &A); }
|
||||
|
||||
/************************************************ syncdb **************************************************************/
|
||||
cmd ::= DELETE FROM full_table_name(A) where_clause_opt(B). { pCxt->pRootNode = createDeleteStmt(pCxt, A, B); }
|
||||
|
||||
/************************************************ select **************************************************************/
|
||||
cmd ::= query_expression(A). { pCxt->pRootNode = A; }
|
||||
|
||||
|
|
|
@ -1488,3 +1488,12 @@ SNode* createRevokeStmt(SAstCreateContext* pCxt, int64_t privileges, SToken* pDb
|
|||
strncpy(pStmt->userName, pUserName->z, pUserName->n);
|
||||
return (SNode*)pStmt;
|
||||
}
|
||||
|
||||
SNode* createDeleteStmt(SAstCreateContext* pCxt, SNode* pTable, SNode* pWhere) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
SDeleteStmt* pStmt = nodesMakeNode(QUERY_NODE_DELETE_STMT);
|
||||
CHECK_OUT_OF_MEM(pStmt);
|
||||
pStmt->pFromTable = pTable;
|
||||
pStmt->pWhere = pWhere;
|
||||
return (SNode*)pStmt;
|
||||
}
|
||||
|
|
|
@ -113,21 +113,26 @@ static EDealRes collectMetaKeyFromFunction(SCollectMetaKeyFromExprCxt* pCxt, SFu
|
|||
return reserveUdfInCache(pFunc->functionName, pCxt->pComCxt->pMetaCache);
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromRealTableImpl(SCollectMetaKeyCxt* pCxt, SRealTableNode* pRealTable,
|
||||
AUTH_TYPE authType) {
|
||||
int32_t code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, pRealTable->table.dbName, pRealTable->table.tableName,
|
||||
pCxt->pMetaCache);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pRealTable->table.dbName, pRealTable->table.tableName,
|
||||
pCxt->pMetaCache);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pRealTable->table.dbName, authType,
|
||||
pCxt->pMetaCache);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = reserveDbVgInfoInCache(pCxt->pParseCxt->acctId, pRealTable->table.dbName, pCxt->pMetaCache);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static EDealRes collectMetaKeyFromRealTable(SCollectMetaKeyFromExprCxt* pCxt, SRealTableNode* pRealTable) {
|
||||
pCxt->errCode = reserveTableMetaInCache(pCxt->pComCxt->pParseCxt->acctId, pRealTable->table.dbName,
|
||||
pRealTable->table.tableName, pCxt->pComCxt->pMetaCache);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pCxt->errCode = reserveTableVgroupInCache(pCxt->pComCxt->pParseCxt->acctId, pRealTable->table.dbName,
|
||||
pRealTable->table.tableName, pCxt->pComCxt->pMetaCache);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pCxt->errCode = reserveUserAuthInCache(pCxt->pComCxt->pParseCxt->acctId, pCxt->pComCxt->pParseCxt->pUser,
|
||||
pRealTable->table.dbName, AUTH_TYPE_READ, pCxt->pComCxt->pMetaCache);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pCxt->errCode =
|
||||
reserveDbVgInfoInCache(pCxt->pComCxt->pParseCxt->acctId, pRealTable->table.dbName, pCxt->pComCxt->pMetaCache);
|
||||
}
|
||||
pCxt->errCode = collectMetaKeyFromRealTableImpl(pCxt->pComCxt, pRealTable, AUTH_TYPE_READ);
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
|
@ -347,6 +352,10 @@ static int32_t collectMetaKeyFromShowTransactions(SCollectMetaKeyCxt* pCxt, SSho
|
|||
pCxt->pMetaCache);
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromDelete(SCollectMetaKeyCxt* pCxt, SDeleteStmt* pStmt) {
|
||||
return collectMetaKeyFromRealTableImpl(pCxt, (SRealTableNode*)pStmt->pFromTable, AUTH_TYPE_WRITE);
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
|
||||
switch (nodeType(pStmt)) {
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
|
@ -405,6 +414,8 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
|
|||
return collectMetaKeyFromShowTopics(pCxt, (SShowStmt*)pStmt);
|
||||
case QUERY_NODE_SHOW_TRANSACTIONS_STMT:
|
||||
return collectMetaKeyFromShowTransactions(pCxt, (SShowStmt*)pStmt);
|
||||
case QUERY_NODE_DELETE_STMT:
|
||||
return collectMetaKeyFromDelete(pCxt, (SDeleteStmt*)pStmt);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,10 @@ static int32_t authDropUser(SAuthCxt* pCxt, SDropUserStmt* pStmt) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t authDelete(SAuthCxt* pCxt, SDeleteStmt* pDelete) {
|
||||
return checkAuth(pCxt, ((SRealTableNode*)pDelete->pFromTable)->table.dbName, AUTH_TYPE_WRITE);
|
||||
}
|
||||
|
||||
static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) {
|
||||
switch (nodeType(pStmt)) {
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
|
@ -88,6 +92,8 @@ static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) {
|
|||
return authSelect(pCxt, (SSelectStmt*)pStmt);
|
||||
case QUERY_NODE_DROP_USER_STMT:
|
||||
return authDropUser(pCxt, (SDropUserStmt*)pStmt);
|
||||
case QUERY_NODE_DELETE_STMT:
|
||||
return authDelete(pCxt, (SDeleteStmt*)pStmt);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -135,11 +135,11 @@ static int32_t rewriteConditionForFromTable(SCalcConstContext* pCxt, SNode* pTab
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t calcConstFromTable(SCalcConstContext* pCxt, SSelectStmt* pSelect) {
|
||||
return rewriteConditionForFromTable(pCxt, pSelect->pFromTable);
|
||||
static int32_t calcConstFromTable(SCalcConstContext* pCxt, SNode* pTable) {
|
||||
return rewriteConditionForFromTable(pCxt, pTable);
|
||||
}
|
||||
|
||||
static void rewriteConstCondition(SSelectStmt* pSelect, SNode** pCond) {
|
||||
static void rewriteConstCondition(SNode** pCond, bool* pAlwaysFalse) {
|
||||
if (QUERY_NODE_VALUE != nodeType(*pCond)) {
|
||||
return;
|
||||
}
|
||||
|
@ -147,11 +147,11 @@ static void rewriteConstCondition(SSelectStmt* pSelect, SNode** pCond) {
|
|||
nodesDestroyNode(*pCond);
|
||||
*pCond = NULL;
|
||||
} else {
|
||||
pSelect->isEmptyResult = true;
|
||||
*pAlwaysFalse = true;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t calcConstSelectCondition(SCalcConstContext* pCxt, SSelectStmt* pSelect, SNode** pCond) {
|
||||
static int32_t calcConstStmtCondition(SCalcConstContext* pCxt, SNode** pCond, bool* pAlwaysFalse) {
|
||||
if (NULL == *pCond) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ static int32_t calcConstSelectCondition(SCalcConstContext* pCxt, SSelectStmt* pS
|
|||
code = calcConstNode(pCond);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
rewriteConstCondition(pSelect, pCond);
|
||||
rewriteConstCondition(pCond, pAlwaysFalse);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -233,12 +233,12 @@ static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) {
|
|||
}
|
||||
|
||||
static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
|
||||
int32_t code = calcConstFromTable(pCxt, pSelect);
|
||||
int32_t code = calcConstFromTable(pCxt, pSelect->pFromTable);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calcConstProjections(pCxt, pSelect, subquery);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calcConstSelectCondition(pCxt, pSelect, &pSelect->pWhere);
|
||||
code = calcConstStmtCondition(pCxt, &pSelect->pWhere, &pSelect->isEmptyResult);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calcConstList(pSelect->pPartitionByList);
|
||||
|
@ -250,7 +250,7 @@ static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bo
|
|||
code = calcConstGroupBy(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calcConstSelectCondition(pCxt, pSelect, &pSelect->pHaving);
|
||||
code = calcConstStmtCondition(pCxt, &pSelect->pHaving, &pSelect->isEmptyResult);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calcConstList(pSelect->pOrderByList);
|
||||
|
@ -258,6 +258,14 @@ static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bo
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t calcConstDelete(SCalcConstContext* pCxt, SDeleteStmt* pDelete) {
|
||||
int32_t code = calcConstFromTable(pCxt, pDelete->pFromTable);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calcConstStmtCondition(pCxt, &pDelete->pWhere, &pDelete->deleteZeroRows);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t calcConstQuery(SCalcConstContext* pCxt, SNode* pStmt, bool subquery) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
switch (nodeType(pStmt)) {
|
||||
|
@ -275,6 +283,9 @@ static int32_t calcConstQuery(SCalcConstContext* pCxt, SNode* pStmt, bool subque
|
|||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_DELETE_STMT:
|
||||
code = calcConstDelete(pCxt, (SDeleteStmt*)pStmt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ static SKeyword keywordTable[] = {
|
|||
{"DATABASES", TK_DATABASES},
|
||||
{"DAYS", TK_DAYS},
|
||||
{"DBS", TK_DBS},
|
||||
{"DELETE", TK_DELETE},
|
||||
{"DESC", TK_DESC},
|
||||
{"DESCRIBE", TK_DESCRIBE},
|
||||
{"DISTINCT", TK_DISTINCT},
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct STranslateContext {
|
|||
SArray* pNsLevel; // element is SArray*, the element of this subarray is STableNode*
|
||||
int32_t currLevel;
|
||||
ESqlClause currClause;
|
||||
SSelectStmt* pCurrStmt;
|
||||
SSelectStmt* pCurrSelectStmt;
|
||||
SCmdMsgInfo* pCmdMsg;
|
||||
SHashObj* pDbs;
|
||||
SHashObj* pTables;
|
||||
|
@ -335,7 +335,7 @@ static bool isIndefiniteRowsFunc(const SNode* pNode) {
|
|||
}
|
||||
|
||||
static bool isDistinctOrderBy(STranslateContext* pCxt) {
|
||||
return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrStmt->isDistinct);
|
||||
return (SQL_CLAUSE_ORDER_BY == pCxt->currClause && pCxt->pCurrSelectStmt->isDistinct);
|
||||
}
|
||||
|
||||
static bool belongTable(const char* currentDb, const SColumnNode* pCol, const STableNode* pTable) {
|
||||
|
@ -360,7 +360,7 @@ static SNodeList* getProjectList(const SNode* pNode) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, bool isTag,
|
||||
static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, int32_t tagFlag,
|
||||
SColumnNode* pCol) {
|
||||
strcpy(pCol->dbName, pTable->table.dbName);
|
||||
strcpy(pCol->tableAlias, pTable->table.tableAlias);
|
||||
|
@ -372,7 +372,8 @@ static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* p
|
|||
pCol->tableId = pTable->pMeta->uid;
|
||||
pCol->tableType = pTable->pMeta->tableType;
|
||||
pCol->colId = pColSchema->colId;
|
||||
pCol->colType = isTag ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN;
|
||||
pCol->colType = (tagFlag >= 0 ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN);
|
||||
pCol->hasIndex = (0 == tagFlag);
|
||||
pCol->node.resType.type = pColSchema->type;
|
||||
pCol->node.resType.bytes = pColSchema->bytes;
|
||||
if (TSDB_DATA_TYPE_TIMESTAMP == pCol->node.resType.type) {
|
||||
|
@ -414,7 +415,7 @@ static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* p
|
|||
if (NULL == pCol) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i >= pMeta->tableInfo.numOfColumns), pCol);
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i - pMeta->tableInfo.numOfColumns), pCol);
|
||||
nodesListAppend(pList, (SNode*)pCol);
|
||||
}
|
||||
} else {
|
||||
|
@ -472,14 +473,14 @@ static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef,
|
|||
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
||||
const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
|
||||
if (isInternalPrimaryKey(pCol)) {
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema, false, pCol);
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema, -1, pCol);
|
||||
*pFound = true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
|
||||
for (int32_t i = 0; i < nums; ++i) {
|
||||
if (0 == strcmp(pCol->colName, pMeta->schema[i].name)) {
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i >= pMeta->tableInfo.numOfColumns), pCol);
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i - pMeta->tableInfo.numOfColumns), pCol);
|
||||
*pFound = true;
|
||||
break;
|
||||
}
|
||||
|
@ -551,7 +552,7 @@ static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNod
|
|||
}
|
||||
if (!found) {
|
||||
if (isInternalPk) {
|
||||
if (NULL != pCxt->pCurrStmt->pWindow) {
|
||||
if (NULL != pCxt->pCurrSelectStmt && NULL != pCxt->pCurrSelectStmt->pWindow) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY);
|
||||
}
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_INTERNAL_PK);
|
||||
|
@ -563,7 +564,7 @@ static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNod
|
|||
}
|
||||
|
||||
static bool translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** pCol) {
|
||||
SNodeList* pProjectionList = pCxt->pCurrStmt->pProjectionList;
|
||||
SNodeList* pProjectionList = pCxt->pCurrSelectStmt->pProjectionList;
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pProjectionList) {
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
|
@ -621,7 +622,7 @@ static int32_t parseTimeFromValueNode(STranslateContext* pCxt, SValueNode* pVal)
|
|||
}
|
||||
|
||||
static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SDataType targetDt) {
|
||||
uint8_t precision = (NULL != pCxt->pCurrStmt ? pCxt->pCurrStmt->precision : targetDt.precision);
|
||||
uint8_t precision = (NULL != pCxt->pCurrSelectStmt ? pCxt->pCurrSelectStmt->precision : targetDt.precision);
|
||||
pVal->node.resType.precision = precision;
|
||||
if (pVal->placeholderNo > 0) {
|
||||
return DEAL_RES_CONTINUE;
|
||||
|
@ -830,7 +831,8 @@ static EDealRes translateComparisonOperator(STranslateContext* pCxt, SOperatorNo
|
|||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pLeft))->aliasName);
|
||||
}
|
||||
if (QUERY_NODE_VALUE != nodeType(pOp->pRight) ||
|
||||
((!IS_STR_DATA_TYPE(((SExprNode*)(pOp->pRight))->resType.type)) && (((SExprNode*)(pOp->pRight))->resType.type != TSDB_DATA_TYPE_NULL))) {
|
||||
((!IS_STR_DATA_TYPE(((SExprNode*)(pOp->pRight))->resType.type)) &&
|
||||
(((SExprNode*)(pOp->pRight))->resType.type != TSDB_DATA_TYPE_NULL))) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName);
|
||||
}
|
||||
}
|
||||
|
@ -910,7 +912,7 @@ static int32_t rewriteCountStar(STranslateContext* pCxt, SFunctionNode* pCount)
|
|||
STableNode* pTable = NULL;
|
||||
int32_t code = findTable(pCxt, ('\0' == pCol->tableAlias[0] ? NULL : pCol->tableAlias), &pTable);
|
||||
if (TSDB_CODE_SUCCESS == code && QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, false, pCol);
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, ((SRealTableNode*)pTable)->pMeta->schema, -1, pCol);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -936,7 +938,7 @@ static int32_t translateAggFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
|||
if (hasInvalidFuncNesting(pFunc->pParameterList)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_AGG_FUNC_NESTING);
|
||||
}
|
||||
if (pCxt->pCurrStmt->hasIndefiniteRowsFunc) {
|
||||
if (pCxt->pCurrSelectStmt->hasIndefiniteRowsFunc) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||
}
|
||||
|
||||
|
@ -948,7 +950,7 @@ static int32_t translateAggFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
|||
|
||||
static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||
if (0 == LIST_LENGTH(pFunc->pParameterList)) {
|
||||
if (QUERY_NODE_REAL_TABLE != nodeType(pCxt->pCurrStmt->pFromTable)) {
|
||||
if (QUERY_NODE_REAL_TABLE != nodeType(pCxt->pCurrSelectStmt->pFromTable)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TBNAME);
|
||||
}
|
||||
} else {
|
||||
|
@ -963,7 +965,8 @@ static int32_t translateScanPseudoColumnFunc(STranslateContext* pCxt, SFunctionN
|
|||
}
|
||||
|
||||
static int32_t translateIndefiniteRowsFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||
if (SQL_CLAUSE_SELECT != pCxt->currClause || pCxt->pCurrStmt->hasIndefiniteRowsFunc || pCxt->pCurrStmt->hasAggFuncs) {
|
||||
if (SQL_CLAUSE_SELECT != pCxt->currClause || pCxt->pCurrSelectStmt->hasIndefiniteRowsFunc ||
|
||||
pCxt->pCurrSelectStmt->hasAggFuncs) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||
}
|
||||
if (hasInvalidFuncNesting(pFunc->pParameterList)) {
|
||||
|
@ -973,10 +976,12 @@ static int32_t translateIndefiniteRowsFunc(STranslateContext* pCxt, SFunctionNod
|
|||
}
|
||||
|
||||
static void setFuncClassification(SSelectStmt* pSelect, SFunctionNode* pFunc) {
|
||||
if (NULL != pSelect) {
|
||||
pSelect->hasAggFuncs = pSelect->hasAggFuncs ? true : fmIsAggFunc(pFunc->funcId);
|
||||
pSelect->hasRepeatScanFuncs = pSelect->hasRepeatScanFuncs ? true : fmIsRepeatScanFunc(pFunc->funcId);
|
||||
pSelect->hasIndefiniteRowsFunc = pSelect->hasIndefiniteRowsFunc ? true : fmIsIndefiniteRowsFunc(pFunc->funcId);
|
||||
}
|
||||
}
|
||||
|
||||
static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) {
|
||||
SNode* pParam = NULL;
|
||||
|
@ -997,7 +1002,7 @@ static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc)
|
|||
pCxt->errCode = translateIndefiniteRowsFunc(pCxt, pFunc);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
setFuncClassification(pCxt->pCurrStmt, pFunc);
|
||||
setFuncClassification(pCxt->pCurrSelectStmt, pFunc);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
|
||||
}
|
||||
|
@ -1045,9 +1050,9 @@ static int32_t translateExprList(STranslateContext* pCxt, SNodeList* pList) {
|
|||
|
||||
static SNodeList* getGroupByList(STranslateContext* pCxt) {
|
||||
if (isDistinctOrderBy(pCxt)) {
|
||||
return pCxt->pCurrStmt->pProjectionList;
|
||||
return pCxt->pCurrSelectStmt->pProjectionList;
|
||||
}
|
||||
return pCxt->pCurrStmt->pGroupByList;
|
||||
return pCxt->pCurrSelectStmt->pGroupByList;
|
||||
}
|
||||
|
||||
static SNode* getGroupByNode(SNode* pNode) {
|
||||
|
@ -1085,7 +1090,7 @@ static EDealRes rewriteColToSelectValFunc(STranslateContext* pCxt, SNode** pNode
|
|||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
*pNode = (SNode*)pFunc;
|
||||
pCxt->pCurrStmt->hasSelectValFunc = true;
|
||||
pCxt->pCurrSelectStmt->hasSelectValFunc = true;
|
||||
} else {
|
||||
nodesDestroyNode(pFunc);
|
||||
}
|
||||
|
@ -1308,6 +1313,8 @@ static int32_t setTableVgroupList(STranslateContext* pCxt, SName* pName, SRealTa
|
|||
static uint8_t getStmtPrecision(SNode* pStmt) {
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
return ((SSelectStmt*)pStmt)->precision;
|
||||
} else if (QUERY_NODE_SET_OPERATOR == nodeType(pStmt)) {
|
||||
return ((SSetOperator*)pStmt)->precision;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1319,10 +1326,10 @@ static bool stmtIsSingleTable(SNode* pStmt) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static uint8_t getJoinTablePrecision(SJoinTableNode* pJoinTable) {
|
||||
uint8_t lp = ((STableNode*)pJoinTable->pLeft)->precision;
|
||||
uint8_t rp = ((STableNode*)pJoinTable->pRight)->precision;
|
||||
return (lp > rp ? rp : lp);
|
||||
static uint8_t calcPrecision(uint8_t lp, uint8_t rp) { return (lp > rp ? rp : lp); }
|
||||
|
||||
static uint8_t calcJoinTablePrecision(SJoinTableNode* pJoinTable) {
|
||||
return calcPrecision(((STableNode*)pJoinTable->pLeft)->precision, ((STableNode*)pJoinTable->pRight)->precision);
|
||||
}
|
||||
|
||||
static bool joinTableIsSingleTable(SJoinTableNode* pJoinTable) {
|
||||
|
@ -1378,7 +1385,7 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) {
|
|||
code = translateTable(pCxt, pJoinTable->pRight);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pJoinTable->table.precision = getJoinTablePrecision(pJoinTable);
|
||||
pJoinTable->table.precision = calcJoinTablePrecision(pJoinTable);
|
||||
pJoinTable->table.singleTable = joinTableIsSingleTable(pJoinTable);
|
||||
code = translateExpr(pCxt, &pJoinTable->pOnCond);
|
||||
}
|
||||
|
@ -1678,71 +1685,40 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static EDealRes isPrimaryKeyCondImpl(SNode* pNode, void* pContext) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
*((bool*)pContext) = ((PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pNode)->colId) ? true : false);
|
||||
return *((bool*)pContext) ? DEAL_RES_CONTINUE : DEAL_RES_END;
|
||||
static int32_t getTimeRange(SNode** pPrimaryKeyCond, STimeWindow* pTimeRange, bool* pIsStrict) {
|
||||
SNode* pNew = NULL;
|
||||
int32_t code = scalarCalculateConstants(*pPrimaryKeyCond, &pNew);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pPrimaryKeyCond = pNew;
|
||||
code = filterGetTimeRange(*pPrimaryKeyCond, pTimeRange, pIsStrict);
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static bool isPrimaryKeyCond(SNode* pNode) {
|
||||
bool isPrimaryKeyCond = false;
|
||||
nodesWalkExpr(pNode, isPrimaryKeyCondImpl, &isPrimaryKeyCond);
|
||||
return isPrimaryKeyCond;
|
||||
}
|
||||
|
||||
static int32_t getTimeRangeFromLogicCond(STranslateContext* pCxt, SLogicConditionNode* pLogicCond,
|
||||
STimeWindow* pTimeRange) {
|
||||
SNodeList* pPrimaryKeyConds = NULL;
|
||||
SNode* pCond = NULL;
|
||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||
if (isPrimaryKeyCond(pCond)) {
|
||||
if (TSDB_CODE_SUCCESS != nodesListMakeAppend(&pPrimaryKeyConds, pCond)) {
|
||||
nodesClearList(pPrimaryKeyConds);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == pPrimaryKeyConds) {
|
||||
*pTimeRange = TSWINDOW_INITIALIZER;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SLogicConditionNode* pPrimaryKeyLogicCond = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||
if (NULL == pPrimaryKeyLogicCond) {
|
||||
nodesClearList(pPrimaryKeyConds);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pPrimaryKeyLogicCond->condType = LOGIC_COND_TYPE_AND;
|
||||
pPrimaryKeyLogicCond->pParameterList = pPrimaryKeyConds;
|
||||
bool isStrict = false;
|
||||
int32_t code = filterGetTimeRange((SNode*)pPrimaryKeyLogicCond, pTimeRange, &isStrict);
|
||||
nodesClearList(pPrimaryKeyConds);
|
||||
pPrimaryKeyLogicCond->pParameterList = NULL;
|
||||
nodesDestroyNode(pPrimaryKeyLogicCond);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t getTimeRange(STranslateContext* pCxt, SNode* pWhere, STimeWindow* pTimeRange) {
|
||||
static int32_t getFillTimeRange(STranslateContext* pCxt, SNode* pWhere, STimeWindow* pTimeRange) {
|
||||
if (NULL == pWhere) {
|
||||
*pTimeRange = TSWINDOW_INITIALIZER;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pWhere) &&
|
||||
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)pWhere)->condType) {
|
||||
return getTimeRangeFromLogicCond(pCxt, (SLogicConditionNode*)pWhere, pTimeRange);
|
||||
SNode* pCond = nodesCloneNode(pWhere);
|
||||
if (NULL == pCond) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (isPrimaryKeyCond(pWhere)) {
|
||||
SNode* pPrimaryKeyCond = NULL;
|
||||
nodesPartitionCond(&pCond, &pPrimaryKeyCond, NULL, NULL);
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (NULL != pPrimaryKeyCond) {
|
||||
bool isStrict = false;
|
||||
return filterGetTimeRange(pWhere, pTimeRange, &isStrict);
|
||||
code = getTimeRange(&pPrimaryKeyCond, pTimeRange, &isStrict);
|
||||
} else {
|
||||
*pTimeRange = TSWINDOW_INITIALIZER;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
nodesDestroyNode(pCond);
|
||||
nodesDestroyNode(pPrimaryKeyCond);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t checkFill(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
|
||||
|
@ -1778,7 +1754,7 @@ static int32_t translateFill(STranslateContext* pCxt, SNode* pWhere, SIntervalWi
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = getTimeRange(pCxt, pWhere, &(((SFillNode*)pInterval->pFill)->timeRange));
|
||||
int32_t code = getFillTimeRange(pCxt, pWhere, &(((SFillNode*)pInterval->pFill)->timeRange));
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkFill(pCxt, pInterval);
|
||||
}
|
||||
|
@ -1924,13 +1900,9 @@ static int32_t translateWhere(STranslateContext* pCxt, SNode** pWhere) {
|
|||
return translateExpr(pCxt, pWhere);
|
||||
}
|
||||
|
||||
static int32_t translateFrom(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) {
|
||||
pCxt->currClause = SQL_CLAUSE_FROM;
|
||||
int32_t code = translateTable(pCxt, pSelect->pFromTable);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pSelect->precision = ((STableNode*)pSelect->pFromTable)->precision;
|
||||
}
|
||||
return code;
|
||||
return translateTable(pCxt, pTable);
|
||||
}
|
||||
|
||||
static int32_t checkLimit(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
|
@ -1991,9 +1963,10 @@ static int32_t rewriteTimelineFunc(STranslateContext* pCxt, SSelectStmt* pSelect
|
|||
}
|
||||
|
||||
static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
pCxt->pCurrStmt = pSelect;
|
||||
int32_t code = translateFrom(pCxt, pSelect);
|
||||
pCxt->pCurrSelectStmt = pSelect;
|
||||
int32_t code = translateFrom(pCxt, pSelect->pFromTable);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pSelect->precision = ((STableNode*)pSelect->pFromTable)->precision;
|
||||
code = translateWhere(pCxt, &pSelect->pWhere);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -2094,6 +2067,10 @@ static int32_t translateSetOperatorImpl(STranslateContext* pCxt, SSetOperator* p
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static uint8_t calcSetOperatorPrecision(SSetOperator* pSetOperator) {
|
||||
return calcPrecision(getStmtPrecision(pSetOperator->pLeft), getStmtPrecision(pSetOperator->pRight));
|
||||
}
|
||||
|
||||
static int32_t translateSetOperator(STranslateContext* pCxt, SSetOperator* pSetOperator) {
|
||||
int32_t code = translateQuery(pCxt, pSetOperator->pLeft);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -2103,11 +2080,55 @@ static int32_t translateSetOperator(STranslateContext* pCxt, SSetOperator* pSetO
|
|||
code = translateQuery(pCxt, pSetOperator->pRight);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pSetOperator->precision = calcSetOperatorPrecision(pSetOperator);
|
||||
code = translateSetOperatorImpl(pCxt, pSetOperator);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t partitionDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelete) {
|
||||
if (NULL == pDelete->pWhere) {
|
||||
pDelete->timeRange = TSWINDOW_INITIALIZER;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SNode* pPrimaryKeyCond = NULL;
|
||||
SNode* pOtherCond = NULL;
|
||||
int32_t code = nodesPartitionCond(&pDelete->pWhere, &pPrimaryKeyCond, &pDelete->pTagIndexCond, &pOtherCond);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pOtherCond) {
|
||||
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DELETE_WHERE);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
bool isStrict = false;
|
||||
code = getTimeRange(&pPrimaryKeyCond, &pDelete->timeRange, &isStrict);
|
||||
if (TSDB_CODE_SUCCESS == code && !isStrict) {
|
||||
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DELETE_WHERE);
|
||||
}
|
||||
}
|
||||
nodesDestroyNode(pPrimaryKeyCond);
|
||||
nodesDestroyNode(pOtherCond);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t translateDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelete) {
|
||||
int32_t code = translateWhere(pCxt, &pDelete->pWhere);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = partitionDeleteWhere(pCxt, pDelete);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t translateDelete(STranslateContext* pCxt, SDeleteStmt* pDelete) {
|
||||
int32_t code = translateFrom(pCxt, pDelete->pFromTable);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateDeleteWhere(pCxt, pDelete);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateExpr(pCxt, &pDelete->pCountFunc);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int64_t getUnitPerMinute(uint8_t precision) {
|
||||
switch (precision) {
|
||||
case TSDB_TIME_PRECISION_MILLI:
|
||||
|
@ -2923,25 +2944,9 @@ static int32_t doTranslateDropSuperTable(STranslateContext* pCxt, const SName* p
|
|||
|
||||
static int32_t translateDropTable(STranslateContext* pCxt, SDropTableStmt* pStmt) {
|
||||
SDropTableClause* pClause = nodesListGetNode(pStmt->pTables, 0);
|
||||
|
||||
STableMeta* pTableMeta = NULL;
|
||||
SName tableName;
|
||||
int32_t code = getTableMetaImpl(
|
||||
pCxt, toName(pCxt->pParseCxt->acctId, pClause->dbName, pClause->tableName, &tableName), &pTableMeta);
|
||||
if ((TSDB_CODE_PAR_TABLE_NOT_EXIST == code || TSDB_CODE_VND_TB_NOT_EXIST == code) && pClause->ignoreNotExists) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (TSDB_SUPER_TABLE == pTableMeta->tableType) {
|
||||
code = doTranslateDropSuperTable(pCxt, &tableName, pClause->ignoreNotExists);
|
||||
} else {
|
||||
// todo : drop normal table or child table
|
||||
code = TSDB_CODE_FAILED;
|
||||
}
|
||||
taosMemoryFreeClear(pTableMeta);
|
||||
}
|
||||
|
||||
return code;
|
||||
return doTranslateDropSuperTable(
|
||||
pCxt, toName(pCxt->pParseCxt->acctId, pClause->dbName, pClause->tableName, &tableName), pClause->ignoreNotExists);
|
||||
}
|
||||
|
||||
static int32_t translateDropSuperTable(STranslateContext* pCxt, SDropSuperTableStmt* pStmt) {
|
||||
|
@ -3449,7 +3454,6 @@ static int32_t buildCreateStreamReq(STranslateContext* pCxt, SCreateStreamStmt*
|
|||
SName name;
|
||||
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->streamName, strlen(pStmt->streamName));
|
||||
tNameGetFullDbName(&name, pReq->name);
|
||||
// tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pCxt->pParseCxt->db, pStmt->streamName, &name), pReq->name);
|
||||
|
||||
if ('\0' != pStmt->targetTabName[0]) {
|
||||
strcpy(name.dbname, pStmt->targetDbName);
|
||||
|
@ -3602,6 +3606,9 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
|
|||
case QUERY_NODE_SET_OPERATOR:
|
||||
code = translateSetOperator(pCxt, (SSetOperator*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_DELETE_STMT:
|
||||
code = translateDelete(pCxt, (SDeleteStmt*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_CREATE_DATABASE_STMT:
|
||||
code = translateCreateDatabase(pCxt, (SCreateDatabaseStmt*)pNode);
|
||||
break;
|
||||
|
@ -3721,11 +3728,11 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
|
|||
static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) {
|
||||
++(pCxt->currLevel);
|
||||
ESqlClause currClause = pCxt->currClause;
|
||||
SSelectStmt* pCurrStmt = pCxt->pCurrStmt;
|
||||
SSelectStmt* pCurrStmt = pCxt->pCurrSelectStmt;
|
||||
int32_t code = translateQuery(pCxt, pNode);
|
||||
--(pCxt->currLevel);
|
||||
pCxt->currClause = currClause;
|
||||
pCxt->pCurrStmt = pCurrStmt;
|
||||
pCxt->pCurrSelectStmt = pCurrStmt;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -4428,7 +4435,6 @@ static SArray* serializeVgroupsCreateTableBatch(int32_t acctId, SHashObj* pVgrou
|
|||
}
|
||||
|
||||
static int32_t rewriteCreateMultiTable(STranslateContext* pCxt, SQuery* pQuery) {
|
||||
|
||||
SCreateMultiTableStmt* pStmt = (SCreateMultiTableStmt*)pQuery->pRoot;
|
||||
|
||||
SHashObj* pVgroupHashmap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||
|
|
|
@ -178,6 +178,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
|||
return "Only tag can be json type";
|
||||
case TSDB_CODE_PAR_VALUE_TOO_LONG:
|
||||
return "Value too long for column/tag: %s";
|
||||
case TSDB_CODE_PAR_INVALID_DELETE_WHERE:
|
||||
return "The DELETE statement must have a definite time window range";
|
||||
case TSDB_CODE_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
default:
|
||||
|
@ -371,7 +373,8 @@ int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag **ppTag, SMs
|
|||
}
|
||||
STagVal val = {0};
|
||||
val.pKey = jsonKey;
|
||||
taosHashPut(keyHash, jsonKey, keyLen, &keyLen, CHAR_BYTES); // add key to hash to remove dumplicate, value is useless
|
||||
taosHashPut(keyHash, jsonKey, keyLen, &keyLen,
|
||||
CHAR_BYTES); // add key to hash to remove dumplicate, value is useless
|
||||
|
||||
if (item->type == cJSON_String) { // add json value format: type|data
|
||||
char* jsonValue = item->valuestring;
|
||||
|
@ -382,8 +385,7 @@ int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag **ppTag, SMs
|
|||
goto end;
|
||||
}
|
||||
val.type = TSDB_DATA_TYPE_NCHAR;
|
||||
if (valLen > 0 && !taosMbsToUcs4(jsonValue, valLen, (TdUcs4*)tmp,
|
||||
(int32_t)(valLen * TSDB_NCHAR_SIZE), &valLen)) {
|
||||
if (valLen > 0 && !taosMbsToUcs4(jsonValue, valLen, (TdUcs4*)tmp, (int32_t)(valLen * TSDB_NCHAR_SIZE), &valLen)) {
|
||||
uError("charset:%s to %s. val:%s, errno:%s, convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, jsonValue,
|
||||
strerror(errno));
|
||||
retCode = buildSyntaxErrMsg(pMsgBuf, "charset convert json error", jsonValue);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,7 +21,21 @@ namespace ParserTest {
|
|||
|
||||
class ParserInitialDTest : public ParserDdlTest {};
|
||||
|
||||
// todo delete
|
||||
// DELETE FROM tb_name [WHERE condition]
|
||||
TEST_F(ParserInitialDTest, delete) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("DELETE FROM t1");
|
||||
|
||||
run("DELETE FROM t1 WHERE ts > now - 2d and ts < now - 1d");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialDTest, deleteSemanticCheck) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("DELETE FROM t1 WHERE c1 > 10", TSDB_CODE_PAR_INVALID_DELETE_WHERE, PARSER_STAGE_TRANSLATE);
|
||||
}
|
||||
|
||||
// todo desc
|
||||
// todo describe
|
||||
// todo DROP account
|
||||
|
|
|
@ -229,14 +229,14 @@ TEST_F(ParserSelectTest, subquery) {
|
|||
run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstartts FROM st1s1 PARTITION BY TBNAME INTERVAL(1m)) INTERVAL(1n)");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, subquerySemanticError) {
|
||||
TEST_F(ParserSelectTest, subquerySemanticCheck) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT SUM(a) FROM (SELECT MAX(c1) a FROM st1s1 INTERVAL(1m)) INTERVAL(1n)", TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, semanticError) {
|
||||
TEST_F(ParserSelectTest, semanticCheck) {
|
||||
useDb("root", "test");
|
||||
|
||||
// TSDB_CODE_PAR_INVALID_COLUMN
|
||||
|
|
|
@ -21,8 +21,10 @@ typedef struct SLogicPlanContext {
|
|||
SPlanContext* pPlanCxt;
|
||||
} SLogicPlanContext;
|
||||
|
||||
typedef int32_t (*FCreateLogicNode)(SLogicPlanContext*, SSelectStmt*, SLogicNode**);
|
||||
typedef int32_t (*FCreateLogicNode)(SLogicPlanContext*, void*, SLogicNode**);
|
||||
typedef int32_t (*FCreateSelectLogicNode)(SLogicPlanContext*, SSelectStmt*, SLogicNode**);
|
||||
typedef int32_t (*FCreateSetOpLogicNode)(SLogicPlanContext*, SSetOperator*, SLogicNode**);
|
||||
typedef int32_t (*FCreateDeleteLogicNode)(SLogicPlanContext*, SDeleteStmt*, SLogicNode**);
|
||||
|
||||
static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
|
||||
SLogicNode** pLogicNode);
|
||||
|
@ -119,12 +121,12 @@ static int32_t pushLogicNode(SLogicPlanContext* pCxt, SLogicNode** pOldRoot, SLo
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t createChildLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, FCreateLogicNode func,
|
||||
static int32_t createRootLogicNode(SLogicPlanContext* pCxt, void* pStmt, uint8_t precision, FCreateLogicNode func,
|
||||
SLogicNode** pRoot) {
|
||||
SLogicNode* pNode = NULL;
|
||||
int32_t code = func(pCxt, pSelect, &pNode);
|
||||
int32_t code = func(pCxt, pStmt, &pNode);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pNode) {
|
||||
pNode->precision = pSelect->precision;
|
||||
pNode->precision = precision;
|
||||
code = pushLogicNode(pCxt, pRoot, pNode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
|
@ -133,56 +135,10 @@ static int32_t createChildLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelec
|
|||
return code;
|
||||
}
|
||||
|
||||
// typedef struct SCreateColumnCxt {
|
||||
// int32_t errCode;
|
||||
// SNodeList* pList;
|
||||
// } SCreateColumnCxt;
|
||||
|
||||
// static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
|
||||
// SCreateColumnCxt* pCxt = (SCreateColumnCxt*)pContext;
|
||||
// switch (nodeType(pNode)) {
|
||||
// case QUERY_NODE_COLUMN: {
|
||||
// SNode* pCol = nodesCloneNode(pNode);
|
||||
// if (NULL == pCol) {
|
||||
// return DEAL_RES_ERROR;
|
||||
// }
|
||||
// return (TSDB_CODE_SUCCESS == nodesListAppend(pCxt->pList, pCol) ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
|
||||
// }
|
||||
// case QUERY_NODE_OPERATOR:
|
||||
// case QUERY_NODE_LOGIC_CONDITION:
|
||||
// case QUERY_NODE_FUNCTION: {
|
||||
// SExprNode* pExpr = (SExprNode*)pNode;
|
||||
// SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
// if (NULL == pCol) {
|
||||
// return DEAL_RES_ERROR;
|
||||
// }
|
||||
// pCol->node.resType = pExpr->resType;
|
||||
// strcpy(pCol->colName, pExpr->aliasName);
|
||||
// return (TSDB_CODE_SUCCESS == nodesListAppend(pCxt->pList, pCol) ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
|
||||
// }
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
// return DEAL_RES_CONTINUE;
|
||||
// }
|
||||
|
||||
// static int32_t createColumnByRewriteExps(SNodeList* pExprs, SNodeList** pList) {
|
||||
// SCreateColumnCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pList = (NULL == *pList ? nodesMakeList() : *pList)};
|
||||
// if (NULL == cxt.pList) {
|
||||
// return TSDB_CODE_OUT_OF_MEMORY;
|
||||
// }
|
||||
|
||||
// nodesWalkExprs(pExprs, doCreateColumn, &cxt);
|
||||
// if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
// nodesDestroyList(cxt.pList);
|
||||
// return cxt.errCode;
|
||||
// }
|
||||
// if (NULL == *pList) {
|
||||
// *pList = cxt.pList;
|
||||
// }
|
||||
// return cxt.errCode;
|
||||
// }
|
||||
static int32_t createSelectRootLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, FCreateSelectLogicNode func,
|
||||
SLogicNode** pRoot) {
|
||||
return createRootLogicNode(pCxt, pSelect, pSelect->precision, (FCreateLogicNode)func, pRoot);
|
||||
}
|
||||
|
||||
static EScanType getScanType(SLogicPlanContext* pCxt, SNodeList* pScanPseudoCols, SNodeList* pScanCols,
|
||||
STableMeta* pMeta) {
|
||||
|
@ -783,25 +739,25 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
|||
SLogicNode* pRoot = NULL;
|
||||
int32_t code = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable, &pRoot);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
|
||||
code = createSelectRootLogicNode(pCxt, pSelect, createPartitionLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
|
||||
code = createSelectRootLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createFillLogicNode, &pRoot);
|
||||
code = createSelectRootLogicNode(pCxt, pSelect, createFillLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
|
||||
code = createSelectRootLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
|
||||
code = createSelectRootLogicNode(pCxt, pSelect, createDistinctLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createSortLogicNode, &pRoot);
|
||||
code = createSelectRootLogicNode(pCxt, pSelect, createSortLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createChildLogicNode(pCxt, pSelect, createProjectLogicNode, &pRoot);
|
||||
code = createSelectRootLogicNode(pCxt, pSelect, createProjectLogicNode, &pRoot);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -813,17 +769,9 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t createSetOpChildLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator,
|
||||
FCreateSetOpLogicNode func, SLogicNode** pRoot) {
|
||||
SLogicNode* pNode = NULL;
|
||||
int32_t code = func(pCxt, pSetOperator, &pNode);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pNode) {
|
||||
code = pushLogicNode(pCxt, pRoot, pNode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyNode(pNode);
|
||||
}
|
||||
return code;
|
||||
static int32_t createSetOpRootLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, FCreateSetOpLogicNode func,
|
||||
SLogicNode** pRoot) {
|
||||
return createRootLogicNode(pCxt, pSetOperator, pSetOperator->precision, (FCreateLogicNode)func, pRoot);
|
||||
}
|
||||
|
||||
static int32_t createSetOpSortLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, SLogicNode** pLogicNode) {
|
||||
|
@ -970,7 +918,7 @@ static int32_t createSetOperatorLogicNode(SLogicPlanContext* pCxt, SSetOperator*
|
|||
SLogicNode* pRoot = NULL;
|
||||
int32_t code = createSetOpLogicNode(pCxt, pSetOperator, &pRoot);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createSetOpChildLogicNode(pCxt, pSetOperator, createSetOpSortLogicNode, &pRoot);
|
||||
code = createSetOpRootLogicNode(pCxt, pSetOperator, createSetOpSortLogicNode, &pRoot);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -1008,6 +956,43 @@ static int32_t createVnodeModifLogicNode(SLogicPlanContext* pCxt, SVnodeModifOpS
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t createDeleteRootLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete, FCreateDeleteLogicNode func,
|
||||
SLogicNode** pRoot) {
|
||||
return createRootLogicNode(pCxt, pDelete, pDelete->precision, (FCreateLogicNode)func, pRoot);
|
||||
}
|
||||
|
||||
static int32_t createDeleteScanLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete, SLogicNode** pLogicNode) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
static int32_t createDeleteAggLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete, SLogicNode** pLogicNode) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
static int32_t createDeleteModifyTableLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete,
|
||||
SLogicNode** pLogicNode) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
static int32_t createDeleteLogicNode(SLogicPlanContext* pCxt, SDeleteStmt* pDelete, SLogicNode** pLogicNode) {
|
||||
SLogicNode* pRoot = NULL;
|
||||
int32_t code = createDeleteRootLogicNode(pCxt, pDelete, createDeleteScanLogicNode, &pRoot);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createDeleteRootLogicNode(pCxt, pDelete, createDeleteAggLogicNode, &pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createDeleteRootLogicNode(pCxt, pDelete, createDeleteModifyTableLogicNode, &pRoot);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pLogicNode = pRoot;
|
||||
} else {
|
||||
nodesDestroyNode(pRoot);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t createQueryLogicNode(SLogicPlanContext* pCxt, SNode* pStmt, SLogicNode** pLogicNode) {
|
||||
switch (nodeType(pStmt)) {
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
|
@ -1018,6 +1003,8 @@ static int32_t createQueryLogicNode(SLogicPlanContext* pCxt, SNode* pStmt, SLogi
|
|||
return createQueryLogicNode(pCxt, ((SExplainStmt*)pStmt)->pQuery, pLogicNode);
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
return createSetOperatorLogicNode(pCxt, (SSetOperator*)pStmt, pLogicNode);
|
||||
case QUERY_NODE_DELETE_STMT:
|
||||
return createDeleteLogicNode(pCxt, (SDeleteStmt*)pStmt, pLogicNode);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -268,30 +268,6 @@ static int32_t cpdMergeCond(SNode** pDst, SNode** pSrc) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t cpdMergeConds(SNode** pDst, SNodeList** pSrc) {
|
||||
if (NULL == *pSrc) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (1 == LIST_LENGTH(*pSrc)) {
|
||||
*pDst = nodesListGetNode(*pSrc, 0);
|
||||
nodesClearList(*pSrc);
|
||||
} else {
|
||||
SLogicConditionNode* pLogicCond = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||
if (NULL == pLogicCond) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL;
|
||||
pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
|
||||
pLogicCond->condType = LOGIC_COND_TYPE_AND;
|
||||
pLogicCond->pParameterList = *pSrc;
|
||||
*pDst = (SNode*)pLogicCond;
|
||||
}
|
||||
*pSrc = NULL;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t cpdCondAppend(SNode** pCond, SNode** pAdditionalCond) {
|
||||
if (NULL == *pCond) {
|
||||
TSWAP(*pCond, *pAdditionalCond);
|
||||
|
@ -310,119 +286,6 @@ static int32_t cpdCondAppend(SNode** pCond, SNode** pAdditionalCond) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static EDealRes cpdIsPrimaryKeyCondImpl(SNode* pNode, void* pContext) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
*((bool*)pContext) = ((PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pNode)->colId) ? true : false);
|
||||
return *((bool*)pContext) ? DEAL_RES_CONTINUE : DEAL_RES_END;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static bool cpdIsPrimaryKeyCond(SNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pNode)) {
|
||||
return false;
|
||||
}
|
||||
bool isPrimaryKeyCond = false;
|
||||
nodesWalkExpr(pNode, cpdIsPrimaryKeyCondImpl, &isPrimaryKeyCond);
|
||||
return isPrimaryKeyCond;
|
||||
}
|
||||
|
||||
static EDealRes cpdIsTagCondImpl(SNode* pNode, void* pContext) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
*((bool*)pContext) = ((COLUMN_TYPE_TAG == ((SColumnNode*)pNode)->colType) ? true : false);
|
||||
return *((bool*)pContext) ? DEAL_RES_CONTINUE : DEAL_RES_END;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static bool cpdIsTagCond(SNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pNode)) {
|
||||
return false;
|
||||
}
|
||||
bool isTagCond = false;
|
||||
nodesWalkExpr(pNode, cpdIsTagCondImpl, &isTagCond);
|
||||
return isTagCond;
|
||||
}
|
||||
|
||||
static int32_t cpdPartitionScanLogicCond(SScanLogicNode* pScan, SNode** pPrimaryKeyCond, SNode** pTagCond,
|
||||
SNode** pOtherCond) {
|
||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pScan->node.pConditions;
|
||||
|
||||
if (LOGIC_COND_TYPE_AND != pLogicCond->condType) {
|
||||
*pPrimaryKeyCond = NULL;
|
||||
*pOtherCond = pScan->node.pConditions;
|
||||
pScan->node.pConditions = NULL;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
SNodeList* pPrimaryKeyConds = NULL;
|
||||
SNodeList* pTagConds = NULL;
|
||||
SNodeList* pOtherConds = NULL;
|
||||
SNode* pCond = NULL;
|
||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||
if (cpdIsPrimaryKeyCond(pCond)) {
|
||||
code = nodesListMakeAppend(&pPrimaryKeyConds, nodesCloneNode(pCond));
|
||||
} else if (cpdIsTagCond(pScan->node.pConditions)) {
|
||||
code = nodesListMakeAppend(&pTagConds, nodesCloneNode(pCond));
|
||||
} else {
|
||||
code = nodesListMakeAppend(&pOtherConds, nodesCloneNode(pCond));
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SNode* pTempPrimaryKeyCond = NULL;
|
||||
SNode* pTempTagCond = NULL;
|
||||
SNode* pTempOtherCond = NULL;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = cpdMergeConds(&pTempPrimaryKeyCond, &pPrimaryKeyConds);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = cpdMergeConds(&pTempTagCond, &pTagConds);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = cpdMergeConds(&pTempOtherCond, &pOtherConds);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pPrimaryKeyCond = pTempPrimaryKeyCond;
|
||||
*pTagCond = pTempTagCond;
|
||||
*pOtherCond = pTempOtherCond;
|
||||
nodesDestroyNode(pScan->node.pConditions);
|
||||
pScan->node.pConditions = NULL;
|
||||
} else {
|
||||
nodesDestroyList(pPrimaryKeyConds);
|
||||
nodesDestroyList(pTagConds);
|
||||
nodesDestroyList(pOtherConds);
|
||||
nodesDestroyNode(pTempPrimaryKeyCond);
|
||||
nodesDestroyNode(pTempTagCond);
|
||||
nodesDestroyNode(pTempOtherCond);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t cpdPartitionScanCond(SScanLogicNode* pScan, SNode** pPrimaryKeyCond, SNode** pTagCond,
|
||||
SNode** pOtherCond) {
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pScan->node.pConditions)) {
|
||||
return cpdPartitionScanLogicCond(pScan, pPrimaryKeyCond, pTagCond, pOtherCond);
|
||||
}
|
||||
|
||||
if (cpdIsPrimaryKeyCond(pScan->node.pConditions)) {
|
||||
*pPrimaryKeyCond = pScan->node.pConditions;
|
||||
} else if (cpdIsTagCond(pScan->node.pConditions)) {
|
||||
*pTagCond = pScan->node.pConditions;
|
||||
} else {
|
||||
*pOtherCond = pScan->node.pConditions;
|
||||
}
|
||||
pScan->node.pConditions = NULL;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t cpdCalcTimeRange(SScanLogicNode* pScan, SNode** pPrimaryKeyCond, SNode** pOtherCond) {
|
||||
bool isStrict = false;
|
||||
int32_t code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict);
|
||||
|
@ -472,7 +335,7 @@ static int32_t cpdOptimizeScanCondition(SOptimizeContext* pCxt, SScanLogicNode*
|
|||
SNode* pPrimaryKeyCond = NULL;
|
||||
SNode* pTagCond = NULL;
|
||||
SNode* pOtherCond = NULL;
|
||||
int32_t code = cpdPartitionScanCond(pScan, &pPrimaryKeyCond, &pTagCond, &pOtherCond);
|
||||
int32_t code = nodesPartitionCond(&pScan->node.pConditions, &pPrimaryKeyCond, &pTagCond, &pOtherCond);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pPrimaryKeyCond) {
|
||||
code = cpdCalcTimeRange(pScan, &pPrimaryKeyCond, &pOtherCond);
|
||||
}
|
||||
|
@ -565,16 +428,16 @@ static int32_t cpdPartitionLogicCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNo
|
|||
SNode* pTempRightChildCond = NULL;
|
||||
SNode* pTempRemainCond = NULL;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = cpdMergeConds(&pTempOnCond, &pOnConds);
|
||||
code = nodesMergeConds(&pTempOnCond, &pOnConds);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = cpdMergeConds(&pTempLeftChildCond, &pLeftChildConds);
|
||||
code = nodesMergeConds(&pTempLeftChildCond, &pLeftChildConds);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = cpdMergeConds(&pTempRightChildCond, &pRightChildConds);
|
||||
code = nodesMergeConds(&pTempRightChildCond, &pRightChildConds);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = cpdMergeConds(&pTempRemainCond, &pRemainConds);
|
||||
code = nodesMergeConds(&pTempRemainCond, &pRemainConds);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -36,6 +36,10 @@ TEST_F(PlanOptimizeTest, ConditionPushDown) {
|
|||
useDb("root", "test");
|
||||
|
||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4");
|
||||
|
||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 or tag1 < 2");
|
||||
|
||||
run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello'");
|
||||
}
|
||||
|
||||
TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
|
||||
|
|
Loading…
Reference in New Issue