Merge pull request #5434 from taosdata/feature/qrefactor
Feature/qrefactor
This commit is contained in:
commit
6b67d09665
|
@ -123,6 +123,7 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
|
||||||
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
|
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
|
||||||
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
|
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
|
||||||
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
|
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
|
||||||
|
bool tscGroupbyColumn(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||||
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||||
|
@ -153,7 +154,6 @@ SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_F
|
||||||
SInternalField* tscFieldInfoGetInternalField(SFieldInfo* pFieldInfo, int32_t index);
|
SInternalField* tscFieldInfoGetInternalField(SFieldInfo* pFieldInfo, int32_t index);
|
||||||
TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index);
|
TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index);
|
||||||
|
|
||||||
void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
|
|
||||||
void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
|
void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
|
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index);
|
||||||
|
|
|
@ -198,9 +198,10 @@ typedef struct STableDataBlocks {
|
||||||
typedef struct SQueryInfo {
|
typedef struct SQueryInfo {
|
||||||
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
||||||
uint32_t type; // query/insert type
|
uint32_t type; // query/insert type
|
||||||
|
STimeWindow window; // the whole query time window
|
||||||
|
|
||||||
STimeWindow window; // query time window
|
SInterval interval; // tumble time window
|
||||||
SInterval interval;
|
SSessionWindow sessionWindow; // session time window
|
||||||
|
|
||||||
SSqlGroupbyExpr groupbyExpr; // group by tags info
|
SSqlGroupbyExpr groupbyExpr; // group by tags info
|
||||||
SArray * colList; // SArray<SColumn*>
|
SArray * colList; // SArray<SColumn*>
|
||||||
|
@ -402,7 +403,6 @@ typedef struct SSqlStream {
|
||||||
|
|
||||||
void tscSetStreamDestTable(SSqlStream* pStream, const char* dstTable);
|
void tscSetStreamDestTable(SSqlStream* pStream, const char* dstTable);
|
||||||
|
|
||||||
|
|
||||||
int tscAcquireRpc(const char *key, const char *user, const char *secret,void **pRpcObj);
|
int tscAcquireRpc(const char *key, const char *user, const char *secret,void **pRpcObj);
|
||||||
void tscReleaseRpc(void *param);
|
void tscReleaseRpc(void *param);
|
||||||
void tscInitMsgsFp();
|
void tscInitMsgsFp();
|
||||||
|
|
|
@ -77,7 +77,7 @@ static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SC
|
||||||
|
|
||||||
static uint8_t convertOptr(SStrToken *pToken);
|
static uint8_t convertOptr(SStrToken *pToken);
|
||||||
|
|
||||||
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery);
|
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool timeWindowQuery);
|
||||||
|
|
||||||
static bool validateIpAddress(const char* ip, size_t size);
|
static bool validateIpAddress(const char* ip, size_t size);
|
||||||
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||||
|
@ -86,8 +86,8 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
|
||||||
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
|
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
|
||||||
|
|
||||||
static int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
|
static int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
|
||||||
static int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
|
static int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken);
|
||||||
static int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
|
static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding);
|
||||||
|
|
||||||
static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem);
|
static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem);
|
||||||
|
|
||||||
|
@ -128,7 +128,11 @@ static int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo);
|
||||||
static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo);
|
static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo);
|
||||||
static int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index);
|
static int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index);
|
||||||
static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid);
|
static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid);
|
||||||
static bool validateDebugFlag(int32_t flag);
|
static bool validateDebugFlag(int32_t v);
|
||||||
|
|
||||||
|
static bool isTimeWindowQuery(SQueryInfo* pQueryInfo) {
|
||||||
|
return pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0;
|
||||||
|
}
|
||||||
|
|
||||||
int16_t getNewResColId(SQueryInfo* pQueryInfo) {
|
int16_t getNewResColId(SQueryInfo* pQueryInfo) {
|
||||||
return pQueryInfo->resColumnId--;
|
return pQueryInfo->resColumnId--;
|
||||||
|
@ -701,21 +705,86 @@ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
// need to add timestamp column in result set, if it is a time window query
|
||||||
|
static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo) {
|
||||||
|
uint64_t uid = tscSqlExprGet(pQueryInfo, 0)->uid;
|
||||||
|
|
||||||
|
int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
|
||||||
|
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||||
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
|
||||||
|
if (pTableMetaInfo->pTableMeta->id.uid == uid) {
|
||||||
|
tableIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
|
tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
|
||||||
|
|
||||||
|
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
|
tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
||||||
const char* msg1 = "invalid query expression";
|
const char* msg1 = "invalid query expression";
|
||||||
|
const char* msg2 = "top/bottom query does not support order by value in time window query";
|
||||||
|
|
||||||
|
// for top/bottom + interval query, we do not add additional timestamp column in the front
|
||||||
|
if (isTopBottomQuery(pQueryInfo)) {
|
||||||
|
|
||||||
|
// invalid sql:
|
||||||
|
// top(col, k) from table_name [interval(1d)|session(ts, 1d)] order by k asc
|
||||||
|
// order by normal column is not supported
|
||||||
|
int32_t colId = pQueryInfo->order.orderColId;
|
||||||
|
if (isTimeWindowQuery(pQueryInfo) && colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* invalid sql:
|
||||||
|
* select count(tbname)/count(tag1)/count(tag2) from super_table_name [interval(1d)|session(ts, 1d)];
|
||||||
|
*/
|
||||||
|
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
|
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||||
|
if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* invalid sql:
|
||||||
|
* select tbname, tags_fields from super_table_name [interval(1s)|session(ts,1s)]
|
||||||
|
*/
|
||||||
|
if (tscQueryTags(pQueryInfo) && isTimeWindowQuery(pQueryInfo)) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
||||||
const char* msg2 = "interval cannot be less than 10 ms";
|
const char* msg2 = "interval cannot be less than 10 ms";
|
||||||
const char* msg3 = "sliding cannot be used without interval";
|
const char* msg3 = "sliding cannot be used without interval";
|
||||||
const char* msg4 = "top/bottom query does not support order by value in interval query";
|
|
||||||
|
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
|
if (pQuerySql->interval.interval.type == 0 || pQuerySql->interval.interval.n == 0) {
|
||||||
if (pQuerySql->sliding.n > 0) {
|
if (pQuerySql->sliding.n > 0) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -725,7 +794,7 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQ
|
||||||
}
|
}
|
||||||
|
|
||||||
// interval is not null
|
// interval is not null
|
||||||
SStrToken* t = &pQuerySql->interval;
|
SStrToken* t = &pQuerySql->interval.interval;
|
||||||
if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval, &pQueryInfo->interval.intervalUnit) != TSDB_CODE_SUCCESS) {
|
if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval, &pQueryInfo->interval.intervalUnit) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
@ -742,78 +811,64 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for top/bottom + interval query, we do not add additional timestamp column in the front
|
if (parseIntervalOffset(pCmd, pQueryInfo, &pQuerySql->interval.offset) != TSDB_CODE_SUCCESS) {
|
||||||
if (isTopBottomQuery(pQueryInfo)) {
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
}
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
if (parseSlidingClause(pCmd, pQueryInfo, &pQuerySql->sliding) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t colId = pQueryInfo->order.orderColId;
|
// The following part is used to check for the invalid query expression.
|
||||||
if (pQueryInfo->interval.interval > 0 && colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
int32_t parseSessionClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL * pQuerySql) {
|
||||||
|
const char* msg1 = "gap should be fixed time window";
|
||||||
|
const char* msg2 = "only one type time window allowed";
|
||||||
|
const char* msg3 = "invalid column name";
|
||||||
|
const char* msg4 = "invalid time window";
|
||||||
|
|
||||||
|
// no session window
|
||||||
|
if (pQuerySql->sessionVal.gap.n == 0 || pQuerySql->sessionVal.col.n == 0) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
SStrToken* col = &pQuerySql->sessionVal.col;
|
||||||
* check invalid SQL:
|
SStrToken* gap = &pQuerySql->sessionVal.gap;
|
||||||
* select count(tbname)/count(tag1)/count(tag2) from super_table_name interval(1d);
|
|
||||||
*/
|
char timeUnit = 0;
|
||||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
if (parseNatualDuration(gap->z, gap->n, &pQueryInfo->sessionWindow.gap, &timeUnit) != TSDB_CODE_SUCCESS) {
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
|
||||||
if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (timeUnit == 'y' || timeUnit == 'n') {
|
||||||
* check invalid SQL:
|
|
||||||
* select tbname, tags_fields from super_table_name interval(1s)
|
|
||||||
*/
|
|
||||||
if (tscQueryTags(pQueryInfo) && pQueryInfo->interval.interval > 0) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to add timestamp column in result set, if interval is existed
|
// if the unit of time window value is millisecond, change the value from microsecond
|
||||||
uint64_t uid = tscSqlExprGet(pQueryInfo, 0)->uid;
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||||
int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL;
|
if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) {
|
||||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
pQueryInfo->sessionWindow.gap = pQueryInfo->sessionWindow.gap / 1000;
|
||||||
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
|
|
||||||
if (pTableMetaInfo->pTableMeta->id.uid == uid) {
|
|
||||||
tableIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
|
if (pQueryInfo->sessionWindow.gap != 0 && pQueryInfo->interval.interval != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||||
tstrncpy(s.name, aAggs[TSDB_FUNC_TS].name, sizeof(s.name));
|
if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
|
||||||
tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL);
|
|
||||||
|
|
||||||
if (parseOffsetClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
// The following part is used to check for the invalid query expression.
|
||||||
|
return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken) {
|
||||||
const char* msg1 = "interval offset cannot be negative";
|
const char* msg1 = "interval offset cannot be negative";
|
||||||
const char* msg2 = "interval offset should be shorter than interval";
|
const char* msg2 = "interval offset should be shorter than interval";
|
||||||
const char* msg3 = "cannot use 'year' as offset when interval is 'month'";
|
const char* msg3 = "cannot use 'year' as offset when interval is 'month'";
|
||||||
|
@ -821,7 +876,7 @@ int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQue
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
SStrToken* t = &pQuerySql->offset;
|
SStrToken* t = offsetToken;
|
||||||
if (t->n == 0) {
|
if (t->n == 0) {
|
||||||
pQueryInfo->interval.offsetUnit = pQueryInfo->interval.intervalUnit;
|
pQueryInfo->interval.offsetUnit = pQueryInfo->interval.intervalUnit;
|
||||||
pQueryInfo->interval.offset = 0;
|
pQueryInfo->interval.offset = 0;
|
||||||
|
@ -864,20 +919,17 @@ int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQue
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding) {
|
||||||
const char* msg0 = "sliding value too small";
|
const char* msg0 = "sliding value too small";
|
||||||
const char* msg1 = "sliding value no larger than the interval value";
|
const char* msg1 = "sliding value no larger than the interval value";
|
||||||
const char* msg2 = "sliding value can not less than 1% of interval value";
|
const char* msg2 = "sliding value can not less than 1% of interval value";
|
||||||
const char* msg3 = "does not support sliding when interval is natural month/year";
|
const char* msg3 = "does not support sliding when interval is natural month/year";
|
||||||
// const char* msg4 = "sliding not support yet in ordinary query";
|
|
||||||
|
|
||||||
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
|
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
SStrToken* pSliding = &pQuerySql->sliding;
|
|
||||||
if (pSliding->n == 0) {
|
if (pSliding->n == 0) {
|
||||||
pQueryInfo->interval.slidingUnit = pQueryInfo->interval.intervalUnit;
|
pQueryInfo->interval.slidingUnit = pQueryInfo->interval.intervalUnit;
|
||||||
pQueryInfo->interval.sliding = pQueryInfo->interval.interval;
|
pQueryInfo->interval.sliding = pQueryInfo->interval.interval;
|
||||||
|
@ -969,7 +1021,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
|
||||||
const char* msg1 = "first column must be timestamp";
|
const char* msg1 = "first column must be timestamp";
|
||||||
const char* msg2 = "row length exceeds max length";
|
const char* msg2 = "row length exceeds max length";
|
||||||
const char* msg3 = "duplicated column names";
|
const char* msg3 = "duplicated column names";
|
||||||
const char* msg4 = "invalid data types";
|
const char* msg4 = "invalid data type";
|
||||||
const char* msg5 = "invalid binary/nchar column length";
|
const char* msg5 = "invalid binary/nchar column length";
|
||||||
const char* msg6 = "invalid column name";
|
const char* msg6 = "invalid column name";
|
||||||
|
|
||||||
|
@ -990,14 +1042,13 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
|
||||||
int32_t nLen = 0;
|
int32_t nLen = 0;
|
||||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
pField = taosArrayGet(pFieldList, i);
|
pField = taosArrayGet(pFieldList, i);
|
||||||
|
if (!isValidDataType(pField->type)) {
|
||||||
if (pField->bytes == 0) {
|
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidDataType(pField->type)) {
|
if (pField->bytes == 0) {
|
||||||
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1190,7 +1241,7 @@ bool validateOneColumn(SSqlCmd* pCmd, TAOS_FIELD* pColField) {
|
||||||
const char* msg1 = "too many columns";
|
const char* msg1 = "too many columns";
|
||||||
const char* msg2 = "duplicated column names";
|
const char* msg2 = "duplicated column names";
|
||||||
const char* msg3 = "column length too long";
|
const char* msg3 = "column length too long";
|
||||||
const char* msg4 = "invalid data types";
|
const char* msg4 = "invalid data type";
|
||||||
const char* msg5 = "invalid column name";
|
const char* msg5 = "invalid column name";
|
||||||
const char* msg6 = "invalid column length";
|
const char* msg6 = "invalid column length";
|
||||||
|
|
||||||
|
@ -1537,7 +1588,7 @@ bool isValidDistinctSql(SQueryInfo* pQueryInfo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool intervalQuery) {
|
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool timeWindowQuery) {
|
||||||
assert(pSelection != NULL && pCmd != NULL);
|
assert(pSelection != NULL && pCmd != NULL);
|
||||||
|
|
||||||
const char* msg2 = "functions or others can not be mixed up";
|
const char* msg2 = "functions or others can not be mixed up";
|
||||||
|
@ -1604,7 +1655,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
|
||||||
addPrimaryTsColIntoResult(pQueryInfo);
|
addPrimaryTsColIntoResult(pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!functionCompatibleCheck(pQueryInfo, joinQuery, intervalQuery)) {
|
if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1872,22 +1923,18 @@ void setResultColName(char* name, tSqlExprItem* pItem, int32_t functionId, SStrT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateLastQueryInfoForGroupby(SQueryInfo* pQueryInfo, STableMeta* pTableMeta, int32_t functionId, int32_t index) {
|
static void updateLastScanOrderIfNeeded(SQueryInfo* pQueryInfo) {
|
||||||
if (functionId != TSDB_FUNC_LAST) { // todo refactor
|
if (pQueryInfo->sessionWindow.gap > 0 || tscGroupbyColumn(pQueryInfo)) {
|
||||||
return;
|
size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
}
|
for (int32_t i = 0; i < numOfExpr; ++i) {
|
||||||
|
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||||
SSqlGroupbyExpr* pGroupBy = &pQueryInfo->groupbyExpr;
|
if (pExpr->functionId != TSDB_FUNC_LAST && pExpr->functionId != TSDB_FUNC_LAST_DST) {
|
||||||
if (pGroupBy->numOfGroupCols > 0) {
|
continue;
|
||||||
for(int32_t k = 0; k < pGroupBy->numOfGroupCols; ++k) {
|
|
||||||
SColIndex* pIndex = taosArrayGet(pGroupBy->columnInfo, k);
|
|
||||||
if (!TSDB_COL_IS_TAG(pIndex->flag) && pIndex->colIndex < tscGetNumOfColumns(pTableMeta)) { // group by normal columns
|
|
||||||
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, index);
|
|
||||||
pExpr->numOfParams = 1;
|
|
||||||
pExpr->param->i64 = TSDB_ORDER_ASC;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pExpr->numOfParams = 1;
|
||||||
|
pExpr->param->i64 = TSDB_ORDER_ASC;
|
||||||
|
pExpr->param->nType = TSDB_DATA_TYPE_INT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2156,8 +2203,6 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult) != 0) {
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLastQueryInfoForGroupby(pQueryInfo, pTableMetaInfo->pTableMeta, functionId, colIndex - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -2181,8 +2226,6 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLastQueryInfoForGroupby(pQueryInfo, pTableMetaInfo->pTableMeta, functionId, colIndex + i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2209,8 +2252,6 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) {
|
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLastQueryInfoForGroupby(pQueryInfo, pTableMetaInfo->pTableMeta, functionId, colIndex);
|
|
||||||
colIndex++;
|
colIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2845,23 +2886,23 @@ static bool groupbyTagsOrNull(SQueryInfo* pQueryInfo) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool intervalQuery) {
|
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool twQuery) {
|
||||||
int32_t startIdx = 0;
|
int32_t startIdx = 0;
|
||||||
|
|
||||||
size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
assert(numOfExpr > 0);
|
assert(numOfExpr > 0);
|
||||||
|
|
||||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
|
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, startIdx);
|
||||||
int32_t functionID = pExpr->functionId;
|
|
||||||
|
|
||||||
// ts function can be simultaneously used with any other functions.
|
// ts function can be simultaneously used with any other functions.
|
||||||
|
int32_t functionID = pExpr->functionId;
|
||||||
if (functionID == TSDB_FUNC_TS || functionID == TSDB_FUNC_TS_DUMMY) {
|
if (functionID == TSDB_FUNC_TS || functionID == TSDB_FUNC_TS_DUMMY) {
|
||||||
startIdx++;
|
startIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
|
int32_t factor = functionCompatList[tscSqlExprGet(pQueryInfo, startIdx)->functionId];
|
||||||
|
|
||||||
if (tscSqlExprGet(pQueryInfo, 0)->functionId == TSDB_FUNC_LAST_ROW && (joinQuery || intervalQuery || !groupbyTagsOrNull(pQueryInfo))) {
|
if (tscSqlExprGet(pQueryInfo, 0)->functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2889,7 +2930,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionId == TSDB_FUNC_LAST_ROW && (joinQuery || intervalQuery || !groupbyTagsOrNull(pQueryInfo))) {
|
if (functionId == TSDB_FUNC_LAST_ROW && (joinQuery || twQuery || !groupbyTagsOrNull(pQueryInfo))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5919,8 +5960,8 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
|
||||||
SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
|
SColumnList ids = getColumnList(1, 0, pColIndex->colIndex);
|
||||||
insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
|
insertResultField(pQueryInfo, (int32_t)size, &ids, bytes, (int8_t)type, name, pExpr);
|
||||||
} else {
|
} else {
|
||||||
// if this query is "group by" normal column, interval is not allowed
|
// if this query is "group by" normal column, time window query is not allowed
|
||||||
if (pQueryInfo->interval.interval > 0) {
|
if (isTimeWindowQuery(pQueryInfo)) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5982,7 +6023,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || pQueryInfo->interval.interval > 0) {
|
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 || isTimeWindowQuery(pQueryInfo)) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
} else {
|
} else {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -6557,8 +6598,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pQueryInfo->interval.interval > 0) &&
|
if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
||||||
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6790,10 +6830,10 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t joinQuery = (pQuerySql->from != NULL && taosArrayGetSize(pQuerySql->from) > 2);
|
int32_t joinQuery = (pQuerySql->from != NULL && taosArrayGetSize(pQuerySql->from) > 2);
|
||||||
|
int32_t timeWindowQuery = !(pQuerySql->interval.interval.type == 0 || pQuerySql->interval.interval.n == 0 ||
|
||||||
|
pQuerySql->sessionVal.gap.n == 0);
|
||||||
|
|
||||||
int32_t intervalQuery = !(pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0);
|
if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery, timeWindowQuery) != TSDB_CODE_SUCCESS) {
|
||||||
|
|
||||||
if (parseSelectClause(pCmd, index, pQuerySql->pSelection, isSTable, joinQuery, intervalQuery) != TSDB_CODE_SUCCESS) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6806,12 +6846,16 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
} else {
|
} else {
|
||||||
if ((pQueryInfo->interval.interval > 0) &&
|
if (isTimeWindowQuery(pQueryInfo) &&
|
||||||
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parseSessionClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
}
|
||||||
|
|
||||||
// no result due to invalid query time range
|
// no result due to invalid query time range
|
||||||
if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
|
if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
|
||||||
pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
||||||
|
@ -6825,7 +6869,6 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
// in case of join query, time range is required.
|
// in case of join query, time range is required.
|
||||||
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
|
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
|
||||||
int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
|
int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
|
||||||
|
|
||||||
if (timeRange == 0 && pQueryInfo->window.skey == 0) {
|
if (timeRange == 0 && pQueryInfo->window.skey == 0) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
}
|
}
|
||||||
|
@ -6839,6 +6882,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateLastScanOrderIfNeeded(pQueryInfo);
|
||||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||||
|
|
||||||
if (pQuerySql->fillType != NULL) {
|
if (pQuerySql->fillType != NULL) {
|
||||||
|
|
|
@ -643,7 +643,6 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
||||||
}
|
}
|
||||||
|
|
||||||
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
|
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
|
||||||
|
|
||||||
pQueryMsg->head.vgId = htonl(vgId);
|
pQueryMsg->head.vgId = htonl(vgId);
|
||||||
|
|
||||||
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
|
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
|
||||||
|
@ -658,8 +657,6 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
||||||
int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
|
int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
|
||||||
assert(index >= 0 && index < numOfVgroups);
|
assert(index >= 0 && index < numOfVgroups);
|
||||||
|
|
||||||
tscDebug("%p query on stable, vgIndex:%d, numOfVgroups:%d", pSql, index, numOfVgroups);
|
|
||||||
|
|
||||||
SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, index);
|
SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, index);
|
||||||
|
|
||||||
// set the vgroup info
|
// set the vgroup info
|
||||||
|
@ -668,7 +665,10 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
||||||
|
|
||||||
int32_t numOfTables = (int32_t)taosArrayGetSize(pTableIdList->itemList);
|
int32_t numOfTables = (int32_t)taosArrayGetSize(pTableIdList->itemList);
|
||||||
pQueryMsg->numOfTables = htonl(numOfTables); // set the number of tables
|
pQueryMsg->numOfTables = htonl(numOfTables); // set the number of tables
|
||||||
|
|
||||||
|
tscDebug("%p query on stable, vgId:%d, numOfTables:%d, vgIndex:%d, numOfVgroups:%d", pSql,
|
||||||
|
pTableIdList->vgInfo.vgId, numOfTables, index, numOfVgroups);
|
||||||
|
|
||||||
// serialize each table id info
|
// serialize each table id info
|
||||||
for(int32_t i = 0; i < numOfTables; ++i) {
|
for(int32_t i = 0; i < numOfTables; ++i) {
|
||||||
STableIdInfo* pItem = taosArrayGet(pTableIdList->itemList, i);
|
STableIdInfo* pItem = taosArrayGet(pTableIdList->itemList, i);
|
||||||
|
@ -754,6 +754,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit);
|
pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit);
|
||||||
pQueryMsg->sqlstrLen = htonl(sqlLen);
|
pQueryMsg->sqlstrLen = htonl(sqlLen);
|
||||||
pQueryMsg->prevResultLen = htonl(pQueryInfo->bufLen);
|
pQueryMsg->prevResultLen = htonl(pQueryInfo->bufLen);
|
||||||
|
pQueryMsg->sw.gap = htobe64(pQueryInfo->sessionWindow.gap);
|
||||||
|
pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
||||||
|
|
||||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
||||||
|
|
|
@ -1062,7 +1062,6 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows);
|
tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows);
|
||||||
|
|
||||||
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
|
||||||
if (quitAllSubquery(pSql, pParentSql, pSupporter)){
|
if (quitAllSubquery(pSql, pParentSql, pSupporter)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,6 +239,21 @@ bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tscGroupbyColumn(SQueryInfo* pQueryInfo) {
|
||||||
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
|
SSqlGroupbyExpr* pGroupbyExpr = &pQueryInfo->groupbyExpr;
|
||||||
|
for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) {
|
||||||
|
SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, k);
|
||||||
|
if (!TSDB_COL_IS_TAG(pIndex->flag) && pIndex->colIndex < numOfCols) { // group by normal columns
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool tscIsTWAQuery(SQueryInfo* pQueryInfo) {
|
bool tscIsTWAQuery(SQueryInfo* pQueryInfo) {
|
||||||
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||||
|
|
|
@ -485,12 +485,13 @@ typedef struct {
|
||||||
int16_t orderColId;
|
int16_t orderColId;
|
||||||
int16_t numOfCols; // the number of columns will be load from vnode
|
int16_t numOfCols; // the number of columns will be load from vnode
|
||||||
SInterval interval;
|
SInterval interval;
|
||||||
|
SSessionWindow sw; // session window
|
||||||
uint16_t tagCondLen; // tag length in current query
|
uint16_t tagCondLen; // tag length in current query
|
||||||
uint32_t tbnameCondLen; // table name filter condition string length
|
uint32_t tbnameCondLen; // table name filter condition string length
|
||||||
int16_t numOfGroupCols; // num of group by columns
|
int16_t numOfGroupCols; // num of group by columns
|
||||||
int16_t orderByIdx;
|
int16_t orderByIdx;
|
||||||
int16_t orderType; // used in group by xx order by xxx
|
int16_t orderType; // used in group by xx order by xxx
|
||||||
int64_t vgroupLimit; // limit the number of rows for each table, used in order by + limit in stable projection query.
|
int64_t vgroupLimit; // limit the number of rows for each table, used in order by + limit in stable projection query.
|
||||||
int16_t prjOrder; // global order in super table projection query.
|
int16_t prjOrder; // global order in super table projection query.
|
||||||
int64_t limit;
|
int64_t limit;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
|
|
|
@ -135,74 +135,75 @@
|
||||||
#define TK_FROM 116
|
#define TK_FROM 116
|
||||||
#define TK_VARIABLE 117
|
#define TK_VARIABLE 117
|
||||||
#define TK_INTERVAL 118
|
#define TK_INTERVAL 118
|
||||||
#define TK_FILL 119
|
#define TK_SESSION 119
|
||||||
#define TK_SLIDING 120
|
#define TK_FILL 120
|
||||||
#define TK_ORDER 121
|
#define TK_SLIDING 121
|
||||||
#define TK_BY 122
|
#define TK_ORDER 122
|
||||||
#define TK_ASC 123
|
#define TK_BY 123
|
||||||
#define TK_DESC 124
|
#define TK_ASC 124
|
||||||
#define TK_GROUP 125
|
#define TK_DESC 125
|
||||||
#define TK_HAVING 126
|
#define TK_GROUP 126
|
||||||
#define TK_LIMIT 127
|
#define TK_HAVING 127
|
||||||
#define TK_OFFSET 128
|
#define TK_LIMIT 128
|
||||||
#define TK_SLIMIT 129
|
#define TK_OFFSET 129
|
||||||
#define TK_SOFFSET 130
|
#define TK_SLIMIT 130
|
||||||
#define TK_WHERE 131
|
#define TK_SOFFSET 131
|
||||||
#define TK_NOW 132
|
#define TK_WHERE 132
|
||||||
#define TK_RESET 133
|
#define TK_NOW 133
|
||||||
#define TK_QUERY 134
|
#define TK_RESET 134
|
||||||
#define TK_ADD 135
|
#define TK_QUERY 135
|
||||||
#define TK_COLUMN 136
|
#define TK_ADD 136
|
||||||
#define TK_TAG 137
|
#define TK_COLUMN 137
|
||||||
#define TK_CHANGE 138
|
#define TK_TAG 138
|
||||||
#define TK_SET 139
|
#define TK_CHANGE 139
|
||||||
#define TK_KILL 140
|
#define TK_SET 140
|
||||||
#define TK_CONNECTION 141
|
#define TK_KILL 141
|
||||||
#define TK_STREAM 142
|
#define TK_CONNECTION 142
|
||||||
#define TK_COLON 143
|
#define TK_STREAM 143
|
||||||
#define TK_ABORT 144
|
#define TK_COLON 144
|
||||||
#define TK_AFTER 145
|
#define TK_ABORT 145
|
||||||
#define TK_ATTACH 146
|
#define TK_AFTER 146
|
||||||
#define TK_BEFORE 147
|
#define TK_ATTACH 147
|
||||||
#define TK_BEGIN 148
|
#define TK_BEFORE 148
|
||||||
#define TK_CASCADE 149
|
#define TK_BEGIN 149
|
||||||
#define TK_CLUSTER 150
|
#define TK_CASCADE 150
|
||||||
#define TK_CONFLICT 151
|
#define TK_CLUSTER 151
|
||||||
#define TK_COPY 152
|
#define TK_CONFLICT 152
|
||||||
#define TK_DEFERRED 153
|
#define TK_COPY 153
|
||||||
#define TK_DELIMITERS 154
|
#define TK_DEFERRED 154
|
||||||
#define TK_DETACH 155
|
#define TK_DELIMITERS 155
|
||||||
#define TK_EACH 156
|
#define TK_DETACH 156
|
||||||
#define TK_END 157
|
#define TK_EACH 157
|
||||||
#define TK_EXPLAIN 158
|
#define TK_END 158
|
||||||
#define TK_FAIL 159
|
#define TK_EXPLAIN 159
|
||||||
#define TK_FOR 160
|
#define TK_FAIL 160
|
||||||
#define TK_IGNORE 161
|
#define TK_FOR 161
|
||||||
#define TK_IMMEDIATE 162
|
#define TK_IGNORE 162
|
||||||
#define TK_INITIALLY 163
|
#define TK_IMMEDIATE 163
|
||||||
#define TK_INSTEAD 164
|
#define TK_INITIALLY 164
|
||||||
#define TK_MATCH 165
|
#define TK_INSTEAD 165
|
||||||
#define TK_KEY 166
|
#define TK_MATCH 166
|
||||||
#define TK_OF 167
|
#define TK_KEY 167
|
||||||
#define TK_RAISE 168
|
#define TK_OF 168
|
||||||
#define TK_REPLACE 169
|
#define TK_RAISE 169
|
||||||
#define TK_RESTRICT 170
|
#define TK_REPLACE 170
|
||||||
#define TK_ROW 171
|
#define TK_RESTRICT 171
|
||||||
#define TK_STATEMENT 172
|
#define TK_ROW 172
|
||||||
#define TK_TRIGGER 173
|
#define TK_STATEMENT 173
|
||||||
#define TK_VIEW 174
|
#define TK_TRIGGER 174
|
||||||
#define TK_SEMI 175
|
#define TK_VIEW 175
|
||||||
#define TK_NONE 176
|
#define TK_SEMI 176
|
||||||
#define TK_PREV 177
|
#define TK_NONE 177
|
||||||
#define TK_LINEAR 178
|
#define TK_PREV 178
|
||||||
#define TK_IMPORT 179
|
#define TK_LINEAR 179
|
||||||
#define TK_METRIC 180
|
#define TK_IMPORT 180
|
||||||
#define TK_TBNAME 181
|
#define TK_METRIC 181
|
||||||
#define TK_JOIN 182
|
#define TK_TBNAME 182
|
||||||
#define TK_METRICS 183
|
#define TK_JOIN 183
|
||||||
#define TK_INSERT 184
|
#define TK_METRICS 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
|
||||||
|
|
|
@ -72,6 +72,11 @@ typedef struct SInterval {
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
} SInterval;
|
} SInterval;
|
||||||
|
|
||||||
|
typedef struct SSessionWindow {
|
||||||
|
int64_t gap; // gap between two session window(in microseconds)
|
||||||
|
int32_t primaryColId; // primary timestamp column
|
||||||
|
} SSessionWindow;
|
||||||
|
|
||||||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision);
|
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision);
|
||||||
int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision);
|
int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision);
|
||||||
int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision);
|
int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision);
|
||||||
|
|
|
@ -185,7 +185,6 @@ typedef struct SQuery {
|
||||||
bool groupbyColumn; // denote if this is a groupby normal column query
|
bool groupbyColumn; // denote if this is a groupby normal column query
|
||||||
bool hasTagResults; // if there are tag values in final result or not
|
bool hasTagResults; // if there are tag values in final result or not
|
||||||
bool timeWindowInterpo;// if the time window start/end required interpolation
|
bool timeWindowInterpo;// if the time window start/end required interpolation
|
||||||
bool queryWindowIdentical; // all query time windows are identical for all tables in one group
|
|
||||||
bool queryBlockDist; // if query data block distribution
|
bool queryBlockDist; // if query data block distribution
|
||||||
bool stabledev; // super table stddev query
|
bool stabledev; // super table stddev query
|
||||||
int32_t interBufSize; // intermediate buffer sizse
|
int32_t interBufSize; // intermediate buffer sizse
|
||||||
|
@ -196,6 +195,7 @@ typedef struct SQuery {
|
||||||
|
|
||||||
STimeWindow window;
|
STimeWindow window;
|
||||||
SInterval interval;
|
SInterval interval;
|
||||||
|
SSessionWindow sw;
|
||||||
int16_t precision;
|
int16_t precision;
|
||||||
int16_t numOfOutput;
|
int16_t numOfOutput;
|
||||||
int16_t fillType;
|
int16_t fillType;
|
||||||
|
@ -279,10 +279,11 @@ enum OPERATOR_TYPE_E {
|
||||||
OP_Groupby = 8,
|
OP_Groupby = 8,
|
||||||
OP_Limit = 9,
|
OP_Limit = 9,
|
||||||
OP_Offset = 10,
|
OP_Offset = 10,
|
||||||
OP_TimeInterval = 11,
|
OP_TimeWindow = 11,
|
||||||
OP_Fill = 12,
|
OP_SessionWindow = 12,
|
||||||
OP_MultiTableAggregate = 13,
|
OP_Fill = 13,
|
||||||
OP_MultiTableTimeInterval = 14,
|
OP_MultiTableAggregate = 14,
|
||||||
|
OP_MultiTableTimeInterval = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SOperatorInfo {
|
typedef struct SOperatorInfo {
|
||||||
|
@ -411,6 +412,14 @@ typedef struct SGroupbyOperatorInfo {
|
||||||
char *prevData; // previous group by value
|
char *prevData; // previous group by value
|
||||||
} SGroupbyOperatorInfo;
|
} SGroupbyOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SSWindowOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
STimeWindow curWindow; // current time window
|
||||||
|
TSKEY prevTs; // previous timestamp
|
||||||
|
int32_t numOfRows; // number of rows
|
||||||
|
int32_t start; // start row index
|
||||||
|
} SSWindowOperatorInfo;
|
||||||
|
|
||||||
void freeParam(SQueryParam *param);
|
void freeParam(SQueryParam *param);
|
||||||
int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param);
|
int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param);
|
||||||
int32_t createQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, SSqlFuncMsg **pExprMsg,
|
int32_t createQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, SSqlFuncMsg **pExprMsg,
|
||||||
|
|
|
@ -58,14 +58,19 @@ typedef struct SIntervalVal {
|
||||||
SStrToken offset;
|
SStrToken offset;
|
||||||
} SIntervalVal;
|
} SIntervalVal;
|
||||||
|
|
||||||
|
typedef struct SSessionWindowVal {
|
||||||
|
SStrToken col;
|
||||||
|
SStrToken gap;
|
||||||
|
} SSessionWindowVal;
|
||||||
|
|
||||||
typedef struct SQuerySQL {
|
typedef struct SQuerySQL {
|
||||||
struct tSQLExprList *pSelection; // select clause
|
struct tSQLExprList *pSelection; // select clause
|
||||||
SArray * from; // from clause SArray<tVariantListItem>
|
SArray * from; // from clause SArray<tVariantListItem>
|
||||||
struct tSQLExpr * pWhere; // where clause [optional]
|
struct tSQLExpr * pWhere; // where clause [optional]
|
||||||
SArray * pGroupby; // groupby clause, only for tags[optional], SArray<tVariantListItem>
|
SArray * pGroupby; // groupby clause, only for tags[optional], SArray<tVariantListItem>
|
||||||
SArray * pSortOrder; // orderby [optional], SArray<tVariantListItem>
|
SArray * pSortOrder; // orderby [optional], SArray<tVariantListItem>
|
||||||
SStrToken interval; // interval [optional]
|
SIntervalVal interval; // (interval, interval_offset) [optional]
|
||||||
SStrToken offset; // offset window [optional]
|
SSessionWindowVal sessionVal; // session window [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]
|
||||||
|
@ -256,8 +261,8 @@ tSQLExprList *tSqlExprListAppend(tSQLExprList *pList, tSQLExpr *pNode, SStrToken
|
||||||
|
|
||||||
void tSqlExprListDestroy(tSQLExprList *pList);
|
void tSqlExprListDestroy(tSQLExprList *pList);
|
||||||
|
|
||||||
SQuerySQL *tSetQuerySqlElems(SStrToken *pSelectToken, tSQLExprList *pSelection, SArray *pFrom, tSQLExpr *pWhere,
|
SQuerySQL *tSetQuerySqlNode(SStrToken *pSelectToken, tSQLExprList *pSelection, SArray *pFrom, tSQLExpr *pWhere,
|
||||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *pSession,
|
||||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pGLimit);
|
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pGLimit);
|
||||||
|
|
||||||
SCreateTableSQL *tSetCreateSqlElems(SArray *pCols, SArray *pTags, SQuerySQL *pSelect, int32_t type);
|
SCreateTableSQL *tSetCreateSqlElems(SArray *pCols, SArray *pTags, SQuerySQL *pSelect, int32_t type);
|
||||||
|
|
|
@ -326,8 +326,8 @@ signed(A) ::= PLUS INTEGER(X). { A = strtol(X.z, NULL, 10); }
|
||||||
signed(A) ::= MINUS INTEGER(X). { A = -strtol(X.z, NULL, 10);}
|
signed(A) ::= MINUS INTEGER(X). { A = -strtol(X.z, NULL, 10);}
|
||||||
|
|
||||||
////////////////////////////////// The CREATE TABLE statement ///////////////////////////////
|
////////////////////////////////// The CREATE TABLE statement ///////////////////////////////
|
||||||
cmd ::= CREATE TABLE create_table_args. {}
|
cmd ::= CREATE TABLE create_table_args. {}
|
||||||
cmd ::= CREATE TABLE create_stable_args. {}
|
cmd ::= CREATE TABLE create_stable_args. {}
|
||||||
cmd ::= CREATE STABLE create_stable_args. {}
|
cmd ::= CREATE STABLE create_stable_args. {}
|
||||||
cmd ::= CREATE TABLE create_table_list(Z). { pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = Z;}
|
cmd ::= CREATE TABLE create_table_list(Z). { pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = Z;}
|
||||||
|
|
||||||
|
@ -452,8 +452,8 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). {
|
||||||
//////////////////////// The SELECT statement /////////////////////////////////
|
//////////////////////// The SELECT statement /////////////////////////////////
|
||||||
%type select {SQuerySQL*}
|
%type select {SQuerySQL*}
|
||||||
%destructor select {doDestroyQuerySql($$);}
|
%destructor select {doDestroyQuerySql($$);}
|
||||||
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) 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) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
||||||
A = tSetQuerySqlElems(&T, W, X, Y, P, Z, &K, &S, F, &L, &G);
|
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G);
|
||||||
}
|
}
|
||||||
|
|
||||||
%type union {SSubclauseInfo*}
|
%type union {SSubclauseInfo*}
|
||||||
|
@ -471,7 +471,7 @@ cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
|
||||||
// select server_version(), select client_version(),
|
// select server_version(), select client_version(),
|
||||||
// select server_state();
|
// select server_state();
|
||||||
select(A) ::= SELECT(T) selcollist(W). {
|
select(A) ::= SELECT(T) selcollist(W). {
|
||||||
A = tSetQuerySqlElems(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
A = tSetQuerySqlNode(&T, W, 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
|
||||||
|
@ -546,13 +546,21 @@ tablelist(A) ::= tablelist(Y) COMMA ids(X) cpxName(Z) ids(F). {
|
||||||
tmvar(A) ::= VARIABLE(X). {A = X;}
|
tmvar(A) ::= VARIABLE(X). {A = X;}
|
||||||
|
|
||||||
%type interval_opt {SIntervalVal}
|
%type interval_opt {SIntervalVal}
|
||||||
interval_opt(N) ::= INTERVAL LP tmvar(E) RP. {N.interval = E; N.offset.n = 0; N.offset.z = NULL; N.offset.type = 0;}
|
interval_opt(N) ::= INTERVAL LP tmvar(E) RP. {N.interval = E; N.offset.n = 0;}
|
||||||
interval_opt(N) ::= INTERVAL LP tmvar(E) COMMA tmvar(O) RP. {N.interval = E; N.offset = O;}
|
interval_opt(N) ::= INTERVAL LP tmvar(E) COMMA tmvar(X) RP. {N.interval = E; N.offset = X;}
|
||||||
interval_opt(N) ::= . {memset(&N, 0, sizeof(N));}
|
interval_opt(N) ::= . {memset(&N, 0, sizeof(N));}
|
||||||
|
|
||||||
|
%type session_option {SSessionWindowVal}
|
||||||
|
session_option(X) ::= . {X.col.n = 0; X.gap.n = 0;}
|
||||||
|
session_option(X) ::= SESSION LP ids(V) cpxName(Z) COMMA tmvar(Y) RP. {
|
||||||
|
V.n += Z.n;
|
||||||
|
X.col = V;
|
||||||
|
X.gap = Y;
|
||||||
|
}
|
||||||
|
|
||||||
%type fill_opt {SArray*}
|
%type fill_opt {SArray*}
|
||||||
%destructor fill_opt {taosArrayDestroy($$);}
|
%destructor fill_opt {taosArrayDestroy($$);}
|
||||||
fill_opt(N) ::= . {N = 0; }
|
fill_opt(N) ::= . { N = 0; }
|
||||||
fill_opt(N) ::= FILL LP ID(Y) COMMA tagitemlist(X) RP. {
|
fill_opt(N) ::= FILL LP ID(Y) COMMA tagitemlist(X) RP. {
|
||||||
tVariant A = {0};
|
tVariant A = {0};
|
||||||
toTSDBType(Y.type);
|
toTSDBType(Y.type);
|
||||||
|
|
|
@ -171,6 +171,7 @@ static SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
||||||
static SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
static SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
||||||
static SOperatorInfo* createOffsetOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
static SOperatorInfo* createOffsetOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
||||||
static SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
static SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
@ -1254,8 +1255,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
||||||
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||||
setNotInterpoWindowKey(pInfo->pCtx, pQuery->numOfOutput, RESULT_ROW_START_INTERP);
|
setNotInterpoWindowKey(pInfo->pCtx, pQuery->numOfOutput, RESULT_ROW_START_INTERP);
|
||||||
|
|
||||||
doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &w, startPos, 0, tsCols, pSDataBlock->info.rows,
|
doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &w, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput);
|
||||||
numOfOutput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore current time window
|
// restore current time window
|
||||||
|
@ -1268,8 +1268,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
||||||
|
|
||||||
// window start key interpolation
|
// window start key interpolation
|
||||||
doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &win, startPos, forwardStep);
|
doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &win, startPos, forwardStep);
|
||||||
doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &win, startPos, forwardStep, tsCols, pSDataBlock->info.rows,
|
doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &win, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput);
|
||||||
numOfOutput);
|
|
||||||
|
|
||||||
STimeWindow nextWin = win;
|
STimeWindow nextWin = win;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -1287,13 +1286,11 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
||||||
}
|
}
|
||||||
|
|
||||||
ekey = reviseWindowEkey(pQuery, &nextWin);
|
ekey = reviseWindowEkey(pQuery, &nextWin);
|
||||||
forwardStep =
|
forwardStep = getNumOfRowsInTimeWindow(pQuery, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true);
|
||||||
getNumOfRowsInTimeWindow(pQuery, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true);
|
|
||||||
|
|
||||||
// window start(end) key interpolation
|
// window start(end) key interpolation
|
||||||
doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &nextWin, startPos, forwardStep);
|
doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &nextWin, startPos, forwardStep);
|
||||||
doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &nextWin, startPos, forwardStep, tsCols,
|
doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &nextWin, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput);
|
||||||
pSDataBlock->info.rows, numOfOutput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQuery->timeWindowInterpo) {
|
if (pQuery->timeWindowInterpo) {
|
||||||
|
@ -1323,6 +1320,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare with the previous row of this column, and do not set the output buffer again if they are identical.
|
||||||
if (pInfo->prevData == NULL || (memcmp(pInfo->prevData, val, bytes) != 0)) {
|
if (pInfo->prevData == NULL || (memcmp(pInfo->prevData, val, bytes) != 0)) {
|
||||||
if (pInfo->prevData == NULL) {
|
if (pInfo->prevData == NULL) {
|
||||||
pInfo->prevData = malloc(bytes);
|
pInfo->prevData = malloc(bytes);
|
||||||
|
@ -1347,6 +1345,66 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) {
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
STableQueryInfo* item = pRuntimeEnv->pQuery->current;
|
||||||
|
|
||||||
|
// primary timestamp column
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, 0);
|
||||||
|
|
||||||
|
bool masterScan = IS_MASTER_SCAN(pRuntimeEnv);
|
||||||
|
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||||
|
|
||||||
|
int64_t gap = pOperator->pRuntimeEnv->pQuery->sw.gap;
|
||||||
|
pInfo->numOfRows = 0;
|
||||||
|
|
||||||
|
TSKEY* tsList = (TSKEY*)pColInfoData->pData;
|
||||||
|
for (int32_t j = 0; j < pSDataBlock->info.rows; ++j) {
|
||||||
|
if (pInfo->prevTs == INT64_MIN) {
|
||||||
|
pInfo->curWindow.skey = tsList[j];
|
||||||
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
|
pInfo->prevTs = tsList[j];
|
||||||
|
pInfo->numOfRows = 1;
|
||||||
|
pInfo->start = j;
|
||||||
|
} else if (tsList[j] - pInfo->prevTs <= gap) {
|
||||||
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
|
pInfo->prevTs = tsList[j];
|
||||||
|
pInfo->numOfRows += 1;
|
||||||
|
pInfo->start = j;
|
||||||
|
} else { // start a new session window
|
||||||
|
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];
|
||||||
|
pInfo->prevTs = tsList[j];
|
||||||
|
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 void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
|
static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
|
||||||
int64_t v = -1;
|
int64_t v = -1;
|
||||||
GET_TYPED_DATA(v, int64_t, type, pData);
|
GET_TYPED_DATA(v, int64_t, type, pData);
|
||||||
|
@ -1700,6 +1758,13 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
||||||
createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput);
|
createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput);
|
||||||
setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot);
|
setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot);
|
||||||
|
|
||||||
|
if (pQuery->pExpr2 != NULL) {
|
||||||
|
pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2);
|
||||||
|
}
|
||||||
|
} else if (pQuery->sw.gap > 0) {
|
||||||
|
pRuntimeEnv->proot = createSWindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput);
|
||||||
|
setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot);
|
||||||
|
|
||||||
if (pQuery->pExpr2 != NULL) {
|
if (pQuery->pExpr2 != NULL) {
|
||||||
pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2);
|
pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2);
|
||||||
}
|
}
|
||||||
|
@ -2482,7 +2547,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa
|
||||||
|
|
||||||
// Calculate all time windows that are overlapping or contain current data block.
|
// Calculate all time windows that are overlapping or contain current data block.
|
||||||
// If current data block is contained by all possible time window, do not load current data block.
|
// If current data block is contained by all possible time window, do not load current data block.
|
||||||
if (pQuery->numOfFilterCols > 0 || pQuery->groupbyColumn ||
|
if (pQuery->numOfFilterCols > 0 || pQuery->groupbyColumn || pQuery->sw.gap > 0 ||
|
||||||
(QUERY_IS_INTERVAL_QUERY(pQuery) && overlapWithTimeWindow(pQuery, &pBlock->info))) {
|
(QUERY_IS_INTERVAL_QUERY(pQuery) && overlapWithTimeWindow(pQuery, &pBlock->info))) {
|
||||||
(*status) = BLK_DATA_ALL_NEEDED;
|
(*status) = BLK_DATA_ALL_NEEDED;
|
||||||
}
|
}
|
||||||
|
@ -3039,7 +3104,7 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult
|
||||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||||
|
|
||||||
int32_t numOfOutput = pOperator->numOfOutput;
|
int32_t numOfOutput = pOperator->numOfOutput;
|
||||||
if (pQuery->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
if (pQuery->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQuery) || pQuery->sw.gap > 0) {
|
||||||
// for each group result, call the finalize function for each column
|
// for each group result, call the finalize function for each column
|
||||||
if (pQuery->groupbyColumn) {
|
if (pQuery->groupbyColumn) {
|
||||||
closeAllResultRows(pResultRowInfo);
|
closeAllResultRows(pResultRowInfo);
|
||||||
|
@ -4240,7 +4305,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf
|
||||||
pTableScanInfo->pCtx = pAggInfo->binfo.pCtx;
|
pTableScanInfo->pCtx = pAggInfo->binfo.pCtx;
|
||||||
pTableScanInfo->pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
|
pTableScanInfo->pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
|
||||||
pTableScanInfo->rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
|
pTableScanInfo->rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
|
||||||
} else if (pDownstream->operatorType == OP_TimeInterval) {
|
} else if (pDownstream->operatorType == OP_TimeWindow) {
|
||||||
STableIntervalOperatorInfo *pIntervalInfo = pDownstream->info;
|
STableIntervalOperatorInfo *pIntervalInfo = pDownstream->info;
|
||||||
|
|
||||||
pTableScanInfo->pCtx = pIntervalInfo->pCtx;
|
pTableScanInfo->pCtx = pIntervalInfo->pCtx;
|
||||||
|
@ -4264,6 +4329,12 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf
|
||||||
} else if (pDownstream->operatorType == OP_Arithmetic) {
|
} else if (pDownstream->operatorType == OP_Arithmetic) {
|
||||||
SArithOperatorInfo *pInfo = pDownstream->info;
|
SArithOperatorInfo *pInfo = pDownstream->info;
|
||||||
|
|
||||||
|
pTableScanInfo->pCtx = pInfo->binfo.pCtx;
|
||||||
|
pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo;
|
||||||
|
pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset;
|
||||||
|
} else if (pDownstream->operatorType == OP_SessionWindow) {
|
||||||
|
SSWindowOperatorInfo* 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;
|
||||||
|
@ -4619,6 +4690,62 @@ static SSDataBlock* doSTableIntervalAgg(void* param) {
|
||||||
return pIntervalInfo->pRes;
|
return pIntervalInfo->pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* doSessionWindowAgg(void* param) {
|
||||||
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSWindowOperatorInfo* pWindowInfo = pOperator->info;
|
||||||
|
SOptrBasicInfo* pBInfo = &pWindowInfo->binfo;
|
||||||
|
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||||
|
int32_t order = pQuery->order.order;
|
||||||
|
STimeWindow win = pQuery->window;
|
||||||
|
|
||||||
|
SOperatorInfo* upstream = pOperator->upstream;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
SSDataBlock* pBlock = upstream->exec(upstream);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
|
setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQuery->order.order);
|
||||||
|
doSessionWindowAggImpl(pOperator, pWindowInfo, pBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore the value
|
||||||
|
pQuery->order.order = order;
|
||||||
|
pQuery->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* hashGroupbyAggregate(void* param) {
|
static SSDataBlock* hashGroupbyAggregate(void* param) {
|
||||||
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
if (pOperator->status == OP_EXEC_DONE) {
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
@ -4908,7 +5035,7 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
||||||
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||||
|
|
||||||
pOperator->name = "TimeIntervalAggOperator";
|
pOperator->name = "TimeIntervalAggOperator";
|
||||||
pOperator->operatorType = OP_TimeInterval;
|
pOperator->operatorType = OP_TimeWindow;
|
||||||
pOperator->blockingOptr = true;
|
pOperator->blockingOptr = true;
|
||||||
pOperator->status = OP_IN_EXECUTING;
|
pOperator->status = OP_IN_EXECUTING;
|
||||||
pOperator->upstream = upstream;
|
pOperator->upstream = upstream;
|
||||||
|
@ -4922,6 +5049,31 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
||||||
return pOperator;
|
return pOperator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
|
SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
pInfo->prevTs = INT64_MIN;
|
||||||
|
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||||
|
|
||||||
|
pOperator->name = "SessionWindowAggOperator";
|
||||||
|
pOperator->operatorType = OP_SessionWindow;
|
||||||
|
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 = doSessionWindowAgg;
|
||||||
|
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
}
|
||||||
|
|
||||||
SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo));
|
STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo));
|
||||||
|
|
||||||
|
@ -4971,7 +5123,7 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato
|
||||||
}
|
}
|
||||||
|
|
||||||
SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||||
int32_t numOfOutput) {
|
int32_t numOfOutput) {
|
||||||
SFillOperatorInfo* pInfo = calloc(1, sizeof(SFillOperatorInfo));
|
SFillOperatorInfo* pInfo = calloc(1, sizeof(SFillOperatorInfo));
|
||||||
pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
|
pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
|
||||||
|
|
||||||
|
@ -5203,6 +5355,17 @@ static bool validateQueryMsg(SQueryTableMsg *pQueryMsg) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pQueryMsg->sw.gap < 0 || pQueryMsg->sw.primaryColId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
|
qError("qmsg:%p illegal value of session window time %" PRId64, pQueryMsg, pQueryMsg->sw.gap);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQueryMsg->sw.gap > 0 && pQueryMsg->interval.interval > 0) {
|
||||||
|
qError("qmsg:%p illegal value of session window time %" PRId64" and interval value %"PRId64, pQueryMsg,
|
||||||
|
pQueryMsg->sw.gap, pQueryMsg->interval.interval);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (pQueryMsg->numOfTables <= 0) {
|
if (pQueryMsg->numOfTables <= 0) {
|
||||||
qError("qmsg:%p illegal value of numOfTables %d", pQueryMsg, pQueryMsg->numOfTables);
|
qError("qmsg:%p illegal value of numOfTables %d", pQueryMsg, pQueryMsg->numOfTables);
|
||||||
return false;
|
return false;
|
||||||
|
@ -5315,6 +5478,8 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
|
||||||
pQueryMsg->secondStageOutput = htonl(pQueryMsg->secondStageOutput);
|
pQueryMsg->secondStageOutput = htonl(pQueryMsg->secondStageOutput);
|
||||||
pQueryMsg->sqlstrLen = htonl(pQueryMsg->sqlstrLen);
|
pQueryMsg->sqlstrLen = htonl(pQueryMsg->sqlstrLen);
|
||||||
pQueryMsg->prevResultLen = htonl(pQueryMsg->prevResultLen);
|
pQueryMsg->prevResultLen = htonl(pQueryMsg->prevResultLen);
|
||||||
|
pQueryMsg->sw.gap = htobe64(pQueryMsg->sw.gap);
|
||||||
|
pQueryMsg->sw.primaryColId = htonl(pQueryMsg->sw.primaryColId);
|
||||||
|
|
||||||
// query msg safety check
|
// query msg safety check
|
||||||
if (!validateQueryMsg(pQueryMsg)) {
|
if (!validateQueryMsg(pQueryMsg)) {
|
||||||
|
@ -5953,7 +6118,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr
|
||||||
pQuery->tagColList = pTagCols;
|
pQuery->tagColList = pTagCols;
|
||||||
pQuery->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit;
|
pQuery->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit;
|
||||||
pQuery->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX;
|
pQuery->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX;
|
||||||
|
pQuery->sw = pQueryMsg->sw;
|
||||||
pQuery->colList = calloc(numOfCols, sizeof(SSingleColumnFilterInfo));
|
pQuery->colList = calloc(numOfCols, sizeof(SSingleColumnFilterInfo));
|
||||||
if (pQuery->colList == NULL) {
|
if (pQuery->colList == NULL) {
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
|
@ -6023,7 +6188,6 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr
|
||||||
changeExecuteScanOrder(pQInfo, pQueryMsg, stableQuery);
|
changeExecuteScanOrder(pQInfo, pQueryMsg, stableQuery);
|
||||||
|
|
||||||
SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv;
|
SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv;
|
||||||
pQuery->queryWindowIdentical = true;
|
|
||||||
bool groupByCol = isGroupbyColumn(pQuery->pGroupbyExpr);
|
bool groupByCol = isGroupbyColumn(pQuery->pGroupbyExpr);
|
||||||
|
|
||||||
STimeWindow window = pQuery->window;
|
STimeWindow window = pQuery->window;
|
||||||
|
@ -6042,11 +6206,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr
|
||||||
|
|
||||||
for(int32_t j = 0; j < s; ++j) {
|
for(int32_t j = 0; j < s; ++j) {
|
||||||
STableKeyInfo* info = taosArrayGet(pa, j);
|
STableKeyInfo* info = taosArrayGet(pa, j);
|
||||||
|
|
||||||
window.skey = info->lastKey;
|
window.skey = info->lastKey;
|
||||||
if (info->lastKey != pQuery->window.skey) {
|
|
||||||
pQInfo->query.queryWindowIdentical = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo);
|
void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo);
|
||||||
STableQueryInfo* item = createTableQueryInfo(pQuery, info->pTable, groupByCol, window, buf);
|
STableQueryInfo* item = createTableQueryInfo(pQuery, info->pTable, groupByCol, window, buf);
|
||||||
|
|
|
@ -550,8 +550,8 @@ void tSqlSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
||||||
/*
|
/*
|
||||||
* extract the select info out of sql string
|
* extract the select info out of sql string
|
||||||
*/
|
*/
|
||||||
SQuerySQL *tSetQuerySqlElems(SStrToken *pSelectToken, tSQLExprList *pSelection, SArray *pFrom, tSQLExpr *pWhere,
|
SQuerySQL *tSetQuerySqlNode(SStrToken *pSelectToken, tSQLExprList *pSelection, SArray *pFrom, tSQLExpr *pWhere,
|
||||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *pSession,
|
||||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pGLimit) {
|
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pGLimit) {
|
||||||
assert(pSelection != NULL);
|
assert(pSelection != NULL);
|
||||||
|
|
||||||
|
@ -574,14 +574,17 @@ SQuerySQL *tSetQuerySqlElems(SStrToken *pSelectToken, tSQLExprList *pSelection,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pInterval != NULL) {
|
if (pInterval != NULL) {
|
||||||
pQuery->interval = pInterval->interval;
|
pQuery->interval = *pInterval;
|
||||||
pQuery->offset = pInterval->offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSliding != NULL) {
|
if (pSliding != NULL) {
|
||||||
pQuery->sliding = *pSliding;
|
pQuery->sliding = *pSliding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pSession != NULL) {
|
||||||
|
pQuery->sessionVal = *pSession;
|
||||||
|
}
|
||||||
|
|
||||||
pQuery->fillType = pFill;
|
pQuery->fillType = pFill;
|
||||||
return pQuery;
|
return pQuery;
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,7 @@ static SKeyword keywordTable[] = {
|
||||||
{"FROM", TK_FROM},
|
{"FROM", TK_FROM},
|
||||||
{"VARIABLE", TK_VARIABLE},
|
{"VARIABLE", TK_VARIABLE},
|
||||||
{"INTERVAL", TK_INTERVAL},
|
{"INTERVAL", TK_INTERVAL},
|
||||||
|
{"SESSION", TK_SESSION},
|
||||||
{"FILL", TK_FILL},
|
{"FILL", TK_FILL},
|
||||||
{"SLIDING", TK_SLIDING},
|
{"SLIDING", TK_SLIDING},
|
||||||
{"ORDER", TK_ORDER},
|
{"ORDER", TK_ORDER},
|
||||||
|
|
|
@ -42,12 +42,11 @@ int32_t getOutputInterResultBufSize(SQuery* pQuery) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t initResultRowInfo(SResultRowInfo *pResultRowInfo, int32_t size, int16_t type) {
|
int32_t initResultRowInfo(SResultRowInfo *pResultRowInfo, int32_t size, int16_t type) {
|
||||||
pResultRowInfo->capacity = size;
|
pResultRowInfo->type = type;
|
||||||
|
|
||||||
pResultRowInfo->type = type;
|
|
||||||
pResultRowInfo->curIndex = -1;
|
|
||||||
pResultRowInfo->size = 0;
|
pResultRowInfo->size = 0;
|
||||||
pResultRowInfo->prevSKey = TSKEY_INITIAL_VAL;
|
pResultRowInfo->prevSKey = TSKEY_INITIAL_VAL;
|
||||||
|
pResultRowInfo->curIndex = -1;
|
||||||
|
pResultRowInfo->capacity = size;
|
||||||
|
|
||||||
pResultRowInfo->pResult = calloc(pResultRowInfo->capacity, POINTER_BYTES);
|
pResultRowInfo->pResult = calloc(pResultRowInfo->capacity, POINTER_BYTES);
|
||||||
if (pResultRowInfo->pResult == NULL) {
|
if (pResultRowInfo->pResult == NULL) {
|
||||||
|
|
2234
src/query/src/sql.c
2234
src/query/src/sql.c
File diff suppressed because it is too large
Load Diff
|
@ -372,7 +372,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) {
|
||||||
|
|
||||||
// kill current query and free corresponding resources.
|
// kill current query and free corresponding resources.
|
||||||
if (pRetrieve->free == 1) {
|
if (pRetrieve->free == 1) {
|
||||||
vWarn("vgId:%d, QInfo:%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, *handle);
|
vDebug("vgId:%d, QInfo:%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, *handle);
|
||||||
qKillQuery(*handle);
|
qKillQuery(*handle);
|
||||||
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true);
|
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue