diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 4e3951ab6be80c0bbe463ed7a981ee83c5fe3d22..6b7973359b2245b0be9a10d102d29ef11b82f186 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -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; + } } } } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 9d523f273016e258940c67eaa1596153de0998eb..d81aab85d991644b3f934c8f4c47fefc274570d3 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -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)); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 31631560af12a01e27d5a71acaecb724cc822b5d..d43becb3a7da1648f50b41a82a17e443709b2d67 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -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, ¶m, 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) { diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index 8f5269c158bd4a733d08b727ed0b3e3741821b25..1bb799ad72b97a0e17699b73e74b66b548b5a045 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -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; diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index 7abe3e99c720af1682fc103beec9a5d4caeb09eb..84030dd9a7a937a16461d37f4cf44a174cef021c 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -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 diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index 31db6492f69c35904970cc5f48cc4a10c9fecd39..eb05882665dc613e111335958ca165349bc3cc1b 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -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 diff --git a/src/query/inc/qFilter.h b/src/query/inc/qFilter.h index af45b816f9e6725579403069843295895cf57cc8..5354d57812c7b8efb8dca71d1fc4d6657f18a8cf 100644 --- a/src/query/inc/qFilter.h +++ b/src/query/inc/qFilter.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 } diff --git a/src/query/inc/qTableMeta.h b/src/query/inc/qTableMeta.h index 746c5f8569ac98c465e8283a2401e27c18cadcc4..6f1a89b6faecfea480aa0aeb8dfec1439c1b0aad 100644 --- a/src/query/inc/qTableMeta.h +++ b/src/query/inc/qTableMeta.h @@ -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 { diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 700cf17fd38f69d4f2363174109c3217891a3e26..e105fe52709f34b207437a94fb993ceb355195e1 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -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, ¶m, 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; diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index 72f8376af6d5b7d25ba154a95e034be4eb0e6f66..a09d92149d9dbc12ec8b4fbcc2fcb40bdf7490e2 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -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; +} diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index d56c12ab8735d0683db146f7000429d4d554dda5..786318425b83c75a55be9d7527fc4f3b4ab93fec 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -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)); diff --git a/src/tsdb/CMakeLists.txt b/src/tsdb/CMakeLists.txt index c5b77df5a25f9f0b1e9294228520f171b9befddd..efbed6f0a6e8218c3a0b46d2913f6a792bf48ce4 100644 --- a/src/tsdb/CMakeLists.txt +++ b/src/tsdb/CMakeLists.txt @@ -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) diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index e3ad254bbb1a4ce0a3c504e9a799a109b7e1159a..78ca44e33aa4ea4dcd7e6aa4c2e339f322340cb8 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -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); -} diff --git a/tests/script/general/parser/condition.sim b/tests/script/general/parser/condition.sim index c3aed7e2a3b04c0ca2e27e2e62d92009e8b2fe8e..c9ef52e6dadb73b66ae1b2fccb512a32ac61a9c6 100644 --- a/tests/script/general/parser/condition.sim +++ b/tests/script/general/parser/condition.sim @@ -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 diff --git a/tests/script/general/parser/condition_query.sim b/tests/script/general/parser/condition_query.sim index 8dfa8dae0c9e0c56116cb4132d1e940e99f45d48..f665382c1511ee8e7bfc15b73bae146bfd58d6d3 100644 --- a/tests/script/general/parser/condition_query.sim +++ b/tests/script/general/parser/condition_query.sim @@ -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