提交 9dabb804 编写于 作者: W wpan

support and/or in tag

上级 de0e8d88
......@@ -75,7 +75,6 @@ static int32_t getDelimiterIndex(SStrToken* pTableName);
static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd);
static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd);
static int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* len);
static void getColumnName(tSqlExprItem* pItem, char* resultFieldName, char* rawName, int32_t nameLength);
static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem,
......@@ -1690,57 +1689,6 @@ static int32_t getDelimiterIndex(SStrToken* pTableName) {
return -1;
}
int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* xlen) {
int32_t totalLen = 0;
if (account != NULL) {
int32_t len = (int32_t)strlen(account);
strcpy(fullName, account);
fullName[len] = TS_PATH_DELIMITER[0];
totalLen += (len + 1);
}
/* db name is not specified, the tableName dose not include db name */
if (pDB != NULL) {
if (pDB->n >= TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
memcpy(&fullName[totalLen], pDB->z, pDB->n);
totalLen += pDB->n;
}
if (tableName != NULL) {
if (pDB != NULL) {
fullName[totalLen] = TS_PATH_DELIMITER[0];
totalLen += 1;
/* here we only check the table name length limitation */
if (!tscValidateTableNameLength(tableName->n)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} else { // pDB == NULL, the db prefix name is specified in tableName
/* the length limitation includes tablename + dbname + sep */
if (tableName->n >= TSDB_TABLE_NAME_LEN + TSDB_DB_NAME_LEN) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
memcpy(&fullName[totalLen], tableName->z, tableName->n);
totalLen += tableName->n;
}
if (xlen != NULL) {
*xlen = totalLen;
}
if (totalLen < TSDB_TABLE_FNAME_LEN) {
fullName[totalLen] = 0;
}
return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_OPERATION;
}
void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t tableUid) {
SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, tableUid, &s);
......@@ -3713,11 +3661,7 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
}
}
if (pExpr->tokenId == TK_LE || pExpr->tokenId == TK_LT) {
retVal = tVariantDump(&pRight->value, (char*)&pColumnFilter->upperBndd, colType, false);
// TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
} else if (pExpr->tokenId == TK_IN) {
if (pExpr->tokenId == TK_IN) {
tVariant *pVal;
if (pRight->tokenId != TK_SET || !serializeExprListToVariant(pRight->Expr.paramList, &pVal, colType, timePrecision)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg);
......@@ -3743,6 +3687,10 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
size_t len = twcslen((wchar_t*)pColumnFilter->pz);
pColumnFilter->len = len * TSDB_NCHAR_SIZE;
} else if (pExpr->tokenId == TK_LE || pExpr->tokenId == TK_LT) {
retVal = tVariantDump(&pRight->value, (char*)&pColumnFilter->upperBndd, colType, false);
// TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
} else {
retVal = tVariantDump(&pRight->value, (char*)&pColumnFilter->lowerBndd, colType, false);
}
......@@ -3795,9 +3743,6 @@ typedef struct SCondExpr {
tSqlExpr* pColumnCond;
tSqlExpr* pTableCond;
int16_t relType; // relation between table name in expression and other tag
// filter condition expression, TK_AND or TK_OR
int16_t tableCondIndex;
tSqlExpr* pJoinExpr; // join condition
......@@ -3806,43 +3751,6 @@ typedef struct SCondExpr {
static int32_t getTimeRange(STimeWindow* win, tSqlExpr* pRight, int32_t optr, int16_t timePrecision);
static int32_t tablenameListToString(tSqlExpr* pExpr, SStringBuilder* sb) {
SArray* pList = pExpr->Expr.paramList;
int32_t size = (int32_t) taosArrayGetSize(pList);
if (size <= 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (size > 0) {
taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
}
for (int32_t i = 0; i < size; ++i) {
tSqlExprItem* pSub = taosArrayGet(pList, i);
tVariant* pVar = &pSub->pNode->value;
taosStringBuilderAppendStringLen(sb, pVar->pz, pVar->nLen);
if (i < size - 1) {
taosStringBuilderAppendString(sb, TBNAME_LIST_SEP);
}
if (pVar->nLen <= 0 || !tscValidateTableNameLength(pVar->nLen)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
return TSDB_CODE_SUCCESS;
}
static int32_t tablenameCondToString(tSqlExpr* pExpr, SStringBuilder* sb) {
taosStringBuilderAppendStringLen(sb, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN);
taosStringBuilderAppendString(sb, pExpr->value.pz);
return TSDB_CODE_SUCCESS;
}
enum {
TSQL_EXPR_TS = 1,
TSQL_EXPR_TAG = 2,
......@@ -3860,7 +3768,6 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
int32_t ret = 0;
const char* msg1 = "non binary column not support like operator";
const char* msg2 = "binary column not support this operator";
const char* msg3 = "bool column not support this operator";
const char* msg4 = "primary key not support this operator";
......@@ -3881,17 +3788,7 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol
pColFilter->filterstr =
((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);
if (pColFilter->filterstr) {
if (pExpr->tokenId != TK_EQ
&& pExpr->tokenId != TK_NE
&& pExpr->tokenId != TK_ISNULL
&& pExpr->tokenId != TK_NOTNULL
&& pExpr->tokenId != TK_LIKE
&& pExpr->tokenId != TK_IN) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
goto _err_ret;
}
} else {
if (!pColFilter->filterstr) {
if (pExpr->tokenId == TK_LIKE) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
goto _err_ret;
......@@ -3921,40 +3818,6 @@ _err_ret:
return ret;
}
static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pTableCond, SStringBuilder* sb) {
const char* msg0 = "invalid table name list";
const char* msg1 = "not string following like";
if (pTableCond == NULL) {
return TSDB_CODE_SUCCESS;
}
tSqlExpr* pLeft = pTableCond->pLeft;
tSqlExpr* pRight = pTableCond->pRight;
if (!isTablenameToken(&pLeft->columnName)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
int32_t ret = TSDB_CODE_SUCCESS;
if (pTableCond->tokenId == TK_IN) {
ret = tablenameListToString(pRight, sb);
} else if (pTableCond->tokenId == TK_LIKE) {
if (pRight->tokenId != TK_STRING) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
ret = tablenameCondToString(pRight, sb);
}
if (ret != TSDB_CODE_SUCCESS) {
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0);
}
return ret;
}
static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr) {
int32_t ret = TSDB_CODE_SUCCESS;
......@@ -4393,17 +4256,6 @@ static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr
return true;
}
static bool validTableNameOptr(tSqlExpr* pExpr) {
const char nameFilterOptr[] = {TK_IN, TK_LIKE};
for (int32_t i = 0; i < tListLen(nameFilterOptr); ++i) {
if (pExpr->tokenId == nameFilterOptr[i]) {
return true;
}
}
return false;
}
static int32_t setExprToCond(tSqlExpr** parent, tSqlExpr* pExpr, const char* msg, int32_t parentOptr, char* msgBuf) {
if (*parent != NULL) {
......@@ -4505,8 +4357,6 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
const char* msg2 = "illegal column name";
const char* msg4 = "too many join tables";
const char* msg5 = "not support ordinary column join";
const char* msg6 = "only one query condition on tbname allowed";
const char* msg7 = "only in/like allowed in filter table name";
tSqlExpr* pLeft = (*pExpr)->pLeft;
tSqlExpr* pRight = (*pExpr)->pRight;
......@@ -4617,54 +4467,30 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
// in case of in operator, keep it in a seprate attribute
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
if (!validTableNameOptr(*pExpr)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
}
if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
if (pRight != NULL && pRight->tokenId == TK_ID) { // join on tag columns for stable query
if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (pCondExpr->pTableCond == NULL) {
pCondExpr->pTableCond = *pExpr;
pCondExpr->relType = parentOptr;
pCondExpr->tableCondIndex = index.tableIndex;
} else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pCmd->payload);
*pExpr = NULL;
if (type) {
*type |= TSQL_EXPR_JOIN;
}
} else {
// do nothing
// ret = setExprToCond(pCmd, &pCondExpr->pTagCond,
// *pExpr, NULL, parentOptr);
tSqlExpr *rexpr = NULL;
if ((*pExpr)->tokenId == TK_NE && (pSchema->type != TSDB_DATA_TYPE_BINARY && pSchema->type != TSDB_DATA_TYPE_NCHAR && pSchema->type != TSDB_DATA_TYPE_BOOL)) {
handleNeOptr(&rexpr, *pExpr);
*pExpr = rexpr;
}
if (type) {
*type |= TSQL_EXPR_TAG;
}
*pExpr = NULL;
} else {
if (pRight != NULL && pRight->tokenId == TK_ID) { // join on tag columns for stable query
if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_QUERY;
ret = setExprToCond(&pCondExpr->pJoinExpr, *pExpr, NULL, parentOptr, pCmd->payload);
*pExpr = NULL;
if (type) {
*type |= TSQL_EXPR_JOIN;
}
} else {
// do nothing
// ret = setExprToCond(pCmd, &pCondExpr->pTagCond,
// *pExpr, NULL, parentOptr);
tSqlExpr *rexpr = NULL;
if ((*pExpr)->tokenId == TK_NE && (pSchema->type != TSDB_DATA_TYPE_BINARY && pSchema->type != TSDB_DATA_TYPE_NCHAR && pSchema->type != TSDB_DATA_TYPE_BOOL)) {
handleNeOptr(&rexpr, *pExpr);
*pExpr = rexpr;
}
if (type) {
*type |= TSQL_EXPR_TAG;
}
}
}
} else { // query on other columns
if (type) {
......@@ -4851,80 +4677,6 @@ int tableNameCompar(const void* lhs, const void* rhs) {
return ret > 0 ? 1 : -1;
}
static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, const char* account,
tSqlExpr* pExpr, int16_t tableCondIndex, SStringBuilder* sb) {
const char* msg = "table name too long";
if (pExpr == NULL) {
return TSDB_CODE_SUCCESS;
}
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableCondIndex);
STagCond* pTagCond = &pQueryInfo->tagCond;
pTagCond->tbnameCond.uid = pTableMetaInfo->pTableMeta->id.uid;
assert(pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_IN);
if (pExpr->tokenId == TK_LIKE) {
char* str = taosStringBuilderGetResult(sb, NULL);
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str);
return TSDB_CODE_SUCCESS;
}
SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
// remove the duplicated input table names
int32_t num = 0;
char* tableNameString = taosStringBuilderGetResult(sb, NULL);
char** segments = strsplit(tableNameString + QUERY_COND_REL_PREFIX_IN_LEN, TBNAME_LIST_SEP, &num);
qsort(segments, num, POINTER_BYTES, tableNameCompar);
int32_t j = 1;
for (int32_t i = 1; i < num; ++i) {
if (strcmp(segments[i], segments[i - 1]) != 0) {
segments[j++] = segments[i];
}
}
num = j;
char name[TSDB_DB_NAME_LEN] = {0};
tNameGetDbName(&pTableMetaInfo->name, name);
SStrToken dbToken = { .type = TK_STRING, .z = name, .n = (uint32_t)strlen(name) };
for (int32_t i = 0; i < num; ++i) {
if (i >= 1) {
taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
}
char idBuf[TSDB_TABLE_FNAME_LEN] = {0};
int32_t xlen = (int32_t)strlen(segments[i]);
SStrToken t = {.z = segments[i], .n = xlen, .type = TK_STRING};
int32_t ret = setObjFullName(idBuf, account, &dbToken, &t, &xlen);
if (ret != TSDB_CODE_SUCCESS) {
taosStringBuilderDestroy(&sb1);
tfree(segments);
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg);
return ret;
}
taosStringBuilderAppendString(&sb1, idBuf);
}
char* str = taosStringBuilderGetResult(&sb1, NULL);
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str);
taosStringBuilderDestroy(&sb1);
tfree(segments);
return TSDB_CODE_SUCCESS;
}
int32_t mergeTimeRange(SSqlCmd* pCmd, STimeWindow* res, STimeWindow* win, int32_t optr) {
const char* msg0 = "only one time stamp window allowed";
......@@ -5064,10 +4816,6 @@ static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr
}
static void cleanQueryExpr(SCondExpr* pCondExpr) {
if (pCondExpr->pTableCond) {
tSqlExprDestroy(pCondExpr->pTableCond);
}
if (pCondExpr->pColumnCond) {
tSqlExprDestroy(pCondExpr->pColumnCond);
}
......@@ -5363,7 +5111,7 @@ static int32_t getQueryTimeRange(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr
//multiple tables's query time range mixed together
tExprNode* p = NULL;
SFilterInfo *filter = NULL;
void *filter = NULL;
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
ret = exprTreeFromSqlExpr(pCmd, &p, *pExpr, pQueryInfo, colList, NULL);
......@@ -5405,7 +5153,6 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq
int32_t ret = TSDB_CODE_SUCCESS;
// tags query condition may be larger than 512bytes, therefore, we need to prepare enough large space
SStringBuilder sb; memset(&sb, 0, sizeof(sb));
SCondExpr condExpr = {0};
if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
......@@ -5438,12 +5185,12 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq
condExpr.pTagCond = (*pExpr);
*pExpr = NULL;
// 1. check if it is a join query
// check if it is a join query
if ((ret = validateJoinExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
goto PARSE_WHERE_EXIT;
}
// 2. get the query time range
// get the query time range
if ((ret = convertTimeRangeFromExpr(&pSql->cmd, pQueryInfo, condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
goto PARSE_WHERE_EXIT;
}
......@@ -5451,19 +5198,13 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq
if ((ret = getQueryTimeRange(&pSql->cmd, pQueryInfo, &condExpr.pTimewindow)) != TSDB_CODE_SUCCESS) {
goto PARSE_WHERE_EXIT;
}
// 3. get the tag query condition
// get the tag query condition
if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr)) != TSDB_CODE_SUCCESS) {
goto PARSE_WHERE_EXIT;
}
// 4. get the table name query condition
if ((ret = getTablenameCond(&pSql->cmd, pQueryInfo, condExpr.pTableCond, &sb)) != TSDB_CODE_SUCCESS) {
goto PARSE_WHERE_EXIT;
}
// 5. other column query condition
// other column query condition
if ((ret = checkColumnQueryCondInfo(&pSql->cmd, pQueryInfo, condExpr.pColumnCond, TK_AND)) != TSDB_CODE_SUCCESS) {
goto PARSE_WHERE_EXIT;
}
......@@ -5472,21 +5213,11 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq
goto PARSE_WHERE_EXIT;
}
// 6. join condition
// join condition
if ((ret = getJoinCondInfo(&pSql->cmd, pQueryInfo, condExpr.pJoinExpr)) != TSDB_CODE_SUCCESS) {
goto PARSE_WHERE_EXIT;
}
// 7. query condition for table name
pQueryInfo->tagCond.relType = (condExpr.relType == TK_AND) ? TSDB_RELATION_AND : TSDB_RELATION_OR;
ret = setTableCondForSTableQuery(&pSql->cmd, pQueryInfo, getAccountId(pSql), condExpr.pTableCond, condExpr.tableCondIndex, &sb);
taosStringBuilderDestroy(&sb);
if (ret) {
goto PARSE_WHERE_EXIT;
}
//if (!validateFilterExpr(pQueryInfo)) {
// ret = invalidOperationMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2);
// goto PARSE_WHERE_EXIT;
......@@ -9182,8 +8913,18 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
(*pExpr)->nodeType = TSQL_NODE_COL;
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
*(*pExpr)->pSchema = *pSchema;
SSchema* pSchema = NULL;
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
pSchema = (*pExpr)->pSchema;
strcpy(pSchema->name, TSQL_TBNAME_L);
pSchema->type = TSDB_DATA_TYPE_BINARY;
pSchema->colId = TSDB_TBNAME_COLUMN_INDEX;
pSchema->bytes = -1;
} else {
pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
*(*pExpr)->pSchema = *pSchema;
}
if (pCols != NULL) { // record the involved columns
SColIndex colIndex = {0};
......@@ -9204,9 +8945,13 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
if (colSize > 0) {
SColIndex* idx = taosArrayGet(pCols, colSize - 1);
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx->colIndex);
if (pSchema != NULL) {
colType = pSchema->type;
if (idx->colIndex == TSDB_TBNAME_COLUMN_INDEX) {
colType = TSDB_DATA_TYPE_BINARY;
} else {
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx->colIndex);
if (pSchema != NULL) {
colType = pSchema->type;
}
}
}
}
......
......@@ -702,11 +702,6 @@ static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql) {
}
}
SCond* pCond = &pQueryInfo->tagCond.tbnameCond;
if (pCond->len > 0) {
srcColListSize += pCond->len;
}
return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + srcColFilterSize + srcTagFilterSize +
exprSize + tsBufSize + tableSerialize + sqlLen + 4096 + pQueryInfo->bufLen;
}
......@@ -951,8 +946,6 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pQueryMsg->numOfOutput = htons((int16_t)query.numOfOutput); // this is the stage one output column number
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
pQueryMsg->tbnameCondLen = htonl(pQueryInfo->tagCond.tbnameCond.len);
pQueryMsg->queryType = htonl(pQueryInfo->type);
pQueryMsg->prevResultLen = htonl(pQueryInfo->bufLen);
......@@ -1067,12 +1060,6 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pMsg += pQueryInfo->bufLen;
}
SCond* pCond = &pQueryInfo->tagCond.tbnameCond;
if (pCond->len > 0) {
strncpy(pMsg, pCond->cond, pCond->len);
pMsg += pCond->len;
}
// compressed ts block
pQueryMsg->tsBuf.tsOffset = htonl((int32_t)(pMsg - pCmd->payload));
......
......@@ -811,7 +811,7 @@ typedef struct SDummyInputInfo {
SSDataBlock *block;
STableQueryInfo *pTableQueryInfo;
SSqlObj *pSql; // refactor: remove it
SFilterInfo *pFilterInfo;
void *pFilterInfo;
} SDummyInputInfo;
typedef struct SJoinStatus {
......@@ -827,7 +827,7 @@ typedef struct SJoinOperatorInfo {
SRspResultInfo resultInfo; // todo refactor, add this info for each operator
} SJoinOperatorInfo;
static void doSetupSDataBlock(SSqlRes* pRes, SSDataBlock* pBlock, SFilterInfo* pFilterInfo) {
static void doSetupSDataBlock(SSqlRes* pRes, SSDataBlock* pBlock, void* pFilterInfo) {
int32_t offset = 0;
char* pData = pRes->data;
......@@ -844,8 +844,9 @@ static void doSetupSDataBlock(SSqlRes* pRes, SSDataBlock* pBlock, SFilterInfo* p
// filter data if needed
if (pFilterInfo) {
//doSetFilterColumnInfo(pFilterInfo, numOfFilterCols, pBlock);
filterSetColFieldData(pFilterInfo, pBlock->info.numOfCols, pBlock->pDataBlock);
SColumnDataParam param = {.numOfCols = pBlock->info.numOfCols, .pDataBlock = pBlock->pDataBlock};
filterSetColFieldData(pFilterInfo, &param, getColumnDataFromId);
bool gotNchar = false;
filterConverNcharColumns(pFilterInfo, pBlock->info.rows, &gotNchar);
int8_t* p = NULL;
......@@ -1108,7 +1109,7 @@ static void destroyDummyInputOperator(void* param, int32_t numOfOutput) {
}
// todo this operator servers as the adapter for Operator tree and SqlRes result, remove it later
SOperatorInfo* createDummyInputOperator(SSqlObj* pSql, SSchema* pSchema, int32_t numOfCols, SFilterInfo* pFilters) {
SOperatorInfo* createDummyInputOperator(SSqlObj* pSql, SSchema* pSchema, int32_t numOfCols, void* pFilters) {
assert(numOfCols > 0);
STimeWindow win = {.skey = INT64_MIN, .ekey = INT64_MAX};
......@@ -1250,7 +1251,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
// if it is a join query, create join operator here
int32_t numOfCol1 = pTableMeta->tableInfo.numOfColumns;
SFilterInfo *pFilters = NULL;
void *pFilters = NULL;
STblCond *pCond = NULL;
if (px->colCond) {
pCond = tsGetTableFilter(px->colCond, pTableMeta->id.uid, 0);
......@@ -1277,7 +1278,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
for(int32_t i = 1; i < px->numOfTables; ++i) {
STableMeta* pTableMeta1 = tscGetMetaInfo(px, i)->pTableMeta;
numOfCol1 = pTableMeta1->tableInfo.numOfColumns;
SFilterInfo *pFilters1 = NULL;
void *pFilters1 = NULL;
SSchema* pSchema1 = tscGetTableSchema(pTableMeta1);
int32_t n = pTableMeta1->tableInfo.numOfColumns;
......@@ -2902,16 +2903,6 @@ bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId, int32_t
int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) {
memset(dest, 0, sizeof(STagCond));
if (src->tbnameCond.cond != NULL) {
dest->tbnameCond.cond = strdup(src->tbnameCond.cond);
if (dest->tbnameCond.cond == NULL) {
return -1;
}
}
dest->tbnameCond.uid = src->tbnameCond.uid;
dest->tbnameCond.len = src->tbnameCond.len;
dest->joinInfo.hasJoin = src->joinInfo.hasJoin;
for (int32_t i = 0; i < TSDB_MAX_JOIN_TABLE_NUM; ++i) {
......@@ -2930,9 +2921,6 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) {
}
}
dest->relType = src->relType;
if (src->pCond == NULL) {
return 0;
}
......@@ -3022,8 +3010,6 @@ void tscColCondRelease(SArray** pCond) {
void tscTagCondRelease(STagCond* pTagCond) {
free(pTagCond->tbnameCond.cond);
if (pTagCond->pCond != NULL) {
size_t s = taosArrayGetSize(pTagCond->pCond);
for (int32_t i = 0; i < s; ++i) {
......
......@@ -492,7 +492,6 @@ typedef struct {
SSessionWindow sw; // session window
uint16_t tagCondLen; // tag length in current query
uint16_t colCondLen; // column length in current query
uint32_t tbnameCondLen; // table name filter condition string length
int16_t numOfGroupCols; // num of group by columns
int16_t orderByIdx;
int16_t orderType; // used in group by xx order by xxx
......@@ -502,7 +501,6 @@ typedef struct {
int64_t offset;
uint32_t queryType; // denote another query process
int16_t numOfOutput; // final output columns numbers
int16_t tagNameRelType; // relation of tag criteria and tbname criteria
int16_t fillType; // interpolate type
uint64_t fillVal; // default value array list
int32_t secondStageOutput;
......
......@@ -351,8 +351,7 @@ SArray *tsdbRetrieveDataBlock(TsdbQueryHandleT *pQueryHandle, SArray *pColumnIdL
* @param pTagCond. tag query condition
*/
int32_t tsdbQuerySTableByTagCond(STsdbRepo *tsdb, uint64_t uid, TSKEY key, const char *pTagCond, size_t len,
int16_t tagNameRelType, const char *tbnameCond, STableGroupInfo *pGroupList,
SColIndex *pColIndex, int32_t numOfCols);
STableGroupInfo *pGroupList, SColIndex *pColIndex, int32_t numOfCols);
/**
* destroy the created table group list, which is generated by tag query
......
......@@ -257,7 +257,7 @@ typedef struct SQueryAttr {
SOrderedPrjQueryInfo prjInfo; // limit value for each vgroup, only available in global order projection query.
SSingleColumnFilterInfo* pFilterInfo;
SFilterInfo *pFilters;
void *pFilters;
void* tsdb;
SMemRef memRef;
......@@ -391,7 +391,6 @@ typedef struct SQueryParam {
char *sql;
char *tagCond;
char *colCond;
char *tbnameCond;
char *prevResult;
SArray *pTableIdList;
SSqlExpr **pExpr;
......@@ -399,7 +398,7 @@ typedef struct SQueryParam {
SExprInfo *pExprs;
SExprInfo *pSecExprs;
SFilterInfo *pFilters;
void *pFilters;
SColIndex *pGroupColIndex;
SColumnInfo *pTagColumnInfo;
......@@ -409,6 +408,11 @@ typedef struct SQueryParam {
SUdfInfo *pUdfInfo;
} SQueryParam;
typedef struct SColumnDataParam{
int32_t numOfCols;
SArray* pDataBlock;
} SColumnDataParam;
typedef struct STableScanInfo {
void *pQueryHandle;
int32_t numOfBlocks;
......@@ -632,11 +636,11 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
SSqlExpr **pExpr, SExprInfo *prevExpr, SUdfInfo *pUdfInfo);
int32_t createQueryFilter(char *data, uint16_t len, SFilterInfo** pFilters);
int32_t createQueryFilter(char *data, uint16_t len, void** pFilters);
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, SFilterInfo* pFilters, int32_t vgId, char* sql, uint64_t qId, SUdfInfo* pUdfInfo);
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, void* pFilters, int32_t vgId, char* sql, uint64_t qId, SUdfInfo* pUdfInfo);
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
int32_t prevResultLen, void* merger);
......@@ -676,5 +680,6 @@ void freeQueryAttr(SQueryAttr *pQuery);
int32_t getMaximumIdleDurationSec();
void doInvokeUdf(SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t type);
int32_t getColumnDataFromId(void *param, int32_t id, void **data);
#endif // TDENGINE_QEXECUTOR_H
......@@ -106,6 +106,7 @@ typedef struct SFilterColRange {
typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const void *, __compar_fn_t);
typedef int32_t(*filter_desc_compare_func)(const void *, const void *);
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SDataStatis *, int16_t);
typedef int32_t (*filer_get_col_from_id)(void *, int32_t, void **);
typedef struct SFilterRangeCompare {
int64_t s;
......@@ -323,14 +324,15 @@ typedef struct SFilterInfo {
#define FILTER_EMPTY_RES(i) FILTER_GET_FLAG((i)->status, FI_STATUS_EMPTY)
extern int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t options);
extern int32_t filterInitFromTree(tExprNode* tree, void **pinfo, uint32_t options);
extern bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols);
extern int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDataBlock);
extern int32_t filterSetColFieldData(SFilterInfo *info, void *param, filer_get_col_from_id fp);
extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win);
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
extern void filterFreeInfo(SFilterInfo *info);
extern bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t numOfCols, int32_t numOfRows);
extern int32_t filterIsIndexedQuery(SFilterInfo* info, int32_t idxId, bool *res);
#ifdef __cplusplus
}
......
......@@ -38,12 +38,6 @@ typedef struct SJoinInfo {
} SJoinInfo;
typedef struct STagCond {
// relation between tbname list and query condition, including : TK_AND or TK_OR
int16_t relType;
// tbname query condition, only support tbname query condition on one table
SCond tbnameCond;
// join condition, only support two tables join currently
SJoinInfo joinInfo;
......@@ -100,7 +94,7 @@ struct SQueryAttr; // query object
typedef struct STableFilter {
uint64_t uid;
SFilterInfo info;
void *info;
} STableFilter;
typedef struct SQueryInfo {
......
......@@ -3053,6 +3053,22 @@ void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFi
}
}
FORCE_INLINE int32_t getColumnDataFromId(void *param, int32_t id, void **data) {
int32_t numOfCols = ((SColumnDataParam *)param)->numOfCols;
SArray* pDataBlock = ((SColumnDataParam *)param)->pDataBlock;
for (int32_t j = 0; j < numOfCols; ++j) {
SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, j);
if (id == pColInfo->info.colId) {
*data = pColInfo->pData;
break;
}
}
return TSDB_CODE_SUCCESS;
}
int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock,
uint32_t* status) {
*status = BLK_DATA_NO_NEEDED;
......@@ -3207,7 +3223,8 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa
}
if (pQueryAttr->pFilters != NULL) {
filterSetColFieldData(pQueryAttr->pFilters, pBlock->info.numOfCols, pBlock->pDataBlock);
SColumnDataParam param = {.numOfCols = pBlock->info.numOfCols, .pDataBlock = pBlock->pDataBlock};
filterSetColFieldData(pQueryAttr->pFilters, &param, getColumnDataFromId);
}
if (pQueryAttr->pFilters != NULL || pRuntimeEnv->pTsBuf != NULL) {
......@@ -7543,7 +7560,6 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
pQueryMsg->order = htons(pQueryMsg->order);
pQueryMsg->orderColId = htons(pQueryMsg->orderColId);
pQueryMsg->queryType = htonl(pQueryMsg->queryType);
pQueryMsg->tagNameRelType = htons(pQueryMsg->tagNameRelType);
pQueryMsg->numOfCols = htons(pQueryMsg->numOfCols);
pQueryMsg->numOfOutput = htons(pQueryMsg->numOfOutput);
......@@ -7558,7 +7574,6 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
pQueryMsg->tsBuf.tsOrder = htonl(pQueryMsg->tsBuf.tsOrder);
pQueryMsg->numOfTags = htonl(pQueryMsg->numOfTags);
pQueryMsg->tbnameCondLen = htonl(pQueryMsg->tbnameCondLen);
pQueryMsg->secondStageOutput = htonl(pQueryMsg->secondStageOutput);
pQueryMsg->sqlstrLen = htonl(pQueryMsg->sqlstrLen);
pQueryMsg->prevResultLen = htonl(pQueryMsg->prevResultLen);
......@@ -7802,17 +7817,6 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
pMsg += pQueryMsg->prevResultLen;
}
if (pQueryMsg->tbnameCondLen > 0) {
param->tbnameCond = calloc(1, pQueryMsg->tbnameCondLen + 1);
if (param->tbnameCond == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _cleanup;
}
strncpy(param->tbnameCond, pMsg, pQueryMsg->tbnameCondLen);
pMsg += pQueryMsg->tbnameCondLen;
}
//skip ts buf
if ((pQueryMsg->tsBuf.tsOffset + pQueryMsg->tsBuf.tsLen) > 0) {
pMsg = (char *)pQueryMsg + pQueryMsg->tsBuf.tsOffset + pQueryMsg->tsBuf.tsLen;
......@@ -8193,7 +8197,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
return TSDB_CODE_SUCCESS;
}
int32_t createQueryFilter(char *data, uint16_t len, SFilterInfo** pFilters) {
int32_t createQueryFilter(char *data, uint16_t len, void** pFilters) {
tExprNode* expr = NULL;
TRY(TSDB_MAX_TAG_CONDITIONS) {
......@@ -8447,7 +8451,7 @@ FORCE_INLINE bool checkQIdEqual(void *qHandle, uint64_t qId) {
}
SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, SExprInfo* pExprs,
SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, SFilterInfo* pFilters, int32_t vgId,
SExprInfo* pSecExprs, STableGroupInfo* pTableGroupInfo, SColumnInfo* pTagCols, void* pFilters, int32_t vgId,
char* sql, uint64_t qId, SUdfInfo* pUdfInfo) {
int16_t numOfCols = pQueryMsg->numOfCols;
int16_t numOfOutput = pQueryMsg->numOfOutput;
......
......@@ -1474,19 +1474,6 @@ _return:
return code;
}
#if 0
int32_t filterInitUnitFunc(SFilterInfo *info) {
for (uint16_t i = 0; i < info->unitNum; ++i) {
SFilterUnit* unit = &info->units[i];
info->cunits[i].func = getComparFunc(FILTER_UNIT_DATA_TYPE(unit), unit->compare.optr);
}
return TSDB_CODE_SUCCESS;
}
#endif
void filterDumpInfoToString(SFilterInfo *info, const char *msg, int32_t options) {
if (qDebugFlag & DEBUG_DEBUG) {
CHK_LRETV(info == NULL, "%s - FilterInfo: EMPTY", msg);
......@@ -3116,7 +3103,7 @@ _return:
return TSDB_CODE_SUCCESS;
}
int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDataBlock) {
int32_t filterSetColFieldData(SFilterInfo *info, void *param, filer_get_col_from_id fp) {
CHK_LRET(info == NULL, TSDB_CODE_QRY_APP_ERROR, "info NULL");
CHK_LRET(info->fields[FLD_TYPE_COLUMN].num <= 0, TSDB_CODE_QRY_APP_ERROR, "no column fileds");
......@@ -3127,15 +3114,8 @@ int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDat
for (uint16_t i = 0; i < info->fields[FLD_TYPE_COLUMN].num; ++i) {
SFilterField* fi = &info->fields[FLD_TYPE_COLUMN].fields[i];
SSchema* sch = fi->desc;
for (int32_t j = 0; j < numOfCols; ++j) {
SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, j);
if (sch->colId == pColInfo->info.colId) {
fi->data = pColInfo->pData;
break;
}
}
(*fp)(param, sch->colId, &fi->data);
}
filterUpdateComUnits(info);
......@@ -3144,7 +3124,7 @@ int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDat
}
int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t options) {
int32_t filterInitFromTree(tExprNode* tree, void **pinfo, uint32_t options) {
int32_t code = TSDB_CODE_SUCCESS;
SFilterInfo *info = NULL;
......@@ -3181,8 +3161,6 @@ int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t option
taosArrayDestroy(group);
return code;
}
//ERR_JRET(filterInitUnitFunc(info));
}
info->unitRes = malloc(info->unitNum * sizeof(*info->unitRes));
......@@ -3425,7 +3403,28 @@ int32_t filterFreeNcharColumns(SFilterInfo* info) {
return TSDB_CODE_SUCCESS;
}
int32_t filterIsIndexedQuery(SFilterInfo* info, int32_t idxId, bool *res) {
CHK_LRET(info == NULL, TSDB_CODE_QRY_APP_ERROR, "null parameter");
CHK_JMP(info->fields[FLD_TYPE_COLUMN].num > 1 || info->fields[FLD_TYPE_COLUMN].num <= 0);
CHK_JMP(info->unitNum > 1 || info->unitNum <= 0);
CHK_JMP(FILTER_GET_COL_FIELD_ID(FILTER_GET_COL_FIELD(info, 0)) != idxId);
int32_t optr = FILTER_UNIT_OPTR(info->units);
CHK_JMP(optr == TSDB_RELATION_LIKE || optr == TSDB_RELATION_IN);
*res = true;
return TSDB_CODE_SUCCESS;
_return:
*res = false;
return TSDB_CODE_SUCCESS;
}
......@@ -53,7 +53,6 @@ static void freeqinfoFn(void *qhandle) {
void freeParam(SQueryParam *param) {
tfree(param->sql);
tfree(param->tagCond);
tfree(param->tbnameCond);
tfree(param->pTableIdList);
taosArrayDestroy(param->pOperator);
tfree(param->pExprs);
......@@ -140,7 +139,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
qDebug("qmsg:%p query stable, uid:%"PRIu64", tid:%d", pQueryMsg, id->uid, id->tid);
code = tsdbQuerySTableByTagCond(tsdb, id->uid, pQueryMsg->window.skey, param.tagCond, pQueryMsg->tagCondLen,
pQueryMsg->tagNameRelType, param.tbnameCond, &tableGroupInfo, param.pGroupColIndex, numOfGroupByCols);
&tableGroupInfo, param.pGroupColIndex, numOfGroupByCols);
if (code != TSDB_CODE_SUCCESS) {
qError("qmsg:%p failed to query stable, reason: %s", pQueryMsg, tstrerror(code));
......
......@@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8...3.20)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
AUX_SOURCE_DIRECTORY(src SRC)
ADD_LIBRARY(tsdb ${SRC})
TARGET_LINK_LIBRARIES(tsdb tfs common tutil)
......
......@@ -25,6 +25,7 @@
#include "tlosertree.h"
#include "tsdbint.h"
#include "texpr.h"
#include "qfilter.h"
#define EXTRA_BYTES 2
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
......@@ -167,6 +168,7 @@ static int32_t doGetExternalRow(STsdbQueryHandle* pQueryHandle, int16_t type, SM
static void* doFreeColumnInfoData(SArray* pColumnInfoData);
static void* destroyTableCheckInfo(SArray* pTableCheckInfo);
static bool tsdbGetExternalRow(TsdbQueryHandleT pHandle);
static int32_t tsdbQueryTableList(STable* pTable, SArray* pRes, void* filterInfo);
static void tsdbInitDataBlockLoadInfo(SDataBlockLoadInfo* pBlockLoadInfo) {
pBlockLoadInfo->slot = -1;
......@@ -2690,21 +2692,6 @@ static int32_t getAllTableList(STable* pSuperTable, SArray* list) {
return TSDB_CODE_SUCCESS;
}
static void destroyHelper(void* param) {
if (param == NULL) {
return;
}
tQueryInfo* pInfo = (tQueryInfo*)param;
if (pInfo->optr != TSDB_RELATION_IN) {
tfree(pInfo->q);
} else {
taosHashCleanup((SHashObj *)(pInfo->q));
}
free(param);
}
static bool loadBlockOfActiveTable(STsdbQueryHandle* pQueryHandle) {
if (pQueryHandle->checkFiles) {
// check if the query range overlaps with the file data block
......@@ -3641,103 +3628,8 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC
return pTableGroup;
}
static bool tableFilterFp(const void* pNode, void* param) {
tQueryInfo* pInfo = (tQueryInfo*) param;
STable* pTable = (STable*)(SL_GET_NODE_DATA((SSkipListNode*)pNode));
char* val = NULL;
if (pInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
val = (char*) TABLE_NAME(pTable);
} else {
val = tdGetKVRowValOfCol(pTable->tagVal, pInfo->sch.colId);
}
if (pInfo->optr == TSDB_RELATION_ISNULL || pInfo->optr == TSDB_RELATION_NOTNULL) {
if (pInfo->optr == TSDB_RELATION_ISNULL) {
return (val == NULL) || isNull(val, pInfo->sch.type);
} else if (pInfo->optr == TSDB_RELATION_NOTNULL) {
return (val != NULL) && (!isNull(val, pInfo->sch.type));
}
} else if (pInfo->optr == TSDB_RELATION_IN) {
int type = pInfo->sch.type;
if (type == TSDB_DATA_TYPE_BOOL || IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_TIMESTAMP) {
int64_t v;
GET_TYPED_DATA(v, int64_t, pInfo->sch.type, val);
return NULL != taosHashGet((SHashObj *)pInfo->q, (char *)&v, sizeof(v));
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
uint64_t v;
GET_TYPED_DATA(v, uint64_t, pInfo->sch.type, val);
return NULL != taosHashGet((SHashObj *)pInfo->q, (char *)&v, sizeof(v));
}
else if (type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_FLOAT) {
double v;
GET_TYPED_DATA(v, double, pInfo->sch.type, val);
return NULL != taosHashGet((SHashObj *)pInfo->q, (char *)&v, sizeof(v));
} else if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR){
return NULL != taosHashGet((SHashObj *)pInfo->q, varDataVal(val), varDataLen(val));
}
}
int32_t ret = 0;
if (val == NULL) { //the val is possible to be null, so check it out carefully
ret = -1; // val is missing in table tags value pairs
} else {
ret = pInfo->compare(val, pInfo->q);
}
switch (pInfo->optr) {
case TSDB_RELATION_EQUAL: {
return ret == 0;
}
case TSDB_RELATION_NOT_EQUAL: {
return ret != 0;
}
case TSDB_RELATION_GREATER_EQUAL: {
return ret >= 0;
}
case TSDB_RELATION_GREATER: {
return ret > 0;
}
case TSDB_RELATION_LESS_EQUAL: {
return ret <= 0;
}
case TSDB_RELATION_LESS: {
return ret < 0;
}
case TSDB_RELATION_LIKE: {
return ret == 0;
}
case TSDB_RELATION_IN: {
return ret == 1;
}
default:
assert(false);
}
return true;
}
static void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SExprTraverseSupp *param);
static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr) {
// query according to the expression tree
SExprTraverseSupp supp = {
.nodeFilterFn = (__result_filter_fn_t) tableFilterFp,
.setupInfoFn = filterPrepare,
.pExtInfo = pSTable->tagSchema,
};
getTableListfromSkipList(pExpr, pSTable->pIndex, pRes, &supp);
tExprTreeDestroy(pExpr, destroyHelper);
return TSDB_CODE_SUCCESS;
}
int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, const char* pTagCond, size_t len,
int16_t tagNameRelType, const char* tbnameCond, STableGroupInfo* pGroupInfo,
SColIndex* pColIndex, int32_t numOfCols) {
int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, const char* pTagCond, size_t len,
STableGroupInfo* pGroupInfo, SColIndex* pColIndex, int32_t numOfCols) {
if (tsdbRLockRepoMeta(tsdb) < 0) goto _error;
STable* pTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid);
......@@ -3763,7 +3655,7 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons
STSchema* pTagSchema = tsdbGetTableTagSchema(pTable);
// no tags and tbname condition, all child tables of this stable are involved
if (tbnameCond == NULL && (pTagCond == NULL || len == 0)) {
if (pTagCond == NULL || len == 0) {
int32_t ret = getAllTableList(pTable, res);
if (ret != TSDB_CODE_SUCCESS) {
tsdbUnlockRepoMeta(tsdb);
......@@ -3785,25 +3677,7 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons
tExprNode* expr = NULL;
TRY(TSDB_MAX_TAG_CONDITIONS) {
expr = exprTreeFromTableName(tbnameCond);
if (expr == NULL) {
expr = exprTreeFromBinary(pTagCond, len);
} else {
CLEANUP_PUSH_VOID_PTR_PTR(true, tExprTreeDestroy, expr, NULL);
tExprNode* tagExpr = exprTreeFromBinary(pTagCond, len);
if (tagExpr != NULL) {
CLEANUP_PUSH_VOID_PTR_PTR(true, tExprTreeDestroy, tagExpr, NULL);
tExprNode* tbnameExpr = expr;
expr = calloc(1, sizeof(tExprNode));
if (expr == NULL) {
THROW( TSDB_CODE_TDB_OUT_OF_MEMORY );
}
expr->nodeType = TSQL_NODE_EXPR;
expr->_node.optr = (uint8_t)tagNameRelType;
expr->_node.pLeft = tagExpr;
expr->_node.pRight = tbnameExpr;
}
}
expr = exprTreeFromBinary(pTagCond, len);
CLEANUP_EXECUTE();
} CATCH( code ) {
......@@ -3815,7 +3689,20 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons
// TODO: more error handling
} END_TRY
doQueryTableList(pTable, res, expr);
void *filterInfo = NULL;
ret = filterInitFromTree(expr, &filterInfo, 0);
if (ret != TSDB_CODE_SUCCESS) {
terrno = ret;
goto _error;
}
tsdbQueryTableList(pTable, res, filterInfo);
filterFreeInfo(filterInfo);
tExprTreeDestroy(expr, NULL);
pGroupInfo->numOfTables = (uint32_t)taosArrayGetSize(res);
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols, skey);
......@@ -3999,55 +3886,10 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) {
pGroupList->numOfTables = 0;
}
static void applyFilterToSkipListNode(SSkipList *pSkipList, tExprNode *pExpr, SArray *pResult, SExprTraverseSupp *param) {
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
// Scan each node in the skiplist by using iterator
while (tSkipListIterNext(iter)) {
SSkipListNode *pNode = tSkipListIterGet(iter);
if (exprTreeApplyFilter(pExpr, pNode, param)) {
taosArrayPush(pResult, &(SL_GET_NODE_DATA(pNode)));
}
}
tSkipListDestroyIter(iter);
}
#if 0
typedef struct {
char* v;
int32_t optr;
} SEndPoint;
typedef struct {
SEndPoint* start;
SEndPoint* end;
} SQueryCond;
// todo check for malloc failure
static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
int32_t optr = queryColInfo->optr;
if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL ||
optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) {
pCond->start = calloc(1, sizeof(SEndPoint));
pCond->start->optr = queryColInfo->optr;
pCond->start->v = queryColInfo->q;
} else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
pCond->end = calloc(1, sizeof(SEndPoint));
pCond->end->optr = queryColInfo->optr;
pCond->end->v = queryColInfo->q;
} else if (optr == TSDB_RELATION_IN) {
pCond->start = calloc(1, sizeof(SEndPoint));
pCond->start->optr = queryColInfo->optr;
pCond->start->v = queryColInfo->q;
} else if (optr == TSDB_RELATION_LIKE) {
assert(0);
}
return TSDB_CODE_SUCCESS;
}
static void queryIndexedColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) {
static void queryIndexedColumn(SSkipList* pSkipList, void* filterInfo, SArray* result) {
SSkipListIterator* iter = NULL;
SQueryCond cond = {0};
......@@ -4184,29 +4026,36 @@ static void queryIndexedColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SAr
tSkipListDestroyIter(iter);
}
static void queryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* res, __result_filter_fn_t filterFp) {
#endif
static FORCE_INLINE int32_t tsdbGetTagDataFromId(void *param, int32_t id, void **data) {
STable* pTable = (STable*)(SL_GET_NODE_DATA((SSkipListNode *)param));
if (id == TSDB_TBNAME_COLUMN_INDEX) {
*data = TABLE_NAME(pTable);
} else {
*data = tdGetKVRowValOfCol(pTable->tagVal, id);
}
return TSDB_CODE_SUCCESS;
}
static void queryIndexlessColumn(SSkipList* pSkipList, void* filterInfo, SArray* res) {
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
while (tSkipListIterNext(iter)) {
bool addToResult = false;
int8_t *addToResult = NULL;
SSkipListNode *pNode = tSkipListIterGet(iter);
filterSetColFieldData(filterInfo, pNode, tsdbGetTagDataFromId);
char *pData = SL_GET_NODE_DATA(pNode);
tstr *name = (tstr*) tsdbGetTableName((void*) pData);
// todo speed up by using hash
if (pQueryInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
if (pQueryInfo->optr == TSDB_RELATION_IN) {
addToResult = pQueryInfo->compare(name, pQueryInfo->q);
} else if (pQueryInfo->optr == TSDB_RELATION_LIKE) {
addToResult = !pQueryInfo->compare(name, pQueryInfo->q);
}
} else {
addToResult = filterFp(pNode, pQueryInfo);
}
if (addToResult) {
bool all = filterExecute(filterInfo, 1, &addToResult, NULL, 0);
if (all || (addToResult && *addToResult)) {
STableKeyInfo info = {.pTable = (void*)pData, .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(res, &info);
}
......@@ -4215,35 +4064,23 @@ static void queryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, S
tSkipListDestroyIter(iter);
}
// Apply the filter expression to each node in the skiplist to acquire the qualified nodes in skip list
void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SExprTraverseSupp *param) {
if (pExpr == NULL) {
return;
}
tExprNode *pLeft = pExpr->_node.pLeft;
tExprNode *pRight = pExpr->_node.pRight;
// column project
if (pLeft->nodeType != TSQL_NODE_EXPR && pRight->nodeType != TSQL_NODE_EXPR) {
assert(pLeft->nodeType == TSQL_NODE_COL && (pRight->nodeType == TSQL_NODE_VALUE || pRight->nodeType == TSQL_NODE_DUMMY));
static int32_t tsdbQueryTableList(STable* pTable, SArray* pRes, void* filterInfo) {
STSchema* pTSSchema = pTable->tagSchema;
bool indexQuery = false;
SSkipList *pSkipList = pTable->pIndex;
filterIsIndexedQuery(filterInfo, pTSSchema->columns->colId, &indexQuery);
//if (indexQuery) {
//queryIndexedColumn(pSkipList, filterInfo, pRes);
//} else {
queryIndexlessColumn(pSkipList, filterInfo, pRes);
//}
param->setupInfoFn(pExpr, param->pExtInfo);
return TSDB_CODE_SUCCESS;
}
tQueryInfo *pQueryInfo = pExpr->_node.info;
if (pQueryInfo->indexed && (pQueryInfo->optr != TSDB_RELATION_LIKE && pQueryInfo->optr != TSDB_RELATION_IN)) {
queryIndexedColumn(pSkipList, pQueryInfo, result);
} else {
queryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn);
}
return;
}
// The value of hasPK is always 0.
uint8_t weight = pLeft->_node.hasPK + pRight->_node.hasPK;
assert(weight == 0 && pSkipList != NULL && taosArrayGetSize(result) == 0);
//apply the hierarchical filter expression to every node in skiplist to find the qualified nodes
applyFilterToSkipListNode(pSkipList, pExpr, result, param);
}
......@@ -135,6 +135,46 @@ while $i < $blockNum
$ts0 = $ts0 + 259200000
endw
sql create table stb5 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 timestamp, t2 int, t3 float, t4 bigint, t5 smallint, t6 tinyint, t7 double, t8 bool, t9 binary(100), t10 nchar(10))
sql create table tb5_1 using stb5 tags('2021-05-05 18:19:01',1,1.0,1,1,1,1.0,true ,'111111111','1')
sql create table tb5_2 using stb5 tags('2021-05-05 18:19:02',2,2.0,2,2,2,2.0,true ,'222222222','2')
sql create table tb5_3 using stb5 tags('2021-05-05 18:19:03',3,3.0,3,3,3,3.0,false,'333333333','3')
sql create table tb5_4 using stb5 tags('2021-05-05 18:19:04',4,4.0,4,4,4,4.0,false,'444444444','4')
sql create table tb5_5 using stb5 tags('2021-05-05 18:19:05',5,5.0,5,5,5,5.0,true,'555555555','5')
sql create table tb5_6 using stb5 tags('2021-05-05 18:19:06',6,6.0,6,6,6,6.0,true,'666666666','6')
sql insert into tb5_1 values ('2021-05-05 18:19:00',1,1.0,1,1,1,1.0,true ,'1','1')
sql insert into tb5_1 values ('2021-05-05 18:19:01',2,2.0,2,2,2,2.0,true ,'2','2')
sql insert into tb5_1 values ('2021-05-05 18:19:02',3,3.0,3,3,3,3.0,false,'3','3')
sql insert into tb5_1 values ('2021-05-05 18:19:03',4,4.0,4,4,4,4.0,false,'4','4')
sql insert into tb5_1 values ('2021-05-05 18:19:04',11,11.0,11,11,11,11.0,true ,'11','11')
sql insert into tb5_1 values ('2021-05-05 18:19:05',12,12.0,12,12,12,12.0,true ,'12','12')
sql insert into tb5_1 values ('2021-05-05 18:19:06',13,13.0,13,13,13,13.0,false,'13','13')
sql insert into tb5_1 values ('2021-05-05 18:19:07',14,14.0,14,14,14,14.0,false,'14','14')
sql insert into tb5_2 values ('2021-05-05 18:19:08',21,21.0,21,21,21,21.0,true ,'21','21')
sql insert into tb5_2 values ('2021-05-05 18:19:09',22,22.0,22,22,22,22.0,true ,'22','22')
sql insert into tb5_2 values ('2021-05-05 18:19:10',23,23.0,23,23,23,23.0,false,'23','23')
sql insert into tb5_2 values ('2021-05-05 18:19:11',24,24.0,24,24,24,24.0,false,'24','24')
sql insert into tb5_3 values ('2021-05-05 18:19:12',31,31.0,31,31,31,31.0,true ,'31','31')
sql insert into tb5_3 values ('2021-05-05 18:19:13',32,32.0,32,32,32,32.0,true ,'32','32')
sql insert into tb5_3 values ('2021-05-05 18:19:14',33,33.0,33,33,33,33.0,false,'33','33')
sql insert into tb5_3 values ('2021-05-05 18:19:15',34,34.0,34,34,34,34.0,false,'34','34')
sql insert into tb5_4 values ('2021-05-05 18:19:16',41,41.0,41,41,41,41.0,true ,'41','41')
sql insert into tb5_4 values ('2021-05-05 18:19:17',42,42.0,42,42,42,42.0,true ,'42','42')
sql insert into tb5_4 values ('2021-05-05 18:19:18',43,43.0,43,43,43,43.0,false,'43','43')
sql insert into tb5_4 values ('2021-05-05 18:19:19',44,44.0,44,44,44,44.0,false,'44','44')
sql insert into tb5_5 values ('2021-05-05 18:19:20',51,51.0,51,51,51,51.0,true ,'51','51')
sql insert into tb5_5 values ('2021-05-05 18:19:21',52,52.0,52,52,52,52.0,true ,'52','52')
sql insert into tb5_5 values ('2021-05-05 18:19:22',53,53.0,53,53,53,53.0,false,'53','53')
sql insert into tb5_5 values ('2021-05-05 18:19:23',54,54.0,54,54,54,54.0,false,'54','54')
sql insert into tb5_6 values ('2021-05-05 18:19:24',61,61.0,61,61,61,61.0,true ,'61','61')
sql insert into tb5_6 values ('2021-05-05 18:19:25',62,62.0,62,62,62,62.0,true ,'62','62')
sql insert into tb5_6 values ('2021-05-05 18:19:26',63,63.0,63,63,63,63.0,false,'63','63')
sql insert into tb5_6 values ('2021-05-05 18:19:27',64,64.0,64,64,64,64.0,false,'64','64')
sql insert into tb5_6 values ('2021-05-05 18:19:28',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)
sleep 100
sql connect
......
......@@ -11,7 +11,7 @@ if $rows != 28 then
return -1
endi
sql_error select * from stb1 where c8 > 0
sql_error select * from stb1 where c7 in (0,2,3,1);
sql_error select * from stb1 where c8 in (true);
sql_error select * from stb1 where c8 in (1,2);
......@@ -33,14 +33,101 @@ sql_error select * from stb1 where c4 != 'null';
sql_error select * from stb1 where c5 >= 'null';
sql_error select * from stb1 where c6 <= 'null';
sql_error select * from stb1 where c7 < 'nuLl';
sql_error select * from stb1 where c8 < 'nuLl';
sql_error select * from stb1 where c9 > 'nuLl';
sql_error select * from (select * from stb1 where c7=true) a, (select * from stb1 where c1 > 30) b;
sql_error select a.ts,a.c1,a.c8 from (select * from stb1 where c7=true) a, (select * from stb1 where c1 > 30) b where a.ts=b.ts and a.c1 > 50 or b.c1 < 60;
sql_error select a.ts,a.c1,a.c8 from (select * from stb1 where c7=true) a, (select * from stb1 where c1 > 30) b where a.ts=b.ts and ((a.c1 > 50 and a.c1 < 60) or (b.c2 > 60));
sql_error select * from stb1 where 'c2' is null;
sql_error select * from stb1 where 'c2' is not null;
sql select * from stb1 where c9 > 'nuLl';
if $rows != 0 then
return -1
endi
sql select * from stb1 where c8 = '22' or c8 >= '62';
if $rows != 4 then
return -1
endi
if $data00 != @21-05-05 18:19:09.000@ then
return -1
endi
if $data10 != @21-05-05 18:19:25.000@ then
return -1
endi
if $data20 != @21-05-05 18:19:26.000@ then
return -1
endi
if $data30 != @21-05-05 18:19:27.000@ then
return -1
endi
sql select * from stb1 where c8 < '11';
if $rows != 4 then
return -1
endi
if $data00 != @21-05-05 18:19:00.000@ then
return -1
endi
if $data10 != @21-05-05 18:19:01.000@ then
return -1
endi
if $data20 != @21-05-05 18:19:02.000@ then
return -1
endi
if $data30 != @21-05-05 18:19:03.000@ then
return -1
endi
sql select * from stb1 where c8 <> '11';
if $rows != 27 then
return -1
endi
sql select * from stb1 where c9 > 'nuLl';
if $rows != 0 then
return -1
endi
sql select * from stb1 where c9 > '11' and c9 <= '21';
if $rows != 4 then
return -1
endi
if $data00 != @21-05-05 18:19:05.000@ then
return -1
endi
if $data10 != @21-05-05 18:19:06.000@ then
return -1
endi
if $data20 != @21-05-05 18:19:07.000@ then
return -1
endi
if $data30 != @21-05-05 18:19:08.000@ then
return -1
endi
sql select * from stb1 where c9 <= '11' and c9 > '2' and c9 <> 3;
if $rows != 2 then
return -1
endi
if $data00 != @21-05-05 18:19:03.000@ then
return -1
endi
if $data10 != @21-05-05 18:19:04.000@ then
return -1
endi
sql select * from stb1 where c8 > 0
if $rows != 28 then
return -1
endi
sql select * from stb1 where c8 < 'nuLl';
if $rows != 28 then
return -1
endi
sql select * from stb1 where c2 > 3.0 or c2 < 60;
if $rows != 28 then
return -1
......@@ -2416,7 +2503,15 @@ if $data40 != @21-05-05 18:19:28.000@ then
endi
print "tbname test"
sql_error select * from stb1 where tbname like '%3' and tbname like '%4';
sql select tbname from stb1;
if $rows != 6 then
return -1
endi
sql select * from stb1 where tbname like '%3' and tbname like '%4';
if $rows != 0 then
return -1
endi
sql select * from stb1 where tbname like 'tb%';
if $rows != 29 then
......@@ -2440,7 +2535,192 @@ if $data30 != @21-05-05 18:19:11.000@ then
return -1
endi
sql select tbname from stb1 where tbname = 'tb1';
if $rows != 1 then
return -1
endi
if $data00 != tb1 then
return -1
endi
sql select tbname from stb1 where tbname = 'tb1' or tbname = 'tb3';
if $rows != 2 then
return -1
endi
if $data00 != tb1 then
return -1
endi
if $data10 != tb3 then
return -1
endi
sql select tbname from stb1 where tbname <> 'tb1';
if $rows != 5 then
return -1
endi
if $data00 != tb2 then
return -1
endi
if $data10 != tb3 then
return -1
endi
if $data20 != tb4 then
return -1
endi
if $data30 != tb5 then
return -1
endi
if $data40 != tb6 then
return -1
endi
sql select tbname from stb1 where tbname <> 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
if $rows != 6 then
return -1
endi
if $data00 != tb1 then
return -1
endi
if $data10 != tb2 then
return -1
endi
if $data20 != tb3 then
return -1
endi
if $data30 != tb4 then
return -1
endi
if $data40 != tb5 then
return -1
endi
if $data50 != tb6 then
return -1
endi
sql select tbname from stb1 where tbname > 'tba';
if $rows != 0 then
return -1
endi
sql select tbname from stb1 where tbname > 'tb2' and tbname <= 'tb5';
if $rows != 3 then
return -1
endi
if $data00 != tb3 then
return -1
endi
if $data10 != tb4 then
return -1
endi
if $data20 != tb5 then
return -1
endi
sql select tbname from stb1 where tbname >= 'tb5' or tbname <= 'tb2';
if $rows != 4 then
return -1
endi
if $data00 != tb1 then
return -1
endi
if $data10 != tb2 then
return -1
endi
if $data20 != tb5 then
return -1
endi
if $data30 != tb6 then
return -1
endi
sql select tbname from stb1 where tbname is null;
if $rows != 0 then
return -1
endi
sql select tbname from stb1 where tbname is not null;
if $rows != 6 then
return -1
endi
if $data00 != tb1 then
return -1
endi
if $data10 != tb2 then
return -1
endi
if $data20 != tb3 then
return -1
endi
if $data30 != tb4 then
return -1
endi
if $data40 != tb5 then
return -1
endi
if $data50 != tb6 then
return -1
endi
sql select tbname from stb1 where tbname in ('tb2','tb6');
if $rows != 2 then
return -1
endi
if $data00 != tb2 then
return -1
endi
if $data10 != tb6 then
return -1
endi
sql select tbname from stb1 where tbname is not null and (tbname in ('tb2','tb6') or tbname like '%3');
if $rows != 3 then
return -1
endi
if $data00 != tb2 then
return -1
endi
if $data10 != tb3 then
return -1
endi
if $data20 != tb6 then
return -1
endi
sql select tbname from stb1 where (tbname like '%5' and tbname like 'tb%');
if $rows != 1 then
return -1
endi
if $data00 != tb5 then
return -1
endi
sql select * from stb1 where tbname = 'tb5' and tbname <> 'tb5';
if $rows != 0 then
return -1
endi
sql select * from stb1 where tbname = 'tb5' and tbname <> 'tb4';
if $rows != 4 then
return -1
endi
if $data00 != @21-05-05 18:19:20.000@ then
return -1
endi
if $data10 != @21-05-05 18:19:21.000@ then
return -1
endi
if $data20 != @21-05-05 18:19:22.000@ then
return -1
endi
if $data30 != @21-05-05 18:19:23.000@ then
return -1
endi
print "tag test"
sql_error select * from tb1 where t1 in (1,2) and t1 in (2,3);
sql select * from stb1 where t1 in (1,2) and t1 in (2,3);
if $rows != 4 then
return -1
......@@ -2458,6 +2738,12 @@ if $data30 != @21-05-05 18:19:11.000@ then
return -1
endi
sql select * from stb1 where t1 in (1,2) or t1 in (2,3);
if $rows != 16 then
return -1
endi
sql select * from stb2 where t1 in (1,2) and t2 in (2) and t3 in ('2021-05-05 18:58:57.000');
if $rows != 0 then
return -1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册