feat: fill physical plan
This commit is contained in:
parent
913354057e
commit
cdfe9929c8
|
@ -28,15 +28,16 @@ typedef int64_t tb_uid_t;
|
|||
#define TSWINDOW_INITIALIZER ((STimeWindow){INT64_MIN, INT64_MAX})
|
||||
#define TSWINDOW_DESC_INITIALIZER ((STimeWindow){INT64_MAX, INT64_MIN})
|
||||
#define IS_TSWINDOW_SPECIFIED(win) (((win).skey != INT64_MIN) || ((win).ekey != INT64_MAX))
|
||||
#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))
|
||||
|
||||
typedef enum {
|
||||
TSDB_SUPER_TABLE = 1, // super table
|
||||
TSDB_CHILD_TABLE = 2, // table created from super table
|
||||
TSDB_NORMAL_TABLE = 3, // ordinary table
|
||||
TSDB_STREAM_TABLE = 4, // table created from stream computing
|
||||
TSDB_TEMP_TABLE = 5, // temp table created by nest query
|
||||
TSDB_SUPER_TABLE = 1, // super table
|
||||
TSDB_CHILD_TABLE = 2, // table created from super table
|
||||
TSDB_NORMAL_TABLE = 3, // ordinary table
|
||||
TSDB_STREAM_TABLE = 4, // table created from stream computing
|
||||
TSDB_TEMP_TABLE = 5, // temp table created by nest query
|
||||
TSDB_SYSTEM_TABLE = 6,
|
||||
TSDB_TABLE_MAX = 7
|
||||
TSDB_TABLE_MAX = 7
|
||||
} ETableType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -86,7 +87,7 @@ typedef enum {
|
|||
|
||||
extern char *qtypeStr[];
|
||||
|
||||
#define TSDB_PORT_HTTP 11
|
||||
#define TSDB_PORT_HTTP 11
|
||||
|
||||
#undef TD_DEBUG_PRINT_ROW
|
||||
|
||||
|
|
|
@ -110,10 +110,11 @@ typedef struct SWindowLogicNode {
|
|||
} SWindowLogicNode;
|
||||
|
||||
typedef struct SFillLogicNode {
|
||||
SLogicNode node;
|
||||
EFillMode mode;
|
||||
SNode* pWStartTs;
|
||||
SNode* pValues; // SNodeListNode
|
||||
SLogicNode node;
|
||||
EFillMode mode;
|
||||
SNode* pWStartTs;
|
||||
SNode* pValues; // SNodeListNode
|
||||
STimeWindow timeRange;
|
||||
} SFillLogicNode;
|
||||
|
||||
typedef struct SSortLogicNode {
|
||||
|
@ -274,11 +275,12 @@ typedef struct SIntervalPhysiNode {
|
|||
} SIntervalPhysiNode;
|
||||
|
||||
typedef struct SFillPhysiNode {
|
||||
SPhysiNode node;
|
||||
EFillMode mode;
|
||||
SNode* pWStartTs; // SColumnNode
|
||||
SNode* pValues; // SNodeListNode
|
||||
SNodeList* pTargets;
|
||||
SPhysiNode node;
|
||||
EFillMode mode;
|
||||
SNode* pWStartTs; // SColumnNode
|
||||
SNode* pValues; // SNodeListNode
|
||||
SNodeList* pTargets;
|
||||
STimeWindow timeRange;
|
||||
} SFillPhysiNode;
|
||||
|
||||
typedef struct SMultiTableIntervalPhysiNode {
|
||||
|
|
|
@ -209,10 +209,11 @@ typedef enum EFillMode {
|
|||
} EFillMode;
|
||||
|
||||
typedef struct SFillNode {
|
||||
ENodeType type; // QUERY_NODE_FILL
|
||||
EFillMode mode;
|
||||
SNode* pValues; // SNodeListNode
|
||||
SNode* pWStartTs; // _wstartts pseudo column
|
||||
ENodeType type; // QUERY_NODE_FILL
|
||||
EFillMode mode;
|
||||
SNode* pValues; // SNodeListNode
|
||||
SNode* pWStartTs; // _wstartts pseudo column
|
||||
STimeWindow timeRange;
|
||||
} SFillNode;
|
||||
|
||||
typedef struct SSelectStmt {
|
||||
|
|
|
@ -619,9 +619,12 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_SLIMIT_LEAK_PARTITION_BY TAOS_DEF_ERROR_CODE(0, 0x2638)
|
||||
#define TSDB_CODE_PAR_INVALID_TOPIC_QUERY TAOS_DEF_ERROR_CODE(0, 0x2639)
|
||||
#define TSDB_CODE_PAR_INVALID_DROP_STABLE TAOS_DEF_ERROR_CODE(0, 0x263A)
|
||||
#define TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE TAOS_DEF_ERROR_CODE(0, 0x263B)
|
||||
|
||||
//planner
|
||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||
#define TSDB_CODE_PLAN_EXPECTED_TS_EQUAL TAOS_DEF_ERROR_CODE(0, 0x2701)
|
||||
#define TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN TAOS_DEF_ERROR_CODE(0, 0x2702)
|
||||
|
||||
//function
|
||||
#define TSDB_CODE_FUNC_FUNTION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2800)
|
||||
|
|
|
@ -41,8 +41,6 @@
|
|||
#define SET_MAIN_SCAN_FLAG(runtime) ((runtime)->scanFlag = MAIN_SCAN)
|
||||
#define SET_REVERSE_SCAN_FLAG(runtime) ((runtime)->scanFlag = REVERSE_SCAN)
|
||||
|
||||
#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))
|
||||
|
||||
#define SDATA_BLOCK_INITIALIZER \
|
||||
(SDataBlockInfo) { {0}, 0 }
|
||||
|
||||
|
|
|
@ -571,6 +571,8 @@ static int32_t jsonToLogicProjectNode(const SJson* pJson, void* pObj) {
|
|||
static const char* jkFillLogicPlanMode = "Mode";
|
||||
static const char* jkFillLogicPlanWStartTs = "WStartTs";
|
||||
static const char* jkFillLogicPlanValues = "Values";
|
||||
static const char* jkFillLogicPlanStartTime = "StartTime";
|
||||
static const char* jkFillLogicPlanEndTime = "EndTime";
|
||||
|
||||
static int32_t logicFillNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFillLogicNode* pNode = (const SFillLogicNode*)pObj;
|
||||
|
@ -585,6 +587,12 @@ static int32_t logicFillNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkFillLogicPlanValues, nodeToJson, pNode->pValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillLogicPlanStartTime, pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillLogicPlanEndTime, pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -602,6 +610,12 @@ static int32_t jsonToLogicFillNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkFillLogicPlanValues, &pNode->pValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillLogicPlanStartTime, &pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillLogicPlanEndTime, &pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1475,6 +1489,8 @@ static const char* jkFillPhysiPlanMode = "Mode";
|
|||
static const char* jkFillPhysiPlanWStartTs = "WStartTs";
|
||||
static const char* jkFillPhysiPlanValues = "Values";
|
||||
static const char* jkFillPhysiPlanTargets = "Targets";
|
||||
static const char* jkFillPhysiPlanStartTime = "StartTime";
|
||||
static const char* jkFillPhysiPlanEndTime = "EndTime";
|
||||
|
||||
static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFillPhysiNode* pNode = (const SFillPhysiNode*)pObj;
|
||||
|
@ -1492,6 +1508,12 @@ static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkFillPhysiPlanTargets, pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanStartTime, pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanEndTime, pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1512,6 +1534,12 @@ static int32_t jsonToPhysiFillNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkFillPhysiPlanTargets, &pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillPhysiPlanStartTime, &pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillPhysiPlanEndTime, &pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2409,6 +2437,8 @@ static int32_t jsonToNodeListNode(const SJson* pJson, void* pObj) {
|
|||
static const char* jkFillMode = "Mode";
|
||||
static const char* jkFillValues = "Values";
|
||||
static const char* jkFillWStartTs = "WStartTs";
|
||||
static const char* jkFillStartTime = "StartTime";
|
||||
static const char* jkFillEndTime = "EndTime";
|
||||
|
||||
static int32_t fillNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFillNode* pNode = (const SFillNode*)pObj;
|
||||
|
@ -2420,6 +2450,12 @@ static int32_t fillNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkFillWStartTs, nodeToJson, pNode->pWStartTs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillStartTime, pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFillEndTime, pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2434,6 +2470,12 @@ static int32_t jsonToFillNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkFillWStartTs, &pNode->pWStartTs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillStartTime, &pNode->timeRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkFillEndTime, &pNode->timeRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "catalog.h"
|
||||
#include "cmdnodes.h"
|
||||
#include "filter.h"
|
||||
#include "functionMgt.h"
|
||||
#include "parUtil.h"
|
||||
#include "scalar.h"
|
||||
|
@ -468,19 +469,19 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
pVal->datum.b = (0 == strcasecmp(pVal->literal, "true"));
|
||||
*(bool*)&pVal->typeData = pVal->datum.b;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:{
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
|
||||
*(int8_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT:{
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
|
||||
*(int16_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT:{
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
|
||||
*(int32_t*)&pVal->typeData = pVal->datum.i;
|
||||
|
@ -489,43 +490,43 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.i = strtoll(pVal->literal, &endPtr, 10);
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UTINYINT:{
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
|
||||
*(uint8_t*)&pVal->typeData = pVal->datum.u;
|
||||
*(uint8_t*)&pVal->typeData = pVal->datum.u;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_USMALLINT:{
|
||||
case TSDB_DATA_TYPE_USMALLINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
|
||||
*(uint16_t*)&pVal->typeData = pVal->datum.u;
|
||||
*(uint16_t*)&pVal->typeData = pVal->datum.u;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UINT:{
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
|
||||
*(uint32_t*)&pVal->typeData = pVal->datum.u;
|
||||
*(uint32_t*)&pVal->typeData = pVal->datum.u;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.u = strtoull(pVal->literal, &endPtr, 10);
|
||||
*(uint64_t*)&pVal->typeData = pVal->datum.u;
|
||||
*(uint64_t*)&pVal->typeData = pVal->datum.u;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:{
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.d = strtold(pVal->literal, &endPtr);
|
||||
*(float*)&pVal->typeData = pVal->datum.d;
|
||||
*(float*)&pVal->typeData = pVal->datum.d;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
char* endPtr = NULL;
|
||||
pVal->datum.d = strtold(pVal->literal, &endPtr);
|
||||
*(double*)&pVal->typeData = pVal->datum.d;
|
||||
*(double*)&pVal->typeData = pVal->datum.d;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
|
@ -543,7 +544,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
TSDB_CODE_SUCCESS) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||
}
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
|
@ -1244,6 +1245,113 @@ 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;
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (isPrimaryKeyCond(pWhere)) {
|
||||
bool isStrict = false;
|
||||
return filterGetTimeRange(pWhere, pTimeRange, &isStrict);
|
||||
} else {
|
||||
*pTimeRange = TSWINDOW_INITIALIZER;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkFill(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
|
||||
SFillNode* pFill = (SFillNode*)pInterval->pFill;
|
||||
if (TSWINDOW_IS_EQUAL(pFill->timeRange, TSWINDOW_INITIALIZER) ||
|
||||
TSWINDOW_IS_EQUAL(pFill->timeRange, TSWINDOW_DESC_INITIALIZER)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
|
||||
}
|
||||
|
||||
int64_t timeRange = TABS(pFill->timeRange.skey - pFill->timeRange.ekey);
|
||||
int64_t intervalRange = 0;
|
||||
SValueNode* pInter = (SValueNode*)pInterval->pInterval;
|
||||
if (TIME_IS_VAR_DURATION(pInter->unit)) {
|
||||
int64_t f = 1;
|
||||
if (pInter->unit == 'n') {
|
||||
f = 30L * MILLISECOND_PER_DAY;
|
||||
} else if (pInter->unit == 'y') {
|
||||
f = 365L * MILLISECOND_PER_DAY;
|
||||
}
|
||||
intervalRange = pInter->datum.i * f;
|
||||
} else {
|
||||
intervalRange = pInter->datum.i;
|
||||
}
|
||||
if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateFill(STranslateContext* pCxt, SNode* pWhere, SIntervalWindowNode* pInterval) {
|
||||
if (NULL == pInterval->pFill) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = getTimeRange(pCxt, pWhere, &(((SFillNode*)pInterval->pFill)->timeRange));
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkFill(pCxt, pInterval);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char unit) {
|
||||
int64_t days = convertTimeFromPrecisionToUnit(val, fromPrecision, 'd');
|
||||
switch (unit) {
|
||||
|
@ -1266,7 +1374,7 @@ static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char uni
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
|
||||
static int32_t checkIntervalWindow(STranslateContext* pCxt, SNode* pWhere, SIntervalWindowNode* pInterval) {
|
||||
uint8_t precision = ((SColumnNode*)pInterval->pCol)->node.resType.precision;
|
||||
|
||||
SValueNode* pInter = (SValueNode*)pInterval->pInterval;
|
||||
|
@ -1308,7 +1416,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
|
|||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return translateFill(pCxt, pWhere, pInterval);
|
||||
}
|
||||
|
||||
static EDealRes checkStateExpr(SNode* pNode, void* pContext) {
|
||||
|
@ -1345,28 +1453,28 @@ static int32_t checkSessionWindow(STranslateContext* pCxt, SSessionWindowNode* p
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkWindow(STranslateContext* pCxt, SNode* pWindow) {
|
||||
switch (nodeType(pWindow)) {
|
||||
static int32_t checkWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
switch (nodeType(pSelect->pWindow)) {
|
||||
case QUERY_NODE_STATE_WINDOW:
|
||||
return checkStateWindow(pCxt, (SStateWindowNode*)pWindow);
|
||||
return checkStateWindow(pCxt, (SStateWindowNode*)pSelect->pWindow);
|
||||
case QUERY_NODE_SESSION_WINDOW:
|
||||
return checkSessionWindow(pCxt, (SSessionWindowNode*)pWindow);
|
||||
return checkSessionWindow(pCxt, (SSessionWindowNode*)pSelect->pWindow);
|
||||
case QUERY_NODE_INTERVAL_WINDOW:
|
||||
return checkIntervalWindow(pCxt, (SIntervalWindowNode*)pWindow);
|
||||
return checkIntervalWindow(pCxt, pSelect->pWhere, (SIntervalWindowNode*)pSelect->pWindow);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateWindow(STranslateContext* pCxt, SNode* pWindow) {
|
||||
if (NULL == pWindow) {
|
||||
static int32_t translateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL == pSelect->pWindow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
pCxt->currClause = SQL_CLAUSE_WINDOW;
|
||||
int32_t code = translateExpr(pCxt, pWindow);
|
||||
int32_t code = translateExpr(pCxt, pSelect->pWindow);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkWindow(pCxt, pWindow);
|
||||
code = checkWindow(pCxt, pSelect);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -1485,7 +1593,7 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
code = translatePartitionBy(pCxt, pSelect->pPartitionByList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateWindow(pCxt, pSelect->pWindow);
|
||||
code = translateWindow(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateGroupBy(pCxt, pSelect);
|
||||
|
|
|
@ -128,6 +128,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
|||
return "Invalid topic query";
|
||||
case TSDB_CODE_PAR_INVALID_DROP_STABLE:
|
||||
return "Cannot drop super table in batch";
|
||||
case TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE:
|
||||
return "start(end) time of query range required or time range too large";
|
||||
case TSDB_CODE_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
default:
|
||||
|
@ -140,7 +142,6 @@ int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...) {
|
|||
va_start(vArgList, errCode);
|
||||
vsnprintf(pBuf->buf, pBuf->len, getSyntaxErrFormat(errCode), vArgList);
|
||||
va_end(vArgList);
|
||||
terrno = errCode;
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ TEST_F(ParserSelectTest, basic) {
|
|||
|
||||
run("SELECT ts, t.c1 FROM (SELECT * FROM t1) t");
|
||||
|
||||
run("SELECT * FROM t1 tt1, t1 tt2 where tt1.c1 = tt2.c1");
|
||||
run("SELECT * FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, constant) {
|
||||
|
@ -43,7 +43,7 @@ TEST_F(ParserSelectTest, constant) {
|
|||
run("SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", "
|
||||
"timestamp '2022-02-09 17:30:20', true, false, 15s FROM t1");
|
||||
|
||||
run("SELECT 123 + 45 FROM t1 where 2 - 1");
|
||||
run("SELECT 123 + 45 FROM t1 WHERE 2 - 1");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, expression) {
|
||||
|
@ -59,9 +59,9 @@ TEST_F(ParserSelectTest, expression) {
|
|||
TEST_F(ParserSelectTest, condition) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT c1 FROM t1 where ts in (true, false)");
|
||||
run("SELECT c1 FROM t1 WHERE ts in (true, false)");
|
||||
|
||||
run("SELECT * FROM t1 where c1 > 10 and c1 is not null");
|
||||
run("SELECT * FROM t1 WHERE c1 > 10 and c1 is not null");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, pseudoColumn) {
|
||||
|
@ -77,7 +77,7 @@ TEST_F(ParserSelectTest, multiResFunc) {
|
|||
|
||||
run("SELECT last(c1, c2), first(t1.*), last_row(c3) FROM t1");
|
||||
|
||||
run("SELECT last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) FROM st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
|
||||
run("SELECT last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) FROM st1s1 t1, st1s2 t2 WHERE t1.ts = t2.ts");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, timelineFunc) {
|
||||
|
@ -96,29 +96,29 @@ TEST_F(ParserSelectTest, clause) {
|
|||
useDb("root", "test");
|
||||
|
||||
// group by clause
|
||||
run("SELECT COUNT(*) cnt FROM t1 where c1 > 0");
|
||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0");
|
||||
|
||||
run("SELECT COUNT(*), c2 cnt FROM t1 where c1 > 0 group by c2");
|
||||
run("SELECT COUNT(*), c2 cnt FROM t1 WHERE c1 > 0 group by c2");
|
||||
|
||||
run("SELECT COUNT(*) cnt FROM t1 where c1 > 0 group by c2 having COUNT(c1) > 10");
|
||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 group by c2 having COUNT(c1) > 10");
|
||||
|
||||
run("SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1 where c1 > 0 group by c2, c1");
|
||||
run("SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 group by c2, c1");
|
||||
|
||||
run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 where c1 > 0 group by c1 + 10, c2");
|
||||
run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 group by c1 + 10, c2");
|
||||
|
||||
// order by clause
|
||||
run("SELECT COUNT(*) cnt FROM t1 where c1 > 0 group by c2 order by cnt");
|
||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 group by c2 order by cnt");
|
||||
|
||||
run("SELECT COUNT(*) cnt FROM t1 where c1 > 0 group by c2 order by 1");
|
||||
run("SELECT COUNT(*) cnt FROM t1 WHERE c1 > 0 group by c2 order by 1");
|
||||
|
||||
// distinct clause
|
||||
// run("SELECT distinct c1, c2 FROM t1 where c1 > 0 order by c1");
|
||||
// run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by c1");
|
||||
|
||||
// run("SELECT distinct c1 + 10, c2 FROM t1 where c1 > 0 order by c1 + 10, c2");
|
||||
// run("SELECT distinct c1 + 10, c2 FROM t1 WHERE c1 > 0 order by c1 + 10, c2");
|
||||
|
||||
// run("SELECT distinct c1 + 10 cc1, c2 cc2 FROM t1 where c1 > 0 order by cc1, c2");
|
||||
// run("SELECT distinct c1 + 10 cc1, c2 cc2 FROM t1 WHERE c1 > 0 order by cc1, c2");
|
||||
|
||||
// run("SELECT distinct COUNT(c2) FROM t1 where c1 > 0 group by c1 order by COUNT(c2)");
|
||||
// run("SELECT distinct COUNT(c2) FROM t1 WHERE c1 > 0 group by c1 order by COUNT(c2)");
|
||||
}
|
||||
|
||||
// INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [FILL(fill_mod_and_val)]
|
||||
|
@ -133,7 +133,8 @@ TEST_F(ParserSelectTest, interval) {
|
|||
// INTERVAL(interval_val, interval_offset) SLIDING (sliding_val)
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10s, 5s) SLIDING(7s)");
|
||||
// INTERVAL(interval_val) FILL(NONE)
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10s) FILL(NONE)");
|
||||
run("SELECT COUNT(*) FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
|
||||
"INTERVAL(10s) FILL(NONE)");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, semanticError) {
|
||||
|
@ -152,7 +153,7 @@ TEST_F(ParserSelectTest, semanticError) {
|
|||
run("SELECT t2.c1 FROM t1", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN
|
||||
run("SELECT c2 FROM t1 tt1, t1 tt2 where tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_WRONG_VALUE_TYPE
|
||||
run("SELECT timestamp '2010' FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE);
|
||||
|
@ -161,7 +162,7 @@ TEST_F(ParserSelectTest, semanticError) {
|
|||
run("SELECT c2 FROM t1 tt1 join t1 tt2 on COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("SELECT c2 FROM t1 where COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
run("SELECT c2 FROM t1 WHERE COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("SELECT c2 FROM t1 group by COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
|
@ -190,13 +191,13 @@ TEST_F(ParserSelectTest, semanticError) {
|
|||
run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
|
||||
|
||||
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
|
||||
run("SELECT distinct c1, c2 FROM t1 where c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("SELECT distinct c1 FROM t1 where c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
run("SELECT distinct c1 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
|
||||
run("SELECT distinct c2 FROM t1 where c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
run("SELECT distinct c2 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
|
||||
PARSER_STAGE_TRANSLATE);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "planner.h"
|
||||
#include "taoserror.h"
|
||||
|
||||
#define QUERY_POLICY_VNODE 1
|
||||
#define QUERY_POLICY_HYBRID 2
|
||||
|
@ -33,6 +34,8 @@ extern "C" {
|
|||
#define planDebug(param, ...) qDebug("PLAN: " param, __VA_ARGS__)
|
||||
#define planTrace(param, ...) qTrace("PLAN: " param, __VA_ARGS__)
|
||||
|
||||
int32_t generateUsageErrMsg(char* pBuf, int32_t len, int32_t errCode, ...);
|
||||
|
||||
int32_t createLogicPlan(SPlanContext* pCxt, SLogicNode** pLogicNode);
|
||||
int32_t optimizeLogicPlan(SPlanContext* pCxt, SLogicNode* pLogicNode);
|
||||
int32_t splitLogicPlan(SPlanContext* pCxt, SLogicNode* pLogicNode, SLogicSubplan** pLogicSubplan);
|
||||
|
|
|
@ -597,6 +597,7 @@ static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
|||
int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_WINDOW, NULL, COLLECT_COL_TYPE_ALL, &pFill->node.pTargets);
|
||||
|
||||
pFill->mode = pFillNode->mode;
|
||||
pFill->timeRange = pFillNode->timeRange;
|
||||
pFill->pValues = nodesCloneNode(pFillNode->pValues);
|
||||
pFill->pWStartTs = nodesCloneNode(pFillNode->pWStartTs);
|
||||
if ((NULL != pFillNode->pValues && NULL == pFill->pValues) || NULL == pFill->pWStartTs) {
|
||||
|
|
|
@ -554,22 +554,19 @@ static bool cpdIsPrimaryKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
|
|||
|
||||
static int32_t cpdCheckOpCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SNode* pOnCond) {
|
||||
if (!cpdIsPrimaryKeyEqualCond(pJoin, pOnCond)) {
|
||||
snprintf(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, "l.ts = r.ts is expected in join expression");
|
||||
return TSDB_CODE_FAILED;
|
||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t cpdCheckLogicCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SLogicConditionNode* pOnCond) {
|
||||
if (LOGIC_COND_TYPE_AND != pOnCond->condType) {
|
||||
snprintf(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, "l.ts = r.ts is expected in join expression");
|
||||
return TSDB_CODE_FAILED;
|
||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL);
|
||||
}
|
||||
SNode* pCond = NULL;
|
||||
FOREACH(pCond, pOnCond->pParameterList) {
|
||||
if (!cpdIsPrimaryKeyEqualCond(pJoin, pCond)) {
|
||||
snprintf(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, "l.ts = r.ts is expected in join expression");
|
||||
return TSDB_CODE_FAILED;
|
||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -577,8 +574,7 @@ static int32_t cpdCheckLogicCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin,
|
|||
|
||||
static int32_t cpdCheckJoinOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||
if (NULL == pJoin->pOnConditions) {
|
||||
snprintf(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, "not support cross join");
|
||||
return TSDB_CODE_FAILED;
|
||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN);
|
||||
}
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pOnConditions)) {
|
||||
return cpdCheckLogicCond(pCxt, pJoin, (SLogicConditionNode*)pJoin->pOnConditions);
|
||||
|
|
|
@ -1037,6 +1037,9 @@ static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pFill->mode = pFillNode->mode;
|
||||
pFill->timeRange = pFillNode->timeRange;
|
||||
|
||||
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
|
||||
int32_t code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->node.pTargets, &pFill->pTargets);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "planInt.h"
|
||||
|
||||
static char* getUsageErrFormat(int32_t errCode) {
|
||||
switch (errCode) {
|
||||
case TSDB_CODE_PLAN_EXPECTED_TS_EQUAL:
|
||||
return "l.ts = r.ts is expected in join expression";
|
||||
case TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN:
|
||||
return "not support cross join";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
int32_t generateUsageErrMsg(char* pBuf, int32_t len, int32_t errCode, ...) {
|
||||
va_list vArgList;
|
||||
va_start(vArgList, errCode);
|
||||
vsnprintf(pBuf, len, getUsageErrFormat(errCode), vArgList);
|
||||
va_end(vArgList);
|
||||
return errCode;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* This program is free software: you can use, redistribute, AND/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
|
@ -20,30 +20,32 @@ using namespace std;
|
|||
|
||||
class PlanBasicTest : public PlannerTestBase {};
|
||||
|
||||
TEST_F(PlanBasicTest, select) {
|
||||
TEST_F(PlanBasicTest, selectClause) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select * from t1");
|
||||
run("select 1 from t1");
|
||||
run("select * from st1");
|
||||
run("select 1 from st1");
|
||||
run("SELECT * FROM t1");
|
||||
run("SELECT 1 FROM t1");
|
||||
run("SELECT * FROM st1");
|
||||
run("SELECT 1 FROM st1");
|
||||
}
|
||||
|
||||
TEST_F(PlanBasicTest, where) {
|
||||
TEST_F(PlanBasicTest, whereClause) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select * from t1 where c1 > 10");
|
||||
run("SELECT * FROM t1 WHERE c1 > 10");
|
||||
|
||||
run("SELECT * FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59'");
|
||||
}
|
||||
|
||||
TEST_F(PlanBasicTest, join) {
|
||||
TEST_F(PlanBasicTest, joinClause) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select t1.c1, t2.c2 from st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
|
||||
run("select t1.c1, t2.c2 from st1s1 t1 join st1s2 t2 on t1.ts = t2.ts");
|
||||
run("SELECT t1.c1, t2.c2 FROM st1s1 t1, st1s2 t2 WHERE t1.ts = t2.ts");
|
||||
run("SELECT t1.c1, t2.c2 FROM st1s1 t1 JOIN st1s2 t2 ON t1.ts = t2.ts");
|
||||
}
|
||||
|
||||
TEST_F(PlanBasicTest, func) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("select diff(c1) from t1");
|
||||
run("SELECT DIFF(c1) FROM t1");
|
||||
}
|
||||
|
|
|
@ -35,7 +35,10 @@ TEST_F(PlanIntervalTest, pseudoCol) {
|
|||
TEST_F(PlanIntervalTest, fill) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10s) FILL(LINEAR)");
|
||||
run("SELECT COUNT(*) FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
|
||||
"INTERVAL(10s) FILL(LINEAR)");
|
||||
|
||||
run("SELECT COUNT(*), sum(c1) FROM t1 INTERVAL(10s) FILL(VALUE, 10, 20)");
|
||||
run("SELECT COUNT(*), SUM(c1) FROM t1 "
|
||||
"WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
|
||||
"INTERVAL(10s) FILL(VALUE, 10, 20)");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue