diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 22e31f87020c1635d68b21b8234d5f28b12ff82d..ad9480422110e94bcd4cf676f128d13fc9fe7041 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1857,6 +1857,14 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSqlExprItem* pItem, int32_t colId) { SExprInfo* pExpr = doAddProjectCol(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex, colId); + if( pItem->pNode->tokenId == TK_ARROW){ + tSqlExpr* right = pItem->pNode->pRight; + assert(right != NULL && right->type == SQL_NODE_VALUE); + tVariantAssign(&(pExpr->base.param[pExpr->base.numOfParams]), &right->value); + pExpr->base.numOfParams++; + pExpr->base.resType = TSDB_DATA_TYPE_BINARY; // tag-> operation transform result type + assert(pExpr->base.numOfParams <= 3); + } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; @@ -2202,6 +2210,8 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t const char* msg1 = "tag for normal table query is not allowed"; const char* msg2 = "invalid column name"; const char* msg3 = "tbname not allowed in outer query"; + const char* msg4 = "-> operate can only used in json type"; + const char* msg5 = "the right value of -> operation must be string"; int32_t startPos = (int32_t)tscNumOfExprs(pQueryInfo); int32_t tokenId = pItem->pNode->tokenId; @@ -2244,10 +2254,25 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t // NOTE: the first parameter is reserved for the tag column id during join query process. pExpr->base.numOfParams = 2; tVariantAssign(&pExpr->base.param[1], &pItem->pNode->value); - } else if (tokenId == TK_ID) { + }else if (tokenId == TK_ID || tokenId == TK_ARROW) { SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pItem->pNode->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + SStrToken* pToken = NULL; + if (tokenId == TK_ARROW){ + tSqlExpr* left = pItem->pNode->pLeft; + assert(left != NULL && left->type == SQL_NODE_TABLE_COLUMN); + pToken = &left->columnName; + + tSqlExpr* right = pItem->pNode->pRight; + assert(right != NULL && right->type == SQL_NODE_VALUE); + if(right->tokenId != TK_STRING){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); + } + }else { + pToken = &pItem->pNode->columnName; + } + + if (getColumnIndexByName(pToken, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } @@ -2294,6 +2319,11 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); + if (tokenId == TK_ARROW && pSchema->type != TSDB_DATA_TYPE_JSON) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); + } + addProjectQueryCol(pQueryInfo, startPos, &index, pItem, getNewResColId(pCmd)); pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 25c0db001f715a130cfd4c5c61dcea63e869fa3f..616d6aa377cc3ea707ab219568fc1e577e52346f 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -5174,6 +5174,48 @@ char* cloneCurrentDBName(SSqlObj* pSql) { return p; } +pExprInfo[j].base.param[0].nLen + +char* findTagValue(void* data, char* key, int32_t keyLen){ + int16_t nCols = kvRowNCols(data); + + bool found = false; + for (int k = 1; k < nCols; ++k) { + SColIdx* pColIdx = kvRowColIdxAt(data, k); + void* result = kvRowColVal(data, pColIdx); + + if (k % 2 != 0) { // json key + char tagJsonKey[TSDB_MAX_TAGS_LEN] = {0}; + int32_t length = taosUcs4ToMbs(varDataVal(result), varDataLen(result), tagJsonKey); + if (length == 0) { + tscError("charset:%s to %s. val:%s convert json key failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, + (char*)result); + continue; + } + if (strncmp(key, tagJsonKey, keyLen) != 0) { + continue; + } + found = true; + } else { // json value + if (!found) continue; + + if (*(char*)result == cJSON_String) { + char tagJsonValue[TSDB_MAX_TAGS_LEN] = {0}; + int32_t length = taosUcs4ToMbs(varDataVal(POINTER_SHIFT(result, CHAR_BYTES)), + varDataLen(POINTER_SHIFT(result, CHAR_BYTES)), tagJsonValue); + if (length == 0) { + tscError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, + (char*)result); + } + } else if (*(char*)result == cJSON_Number) { + double jsonVd = *(double*)(POINTER_SHIFT(result, CHAR_BYTES)); + } else { + tscError("unsupportted json value"); + } + } + } +} + char* parseTagDatatoJson(void *p){ char* string = NULL; cJSON *json = cJSON_CreateObject(); diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index aa1131dfa598a3c2708f24dae0179383684d9093..a334002874733057ab13272130cd75c4b4970ae9 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -30,6 +30,8 @@ #include "tscompression.h" #include "qScript.h" #include "tscLog.h" +#include "cJSON.h" +#include "tsdbMeta.h" #define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN) #define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN) @@ -7176,6 +7178,16 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) { data = tsdbGetTableName(item->pTable); } else { data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.colInfo.colId, type, bytes); + if(pExprInfo[j].base.numOfParams > 0){ // tag-> operation + STSchema *pSchema = tsdbGetTableTagSchema((STable*) item->pTable); + STColumn *pCol = tdGetColOfID(pSchema, pExprInfo[j].base.colInfo.colId); + if (pCol == NULL) { + continue; // No matched tag volumn + } + if(pCol->type == TSDB_DATA_TYPE_JSON){ + + } + } } dst = pColInfo->pData + count * pExprInfo[j].base.resBytes; diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index 81c483f0ef389d41f059a7649ef39314eb9ee8f2..b1b52d6460d54af67bb61cd2a06ac755d1c3aa4c 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -327,6 +327,11 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) { pRSub->Expr.paramList = (SArray *)pRight; pExpr->pRight = pRSub; + } else if (optrType == TK_ARROW) { + pExpr->tokenId = optrType; + pExpr->pLeft = pLeft; + pExpr->pRight = pRight; + pExpr->type = SQL_NODE_TABLE_COLUMN; } else { pExpr->tokenId = optrType; pExpr->pLeft = pLeft; diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c index 608de2e3b94804aa84067b5d96c430d14c33663c..773f76ee222aced3aacc34ad22f114a67ec930d3 100644 --- a/src/tsdb/src/tsdbMeta.c +++ b/src/tsdb/src/tsdbMeta.c @@ -211,14 +211,12 @@ void *tsdbGetTableTagVal(const void* pTable, int32_t colId, int16_t type, int16_ } char *val = NULL; - if (type == TSDB_DATA_TYPE_JSON){ + if (pCol->type == TSDB_DATA_TYPE_JSON){ val = ((STable*)pTable)->tagVal; }else{ val = tdGetKVRowValOfCol(((STable*)pTable)->tagVal, colId); + assert(type == pCol->type && bytes >= pCol->bytes); } - - assert(type == pCol->type && bytes >= pCol->bytes); - // if (val != NULL && IS_VAR_DATA_TYPE(type)) { // assert(varDataLen(val) < pCol->bytes); // }