TD-2570
This commit is contained in:
parent
4fa64be709
commit
3c0617bc59
|
@ -226,6 +226,7 @@ typedef struct SQueryInfo {
|
||||||
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
|
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
|
||||||
int16_t resColumnId; // result column id
|
int16_t resColumnId; // result column id
|
||||||
bool distinctTag; // distinct tag or not
|
bool distinctTag; // distinct tag or not
|
||||||
|
bool windowState; // window state or not
|
||||||
int32_t round; // 0/1/....
|
int32_t round; // 0/1/....
|
||||||
int32_t bufLen;
|
int32_t bufLen;
|
||||||
char* buf;
|
char* buf;
|
||||||
|
|
|
@ -89,6 +89,7 @@ static int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCm
|
||||||
static int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode);
|
static int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode);
|
||||||
static int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken);
|
static int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken);
|
||||||
static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding);
|
static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding);
|
||||||
|
static int32_t validateWindowStateNode(SSqlCmd* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, bool isStable);
|
||||||
|
|
||||||
static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem);
|
static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem);
|
||||||
|
|
||||||
|
@ -828,6 +829,35 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS
|
||||||
// The following part is used to check for the invalid query expression.
|
// The following part is used to check for the invalid query expression.
|
||||||
return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
|
return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
|
||||||
}
|
}
|
||||||
|
static int32_t validateWindowStateNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, bool isStable) {
|
||||||
|
|
||||||
|
const char* msg1 = "invalid column name";
|
||||||
|
const char* msg2 = "invalid window state";
|
||||||
|
const char* msg3 = "not support window_state on super table";
|
||||||
|
|
||||||
|
SStrToken *col = &(pSqlNode->windowstateVal.col) ;
|
||||||
|
if (col->z == NULL || col->n <= 0) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
//TODO(dengyihao): check tag column
|
||||||
|
if (isStable) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||||
|
if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tscSqlExprNumOfExprs(pQueryInfo) == 1) {
|
||||||
|
SSqlExpr* pExpr = &(tscSqlExprGet(pQueryInfo, 0)->base);
|
||||||
|
if (index.columnIndex == pExpr->colInfo.colIndex && pExpr->colType == TSDB_DATA_TYPE_INT) {
|
||||||
|
pQueryInfo->windowState = true;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pSqlNode) {
|
int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pSqlNode) {
|
||||||
const char* msg1 = "gap should be fixed time window";
|
const char* msg1 = "gap should be fixed time window";
|
||||||
|
@ -6721,6 +6751,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
@ -7288,7 +7319,9 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) {
|
||||||
TSDB_CODE_SUCCESS) {
|
TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
if (validateWindowStateNode(pCmd, pQueryInfo, pSqlNode, isSTable) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
}
|
||||||
// set order by info
|
// set order by info
|
||||||
if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) !=
|
if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) !=
|
||||||
TSDB_CODE_SUCCESS) {
|
TSDB_CODE_SUCCESS) {
|
||||||
|
@ -7311,6 +7344,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse the window_state
|
||||||
/*
|
/*
|
||||||
* transfer sql functions that need secondary merge into another format
|
* transfer sql functions that need secondary merge into another format
|
||||||
* in dealing with super table queries such as: count/first/last
|
* in dealing with super table queries such as: count/first/last
|
||||||
|
|
|
@ -3550,6 +3550,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
|
||||||
pQueryAttr->pointInterpQuery = tscIsPointInterpQuery(pQueryInfo);
|
pQueryAttr->pointInterpQuery = tscIsPointInterpQuery(pQueryInfo);
|
||||||
pQueryAttr->timeWindowInterpo = timeWindowInterpoRequired(pQueryInfo);
|
pQueryAttr->timeWindowInterpo = timeWindowInterpoRequired(pQueryInfo);
|
||||||
pQueryAttr->distinctTag = pQueryInfo->distinctTag;
|
pQueryAttr->distinctTag = pQueryInfo->distinctTag;
|
||||||
|
pQueryAttr->windowState = pQueryInfo->windowState;
|
||||||
|
|
||||||
pQueryAttr->numOfCols = numOfCols;
|
pQueryAttr->numOfCols = numOfCols;
|
||||||
pQueryAttr->numOfOutput = numOfOutput;
|
pQueryAttr->numOfOutput = numOfOutput;
|
||||||
|
|
|
@ -17,105 +17,105 @@
|
||||||
#define TDENGINE_TTOKENDEF_H
|
#define TDENGINE_TTOKENDEF_H
|
||||||
|
|
||||||
|
|
||||||
#define TK_ID 1
|
#define TK_ID 1
|
||||||
#define TK_BOOL 2
|
#define TK_BOOL 2
|
||||||
#define TK_TINYINT 3
|
#define TK_TINYINT 3
|
||||||
#define TK_SMALLINT 4
|
#define TK_SMALLINT 4
|
||||||
#define TK_INTEGER 5
|
#define TK_INTEGER 5
|
||||||
#define TK_BIGINT 6
|
#define TK_BIGINT 6
|
||||||
#define TK_FLOAT 7
|
#define TK_FLOAT 7
|
||||||
#define TK_DOUBLE 8
|
#define TK_DOUBLE 8
|
||||||
#define TK_STRING 9
|
#define TK_STRING 9
|
||||||
#define TK_TIMESTAMP 10
|
#define TK_TIMESTAMP 10
|
||||||
#define TK_BINARY 11
|
#define TK_BINARY 11
|
||||||
#define TK_NCHAR 12
|
#define TK_NCHAR 12
|
||||||
#define TK_OR 13
|
#define TK_OR 13
|
||||||
#define TK_AND 14
|
#define TK_AND 14
|
||||||
#define TK_NOT 15
|
#define TK_NOT 15
|
||||||
#define TK_EQ 16
|
#define TK_EQ 16
|
||||||
#define TK_NE 17
|
#define TK_NE 17
|
||||||
#define TK_ISNULL 18
|
#define TK_ISNULL 18
|
||||||
#define TK_NOTNULL 19
|
#define TK_NOTNULL 19
|
||||||
#define TK_IS 20
|
#define TK_IS 20
|
||||||
#define TK_LIKE 21
|
#define TK_LIKE 21
|
||||||
#define TK_GLOB 22
|
#define TK_GLOB 22
|
||||||
#define TK_BETWEEN 23
|
#define TK_BETWEEN 23
|
||||||
#define TK_IN 24
|
#define TK_IN 24
|
||||||
#define TK_GT 25
|
#define TK_GT 25
|
||||||
#define TK_GE 26
|
#define TK_GE 26
|
||||||
#define TK_LT 27
|
#define TK_LT 27
|
||||||
#define TK_LE 28
|
#define TK_LE 28
|
||||||
#define TK_BITAND 29
|
#define TK_BITAND 29
|
||||||
#define TK_BITOR 30
|
#define TK_BITOR 30
|
||||||
#define TK_LSHIFT 31
|
#define TK_LSHIFT 31
|
||||||
#define TK_RSHIFT 32
|
#define TK_RSHIFT 32
|
||||||
#define TK_PLUS 33
|
#define TK_PLUS 33
|
||||||
#define TK_MINUS 34
|
#define TK_MINUS 34
|
||||||
#define TK_DIVIDE 35
|
#define TK_DIVIDE 35
|
||||||
#define TK_TIMES 36
|
#define TK_TIMES 36
|
||||||
#define TK_STAR 37
|
#define TK_STAR 37
|
||||||
#define TK_SLASH 38
|
#define TK_SLASH 38
|
||||||
#define TK_REM 39
|
#define TK_REM 39
|
||||||
#define TK_CONCAT 40
|
#define TK_CONCAT 40
|
||||||
#define TK_UMINUS 41
|
#define TK_UMINUS 41
|
||||||
#define TK_UPLUS 42
|
#define TK_UPLUS 42
|
||||||
#define TK_BITNOT 43
|
#define TK_BITNOT 43
|
||||||
#define TK_SHOW 44
|
#define TK_SHOW 44
|
||||||
#define TK_DATABASES 45
|
#define TK_DATABASES 45
|
||||||
#define TK_TOPICS 46
|
#define TK_TOPICS 46
|
||||||
#define TK_MNODES 47
|
#define TK_MNODES 47
|
||||||
#define TK_DNODES 48
|
#define TK_DNODES 48
|
||||||
#define TK_ACCOUNTS 49
|
#define TK_ACCOUNTS 49
|
||||||
#define TK_USERS 50
|
#define TK_USERS 50
|
||||||
#define TK_MODULES 51
|
#define TK_MODULES 51
|
||||||
#define TK_QUERIES 52
|
#define TK_QUERIES 52
|
||||||
#define TK_CONNECTIONS 53
|
#define TK_CONNECTIONS 53
|
||||||
#define TK_STREAMS 54
|
#define TK_STREAMS 54
|
||||||
#define TK_VARIABLES 55
|
#define TK_VARIABLES 55
|
||||||
#define TK_SCORES 56
|
#define TK_SCORES 56
|
||||||
#define TK_GRANTS 57
|
#define TK_GRANTS 57
|
||||||
#define TK_VNODES 58
|
#define TK_VNODES 58
|
||||||
#define TK_IPTOKEN 59
|
#define TK_IPTOKEN 59
|
||||||
#define TK_DOT 60
|
#define TK_DOT 60
|
||||||
#define TK_CREATE 61
|
#define TK_CREATE 61
|
||||||
#define TK_TABLE 62
|
#define TK_TABLE 62
|
||||||
#define TK_STABLE 63
|
#define TK_STABLE 63
|
||||||
#define TK_DATABASE 64
|
#define TK_DATABASE 64
|
||||||
#define TK_TABLES 65
|
#define TK_TABLES 65
|
||||||
#define TK_STABLES 66
|
#define TK_STABLES 66
|
||||||
#define TK_VGROUPS 67
|
#define TK_VGROUPS 67
|
||||||
#define TK_DROP 68
|
#define TK_DROP 68
|
||||||
#define TK_TOPIC 69
|
#define TK_TOPIC 69
|
||||||
#define TK_DNODE 70
|
#define TK_DNODE 70
|
||||||
#define TK_USER 71
|
#define TK_USER 71
|
||||||
#define TK_ACCOUNT 72
|
#define TK_ACCOUNT 72
|
||||||
#define TK_USE 73
|
#define TK_USE 73
|
||||||
#define TK_DESCRIBE 74
|
#define TK_DESCRIBE 74
|
||||||
#define TK_ALTER 75
|
#define TK_ALTER 75
|
||||||
#define TK_PASS 76
|
#define TK_PASS 76
|
||||||
#define TK_PRIVILEGE 77
|
#define TK_PRIVILEGE 77
|
||||||
#define TK_LOCAL 78
|
#define TK_LOCAL 78
|
||||||
#define TK_IF 79
|
#define TK_IF 79
|
||||||
#define TK_EXISTS 80
|
#define TK_EXISTS 80
|
||||||
#define TK_PPS 81
|
#define TK_PPS 81
|
||||||
#define TK_TSERIES 82
|
#define TK_TSERIES 82
|
||||||
#define TK_DBS 83
|
#define TK_DBS 83
|
||||||
#define TK_STORAGE 84
|
#define TK_STORAGE 84
|
||||||
#define TK_QTIME 85
|
#define TK_QTIME 85
|
||||||
#define TK_CONNS 86
|
#define TK_CONNS 86
|
||||||
#define TK_STATE 87
|
#define TK_STATE 87
|
||||||
#define TK_KEEP 88
|
#define TK_KEEP 88
|
||||||
#define TK_CACHE 89
|
#define TK_CACHE 89
|
||||||
#define TK_REPLICA 90
|
#define TK_REPLICA 90
|
||||||
#define TK_QUORUM 91
|
#define TK_QUORUM 91
|
||||||
#define TK_DAYS 92
|
#define TK_DAYS 92
|
||||||
#define TK_MINROWS 93
|
#define TK_MINROWS 93
|
||||||
#define TK_MAXROWS 94
|
#define TK_MAXROWS 94
|
||||||
#define TK_BLOCKS 95
|
#define TK_BLOCKS 95
|
||||||
#define TK_CTIME 96
|
#define TK_CTIME 96
|
||||||
#define TK_WAL 97
|
#define TK_WAL 97
|
||||||
#define TK_FSYNC 98
|
#define TK_FSYNC 98
|
||||||
#define TK_COMP 99
|
#define TK_COMP 99
|
||||||
#define TK_PRECISION 100
|
#define TK_PRECISION 100
|
||||||
#define TK_UPDATE 101
|
#define TK_UPDATE 101
|
||||||
#define TK_CACHELAST 102
|
#define TK_CACHELAST 102
|
||||||
|
@ -136,74 +136,74 @@
|
||||||
#define TK_VARIABLE 117
|
#define TK_VARIABLE 117
|
||||||
#define TK_INTERVAL 118
|
#define TK_INTERVAL 118
|
||||||
#define TK_SESSION 119
|
#define TK_SESSION 119
|
||||||
#define TK_FILL 120
|
#define TK_WINDOW_STATE 120
|
||||||
#define TK_SLIDING 121
|
#define TK_FILL 121
|
||||||
#define TK_ORDER 122
|
#define TK_SLIDING 122
|
||||||
#define TK_BY 123
|
#define TK_ORDER 123
|
||||||
#define TK_ASC 124
|
#define TK_BY 124
|
||||||
#define TK_DESC 125
|
#define TK_ASC 125
|
||||||
#define TK_GROUP 126
|
#define TK_DESC 126
|
||||||
#define TK_HAVING 127
|
#define TK_GROUP 127
|
||||||
#define TK_LIMIT 128
|
#define TK_HAVING 128
|
||||||
#define TK_OFFSET 129
|
#define TK_LIMIT 129
|
||||||
#define TK_SLIMIT 130
|
#define TK_OFFSET 130
|
||||||
#define TK_SOFFSET 131
|
#define TK_SLIMIT 131
|
||||||
#define TK_WHERE 132
|
#define TK_SOFFSET 132
|
||||||
#define TK_NOW 133
|
#define TK_WHERE 133
|
||||||
#define TK_RESET 134
|
#define TK_NOW 134
|
||||||
#define TK_QUERY 135
|
#define TK_RESET 135
|
||||||
#define TK_SYNCDB 136
|
#define TK_QUERY 136
|
||||||
#define TK_ADD 137
|
#define TK_SYNCDB 137
|
||||||
#define TK_COLUMN 138
|
#define TK_ADD 138
|
||||||
#define TK_TAG 139
|
#define TK_COLUMN 139
|
||||||
#define TK_CHANGE 140
|
#define TK_TAG 140
|
||||||
#define TK_SET 141
|
#define TK_CHANGE 141
|
||||||
#define TK_KILL 142
|
#define TK_SET 142
|
||||||
#define TK_CONNECTION 143
|
#define TK_KILL 143
|
||||||
#define TK_STREAM 144
|
#define TK_CONNECTION 144
|
||||||
#define TK_COLON 145
|
#define TK_STREAM 145
|
||||||
#define TK_ABORT 146
|
#define TK_COLON 146
|
||||||
#define TK_AFTER 147
|
#define TK_ABORT 147
|
||||||
#define TK_ATTACH 148
|
#define TK_AFTER 148
|
||||||
#define TK_BEFORE 149
|
#define TK_ATTACH 149
|
||||||
#define TK_BEGIN 150
|
#define TK_BEFORE 150
|
||||||
#define TK_CASCADE 151
|
#define TK_BEGIN 151
|
||||||
#define TK_CLUSTER 152
|
#define TK_CASCADE 152
|
||||||
#define TK_CONFLICT 153
|
#define TK_CLUSTER 153
|
||||||
#define TK_COPY 154
|
#define TK_CONFLICT 154
|
||||||
#define TK_DEFERRED 155
|
#define TK_COPY 155
|
||||||
#define TK_DELIMITERS 156
|
#define TK_DEFERRED 156
|
||||||
#define TK_DETACH 157
|
#define TK_DELIMITERS 157
|
||||||
#define TK_EACH 158
|
#define TK_DETACH 158
|
||||||
#define TK_END 159
|
#define TK_EACH 159
|
||||||
#define TK_EXPLAIN 160
|
#define TK_END 160
|
||||||
#define TK_FAIL 161
|
#define TK_EXPLAIN 161
|
||||||
#define TK_FOR 162
|
#define TK_FAIL 162
|
||||||
#define TK_IGNORE 163
|
#define TK_FOR 163
|
||||||
#define TK_IMMEDIATE 164
|
#define TK_IGNORE 164
|
||||||
#define TK_INITIALLY 165
|
#define TK_IMMEDIATE 165
|
||||||
#define TK_INSTEAD 166
|
#define TK_INITIALLY 166
|
||||||
#define TK_MATCH 167
|
#define TK_INSTEAD 167
|
||||||
#define TK_KEY 168
|
#define TK_MATCH 168
|
||||||
#define TK_OF 169
|
#define TK_KEY 169
|
||||||
#define TK_RAISE 170
|
#define TK_OF 170
|
||||||
#define TK_REPLACE 171
|
#define TK_RAISE 171
|
||||||
#define TK_RESTRICT 172
|
#define TK_REPLACE 172
|
||||||
#define TK_ROW 173
|
#define TK_RESTRICT 173
|
||||||
#define TK_STATEMENT 174
|
#define TK_ROW 174
|
||||||
#define TK_TRIGGER 175
|
#define TK_STATEMENT 175
|
||||||
#define TK_VIEW 176
|
#define TK_TRIGGER 176
|
||||||
#define TK_SEMI 177
|
#define TK_VIEW 177
|
||||||
#define TK_NONE 178
|
#define TK_SEMI 178
|
||||||
#define TK_PREV 179
|
#define TK_NONE 179
|
||||||
#define TK_LINEAR 180
|
#define TK_PREV 180
|
||||||
#define TK_IMPORT 181
|
#define TK_LINEAR 181
|
||||||
#define TK_TBNAME 182
|
#define TK_IMPORT 182
|
||||||
#define TK_JOIN 183
|
#define TK_TBNAME 183
|
||||||
#define TK_INSERT 184
|
#define TK_JOIN 184
|
||||||
#define TK_INTO 185
|
#define TK_INSERT 185
|
||||||
#define TK_VALUES 186
|
#define TK_INTO 186
|
||||||
|
#define TK_VALUES 187
|
||||||
|
|
||||||
#define TK_SPACE 300
|
#define TK_SPACE 300
|
||||||
#define TK_COMMENT 301
|
#define TK_COMMENT 301
|
||||||
|
|
|
@ -196,6 +196,7 @@ typedef struct SQueryAttr {
|
||||||
bool pointInterpQuery; // point interpolation query
|
bool pointInterpQuery; // point interpolation query
|
||||||
bool needReverseScan; // need reverse scan
|
bool needReverseScan; // need reverse scan
|
||||||
bool distinctTag; // distinct tag query
|
bool distinctTag; // distinct tag query
|
||||||
|
bool windowState; // window State on sub/normal table
|
||||||
int32_t interBufSize; // intermediate buffer sizse
|
int32_t interBufSize; // intermediate buffer sizse
|
||||||
|
|
||||||
int32_t havingNum; // having expr number
|
int32_t havingNum; // having expr number
|
||||||
|
@ -302,6 +303,7 @@ enum OPERATOR_TYPE_E {
|
||||||
OP_GlobalAggregate = 18, // global merge for the multi-way data sources.
|
OP_GlobalAggregate = 18, // global merge for the multi-way data sources.
|
||||||
OP_Filter = 19,
|
OP_Filter = 19,
|
||||||
OP_Distinct = 20,
|
OP_Distinct = 20,
|
||||||
|
OP_StateWindow = 21,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SOperatorInfo {
|
typedef struct SOperatorInfo {
|
||||||
|
@ -465,6 +467,16 @@ typedef struct SSWindowOperatorInfo {
|
||||||
int32_t start; // start row index
|
int32_t start; // start row index
|
||||||
} SSWindowOperatorInfo;
|
} SSWindowOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SStateWindowOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
STimeWindow curWindow; // current time window
|
||||||
|
int32_t numOfRows; // number of rows
|
||||||
|
int32_t colIndex; // start row index
|
||||||
|
int32_t start;
|
||||||
|
char* prevData; // previous data
|
||||||
|
|
||||||
|
} SStateWindowOperatorInfo ;
|
||||||
|
|
||||||
typedef struct SDistinctOperatorInfo {
|
typedef struct SDistinctOperatorInfo {
|
||||||
SHashObj *pSet;
|
SHashObj *pSet;
|
||||||
SSDataBlock *pRes;
|
SSDataBlock *pRes;
|
||||||
|
@ -512,6 +524,7 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
|
||||||
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
||||||
int32_t numOfRows, void* merger, bool groupMix);
|
int32_t numOfRows, void* merger, bool groupMix);
|
||||||
|
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param);
|
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param);
|
||||||
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
||||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
|
|
@ -89,6 +89,10 @@ typedef struct SSessionWindowVal {
|
||||||
SStrToken gap;
|
SStrToken gap;
|
||||||
} SSessionWindowVal;
|
} SSessionWindowVal;
|
||||||
|
|
||||||
|
typedef struct SWindowStateVal {
|
||||||
|
SStrToken col;
|
||||||
|
} SWindowStateVal;
|
||||||
|
|
||||||
struct SRelationInfo;
|
struct SRelationInfo;
|
||||||
|
|
||||||
typedef struct SSqlNode {
|
typedef struct SSqlNode {
|
||||||
|
@ -100,6 +104,7 @@ typedef struct SSqlNode {
|
||||||
SArray *fillType; // fill type[optional], SArray<tVariantListItem>
|
SArray *fillType; // fill type[optional], SArray<tVariantListItem>
|
||||||
SIntervalVal interval; // (interval, interval_offset) [optional]
|
SIntervalVal interval; // (interval, interval_offset) [optional]
|
||||||
SSessionWindowVal sessionVal; // session window [optional]
|
SSessionWindowVal sessionVal; // session window [optional]
|
||||||
|
SWindowStateVal windowstateVal; // window_state(col) [optional]
|
||||||
SStrToken sliding; // sliding window [optional]
|
SStrToken sliding; // sliding window [optional]
|
||||||
SLimitVal limit; // limit offset [optional]
|
SLimitVal limit; // limit offset [optional]
|
||||||
SLimitVal slimit; // group limit offset [optional]
|
SLimitVal slimit; // group limit offset [optional]
|
||||||
|
@ -271,7 +276,7 @@ SArray *tSqlExprListAppend(SArray *pList, tSqlExpr *pNode, SStrToken *pDistinc
|
||||||
void tSqlExprListDestroy(SArray *pList);
|
void tSqlExprListDestroy(SArray *pList);
|
||||||
|
|
||||||
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
||||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps,
|
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps, SWindowStateVal *pw,
|
||||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving);
|
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving);
|
||||||
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right);
|
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right);
|
||||||
|
|
||||||
|
|
|
@ -456,8 +456,8 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). {
|
||||||
//////////////////////// The SELECT statement /////////////////////////////////
|
//////////////////////// The SELECT statement /////////////////////////////////
|
||||||
%type select {SSqlNode*}
|
%type select {SSqlNode*}
|
||||||
%destructor select {destroySqlNode($$);}
|
%destructor select {destroySqlNode($$);}
|
||||||
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) windowstate_option(D) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
||||||
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G, N);
|
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &D, &S, F, &L, &G, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
select(A) ::= LP select(B) RP. {A = B;}
|
select(A) ::= LP select(B) RP. {A = B;}
|
||||||
|
@ -475,7 +475,7 @@ cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
|
||||||
// select client_version()
|
// select client_version()
|
||||||
// select server_state()
|
// select server_state()
|
||||||
select(A) ::= SELECT(T) selcollist(W). {
|
select(A) ::= SELECT(T) selcollist(W). {
|
||||||
A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// selcollist is a list of expressions that are to become the return
|
// selcollist is a list of expressions that are to become the return
|
||||||
|
@ -552,6 +552,11 @@ session_option(X) ::= SESSION LP ids(V) cpxName(Z) COMMA tmvar(Y) RP. {
|
||||||
X.col = V;
|
X.col = V;
|
||||||
X.gap = Y;
|
X.gap = Y;
|
||||||
}
|
}
|
||||||
|
%type windowstate_option {SWindowStateVal}
|
||||||
|
windowstate_option(X) ::= . {X.col.n = 0;}
|
||||||
|
windowstate_option(X) ::= WINDOW_STATE LP ids(V) RP. {
|
||||||
|
X.col = V;
|
||||||
|
}
|
||||||
|
|
||||||
%type fill_opt {SArray*}
|
%type fill_opt {SArray*}
|
||||||
%destructor fill_opt {taosArrayDestroy($$);}
|
%destructor fill_opt {taosArrayDestroy($$);}
|
||||||
|
|
|
@ -1758,6 +1758,11 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_StateWindow: {
|
||||||
|
pRuntimeEnv->proot = createStatewindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||||
|
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case OP_Limit: {
|
case OP_Limit: {
|
||||||
pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot);
|
pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot);
|
||||||
|
@ -4413,6 +4418,12 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf
|
||||||
} else if (pDownstream->operatorType == OP_SessionWindow) {
|
} else if (pDownstream->operatorType == OP_SessionWindow) {
|
||||||
SSWindowOperatorInfo* pInfo = pDownstream->info;
|
SSWindowOperatorInfo* pInfo = pDownstream->info;
|
||||||
|
|
||||||
|
pTableScanInfo->pCtx = pInfo->binfo.pCtx;
|
||||||
|
pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo;
|
||||||
|
pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset;
|
||||||
|
} else if (pDownstream->operatorType == OP_StateWindow) {
|
||||||
|
SStateWindowOperatorInfo* pInfo = pDownstream->info;
|
||||||
|
|
||||||
pTableScanInfo->pCtx = pInfo->binfo.pCtx;
|
pTableScanInfo->pCtx = pInfo->binfo.pCtx;
|
||||||
pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo;
|
pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo;
|
||||||
pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset;
|
pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset;
|
||||||
|
@ -5050,6 +5061,121 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) {
|
||||||
return pIntervalInfo->pRes;
|
return pIntervalInfo->pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) {
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex);
|
||||||
|
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||||
|
int16_t bytes = pColInfoData->info.bytes;
|
||||||
|
int16_t type = pColInfoData->info.type;
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
STableQueryInfo* item = pRuntimeEnv->current;
|
||||||
|
bool masterScan = IS_MASTER_SCAN(pRuntimeEnv);
|
||||||
|
|
||||||
|
SColumnInfoData* pTsColInfoData = taosArrayGet(pSDataBlock->pDataBlock, 0);
|
||||||
|
TSKEY* tsList = (TSKEY*)pTsColInfoData->pData;
|
||||||
|
|
||||||
|
if (type == TSDB_DATA_TYPE_FLOAT || type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||||
|
qError("QInfo:0x%"PRIx64" group by not supported on double/float columns, abort", GET_QID(pRuntimeEnv));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int32_t j = 0; j < pSDataBlock->info.rows; ++j) {
|
||||||
|
char* val = ((char*)pColInfoData->pData) + bytes * j;
|
||||||
|
if (isNull(val, type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pInfo->prevData == NULL) {
|
||||||
|
pInfo->prevData = malloc(bytes);
|
||||||
|
memcpy(pInfo->prevData, val, bytes);
|
||||||
|
pInfo->curWindow.skey = tsList[j];
|
||||||
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
|
pInfo->numOfRows = 1;
|
||||||
|
pInfo->start = j;
|
||||||
|
} else if (0 == memcmp(pInfo->prevData, val, bytes)) {
|
||||||
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
|
pInfo->numOfRows += 1;
|
||||||
|
pInfo->start = j;
|
||||||
|
} else {
|
||||||
|
SResultRow* pResult = NULL;
|
||||||
|
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan,
|
||||||
|
&pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
|
||||||
|
pBInfo->rowCellInfoOffset);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||||
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
doApplyFunctions(pRuntimeEnv, pBInfo->pCtx, &pInfo->curWindow, pInfo->start, pInfo->numOfRows, tsList,
|
||||||
|
pSDataBlock->info.rows, pOperator->numOfOutput);
|
||||||
|
|
||||||
|
pInfo->curWindow.skey = tsList[j];
|
||||||
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
|
memcpy(pInfo->prevData, val, bytes);
|
||||||
|
pInfo->numOfRows = 1;
|
||||||
|
pInfo->start = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SResultRow* pResult = NULL;
|
||||||
|
|
||||||
|
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan,
|
||||||
|
&pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
|
||||||
|
pBInfo->rowCellInfoOffset);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||||
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
doApplyFunctions(pRuntimeEnv, pBInfo->pCtx, &pInfo->curWindow, pInfo->start, pInfo->numOfRows, tsList,
|
||||||
|
pSDataBlock->info.rows, pOperator->numOfOutput);
|
||||||
|
|
||||||
|
}
|
||||||
|
static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) {
|
||||||
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
SStateWindowOperatorInfo* pWindowInfo = pOperator->info;
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
|
SOptrBasicInfo* pBInfo = &pWindowInfo->binfo;
|
||||||
|
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||||
|
toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes);
|
||||||
|
|
||||||
|
if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
return pBInfo->pRes;
|
||||||
|
}
|
||||||
|
int32_t order = pQueryAttr->order.order;
|
||||||
|
STimeWindow win = pQueryAttr->window;
|
||||||
|
SOperatorInfo* upstream = pOperator->upstream;
|
||||||
|
while (1) {
|
||||||
|
SSDataBlock* pBlock = upstream->exec(upstream, newgroup);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQueryAttr->order.order);
|
||||||
|
if (pWindowInfo->colIndex == -1) {
|
||||||
|
pWindowInfo->colIndex = pOperator->pExpr->base.colInfo.colIndex;
|
||||||
|
}
|
||||||
|
doStateWindowAggImpl(pOperator, pWindowInfo, pBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore the value
|
||||||
|
pQueryAttr->order.order = order;
|
||||||
|
pQueryAttr->window = win;
|
||||||
|
|
||||||
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
|
closeAllResultRows(&pBInfo->resultRowInfo);
|
||||||
|
setQueryStatus(pRuntimeEnv, QUERY_COMPLETED);
|
||||||
|
finalizeQueryResult(pOperator, pBInfo->pCtx, &pBInfo->resultRowInfo, pBInfo->rowCellInfoOffset);
|
||||||
|
|
||||||
|
initGroupResInfo(&pRuntimeEnv->groupResInfo, &pBInfo->resultRowInfo);
|
||||||
|
toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes);
|
||||||
|
|
||||||
|
if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBInfo->pRes->info.rows == 0? NULL:pBInfo->pRes;
|
||||||
|
}
|
||||||
static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) {
|
static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) {
|
||||||
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
if (pOperator->status == OP_EXEC_DONE) {
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
@ -5500,7 +5626,28 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
||||||
|
|
||||||
return pOperator;
|
return pOperator;
|
||||||
}
|
}
|
||||||
|
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
|
SStateWindowOperatorInfo* pInfo = calloc(1, sizeof(SStateWindowOperatorInfo));
|
||||||
|
pInfo->colIndex = -1;
|
||||||
|
pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
|
||||||
|
pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
|
||||||
|
initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT);
|
||||||
|
|
||||||
|
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||||
|
pOperator->name = "StateWindowOperator";
|
||||||
|
pOperator->operatorType = OP_StateWindow;
|
||||||
|
pOperator->blockingOptr = true;
|
||||||
|
pOperator->status = OP_IN_EXECUTING;
|
||||||
|
pOperator->upstream = upstream;
|
||||||
|
pOperator->pExpr = pExpr;
|
||||||
|
pOperator->numOfOutput = numOfOutput;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||||
|
pOperator->exec = doStateWindowAgg;
|
||||||
|
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||||
|
return pOperator;
|
||||||
|
|
||||||
|
}
|
||||||
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo));
|
SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo));
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,10 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
|
||||||
if (pQueryAttr->stableQuery && !pQueryAttr->tsCompQuery) {
|
if (pQueryAttr->stableQuery && !pQueryAttr->tsCompQuery) {
|
||||||
op = OP_MultiTableAggregate;
|
op = OP_MultiTableAggregate;
|
||||||
} else {
|
} else {
|
||||||
|
if (pQueryAttr->windowState) {
|
||||||
|
op = OP_StateWindow;
|
||||||
|
taosArrayPush(plan, &op);
|
||||||
|
}
|
||||||
op = OP_Aggregate;
|
op = OP_Aggregate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -725,7 +725,7 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
||||||
*/
|
*/
|
||||||
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
||||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
||||||
SSessionWindowVal *pSession, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit,
|
SSessionWindowVal *pSession, SWindowStateVal *pWindowStateVal, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit,
|
||||||
SLimitVal *psLimit, tSqlExpr *pHaving) {
|
SLimitVal *psLimit, tSqlExpr *pHaving) {
|
||||||
assert(pSelNodeList != NULL);
|
assert(pSelNodeList != NULL);
|
||||||
|
|
||||||
|
@ -777,6 +777,12 @@ SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelat
|
||||||
TPARSER_SET_NONE_TOKEN(pSqlNode->sessionVal.col);
|
TPARSER_SET_NONE_TOKEN(pSqlNode->sessionVal.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pWindowStateVal != NULL) {
|
||||||
|
pSqlNode->windowstateVal = *pWindowStateVal;
|
||||||
|
} else {
|
||||||
|
TPARSER_SET_NONE_TOKEN(pSqlNode->windowstateVal.col);
|
||||||
|
}
|
||||||
|
|
||||||
return pSqlNode;
|
return pSqlNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,7 @@ static SKeyword keywordTable[] = {
|
||||||
{"VARIABLE", TK_VARIABLE},
|
{"VARIABLE", TK_VARIABLE},
|
||||||
{"INTERVAL", TK_INTERVAL},
|
{"INTERVAL", TK_INTERVAL},
|
||||||
{"SESSION", TK_SESSION},
|
{"SESSION", TK_SESSION},
|
||||||
|
{"WINDOW_STATE", TK_WINDOW_STATE},
|
||||||
{"FILL", TK_FILL},
|
{"FILL", TK_FILL},
|
||||||
{"SLIDING", TK_SLIDING},
|
{"SLIDING", TK_SLIDING},
|
||||||
{"ORDER", TK_ORDER},
|
{"ORDER", TK_ORDER},
|
||||||
|
|
Loading…
Reference in New Issue