enh: support timeline functions

This commit is contained in:
dapan1121 2024-03-15 18:10:08 +08:00
parent 3f36f7ea52
commit 1c8dcaf46c
25 changed files with 1901 additions and 201 deletions

View File

@ -80,6 +80,7 @@ typedef struct SColumnNode {
uint16_t projIdx; // the idx in project list, start from 1
EColumnType colType; // column or tag
bool hasIndex;
bool isPrimTs;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
char tableAlias[TSDB_TABLE_NAME_LEN];
@ -210,6 +211,7 @@ typedef struct SViewNode {
#define JOIN_JLIMIT_MAX_VALUE 1024
#define IS_INNER_NONE_JOIN(_type, _stype) ((_type) == JOIN_TYPE_INNER && (_stype) == JOIN_STYPE_NONE)
#define IS_SEMI_JOIN(_stype) ((_stype) == JOIN_STYPE_SEMI)
#define IS_WINDOW_JOIN(_stype) ((_stype) == JOIN_STYPE_WIN)
#define IS_ASOF_JOIN(_stype) ((_stype) == JOIN_STYPE_ASOF)
@ -329,6 +331,7 @@ typedef enum EFillMode {
typedef enum ETimeLineMode {
TIME_LINE_NONE = 1,
TIME_LINE_BLOCK,
TIME_LINE_MULTI,
TIME_LINE_GLOBAL,
} ETimeLineMode;
@ -416,6 +419,7 @@ typedef struct SSelectStmt {
bool onlyHasKeepOrderFunc;
bool groupSort;
bool tagScan;
bool joinContains;
} SSelectStmt;
typedef enum ESetOperatorType { SET_OP_TYPE_UNION_ALL = 1, SET_OP_TYPE_UNION } ESetOperatorType;
@ -431,6 +435,7 @@ typedef struct SSetOperator {
char stmtName[TSDB_TABLE_NAME_LEN];
uint8_t precision;
ETimeLineMode timeLineResMode;
bool joinContains;
} SSetOperator;
typedef enum ESqlClause {

View File

@ -158,6 +158,7 @@ int32_t rewriteToVnodeModifyOpStmt(SQuery* pQuery, SArray* pBufArray);
SArray* serializeVgroupsCreateTableBatch(SHashObj* pVgroupHashmap);
SArray* serializeVgroupsDropTableBatch(SHashObj* pVgroupHashmap);
void destoryCatalogReq(SCatalogReq *pCatalogReq);
bool isPrimaryKeyImpl(SNode* pExpr);
#ifdef __cplusplus
}

View File

@ -762,6 +762,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_GRP_WINDOW_NOT_ALLOWED TAOS_DEF_ERROR_CODE(0, 0x2671)
#define TSDB_CODE_PAR_INVALID_WJOIN_HAVING_EXPR TAOS_DEF_ERROR_CODE(0, 0x2672)
#define TSDB_CODE_PAR_INVALID_WIN_OFFSET_UNIT TAOS_DEF_ERROR_CODE(0, 0x2673)
#define TSDB_CODE_PAR_VALID_PRIM_TS_REQUIRED TAOS_DEF_ERROR_CODE(0, 0x2674)
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF)
//planner

View File

@ -19,7 +19,7 @@
extern "C" {
#endif
#if 1
#if 0
#define MJOIN_DEFAULT_BLK_ROWS_NUM 2 //4096
#define MJOIN_HJOIN_CART_THRESHOLD 10
#define MJOIN_BLK_SIZE_LIMIT 0 //10485760

View File

@ -799,7 +799,7 @@ static int32_t mJoinInitPrimExprCtx(SNode* pNode, SMJoinPrimExprCtx* pCtx, SMJoi
pCtx->truncateUnit = pUnit->typeData;
if ((NULL == pCurrTz || 1 == pCurrTz->typeData) && pCtx->truncateUnit >= (86400 * TSDB_TICK_PER_SECOND(pFunc->node.resType.precision))) {
pCtx->timezoneUnit = offsetFromTz(pTimeZone->datum.p, TSDB_TICK_PER_SECOND(pFunc->node.resType.precision));
pCtx->timezoneUnit = offsetFromTz(varDataVal(pTimeZone->datum.p), TSDB_TICK_PER_SECOND(pFunc->node.resType.precision));
}
pCtx->targetSlotId = pTarget->slotId;

View File

@ -66,7 +66,7 @@ enum {
};
#define COL_DISPLAY_WIDTH 18
#define JT_MAX_LOOP 5000
#define JT_MAX_LOOP 10000
#define LEFT_BLK_ID 0
#define RIGHT_BLK_ID 1
@ -101,6 +101,7 @@ typedef struct {
bool printInputRow;
bool printResRow;
bool logHistory;
bool noKeepResRows;
} SJoinTestCtrl;
@ -181,6 +182,8 @@ typedef struct {
SArray* leftRowsList;
SArray* rightRowsList;
SArray* rightFilterOut;
int64_t startTsUs;
} SJoinTestCtx;
typedef struct {
@ -203,7 +206,7 @@ typedef struct {
SJoinTestCtx jtCtx = {0};
SJoinTestCtrl jtCtrl = {1, 1, 1, 0};
SJoinTestCtrl jtCtrl = {1, 1, 1, 0, 0};
SJoinTestStat jtStat = {0};
SJoinTestResInfo jtRes = {0};
@ -246,6 +249,7 @@ void printResRow(char* value, int32_t type) {
void pushResRow(char* buf, int32_t size) {
jtCtx.resRows++;
if (!jtCtrl.noKeepResRows) {
int32_t* rows = (int32_t*)tSimpleHashGet(jtCtx.jtResRows, buf, size);
if (rows) {
(*rows)++;
@ -253,6 +257,7 @@ void pushResRow(char* buf, int32_t size) {
int32_t n = 1;
tSimpleHashPut(jtCtx.jtResRows, buf, size, &n, sizeof(n));
}
}
}
void rmResRow() {
@ -915,6 +920,7 @@ void appendAsofLeftEachResGrps(char* leftInRow, int32_t rightOffset, int32_t rig
}
void appendLeftNonMatchGrp(char* leftInRow) {
if (!jtCtrl.noKeepResRows) {
memset(jtCtx.resColBuf, 0, jtCtx.resColSize);
for (int32_t c = 0; c < MAX_SLOT_NUM; ++c) {
if (!jtCtx.resColList[c]) {
@ -933,6 +939,7 @@ void appendLeftNonMatchGrp(char* leftInRow) {
*(char*)(jtCtx.resColBuf + MAX_SLOT_NUM + c) = true;
}
}
}
pushResRow(jtCtx.resColBuf, jtCtx.resColSize);
}
@ -1390,6 +1397,7 @@ void makeAppendBlkData(SSDataBlock** ppLeft, SSDataBlock** ppRight, int32_t left
}
void putNMatchRowToRes(char* lrow, int32_t tableOffset, int32_t peerOffset) {
if (!jtCtrl.noKeepResRows) {
memset(jtCtx.resColBuf, 0, jtCtx.resColSize);
for (int32_t c = 0; c < MAX_SLOT_NUM; ++c) {
@ -1407,11 +1415,13 @@ void putNMatchRowToRes(char* lrow, int32_t tableOffset, int32_t peerOffset) {
*(bool*)(jtCtx.resColBuf + peerOffset + c) = true;
}
}
}
pushResRow(jtCtx.resColBuf, jtCtx.resColSize);
}
void putMatchRowToRes(char* lrow, char* rrow, int32_t cols) {
if (!jtCtrl.noKeepResRows) {
memset(jtCtx.resColBuf, 0, jtCtx.resColSize);
if (cols & LEFT_TABLE_COLS) {
@ -1437,6 +1447,7 @@ void putMatchRowToRes(char* lrow, char* rrow, int32_t cols) {
}
}
}
}
pushResRow(jtCtx.resColBuf, jtCtx.resColSize);
}
@ -2636,13 +2647,14 @@ void printActualResInfo() {
}
printf("Actual Result Summary:\n\t blkNum:%d\n\t rowNum:%d%s\n\t leftBlkRead:%d\n\t rightBlkRead:%d\n\t +rows:%d%s\n\t "
"-rows:%d%s\n\t matchRows:%d%s\n",
"-rows:%d%s\n\t matchRows:%d%s\n\t executionTime:%" PRId64 "us\n",
jtRes.blkNum, jtRes.rowNum,
jtRes.rowNum == jtCtx.resRows ? "" : "*",
jtCtx.leftBlkReadIdx, jtCtx.rightBlkReadIdx,
jtRes.addRowNum, jtRes.addRowNum ? "*" : "",
jtRes.subRowNum, jtRes.subRowNum ? "*" : "",
jtRes.matchNum, jtRes.matchNum == jtCtx.resRows ? "" : "*");
jtRes.matchNum, jtRes.matchNum == jtCtx.resRows ? "" : "*",
taosGetTimestampUs() - jtCtx.startTsUs);
}
void printStatInfo(char* caseName) {
@ -2655,6 +2667,7 @@ void checkJoinDone(char* caseName) {
int32_t iter = 0;
void* p = NULL;
void* key = NULL;
if (!jtCtrl.noKeepResRows) {
while (NULL != (p = tSimpleHashIterate(jtCtx.jtResRows, p, &iter))) {
key = tSimpleHashGetKey(p, NULL);
jtRes.succeed = false;
@ -2663,6 +2676,7 @@ void checkJoinDone(char* caseName) {
printResRow((char*)key, 0);
}
}
}
printActualResInfo();
@ -2712,6 +2726,9 @@ void checkJoinRes(SSDataBlock* pBlock) {
}
jtStat.totalResRows += pBlock->info.rows;
if (jtCtrl.noKeepResRows) {
jtRes.matchNum += pBlock->info.rows;
} else {
for (int32_t r = 0; r < pBlock->info.rows; ++r) {
memset(jtCtx.resColBuf, 0, jtCtx.resColSize);
@ -2732,6 +2749,7 @@ void checkJoinRes(SSDataBlock* pBlock) {
printResRow(jtCtx.resColBuf, 2);
jtRes.matchNum++;
}
}
}
void resetForJoinRerun(int32_t dsNum, SSortMergeJoinPhysiNode* pNode, SExecTaskInfo* pTask) {
@ -2840,7 +2858,7 @@ void runSingleTest(char* caseName, SJoinTestParam* param) {
bool contLoop = true;
SSortMergeJoinPhysiNode* pNode = createDummySortMergeJoinPhysiNode(param);
createDummyBlkList(100, 10, 100, 10, 10);
createDummyBlkList(10, 10, 10, 10, 3);
while (contLoop) {
rerunBlockedHere();
@ -2848,6 +2866,7 @@ void runSingleTest(char* caseName, SJoinTestParam* param) {
printBasicInfo(caseName);
printOutputInfo();
jtCtx.startTsUs = taosGetTimestampUs();
while (true) {
SSDataBlock* pBlock = jtCtx.pJoinOp->fpSet.getNextFn(jtCtx.pJoinOp);
if (NULL == pBlock) {
@ -2872,7 +2891,7 @@ void handleCaseEnd() {
} // namespace
#if 1
#if 0
#if 1
TEST(innerJoin, noCondTest) {
SJoinTestParam param;
@ -2983,7 +3002,7 @@ TEST(innerJoin, fullCondTest) {
#endif
#if 1
#if 0
#if 1
TEST(leftOuterJoin, noCondTest) {
SJoinTestParam param;
@ -3094,7 +3113,7 @@ TEST(leftOuterJoin, fullCondTest) {
#endif
#endif
#if 1
#if 0
#if 1
TEST(fullOuterJoin, noCondTest) {
SJoinTestParam param;
@ -3205,7 +3224,7 @@ TEST(fullOuterJoin, fullCondTest) {
#endif
#endif
#if 1
#if 0
#if 1
TEST(leftSemiJoin, noCondTest) {
SJoinTestParam param;
@ -3316,7 +3335,7 @@ TEST(leftSemiJoin, fullCondTest) {
#endif
#endif
#if 1
#if 0
#if 1
TEST(leftAntiJoin, noCondTest) {
SJoinTestParam param;
@ -3427,7 +3446,7 @@ TEST(leftAntiJoin, fullCondTest) {
#endif
#endif
#if 1
#if 0
#if 1
TEST(leftAsofJoin, noCondGreaterThanTest) {
SJoinTestParam param;

View File

@ -113,6 +113,7 @@ static int32_t columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
COPY_SCALAR_FIELD(projIdx);
COPY_SCALAR_FIELD(colType);
COPY_SCALAR_FIELD(hasIndex);
COPY_SCALAR_FIELD(isPrimTs);
COPY_CHAR_ARRAY_FIELD(dbName);
COPY_CHAR_ARRAY_FIELD(tableName);
COPY_CHAR_ARRAY_FIELD(tableAlias);

View File

@ -761,6 +761,7 @@ static SNode* createPrimaryKeyCol(SAstCreateContext* pCxt, const SToken* pFuncNa
} else {
strncpy(pCol->colName, pFuncName->z, pFuncName->n);
}
pCol->isPrimTs = true;
return (SNode*)pCol;
}

View File

@ -897,14 +897,14 @@ static bool isTimeLineAlignedQuery(SNode* pStmt) {
return false;
}
static bool isPrimaryKeyImpl(SNode* pExpr) {
bool isPrimaryKeyImpl(SNode* pExpr) {
if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
return (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId);
return ((PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId) && ((SColumnNode*)pExpr)->isPrimTs);
} else if (QUERY_NODE_FUNCTION == nodeType(pExpr)) {
SFunctionNode* pFunc = (SFunctionNode*)pExpr;
if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType || FUNCTION_TYPE_GROUP_KEY == pFunc->funcType ||
FUNCTION_TYPE_FIRST == pFunc->funcType || FUNCTION_TYPE_LAST == pFunc->funcType ||
FUNCTION_TYPE_LAST_ROW == pFunc->funcType) {
FUNCTION_TYPE_LAST_ROW == pFunc->funcType || FUNCTION_TYPE_TIMETRUNCATE == pFunc->funcType) {
return isPrimaryKeyImpl(nodesListGetNode(pFunc->pParameterList, 0));
} else if (FUNCTION_TYPE_WSTART == pFunc->funcType || FUNCTION_TYPE_WEND == pFunc->funcType ||
FUNCTION_TYPE_IROWTS == pFunc->funcType) {
@ -969,7 +969,8 @@ static void setColumnInfoByExpr(STempTableNode* pTable, SExprNode* pExpr, SColum
taosArrayPush(pExpr->pAssociation, &assNode);
strcpy(pCol->tableAlias, pTable->table.tableAlias);
pCol->colId = isPrimaryKey(pTable, (SNode*)pExpr) ? PRIMARYKEY_TIMESTAMP_COL_ID : 0;
pCol->isPrimTs = isPrimaryKey(pTable, (SNode*)pExpr);
pCol->colId = pCol->isPrimTs ? PRIMARYKEY_TIMESTAMP_COL_ID : 0;
strcpy(pCol->colName, pExpr->aliasName);
if ('\0' == pCol->node.aliasName[0]) {
strcpy(pCol->node.aliasName, pCol->colName);
@ -1019,10 +1020,73 @@ static bool isInternalPrimaryKey(const SColumnNode* pCol) {
(0 == strcmp(pCol->colName, ROWTS_PSEUDO_COLUMN_NAME) || 0 == strcmp(pCol->colName, C0_PSEUDO_COLUMN_NAME));
}
static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef, const STableNode* pTable,
bool* pFound) {
static void setColumnPrimTs(STranslateContext* pCxt, SColumnNode* pCol, STableNode* pTable) {
if (PRIMARYKEY_TIMESTAMP_COL_ID != pCol->colId) {
return;
}
bool joinQuery = false;
SJoinTableNode* pJoinTable = NULL;
if (QUERY_NODE_SELECT_STMT == nodeType(pCxt->pCurrStmt) &&
NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable &&
QUERY_NODE_JOIN_TABLE == nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) {
joinQuery = true;
pJoinTable = (SJoinTableNode*)((SSelectStmt*)pCxt->pCurrStmt)->pFromTable;
}
pCol->isPrimTs = true;
if (!joinQuery) {
return;
}
switch (pJoinTable->joinType) {
case JOIN_TYPE_INNER:
pCol->isPrimTs = true;
break;
case JOIN_TYPE_LEFT:
if (!IS_SEMI_JOIN(pJoinTable->subType) && 0 != strcmp(pTable->tableAlias, ((STableNode*)pJoinTable->pLeft)->tableAlias)) {
pCol->isPrimTs = false;
}
break;
case JOIN_TYPE_RIGHT:
if (!IS_SEMI_JOIN(pJoinTable->subType) && 0 != strcmp(pTable->tableAlias, ((STableNode*)pJoinTable->pRight)->tableAlias)) {
pCol->isPrimTs = false;
}
break;
default:
pCol->isPrimTs = false;
break;
}
}
static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef, STableNode* pTable,
bool* pFound, bool keepOriginTable) {
SColumnNode* pCol = *pColRef;
*pFound = false;
bool joinQuery = false;
SJoinTableNode* pJoinTable = NULL;
if (QUERY_NODE_SELECT_STMT == nodeType(pCxt->pCurrStmt) &&
NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable &&
QUERY_NODE_JOIN_TABLE == nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) {
joinQuery = true;
pJoinTable = (SJoinTableNode*)((SSelectStmt*)pCxt->pCurrStmt)->pFromTable;
if (isInternalPrimaryKey(pCol) && (!IS_WINDOW_JOIN(pJoinTable->subType) || !keepOriginTable)) {
switch (pJoinTable->joinType) {
case JOIN_TYPE_LEFT:
pTable = (STableNode*)pJoinTable->pLeft;
break;
case JOIN_TYPE_RIGHT:
pTable = (STableNode*)pJoinTable->pRight;
break;
default:
break;
}
}
}
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
if (isInternalPrimaryKey(pCol)) {
@ -1031,6 +1095,7 @@ static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef,
}
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema, -1, pCol);
pCol->isPrimTs = true;
*pFound = true;
return TSDB_CODE_SUCCESS;
}
@ -1039,6 +1104,7 @@ static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef,
if (0 == strcmp(pCol->colName, pMeta->schema[i].name) &&
!invisibleColumn(pCxt->pParseCxt->enableSysInfo, pMeta->tableType, pMeta->schema[i].flags)) {
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i - pMeta->tableInfo.numOfColumns), pCol);
setColumnPrimTs(pCxt, pCol, pTable);
*pFound = true;
break;
}
@ -1057,6 +1123,7 @@ static int32_t findAndSetColumn(STranslateContext* pCxt, SColumnNode** pColRef,
*pFound = true;
} else if (isPrimaryKey(pTempTable, pNode) && isInternalPrimaryKey(pCol)) {
setColumnInfoByExpr(pTempTable, pExpr, pColRef);
pCol->isPrimTs = true;
*pFound = true;
}
}
@ -1073,7 +1140,7 @@ static EDealRes translateColumnWithPrefix(STranslateContext* pCxt, SColumnNode**
if (belongTable((*pCol), pTable)) {
foundTable = true;
bool foundCol = false;
pCxt->errCode = findAndSetColumn(pCxt, pCol, pTable, &foundCol);
pCxt->errCode = findAndSetColumn(pCxt, pCol, pTable, &foundCol, false);
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
return DEAL_RES_ERROR;
}
@ -1097,7 +1164,7 @@ static EDealRes translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNod
for (size_t i = 0; i < nums; ++i) {
STableNode* pTable = taosArrayGetP(pTables, i);
bool foundCol = false;
pCxt->errCode = findAndSetColumn(pCxt, pCol, pTable, &foundCol);
pCxt->errCode = findAndSetColumn(pCxt, pCol, pTable, &foundCol, false);
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
return DEAL_RES_ERROR;
}
@ -1988,6 +2055,8 @@ static int32_t translateInterpPseudoColumnFunc(STranslateContext* pCxt, SNode**
return TSDB_CODE_SUCCESS;
}
static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFunc) {
if (!fmIsTimelineFunc(pFunc->funcId)) {
return TSDB_CODE_SUCCESS;
@ -1997,12 +2066,15 @@ static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFu
"%s function must be used in select statements", pFunc->functionName);
}
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
if (NULL != pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
if ((NULL != pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
!isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery) &&
!isTimeLineAlignedQuery(pCxt->pCurrStmt)) {
!isTimeLineAlignedQuery(pCxt->pCurrStmt)) ||
(NULL != pSelect->pFromTable && QUERY_NODE_JOIN_TABLE == nodeType(pSelect->pFromTable) &&
(TIME_LINE_GLOBAL != pSelect->timeLineResMode && TIME_LINE_MULTI != pSelect->timeLineResMode))) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
"%s function requires valid time series input", pFunc->functionName);
}
return TSDB_CODE_SUCCESS;
}
@ -2826,7 +2898,7 @@ static int32_t checkExprForGroupBy(STranslateContext* pCxt, SNode** pNode) {
}
static int32_t checkExprListForGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect, SNodeList* pList) {
if (NULL == getGroupByList(pCxt) && NULL == pSelect->pWindow && (!isWindowJoinStmt(pSelect) || !pSelect->hasAggFuncs)) {
if (NULL == getGroupByList(pCxt) && NULL == pSelect->pWindow && (!isWindowJoinStmt(pSelect) || (!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc))) {
return TSDB_CODE_SUCCESS;
}
nodesRewriteExprs(pList, doCheckExprForGroupBy, pCxt);
@ -3331,19 +3403,68 @@ static int32_t addPrimJoinEqCond(SNode** pCond, SRealTableNode* leftTable, SReal
return TSDB_CODE_SUCCESS;
}
static bool getJoinContais(SNode* pNode) {
if (QUERY_NODE_REAL_TABLE == nodeType(pNode)) {
return false;
}
if (QUERY_NODE_JOIN_TABLE == nodeType(pNode)) {
return true;
}
if (QUERY_NODE_TEMP_TABLE == nodeType(pNode)) {
pNode = ((STempTableNode*)pNode)->pSubquery;
}
switch (nodeType(pNode)) {
case QUERY_NODE_REAL_TABLE:
return false;
case QUERY_NODE_JOIN_TABLE:
return true;
case QUERY_NODE_TEMP_TABLE:
pNode = ((STempTableNode*)pNode)->pSubquery;
break;
default:
break;
}
switch (nodeType(pNode)) {
case QUERY_NODE_SELECT_STMT: {
SSelectStmt* pSelect = (SSelectStmt*)pNode;
return pSelect->joinContains;
}
case QUERY_NODE_SET_OPERATOR: {
SSetOperator* pSet = (SSetOperator*)pNode;
return pSet->joinContains;
}
default:
break;
}
return false;
}
static bool getBothJoinContais(SNode* pLeft, SNode* pRight) {
bool joinContains = false;
if (NULL != pLeft) {
joinContains= getJoinContais(pLeft);
}
if (NULL != pRight && !joinContains) {
joinContains= getJoinContais(pRight);
}
return joinContains;
}
static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTable) {
if ((QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pLeft) &&
!isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pLeft)->pSubquery)) ||
(QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pRight) &&
!isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pRight)->pSubquery))) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
"Join requires valid time series input");
if (JOIN_STYPE_NONE != pJoinTable->subType && getBothJoinContais(pJoinTable->pLeft, pJoinTable->pRight)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN, "Nested join not supported now");
}
if (IS_ASOF_JOIN(pJoinTable->subType) || IS_WINDOW_JOIN(pJoinTable->subType)) {
if (QUERY_NODE_REAL_TABLE != nodeType(pJoinTable->pLeft) || QUERY_NODE_REAL_TABLE != nodeType(pJoinTable->pRight)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
"Only support ASOF/WINDOW join between tables");
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN, "Only support ASOF/WINDOW join between tables");
}
SRealTableNode* pLeft = (SRealTableNode*)pJoinTable->pLeft;
@ -3358,7 +3479,26 @@ static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTabl
"Unsupported ASOF/WINDOW join table type");
}
return addPrimJoinEqCond(&pJoinTable->addPrimCond, pLeft, pRight, pJoinTable->joinType, pJoinTable->subType);
int32_t code = addPrimJoinEqCond(&pJoinTable->addPrimCond, pLeft, pRight, pJoinTable->joinType, pJoinTable->subType);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
}
if (IS_WINDOW_JOIN(pJoinTable->subType)) {
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
if (NULL != pCurrSmt->pWindow || NULL != pCurrSmt->pPartitionByList || NULL != pCurrSmt->pGroupByList) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
"No WINDOW/GROUP BY/PARTITION BY allowed in WINDOW join");
}
}
if ((QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pLeft) &&
!isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pLeft)->pSubquery)) ||
(QUERY_NODE_TEMP_TABLE == nodeType(pJoinTable->pRight) &&
!isGlobalTimeLineQuery(((STempTableNode*)pJoinTable->pRight)->pSubquery))) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
"Join requires valid time series input");
}
return TSDB_CODE_SUCCESS;
@ -3368,6 +3508,7 @@ static int32_t translateJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoin
int32_t code = TSDB_CODE_SUCCESS;
EJoinType type = pJoinTable->joinType;
EJoinSubType* pSType = &pJoinTable->subType;
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
switch (type) {
case JOIN_TYPE_INNER:
@ -3495,6 +3636,7 @@ int32_t validateJoinConds(STranslateContext* pCxt, SJoinTableNode* pJoinTable) {
return code;
}
static int32_t translateAudit(STranslateContext* pCxt, SRealTableNode* pRealTable, SName* pName) {
if (pRealTable->pMeta->tableType == TSDB_SUPER_TABLE) {
if (IS_AUDIT_DBNAME(pName->dbname) && IS_AUDIT_STB_NAME(pName->tname)) {
@ -3508,7 +3650,170 @@ static int32_t translateAudit(STranslateContext* pCxt, SRealTableNode* pRealTabl
return 0;
}
static bool isJoinTagEqualOnCond(SNode* pCond, char* leftTableAlias, char* rightTableAlias) {
if (QUERY_NODE_OPERATOR != nodeType(pCond)) {
return false;
}
SOperatorNode* pOper = (SOperatorNode*)pCond;
if (QUERY_NODE_COLUMN != nodeType(pOper->pLeft) || NULL == pOper->pRight || QUERY_NODE_COLUMN != nodeType(pOper->pRight)) {
return false;
}
SColumnNode* pLeft = (SColumnNode*)(pOper->pLeft);
SColumnNode* pRight = (SColumnNode*)(pOper->pRight);
if ((COLUMN_TYPE_TAG != pLeft->colType) || (COLUMN_TYPE_TAG != pRight->colType)) {
return false;
}
if (OP_TYPE_EQUAL != pOper->opType) {
return false;
}
if (pLeft->node.resType.type != pRight->node.resType.type ||
pLeft->node.resType.bytes != pRight->node.resType.bytes) {
return false;
}
bool isEqual = false;
if (0 == strcmp(pLeft->tableAlias, leftTableAlias)) {
isEqual = (0 == strcmp(pRight->tableAlias, rightTableAlias));
} else if (0 == strcmp(pLeft->tableAlias, rightTableAlias)) {
isEqual = (0 == strcmp(pRight->tableAlias, leftTableAlias));
}
return isEqual;
}
static bool joinTagEqCondContains(SNode* pCond, char* leftTableAlias, char* rightTableAlias) {
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pCond)) {
SLogicConditionNode* pLogic = (SLogicConditionNode*)pCond;
if (LOGIC_COND_TYPE_AND != pLogic->condType) {
return false;
}
FOREACH(pCond, pLogic->pParameterList) {
if (isJoinTagEqualOnCond(pCond, leftTableAlias, rightTableAlias)) {
return true;
}
}
return false;
}
if (QUERY_NODE_OPERATOR == nodeType(pCond)) {
return isJoinTagEqualOnCond(pCond, leftTableAlias, rightTableAlias);
}
return false;
}
static bool innerJoinTagEqCondContains(SJoinTableNode* pJoinTable, SNode* pWhere) {
bool condContains = false;
SRealTableNode *pLeftTable = (SRealTableNode*)pJoinTable->pLeft;
SRealTableNode *pRightTable = (SRealTableNode*)pJoinTable->pRight;
if (NULL != pJoinTable->pOnCond) {
condContains = joinTagEqCondContains(pJoinTable->pOnCond, pLeftTable->table.tableAlias, pRightTable->table.tableAlias);
}
if (NULL != pWhere && !condContains) {
condContains = joinTagEqCondContains(pWhere, pLeftTable->table.tableAlias, pRightTable->table.tableAlias);
}
return condContains;
}
static bool joinNonPrimColCondContains(SJoinTableNode* pJoinTable) {
if (NULL == pJoinTable->pOnCond) {
return false;
}
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoinTable->pOnCond)) {
SLogicConditionNode* pLogic = (SLogicConditionNode*)pJoinTable->pOnCond;
if (LOGIC_COND_TYPE_AND != pLogic->condType) {
return false;
}
SNode* pNode = NULL;
FOREACH(pNode, pLogic->pParameterList) {
if (QUERY_NODE_OPERATOR != nodeType(pNode)) {
continue;
}
SOperatorNode* pOp = (SOperatorNode*)pNode;
if (OP_TYPE_EQUAL != pOp->opType) {
continue;
}
if (QUERY_NODE_COLUMN != nodeType(pOp->pLeft) || NULL == pOp->pRight || QUERY_NODE_COLUMN != nodeType(pOp->pRight)) {
continue;
}
if (isPrimaryKeyImpl(pOp->pLeft) || isPrimaryKeyImpl(pOp->pRight)) {
continue;
}
return true;
}
return false;
}
if (QUERY_NODE_OPERATOR == nodeType(pJoinTable->pOnCond)) {
SOperatorNode* pOp = (SOperatorNode*)pJoinTable->pOnCond;
if (OP_TYPE_EQUAL != pOp->opType) {
return false;
}
if (QUERY_NODE_COLUMN != nodeType(pOp->pLeft) || NULL == pOp->pRight || QUERY_NODE_COLUMN != nodeType(pOp->pRight)) {
return false;
}
if (isPrimaryKeyImpl(pOp->pLeft) || isPrimaryKeyImpl(pOp->pRight)) {
return false;
}
return true;
}
return false;
}
static int32_t setJoinTimeLineResMode(STranslateContext* pCxt) {
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
if (QUERY_NODE_JOIN_TABLE != nodeType(pCurrSmt->pFromTable)) {
return TSDB_CODE_SUCCESS;
}
SJoinTableNode* pJoinTable = (SJoinTableNode*)pCurrSmt->pFromTable;
if (JOIN_TYPE_FULL == pJoinTable->joinType) {
pCurrSmt->timeLineResMode = TIME_LINE_NONE;
return TSDB_CODE_SUCCESS;
}
if (TIME_LINE_NONE == pCurrSmt->timeLineResMode) {
return TSDB_CODE_SUCCESS;
}
if (pJoinTable->table.singleTable || pJoinTable->hasSubQuery || pJoinTable->isLowLevelJoin) {
return TSDB_CODE_SUCCESS;
}
switch (pJoinTable->subType) {
case JOIN_STYPE_NONE: {
if (innerJoinTagEqCondContains(pJoinTable, pCurrSmt->pWhere)) {
pCurrSmt->timeLineResMode = TIME_LINE_BLOCK;
}
break;
}
case JOIN_STYPE_ASOF:
case JOIN_STYPE_WIN: {
if (joinNonPrimColCondContains(pJoinTable)) {
pCurrSmt->timeLineResMode = TIME_LINE_BLOCK;
}
break;
}
default:
break;
}
return TSDB_CODE_SUCCESS;
}
int32_t translateTable(STranslateContext* pCxt, SNode** pTable, SNode* pJoinParent) {
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
int32_t code = TSDB_CODE_SUCCESS;
switch (nodeType(*pTable)) {
case QUERY_NODE_REAL_TABLE: {
@ -3561,10 +3866,12 @@ int32_t translateTable(STranslateContext* pCxt, SNode** pTable, SNode* pJoinPare
((SSelectStmt*)pCxt->pCurrStmt)->isEmptyResult = true;
}
if (QUERY_NODE_SELECT_STMT == nodeType(pTempTable->pSubquery) && isSelectStmt(pCxt->pCurrStmt)) {
pCurrSmt->joinContains = ((SSelectStmt*)pTempTable->pSubquery)->joinContains;
SSelectStmt* pSubStmt = (SSelectStmt*)pTempTable->pSubquery;
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
pCurrSmt->timeLineResMode = pSubStmt->timeLineResMode;
}
pCurrSmt->joinContains = (getJoinContais(pTempTable->pSubquery) ? true : false);
pTempTable->table.precision = getStmtPrecision(pTempTable->pSubquery);
pTempTable->table.singleTable = stmtIsSingleTable(pTempTable->pSubquery);
code = addNamespace(pCxt, pTempTable);
@ -3600,6 +3907,7 @@ int32_t translateTable(STranslateContext* pCxt, SNode** pTable, SNode* pJoinPare
}
code = validateJoinConds(pCxt, pJoinTable);
}
pCurrSmt->joinContains = true;
break;
}
default:
@ -4333,7 +4641,7 @@ static int32_t translateSessionWindow(STranslateContext* pCxt, SSelectStmt* pSel
if ('y' == pSession->pGap->unit || 'n' == pSession->pGap->unit || 0 == pSession->pGap->datum.i) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SESSION_GAP);
}
if (PRIMARYKEY_TIMESTAMP_COL_ID != pSession->pCol->colId) {
if (!isPrimaryKeyImpl((SNode*)pSession->pCol)) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SESSION_COL);
}
return TSDB_CODE_SUCCESS;
@ -4439,6 +4747,14 @@ static int32_t translateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType == TSDB_SYSTEM_TABLE) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED, "WINDOW");
}
if ((NULL != pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
!isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery) &&
!isTimeLineAlignedQuery(pCxt->pCurrStmt)) ||
(NULL != pSelect->pFromTable && QUERY_NODE_JOIN_TABLE == nodeType(pSelect->pFromTable) &&
((QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow) && TIME_LINE_GLOBAL != pSelect->timeLineResMode && TIME_LINE_MULTI != pSelect->timeLineResMode) || (QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow) && TIME_LINE_NONE == pSelect->timeLineResMode)))) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY);
}
pCxt->currClause = SQL_CLAUSE_WINDOW;
int32_t code = translateExpr(pCxt, &pSelect->pWindow);
if (TSDB_CODE_SUCCESS == code) {
@ -4919,9 +5235,9 @@ static int32_t createPrimaryKeyColByTable(STranslateContext* pCxt, STableNode* p
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
strcpy(pCol->colName, ROWTS_PSEUDO_COLUMN_NAME);
bool found = false;
int32_t code = findAndSetColumn(pCxt, &pCol, pTable, &found);
int32_t code = findAndSetColumn(pCxt, &pCol, pTable, &found, true);
if (TSDB_CODE_SUCCESS != code || !found) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TIMELINE_FUNC);
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_VALID_PRIM_TS_REQUIRED);
}
*pPrimaryKey = (SNode*)pCol;
return TSDB_CODE_SUCCESS;
@ -5077,69 +5393,6 @@ static int32_t translateSelectWithoutFrom(STranslateContext* pCxt, SSelectStmt*
return translateExprList(pCxt, pSelect->pProjectionList);
}
static int32_t translateWinJoin(STranslateContext* pCxt, SSelectStmt* pSelect) {
if (QUERY_NODE_JOIN_TABLE != nodeType(pSelect->pFromTable) || !pSelect->hasAggFuncs) {
return TSDB_CODE_SUCCESS;
}
SJoinTableNode* pJoinTable = (SJoinTableNode*)pSelect->pFromTable;
if (JOIN_STYPE_WIN != pJoinTable->subType) {
return TSDB_CODE_SUCCESS;
}
if (pSelect->pGroupByList || pSelect->pPartitionByList || pSelect->pWindow) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GRP_WINDOW_NOT_ALLOWED);
}
/*
SRealTableNode* pProbeTable = NULL;
switch (pJoinTable->joinType) {
case JOIN_TYPE_LEFT:
pProbeTable = (SRealTableNode*)pJoinTable->pLeft;
break;
case JOIN_TYPE_RIGHT:
pProbeTable = (SRealTableNode*)pJoinTable->pRight;
break;
default:
return TSDB_CODE_PAR_INTERNAL_ERROR;
}
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
if (NULL == pCol) {
return TSDB_CODE_OUT_OF_MEMORY;
}
SSchema* pColSchema = &pProbeTable->pMeta->schema[0];
strcpy(pCol->dbName, pProbeTable->table.dbName);
strcpy(pCol->tableAlias, pProbeTable->table.tableAlias);
strcpy(pCol->tableName, pProbeTable->table.tableName);
strcpy(pCol->colName, pColSchema->name);
strcpy(pCol->node.aliasName, pColSchema->name);
strcpy(pCol->node.userAlias, pColSchema->name);
pCol->tableId = pProbeTable->pMeta->uid;
pCol->tableType = pProbeTable->pMeta->tableType;
pCol->colId = pColSchema->colId;
pCol->colType = COLUMN_TYPE_COLUMN;
pCol->hasIndex = (pColSchema != NULL && IS_IDX_ON(pColSchema));
pCol->node.resType.type = pColSchema->type;
pCol->node.resType.bytes = pColSchema->bytes;
pCol->node.resType.precision = pProbeTable->pMeta->tableInfo.precision;
SGroupingSetNode* groupingSet = (SGroupingSetNode*)nodesMakeNode(QUERY_NODE_GROUPING_SET);
if (NULL == groupingSet) {
nodesDestroyNode((SNode*)pCol);
return TSDB_CODE_OUT_OF_MEMORY;
}
groupingSet->groupingSetType = GP_TYPE_NORMAL;
groupingSet->pParameterList = nodesMakeList();
nodesListAppend(groupingSet->pParameterList, (SNode*)pCol);
pSelect->pGroupByList = nodesMakeList();
nodesListAppend(pSelect->pGroupByList, (SNode*)groupingSet);
*/
return TSDB_CODE_SUCCESS;
}
static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect) {
pCxt->pCurrStmt = (SNode*)pSelect;
int32_t code = translateFrom(pCxt, &pSelect->pFromTable);
@ -5147,6 +5400,9 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
pSelect->precision = ((STableNode*)pSelect->pFromTable)->precision;
code = translateWhere(pCxt, pSelect);
}
if (TSDB_CODE_SUCCESS == code) {
code = setJoinTimeLineResMode(pCxt);
}
if (TSDB_CODE_SUCCESS == code) {
code = translatePartitionBy(pCxt, pSelect);
}
@ -5174,9 +5430,6 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
if (TSDB_CODE_SUCCESS == code) {
code = checkIsEmptyResult(pCxt, pSelect);
}
if (TSDB_CODE_SUCCESS == code) {
code = translateWinJoin(pCxt, pSelect);
}
if (TSDB_CODE_SUCCESS == code) {
resetSelectFuncNumWithoutDup(pSelect);
code = checkAggColCoexist(pCxt, pSelect);
@ -5327,6 +5580,9 @@ static int32_t translateSetOperator(STranslateContext* pCxt, SSetOperator* pSetO
if (TSDB_CODE_SUCCESS == code) {
code = translateQuery(pCxt, pSetOperator->pRight);
}
if (TSDB_CODE_SUCCESS == code) {
pSetOperator->joinContains = getBothJoinContais(pSetOperator->pLeft, pSetOperator->pRight);
}
if (TSDB_CODE_SUCCESS == code) {
pSetOperator->precision = calcSetOperatorPrecision(pSetOperator);
code = translateSetOperProject(pCxt, pSetOperator);

View File

@ -153,7 +153,7 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "Some functions are allowed only in the SELECT list of a query. "
"And, cannot be mixed with other non scalar functions or columns.";
case TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY:
return "Window query not supported, since the result of subquery not include valid timestamp column";
return "Window query not supported, since not valid primary timestamp column as input";
case TSDB_CODE_PAR_INVALID_DROP_COL:
return "No columns can be dropped";
case TSDB_CODE_PAR_INVALID_COL_JSON:
@ -198,6 +198,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "Not supported window join having expr";
case TSDB_CODE_PAR_INVALID_WIN_OFFSET_UNIT:
return "Invalid WINDOW_OFFSET unit \"%s\"";
case TSDB_CODE_PAR_VALID_PRIM_TS_REQUIRED:
return "Valid primary timestamp required";
default:
return "Unknown error";
}

View File

@ -62,6 +62,8 @@ SFunctionNode* createGroupKeyAggFunc(SColumnNode* pGroupCol);
#define CLONE_SLIMIT 1 << 1
#define CLONE_LIMIT_SLIMIT (CLONE_LIMIT | CLONE_SLIMIT)
bool cloneLimit(SLogicNode* pParent, SLogicNode* pChild, uint8_t cloneWhat);
int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool groupSort, SSortLogicNode* pSort,
bool* pNotOptimize, SNodeList** pSequencingNodes, bool* keepSort);
#ifdef __cplusplus
}

View File

@ -17,6 +17,7 @@
#include "filter.h"
#include "functionMgt.h"
#include "tglobal.h"
#include "parser.h"
typedef struct SLogicPlanContext {
SPlanContext* pPlanCxt;
@ -57,12 +58,14 @@ static void setColumnInfo(SFunctionNode* pFunc, SColumnNode* pCol, bool isPartit
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
}
pCol->colType = COLUMN_TYPE_WINDOW_START;
pCol->isPrimTs = true;
break;
case FUNCTION_TYPE_WEND:
if (!isPartitionBy) {
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
}
pCol->colType = COLUMN_TYPE_WINDOW_END;
pCol->isPrimTs = true;
break;
case FUNCTION_TYPE_WDURATION:
pCol->colType = COLUMN_TYPE_WINDOW_DURATION;
@ -551,7 +554,7 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
pJoin->pJLimit = nodesCloneNode(pJoinTable->pJLimit);
pJoin->addPrimEqCond = nodesCloneNode(pJoinTable->addPrimCond);
pJoin->node.pChildren = nodesMakeList();
pJoin->seqWinGroup = (JOIN_STYPE_WIN == pJoinTable->subType) && pSelect->hasAggFuncs;
pJoin->seqWinGroup = (JOIN_STYPE_WIN == pJoinTable->subType) && (pSelect->hasAggFuncs || pSelect->hasIndefiniteRowsFunc);
if (NULL == pJoin->node.pChildren) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
@ -1250,7 +1253,7 @@ static bool isPrimaryKeySort(SNodeList* pOrderByList) {
if (QUERY_NODE_COLUMN != nodeType(pExpr)) {
return false;
}
return PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pExpr)->colId;
return isPrimaryKeyImpl(pExpr);
}
static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {

View File

@ -19,6 +19,7 @@
#include "systable.h"
#include "tglobal.h"
#include "ttime.h"
#include "parser.h"
#define OPTIMIZE_FLAG_MASK(n) (1 << n)
@ -1634,7 +1635,7 @@ static bool sortPriKeyOptIsPriKeyOrderBy(SNodeList* pSortKeys) {
return false;
}
SNode* pNode = ((SOrderByExprNode*)nodesListGetNode(pSortKeys, 0))->pExpr;
return (QUERY_NODE_COLUMN == nodeType(pNode) ? (PRIMARYKEY_TIMESTAMP_COL_ID == ((SColumnNode*)pNode)->colId) : false);
return (QUERY_NODE_COLUMN == nodeType(pNode) ? isPrimaryKeyImpl(pNode) : false);
}
static bool sortPriKeyOptMayBeOptimized(SLogicNode* pNode) {
@ -1646,7 +1647,14 @@ static bool sortPriKeyOptMayBeOptimized(SLogicNode* pNode) {
1 != LIST_LENGTH(pSort->node.pChildren)) {
return false;
}
SNode* pChild;
SNode* pChild = nodesListGetNode(pSort->node.pChildren, 0);
if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild)) {
SJoinLogicNode* pJoin = (SJoinLogicNode*)pChild;
if (JOIN_TYPE_FULL == pJoin->joinType) {
return false;
}
}
FOREACH(pChild, pSort->node.pChildren) {
SLogicNode* pSortDescendent = optFindPossibleNode((SLogicNode*)pChild, sortPriKeyOptMayBeOptimized);
if (pSortDescendent != NULL) {
@ -1656,13 +1664,124 @@ static bool sortPriKeyOptMayBeOptimized(SLogicNode* pNode) {
return true;
}
static int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool groupSort, EOrder sortOrder,
bool* pNotOptimize, SNodeList** pSequencingNodes) {
static int32_t sortPriKeyOptHandleLeftRightJoinSort(SJoinLogicNode* pJoin, SSortLogicNode* pSort, bool* pNotOptimize, bool* keepSort) {
if (JOIN_STYPE_SEMI == pJoin->subType || JOIN_STYPE_NONE == pJoin->subType) {
return TSDB_CODE_SUCCESS;
}
SSHashObj* pLeftTables = NULL;
SSHashObj* pRightTables = NULL;
bool sortByLeft = true, sortByRight = true, sortByProbe = false;
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 0), &pLeftTables);
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 1), &pRightTables);
SOrderByExprNode* pExprNode = (SOrderByExprNode*)nodesListGetNode(pSort->pSortKeys, 0);
SColumnNode* pSortCol = (SColumnNode*)pExprNode->pExpr;
if (NULL == tSimpleHashGet(pLeftTables, pSortCol->tableAlias, strlen(pSortCol->tableAlias))) {
sortByLeft = false;
}
if (NULL == tSimpleHashGet(pRightTables, pSortCol->tableAlias, strlen(pSortCol->tableAlias))) {
sortByRight = false;
}
tSimpleHashCleanup(pLeftTables);
tSimpleHashCleanup(pRightTables);
if (!sortByLeft && !sortByRight) {
planError("sort by primary key not in any join subtable, tableAlias: %s", pSortCol->tableAlias);
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
if (sortByLeft && sortByRight) {
planError("sort by primary key in both join subtables, tableAlias: %s", pSortCol->tableAlias);
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
if ((JOIN_TYPE_LEFT == pJoin->joinType && sortByLeft) || (JOIN_TYPE_RIGHT == pJoin->joinType && sortByRight)) {
sortByProbe = true;
}
switch (pJoin->subType) {
case JOIN_STYPE_OUTER: {
if (sortByProbe) {
return TSDB_CODE_SUCCESS;
}
*pNotOptimize = true;
return TSDB_CODE_SUCCESS;
}
case JOIN_STYPE_ANTI: {
if (sortByProbe) {
return TSDB_CODE_SUCCESS;
}
*keepSort = false;
return TSDB_CODE_SUCCESS;
}
case JOIN_STYPE_ASOF:
case JOIN_STYPE_WIN: {
if (sortByProbe) {
if (NULL != pJoin->pLeftEqNodes && pJoin->pLeftEqNodes->length > 0) {
*pNotOptimize = true;
}
return TSDB_CODE_SUCCESS;
}
*pNotOptimize = true;
return TSDB_CODE_SUCCESS;
}
default:
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
return TSDB_CODE_SUCCESS;
}
static int32_t sortPriKeyOptHandleJoinSort(SLogicNode* pNode, bool groupSort, SSortLogicNode* pSort,
bool* pNotOptimize, SNodeList** pSequencingNodes, bool* keepSort) {
SJoinLogicNode* pJoin = (SJoinLogicNode*)pNode;
int32_t code = TSDB_CODE_SUCCESS;
switch (pJoin->joinType) {
case JOIN_TYPE_LEFT:
case JOIN_TYPE_RIGHT: {
code = sortPriKeyOptHandleLeftRightJoinSort(pJoin, pSort, pNotOptimize, keepSort);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
if (*pNotOptimize || !(*keepSort)) {
return TSDB_CODE_SUCCESS;
}
break;
}
default:
break;
}
code = sortPriKeyOptGetSequencingNodesImpl((SLogicNode*)nodesListGetNode(pNode->pChildren, 0), groupSort,
pSort, pNotOptimize, pSequencingNodes, keepSort);
if (TSDB_CODE_SUCCESS == code) {
code = sortPriKeyOptGetSequencingNodesImpl((SLogicNode*)nodesListGetNode(pNode->pChildren, 1), groupSort,
pSort, pNotOptimize, pSequencingNodes, keepSort);
}
return code;
}
static EOrder sortPriKeyOptGetPriKeyOrder(SSortLogicNode* pSort) {
return ((SOrderByExprNode*)nodesListGetNode(pSort->pSortKeys, 0))->order;
}
int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool groupSort, SSortLogicNode* pSort,
bool* pNotOptimize, SNodeList** pSequencingNodes, bool* keepSort) {
if (NULL != pNode->pLimit || NULL != pNode->pSlimit) {
*pNotOptimize = false;
return TSDB_CODE_SUCCESS;
}
EOrder sortOrder = sortPriKeyOptGetPriKeyOrder(pSort);
switch (nodeType(pNode)) {
case QUERY_NODE_LOGIC_PLAN_SCAN: {
SScanLogicNode* pScan = (SScanLogicNode*)pNode;
@ -1673,13 +1792,7 @@ static int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool group
return nodesListMakeAppend(pSequencingNodes, (SNode*)pNode);
}
case QUERY_NODE_LOGIC_PLAN_JOIN: {
int32_t code = sortPriKeyOptGetSequencingNodesImpl((SLogicNode*)nodesListGetNode(pNode->pChildren, 0), groupSort,
sortOrder, pNotOptimize, pSequencingNodes);
if (TSDB_CODE_SUCCESS == code) {
code = sortPriKeyOptGetSequencingNodesImpl((SLogicNode*)nodesListGetNode(pNode->pChildren, 1), groupSort,
sortOrder, pNotOptimize, pSequencingNodes);
}
return code;
return sortPriKeyOptHandleJoinSort(pNode, groupSort, pSort, pNotOptimize, pSequencingNodes, keepSort);
}
case QUERY_NODE_LOGIC_PLAN_WINDOW: {
SWindowLogicNode* pWindowLogicNode = (SWindowLogicNode*)pNode;
@ -1703,19 +1816,16 @@ static int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool group
return TSDB_CODE_SUCCESS;
}
return sortPriKeyOptGetSequencingNodesImpl((SLogicNode*)nodesListGetNode(pNode->pChildren, 0), groupSort, sortOrder,
pNotOptimize, pSequencingNodes);
return sortPriKeyOptGetSequencingNodesImpl((SLogicNode*)nodesListGetNode(pNode->pChildren, 0), groupSort, pSort,
pNotOptimize, pSequencingNodes, keepSort);
}
static EOrder sortPriKeyOptGetPriKeyOrder(SSortLogicNode* pSort) {
return ((SOrderByExprNode*)nodesListGetNode(pSort->pSortKeys, 0))->order;
}
static int32_t sortPriKeyOptGetSequencingNodes(SSortLogicNode* pSort, bool groupSort, SNodeList** pSequencingNodes) {
static int32_t sortPriKeyOptGetSequencingNodes(SSortLogicNode* pSort, bool groupSort, SNodeList** pSequencingNodes, bool* keepSort) {
bool notOptimize = false;
int32_t code =
sortPriKeyOptGetSequencingNodesImpl((SLogicNode*)nodesListGetNode(pSort->node.pChildren, 0), groupSort,
sortPriKeyOptGetPriKeyOrder(pSort), &notOptimize, pSequencingNodes);
pSort, &notOptimize, pSequencingNodes, keepSort);
if (TSDB_CODE_SUCCESS != code || notOptimize) {
NODES_CLEAR_LIST(*pSequencingNodes);
}
@ -1761,10 +1871,22 @@ static int32_t sortPriKeyOptApply(SOptimizeContext* pCxt, SLogicSubplan* pLogicS
static int32_t sortPrimaryKeyOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SSortLogicNode* pSort) {
SNodeList* pSequencingNodes = NULL;
int32_t code = sortPriKeyOptGetSequencingNodes(pSort, pSort->groupSort, &pSequencingNodes);
bool keepSort = true;
int32_t code = sortPriKeyOptGetSequencingNodes(pSort, pSort->groupSort, &pSequencingNodes, &keepSort);
if (TSDB_CODE_SUCCESS == code) {
if (pSequencingNodes != NULL) {
code = sortPriKeyOptApply(pCxt, pLogicSubplan, pSort, pSequencingNodes);
} else if (!keepSort) {
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pSort->node.pChildren, 0);
if (NULL == pSort->node.pParent) {
TSWAP(pSort->node.pTargets, pChild->pTargets);
}
int32_t code = replaceLogicNode(pLogicSubplan, (SLogicNode*)pSort, pChild);
if (TSDB_CODE_SUCCESS == code) {
NODES_CLEAR_LIST(pSort->node.pChildren);
nodesDestroyNode((SNode*)pSort);
}
pCxt->optimized = true;
} else {
// if we decided not to push down sort info to children, we should propagate output ts order to parents of pSort
optSetParentOrder(pSort->node.pParent, sortPriKeyOptGetPriKeyOrder(pSort), 0);

View File

@ -595,7 +595,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_FUNCTION_NAME, "Invalid function na
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_COMMENT_TOO_LONG, "Comment too long")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_ALLOWED_FUNC, "Some functions are allowed only in the SELECT list of a query. "
"And, cannot be mixed with other non scalar functions or columns.")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY, "Window query not supported, since the result of subquery not include valid timestamp column")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY, "Window query not supported, since not valid primary timestamp column as input")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_DROP_COL, "No columns can be dropped")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COL_JSON, "Only tag can be json type")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_VALUE_TOO_LONG, "Value too long for column/tag")
@ -626,6 +626,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_SUPPORT_MULTI_RESULT, "Operator not suppor
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_WJOIN_HAVING_EXPR, "Invalid window join having expr")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_GRP_WINDOW_NOT_ALLOWED, "GROUP BY/PARTITION BY/WINDOW-clause can't be used in WINDOW join")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_WIN_OFFSET_UNIT, "Invalid window offset unit")
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_VALID_PRIM_TS_REQUIRED, "Valid primary timestamp required")
//planner
TAOS_DEFINE_ERROR(TSDB_CODE_PLAN_INTERNAL_ERROR, "Planner internal error")

View File

@ -144,3 +144,97 @@ sql select a.ts, b.ts from tba1 a full join tba2 b on a.ts = b.ts and a.ts < '20
if $rows != 7 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data40 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data50 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data60 != @23-11-17 16:29:04.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a full join tba2 b on a.ts = b.ts and a.ts < '2023-11-17 16:29:03' and b.ts < '2023-11-17 16:29:03' order by b.ts desc;
if $rows != 7 then
return -1
endi
if $data01 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data21 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data31 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data41 != NULL then
return -1
endi
if $data51 != NULL then
return -1
endi
if $data61 != NULL then
return -1
endi
sql select b.ts, a.ts from tba1 a full join tba2 b on a.ts = b.ts and a.ts < '2023-11-17 16:29:03' and b.ts < '2023-11-17 16:29:03' order by b.ts desc, a.ts;
if $rows != 7 then
return -1
endi
if $data00 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data20 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data30 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data40 != NULL then
return -1
endi
if $data50 != NULL then
return -1
endi
if $data60 != NULL then
return -1
endi
if $data01 != NULL then
return -1
endi
if $data11 != NULL then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data31 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data41 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data51 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data61 != @23-11-17 16:29:04.000@ then
return -1
endi

View File

@ -168,5 +168,20 @@ if $data11 != @23-11-17 16:29:04.000@ then
return -1
endi
sql select a.ts, b.ts from sta a join sta b on a.ts=b.ts order by a.ts desc, b.ts;
if $rows != 12 then
return -1
endi
if $data00 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data01 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:04.000@ then
return -1
endi

View File

@ -70,6 +70,8 @@ run tsim/join/right_asof_join.sim
run tsim/join/left_win_join.sim
run tsim/join/right_win_join.sim
run tsim/join/join_scalar.sim
run tsim/join/join_timeline.sim
run tsim/join/join_nested.sim
print ================== restart server to commit data into disk
system sh/exec.sh -n dnode1 -s stop -x SIGINT
@ -89,5 +91,7 @@ run tsim/join/right_asof_join.sim
run tsim/join/left_win_join.sim
run tsim/join/right_win_join.sim
run tsim/join/join_scalar.sim
run tsim/join/join_timeline.sim
run tsim/join/join_nested.sim
system sh/exec.sh -n dnode1 -s stop -x SIGINT

View File

@ -0,0 +1,110 @@
sql connect
sql use test0;
sql select a.ts from sta a ,(select TIMETRUNCATE(ts,1d) ts from sta) b where timetruncate(a.ts, 1d) = b.ts;
if $rows != 64 then
return -1
endi
sql select a.*,b.* from (select * from sta partition by tbname) a join (select * from sta partition by tbname order by ts) b on a.ts = b.ts;
sql select a.*,b.* from (select * from sta partition by tbname order by ts) a join (select * from sta partition by tbname order by ts) b on a.ts = b.ts;
sql select sum(c1) from (select a.col1 c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1);
if $rows != 1 then
return -1
endi
if $data00 != 30 then
return -1
endi
sql select sum(c1) from (select a.col1 c1 from sta a join sta b on a.ts = b.ts);
if $rows != 1 then
return -1
endi
if $data00 != 42 then
return -1
endi
sql select diff(c1) from (select a.ts, a.col1 c1 from tba1 a join sta b on a.ts = b.ts where b.t1 > 1);
if $rows != 1 then
return -1
endi
if $data00 != 3 then
return -1
endi
sql select diff(c1) from (select b.col1 c1, a.ts from sta a join sta b on a.ts = b.ts and a.t1 = b.t1 where a.t1 > 1 order by a.ts);
if $rows != 3 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 2 then
return -1
endi
if $data20 != 2 then
return -1
endi
sql select count(c1) from (select a.ts, a.col1 c1 from tba1 a join sta b on a.ts = b.ts) interval(1s);
if $rows != 4 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 2 then
return -1
endi
if $data30 != 1 then
return -1
endi
sql select count(c1) from (select a.ts ts1, a.col1 c1 from tba1 a join sta b on a.ts = b.ts) c session(c.ts1, 1s);
if $rows != 2 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 4 then
return -1
endi
sql select count(c1) from (select b.ts, a.col1 c1 from tba1 a join sta b on a.ts = b.ts) c session(c.ts, 1s);
if $rows != 2 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 4 then
return -1
endi
sql select count(c1) from (select b.ts, a.col1 c1 from tba1 a join sta b on a.ts = b.ts partition by a.col1 order by a.ts) c session(c.ts, 1s);
if $rows != 2 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 4 then
return -1
endi
sql_error select diff(c1) from (select a.ts, a.col1 c1 from sta a join sta b on a.ts = b.ts);
sql_error select diff(c1) from (select a.col1 c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1);
sql_error select diff(c1) from (select a.col1 c1 from sta a join sta b on a.ts = b.ts);
sql_error select diff(c1) from (select a.col1 c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1 order by a.ts);
sql_error select diff(c1) from (select a.col1 c1, a.ts from sta a join sta b on a.ts = b.ts and a.t1 = b.t1 order by a.ts);
sql_error select count(c1) from (select a.col1 c1 from tba1 a join sta b on a.ts = b.ts) interval(1s);
sql_error select count(c1) from (select b.ts, a.col1 c1 from tba1 a join sta b on a.ts = b.ts partition by a.col1) c session(c.ts, 1s);

View File

@ -0,0 +1,658 @@
sql connect
sql use test0;
#inner join + join group
sql select sum(a.col1) c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1;
if $rows != 1 then
return -1
endi
if $data00 != 30 then
return -1
endi
sql_error select diff(a.col1) c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1;
sql_error select csum(b.col1) from sta a join sta b on a.ts = b.ts and a.t1 = b.t1;
sql select count(a.col1) c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1 interval(1s);
if $rows != 6 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 2 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
sql_error select count(a.col1) c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1 session(a.ts, 1s);
sql_error select count(a.col1) c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1 session(b.ts, 1s);
sql_error select count(a.col1) c1 from sta a join sta b on a.ts = b.ts and a.t1 = b.t1 state_window(b.col1);
sql_error select csum(b.col1) from sta a join sta b on a.ts = b.ts and a.t1 = b.t1 interval(1s);
#inner join + no join group
sql select sum(a.col1) c1 from sta a join sta b on a.ts = b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 42 then
return -1
endi
sql select diff(a.col1) c1 from tba1 a join tba2 b on a.ts = b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 3 then
return -1
endi
sql_error select csum(b.col1) from sta a join sta b on a.ts = b.ts;
sql select csum(b.col1) from tba1 a join tba2 b on a.ts = b.ts;
if $rows != 2 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 7 then
return -1
endi
sql select count(a.col1) c1 from sta a join sta b on a.ts = b.ts interval(1s);
if $rows != 6 then
return -1
endi
if $data00 != 4 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 4 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
sql select count(a.col1) c1 from sta a join sta b on a.ts = b.ts session(a.ts, 1s);
if $rows != 1 then
return -1
endi
if $data00 != 12 then
return -1
endi
sql select count(a.col1) c1 from sta a join sta b on a.ts = b.ts session(b.ts, 1s);
if $rows != 1 then
return -1
endi
if $data00 != 12 then
return -1
endi
sql select count(a.col1) c1 from sta a join sta b on a.ts = b.ts state_window(b.col1);
#left join
sql select sum(a.col1) c1 from sta a left join sta b on a.ts = b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 42 then
return -1
endi
sql select diff(a.col1) c1 from tba1 a left join tba2 b on a.ts = b.ts;
if $rows != 3 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
sql select diff(b.col1) c1 from tba1 a left join tba2 b on a.ts = b.ts;
if $rows != 3 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != 3 then
return -1
endi
if $data20 != NULL then
return -1
endi
sql_error select csum(b.col1) from sta a left join sta b on a.ts = b.ts;
sql select csum(b.col1) from tba1 a left join tba2 b on a.ts = b.ts;
if $rows != 2 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 7 then
return -1
endi
sql select count(a.col1) c1 from sta a left join sta b on a.ts = b.ts interval(1s);
if $rows != 6 then
return -1
endi
if $data00 != 4 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 4 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
sql select count(a.col1) c1 from sta a left join sta b on a.ts = b.ts session(a.ts, 1s);
if $rows != 1 then
return -1
endi
if $data00 != 12 then
return -1
endi
sql_error select count(a.col1) c1 from sta a left join sta b on a.ts = b.ts session(b.ts, 1s);
sql select count(a.col1) c1 from sta a left join sta b on a.ts = b.ts state_window(b.col1);
#left semi join
sql select sum(a.col1) c1 from sta a left semi join sta b on a.ts = b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 30 then
return -1
endi
sql select diff(a.col1) c1 from tba1 a left semi join tba2 b on a.ts = b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 3 then
return -1
endi
sql select diff(b.col1) c1 from tba1 a left semi join tba2 b on a.ts = b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 3 then
return -1
endi
sql_error select csum(b.col1) from sta a left semi join sta b on a.ts = b.ts;
sql select csum(b.col1) from tba1 a left semi join tba2 b on a.ts = b.ts;
if $rows != 2 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 7 then
return -1
endi
sql select count(a.col1) c1 from sta a left semi join sta b on a.ts = b.ts interval(1s);
if $rows != 6 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 2 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
sql select count(a.col1) c1 from sta a left semi join sta b on a.ts = b.ts session(a.ts, 1s);
if $rows != 1 then
return -1
endi
if $data00 != 8 then
return -1
endi
sql select count(a.col1) c1 from sta a left semi join sta b on a.ts = b.ts session(b.ts, 1s);
if $rows != 1 then
return -1
endi
if $data00 != 8 then
return -1
endi
sql select count(a.col1) c1 from sta a left semi join sta b on a.ts = b.ts state_window(b.col1);
#left anti join
sql select sum(a.col1) c1 from sta a left anti join sta b on a.ts = b.ts;
if $rows != 0 then
return -1
endi
sql select diff(a.col1) c1 from tba1 a left anti join tba2 b on a.ts = b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 2 then
return -1
endi
#???????
sql select diff(b.col1) c1 from tba1 a left anti join tba2 b on a.ts = b.ts;
sql select csum(b.col1) from sta a left anti join sta b on a.ts = b.ts;
if $rows != 0 then
return -1
endi
sql select csum(b.col1) from tba1 a left anti join tba2 b on a.ts = b.ts;
if $rows != 0 then
return -1
endi
sql select count(a.col1) c1 from sta a left anti join sta b on a.ts = b.ts interval(1s);
if $rows != 0 then
return -1
endi
sql select count(a.col1) c1 from tba1 a left anti join tba2 b on a.ts = b.ts interval(1s);
if $rows != 2 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
sql select count(a.col1) c1 from sta a left anti join sta b on a.ts = b.ts session(a.ts, 1s);
if $rows != 0 then
return -1
endi
sql select count(a.col1) c1 from tba1 a left anti join tba2 b on a.ts = b.ts session(a.ts, 1s);
if $rows != 2 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
sql_error select count(a.col1) c1 from sta a left anti join sta b on a.ts = b.ts session(b.ts, 1s);
sql select count(a.col1) c1 from sta a left semi join sta b on a.ts = b.ts state_window(b.col1);
#left asof join + join group
sql select sum(a.col1) c1 from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1;
if $rows != 1 then
return -1
endi
if $data00 != 30 then
return -1
endi
sql_error select diff(a.col1) c1 from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1;
sql_error select diff(b.col1) c1 from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1;
sql_error select csum(a.col1) from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1;
sql_error select csum(b.col1) from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1;
sql select count(a.col1) c1 from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1 interval(1s);
if $rows != 6 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 2 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
sql_error select count(a.col1) c1 from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1 session(a.ts, 1s);
sql_error select count(a.col1) c1 from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1 session(b.ts, 1s);
sql_error select count(a.col1) c1 from sta a left asof join sta b on a.ts > b.ts and a.t1 = b.t1 state_window(b.col1);
#left asof join + no join group
sql select sum(a.col1) c1 from sta a left asof join sta b on a.ts > b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 30 then
return -1
endi
sql_error select diff(a.col1) c1 from sta a left asof join sta b on a.ts > b.ts;
sql select diff(a.col1) c1 from tba1 a left asof join tba2 b on a.ts > b.ts;
if $rows != 3 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
sql select diff(b.col1) c1 from tba1 a left asof join tba2 b on a.ts > b.ts;
if $rows != 3 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != 0 then
return -1
endi
if $data20 != 2 then
return -1
endi
sql select csum(a.col1) from tba1 a left asof join tba2 b on a.ts > b.ts;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 4 then
return -1
endi
if $data20 != 8 then
return -1
endi
if $data30 != 13 then
return -1
endi
sql select csum(b.col1) from tba1 a left asof join tba2 b on a.ts > b.ts;
if $rows != 3 then
return -1
endi
if $data00 != 3 then
return -1
endi
if $data10 != 6 then
return -1
endi
if $data20 != 11 then
return -1
endi
sql select count(a.col1) c1 from tba1 a left asof join tba2 b on a.ts > b.ts interval(1s);
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 1 then
return -1
endi
sql select count(a.col1) c1 from tba1 a left asof join tba2 b on a.ts > b.ts session(a.ts, 1s);
if $rows != 2 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 3 then
return -1
endi
sql_error select count(a.col1) c1 from tba1 a left asof join tba2 b on a.ts > b.ts session(b.ts, 1s);
sql select count(a.col1) c1 from tba1 a left asof join tba2 b on a.ts > b.ts state_window(b.col1);
#left win join + join group
sql select sum(a.col1) c1 from sta a left window join sta b on a.t1 = b.t1 window_offset(-1s, 1s);
if $rows != 8 then
return -1
endi
if $data00 != 4 then
return -1
endi
if $data10 != 6 then
return -1
endi
if $data20 != 5 then
return -1
endi
if $data30 != 7 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 6 then
return -1
endi
if $data60 != 12 then
return -1
endi
if $data70 != 10 then
return -1
endi
sql_error select diff(a.col1) c1 from sta a left window join sta b on a.t1 = b.t1 window_offset(-1s, 1s);
sql_error select csum(a.col1) from sta a left window join sta b on a.t1 = b.t1 window_offset(-1s, 1s);
sql_error select count(a.col1) c1 from sta a left window join sta b on a.t1 = b.t1 window_offset(-1s, 1s) interval(1s);
sql_error select count(a.col1) c1 from sta a left window join sta b on a.t1 = b.t1 window_offset(-1s, 1s) session(a.ts, 1s);
sql_error select count(a.col1) c1 from sta a left window join sta b on a.t1 = b.t1 window_offset(-1s, 1s) session(b.ts, 1s);
sql_error select count(a.col1) c1 from sta a left window join sta b on a.t1 = b.t1 window_offset(-1s, 1s) state_window(b.col1);
#left win join + no join group
sql select sum(a.col1) c1 from sta a left window join sta b window_offset(-1s, 1s) order by c1;
if $rows != 8 then
return -1
endi
if $data00 != 3 then
return -1
endi
if $data10 != 6 then
return -1
endi
if $data20 != 12 then
return -1
endi
if $data30 != 12 then
return -1
endi
if $data40 != 14 then
return -1
endi
if $data50 != 16 then
return -1
endi
if $data60 != 20 then
return -1
endi
if $data70 != 20 then
return -1
endi
sql_error select diff(a.col1) c1 from sta a left window join sta b window_offset(-1s, 1s);
sql select diff(a.col1) c1 from tba1 a left window join tba2 b window_offset(-1s, 0s);
if $rows != 0 then
return -1
endi
sql select diff(b.col1) c1 from tba1 a left window join tba2 b window_offset(-1s, 0s);
if $rows != 0 then
return -1
endi
sql select diff(b.col1) c1 from sta a left window join tba1 b window_offset(-1s, 1s);
if $rows != 7 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 1 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
if $data60 != 1 then
return -1
endi
sql_error select csum(a.col1) from sta a left window join sta b window_offset(-1s, 1s);
sql_error select csum(a.col1) from tba1 a left window join tba2 b window_offset(-1s, 1s);
sql select csum(a.col1) from tba1 a left window join tba2 b window_offset(-1s, 0s);
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 3 then
return -1
endi
if $data20 != 4 then
return -1
endi
if $data30 != 5 then
return -1
endi
sql select csum(b.col1) from tba1 a left window join tba2 b window_offset(-1s, 1s);
if $rows != 7 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 5 then
return -1
endi
if $data20 != 3 then
return -1
endi
if $data30 != 8 then
return -1
endi
if $data40 != 5 then
return -1
endi
if $data50 != 5 then
return -1
endi
if $data60 != 12 then
return -1
endi
sql_error select count(a.col1) c1 from sta a left window join sta b window_offset(-1s, 1s) interval(1s);
sql_error select count(a.col1) c1 from sta a left window join sta b window_offset(-1s, 1s) session(a.ts, 1s);
sql_error select count(a.col1) c1 from sta a left window join sta b window_offset(-1s, 1s) session(b.ts, 1s);
sql_error select count(a.col1) c1 from sta a left window join sta b window_offset(-1s, 1s) state_window(b.col1);
#full join
sql select sum(a.col1) c1 from sta a full join sta b on a.ts = b.ts;
if $rows != 1 then
return -1
endi
if $data00 != 42 then
return -1
endi
sql_error select diff(a.col1) c1 from tba1 a full join tba2 b on a.ts = b.ts;
sql_error select diff(b.col1) c1 from tba1 a full join tba2 b on a.ts = b.ts;
sql_error select csum(b.col1) from sta a full join sta b on a.ts = b.ts;
sql_error select csum(b.col1) from tba1 a full join tba2 b on a.ts = b.ts;
sql_error select count(a.col1) c1 from sta a full join sta b on a.ts = b.ts interval(1s);
sql_error select count(a.col1) c1 from sta a full join sta b on a.ts = b.ts session(a.ts, 1s);
sql_error select count(a.col1) c1 from sta a full join sta b on a.ts = b.ts session(b.ts, 1s);
sql_error select count(a.col1) c1 from sta a full join sta b on a.ts = b.ts state_window(b.col1);

View File

@ -119,3 +119,73 @@ endi
if $data11 != NULL then
return -1
endi
if $data20 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data30 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data31 != NULL then
return -1
endi
sql select a.ts, b.ts from sta a left anti join sta b on a.ts = b.ts and b.ts < '2023-11-17 16:29:03.000' order by b.ts desc;
if $rows != 4 then
return -1
endi
if $data00 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data01 != NULL then
return -1
endi
if $data10 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data11 != NULL then
return -1
endi
if $data20 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data30 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data31 != NULL then
return -1
endi
sql select a.ts, b.ts from sta a left anti join sta b on a.ts = b.ts and b.ts < '2023-11-17 16:29:03.000' order by a.ts desc, b.ts;
if $rows != 4 then
return -1
endi
if $data00 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data01 != NULL then
return -1
endi
if $data10 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data11 != NULL then
return -1
endi
if $data20 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data30 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data31 != NULL then
return -1
endi

View File

@ -506,6 +506,69 @@ if $data31 != @23-11-17 16:29:03.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a left asof join tba2 b on a.ts > b.ts and a.col1=b.col1 jlimit 2 order by a.ts desc;
if $rows != 4 then
return -1
endi
if $data00 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data01 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data11 != NULL then
return -1
endi
if $data20 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data21 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data30 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data31 != NULL then
return -1
endi
sql select a.ts, b.ts from tba1 a left asof join tba2 b on a.ts > b.ts and a.col1=b.col1 jlimit 2 order by b.ts desc;
if $rows != 4 then
return -1
endi
if $data01 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data31 != NULL then
return -1
endi
sql select a.ts, b.ts from tba1 a left asof join tba2 b on a.ts > b.ts and a.col1=b.col1 jlimit 2 order by b.ts desc, a.ts;
if $rows != 4 then
return -1
endi
if $data00 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data20 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data30 != @23-11-17 16:29:03.000@ then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b on a.ts > b.ts and a.col1=b.col1 jlimit 2 order by a.ts
if $rows != 8 then
return -1
@ -1125,6 +1188,55 @@ if $data11 != @23-11-17 16:29:05.000@ then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b on a.ts < b.ts jlimit 2 order by b.ts desc;
if $rows != 14 then
return -1
endi
if $data01 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data21 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data31 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data41 != @23-11-17 16:29:04.000@ then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b on a.ts < b.ts jlimit 2 order by b.ts desc, a.ts;
if $rows != 14 then
return -1
endi
if $data00 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data20 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data30 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data40 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data50 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data60 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data70 != @23-11-17 16:29:02.000@ then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b on a.ts = b.ts order by a.ts desc;
if $rows != 8 then
return -1

View File

@ -204,3 +204,48 @@ if $data11 != @23-11-17 16:29:04.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a left join tba2 b on a.ts=b.ts order by b.ts desc;
if $rows != 4 then
return -1
endi
if $data01 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data31 != NULL then
return -1
endi
sql select a.ts, b.ts from tba1 a left join tba2 b on a.ts=b.ts order by b.ts desc, a.ts desc;
if $rows != 4 then
return -1
endi
if $data00 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data01 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data20 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data30 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data31 != NULL then
return -1
endi

View File

@ -108,6 +108,40 @@ if $data11 != @23-11-17 16:29:04.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a left semi join tba2 b on a.ts = b.ts order by b.ts desc;
if $rows != 2 then
return -1
endi
if $data00 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data01 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:00.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a left semi join tba2 b on a.ts = b.ts order by b.ts desc, a.ts;
if $rows != 2 then
return -1
endi
if $data00 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data01 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:00.000@ then
return -1
endi
sql_error select a.ts, b.ts from sta a left semi join sta b jlimit 3 where a.ts > b.ts;
sql_error select a.ts, b.ts from sta a left semi join sta b where a.ts > b.ts;

View File

@ -783,6 +783,51 @@ if $data21 != @23-11-17 16:29:04.000@ then
return -1
endi
sql select a.ts, b.ts from sta a left window join sta b window_offset(1s, 2s) order by b.ts desc;
if $rows != 16 then
return -1
endi
if $data01 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data21 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data31 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data41 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data51 != @23-11-17 16:29:04.000@ then
return -1
endi
sql select a.ts, b.ts from sta a left window join sta b window_offset(1s, 2s) order by b.ts;
if $rows != 16 then
return -1
endi
if $data01 != NULL then
return -1
endi
if $data11 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data21 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data31 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data41 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data51 != @23-11-17 16:29:02.000@ then
return -1
endi
sql select a.ts, b.ts from sta a left window join sta b on a.t1=b.t1 window_offset(-2s, -1s) order by a.ts desc, b.ts;
if $rows != 9 then
return -1

View File

@ -104,6 +104,105 @@ if $data61 != @23-11-17 16:29:05.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a right window join tba2 b window_offset(-1s, 1s) order by b.ts desc;
if $rows != 7 then
return -1
endi
if $data01 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data21 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data31 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data41 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data51 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data61 != @23-11-17 16:29:00.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a right window join tba2 b window_offset(-1s, 1s) order by a.ts desc;
if $rows != 7 then
return -1
endi
if $data00 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data20 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data30 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data40 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data50 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data60 != @23-11-17 16:29:00.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a right window join tba2 b window_offset(-1s, 1s) order by b.ts desc, a.ts;
if $rows != 7 then
return -1
endi
if $data00 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data01 != @23-11-17 16:29:05.000@ then
return -1
endi
if $data10 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data11 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data20 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data21 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data30 != @23-11-17 16:29:04.000@ then
return -1
endi
if $data31 != @23-11-17 16:29:03.000@ then
return -1
endi
if $data40 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data41 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data50 != @23-11-17 16:29:02.000@ then
return -1
endi
if $data51 != @23-11-17 16:29:01.000@ then
return -1
endi
if $data60 != @23-11-17 16:29:00.000@ then
return -1
endi
if $data61 != @23-11-17 16:29:00.000@ then
return -1
endi
sql select a.ts, b.ts from tba1 a right window join tba2 b window_offset(-1s, 1s) jlimit 1;
if $rows != 4 then
return -1