diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index b183598fcceff926cfba235e42d8634546b36a48..7baa1bd08877164a0fcacb6e1a95660347a2c0e2 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -256,7 +256,7 @@ void tscColumnListDestroy(SArray* pColList); void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid); void tscColumnListCopyAll(SArray* dst, const SArray* src); -void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar); +void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar, bool convertJson); void tscDequoteAndTrimToken(SStrToken* pToken); void tscRmEscapeAndTrimToken(SStrToken* pToken); @@ -264,7 +264,7 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded) void tscIncStreamExecutionCount(void* pStream); -bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId, int32_t numOfParams); +bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId); // get starter position of metric query condition (query on tags) in SSqlCmd.payload SCond* tsGetSTableQueryCond(STagCond* pCond, uint64_t uid); @@ -394,6 +394,9 @@ void tscRemoveCachedTableMeta(STableMetaInfo* pTableMetaInfo, uint64_t id); char* cloneCurrentDBName(SSqlObj* pSql); +int parseJsontoTagData(char* json, SKVRowBuilder* kvRowBuilder, char* errMsg, int16_t startColId); +int8_t jsonType2DbType(double data, int jsonType); +void getJsonKey(SStrToken *t0); char* cloneCurrentDBName(SSqlObj* pSql); diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 7f35cf0ea5080cbb49db3a78b7d53df58cb9724c..84296f8e7d325154b445aae12630637f6aee56fa 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -453,7 +453,7 @@ void tscRestoreFuncForSTableQuery(SQueryInfo *pQueryInfo); int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo); void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo, bool converted); -void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock, bool convertNchar); +void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock, bool convertNchar, bool convertJson); void handleDownstreamOperator(SSqlObj** pSqlList, int32_t numOfUpstream, SQueryInfo* px, SSqlObj* pParent); void destroyTableNameList(SInsertStatementParam* pInsertParam); diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c index 5127aaf665b8059a12ef0985140c2a01ea328bfa..32a07b3aad20d8399620b13bf8c4fdb440a8e106 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -547,6 +547,11 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn jniFromNCharToByteArray(env, (char *)row[i], length[i])); break; } + case TSDB_DATA_TYPE_JSON: { + (*env)->CallVoidMethod(env, rowobj, g_rowdataSetByteArrayFp, i, + jniFromNCharToByteArray(env, (char *)row[i], length[i])); + break; + } case TSDB_DATA_TYPE_TIMESTAMP: { int precision = taos_result_precision(result); (*env)->CallVoidMethod(env, rowobj, g_rowdataSetTimestampFp, i, (jlong) * ((int64_t *)row[i]), precision); diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index 96aa3ef711c20d7ef75c8fe74187751614a7fe3b..90379e6f7e5ccb5da12e6007ca0e94cfc859ee53 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -85,16 +85,15 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1); dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i; - STR_WITH_MAXSIZE_TO_VARSTR(dst, type, pField->bytes); - + int32_t bytes = pSchema[i].bytes; - if (pSchema[i].type == TSDB_DATA_TYPE_BINARY || pSchema[i].type == TSDB_DATA_TYPE_NCHAR) { + if (pSchema[i].type == TSDB_DATA_TYPE_BINARY){ bytes -= VARSTR_HEADER_SIZE; - - if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) { - bytes = bytes / TSDB_NCHAR_SIZE; - } + } + else if(pSchema[i].type == TSDB_DATA_TYPE_NCHAR || pSchema[i].type == TSDB_DATA_TYPE_JSON) { + bytes -= VARSTR_HEADER_SIZE; + bytes = bytes / TSDB_NCHAR_SIZE; } pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 2); @@ -222,7 +221,7 @@ static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengt return -1; } uint8_t type = fields[idx].type; - int32_t length = lengths[idx]; + int32_t length = lengths[idx]; switch (type) { case TSDB_DATA_TYPE_BOOL: @@ -248,6 +247,7 @@ static int32_t tscGetNthFieldResult(TAOS_ROW row, TAOS_FIELD* fields, int *lengt break; case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_JSON: memcpy(result, val, length); break; case TSDB_DATA_TYPE_TIMESTAMP: diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 94f9a3018aae175f0f27c1c24b735f5a0392102d..3c6c79ad40454a19eb373e7c2f3dce3e773e48db 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -385,6 +385,19 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha } break; + case TSDB_DATA_TYPE_JSON: + if (pToken->n >= pSchema->bytes) { // reserve 1 byte for select + return tscInvalidOperationMsg(msg, "json tag length too long", pToken->z); + } + if (pToken->type == TK_NULL) { + *(int8_t *)payload = TSDB_DATA_TINYINT_NULL; + } else if (pToken->type != TK_STRING){ + tscInvalidOperationMsg(msg, "invalid json data", pToken->z); + } else{ + *((int8_t *)payload) = TSDB_DATA_JSON_PLACEHOLDER; + } + break; + case TSDB_DATA_TYPE_TIMESTAMP: { if (pToken->type == TK_NULL) { if (primaryKey) { @@ -1094,9 +1107,26 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC return code; } - tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal); - } + tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal, false); + if(pSchema->type == TSDB_DATA_TYPE_JSON){ + assert(spd.numOfBound == 1); + if(sToken.n > TSDB_MAX_JSON_TAGS_LEN/TSDB_NCHAR_SIZE){ + tdDestroyKVRowBuilder(&kvRowBuilder); + tscDestroyBoundColumnInfo(&spd); + return tscSQLSyntaxErrMsg(pInsertParam->msg, "json tag too long", NULL); + } + char* json = strndup(sToken.z, sToken.n); + code = parseJsontoTagData(json, &kvRowBuilder, pInsertParam->msg, pTagSchema[spd.boundedColumns[0]].colId); + if (code != TSDB_CODE_SUCCESS) { + tdDestroyKVRowBuilder(&kvRowBuilder); + tscDestroyBoundColumnInfo(&spd); + tfree(json); + return code; + } + tfree(json); + } + } tscDestroyBoundColumnInfo(&spd); SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder); @@ -1110,7 +1140,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC if (pInsertParam->tagData.dataLen <= 0){ return tscSQLSyntaxErrMsg(pInsertParam->msg, "tag value expected", NULL); } - + char* pTag = realloc(pInsertParam->tagData.data, pInsertParam->tagData.dataLen); if (pTag == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index a92bf7c22bef8cde1546b3cde4da46f9826f02e9..a775f3982a64a63c1f9b1b4f1f84aad591ae6fa6 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -41,6 +41,7 @@ #include "qScript.h" #include "ttype.h" #include "qFilter.h" +#include "cJSON.h" #define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0" @@ -163,6 +164,7 @@ bool serializeExprListToVariant(SArray* pList, tVariant **dst, int16_t colType, tSqlExpr* item = ((tSqlExprItem*)(taosArrayGet(pList, 0)))->pNode; int32_t firstVarType = item->value.nType; + if(colType == TSDB_DATA_TYPE_JSON) colType = firstVarType; SBufferWriter bw = tbufInitWriter( NULL, false); tbufEnsureCapacity(&bw, 512); @@ -284,6 +286,10 @@ static uint8_t convertRelationalOperator(SStrToken *pToken) { return TSDB_RELATION_MATCH; case TK_NMATCH: return TSDB_RELATION_NMATCH; + case TK_CONTAINS: + return TSDB_RELATION_CONTAINS; + case TK_ARROW: + return TSDB_RELATION_ARROW; case TK_ISNULL: return TSDB_RELATION_ISNULL; case TK_NOTNULL: @@ -1520,7 +1526,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { int32_t nLen = 0; for (int32_t i = 0; i < numOfCols; ++i) { pField = taosArrayGet(pFieldList, i); - if (!isValidDataType(pField->type)) { + if (!isValidDataType(pField->type) || pField->type == TSDB_DATA_TYPE_JSON) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); return false; } @@ -1559,7 +1565,6 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { return true; } - static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd) { assert(pTagsList != NULL); @@ -1570,6 +1575,7 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC const char* msg5 = "invalid data type in tags"; const char* msg6 = "invalid tag name or length"; const char* msg7 = "invalid binary/nchar tag length"; + const char* msg8 = "only support one tag if include json type"; // number of fields at least 1 size_t numOfTags = taosArrayGetSize(pTagsList); @@ -1585,6 +1591,11 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC return false; } + if (p->type == TSDB_DATA_TYPE_JSON && numOfTags != 1) { + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); + return false; + } + if ((p->type == TSDB_DATA_TYPE_BINARY && p->bytes <= 0) || (p->type == TSDB_DATA_TYPE_NCHAR && p->bytes <= 0)) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); @@ -1603,18 +1614,21 @@ static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pC } int32_t nLen = 0; + bool isJsonTag = false; for (int32_t i = 0; i < numOfTags; ++i) { TAOS_FIELD* p = taosArrayGet(pTagsList, i); if (p->bytes == 0) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); return false; } - + if(p->type == TSDB_DATA_TYPE_JSON){ + isJsonTag = true; + } nLen += p->bytes; } // max tag row length must be less than TSDB_MAX_TAGS_LEN - if (nLen > TSDB_MAX_TAGS_LEN) { + if (!isJsonTag && nLen > TSDB_MAX_TAGS_LEN) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); return false; } @@ -1641,6 +1655,7 @@ int32_t validateOneTag(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { const char* msg5 = "invalid binary/nchar tag length"; const char* msg6 = "invalid data type in tags"; const char* msg7 = "too many columns"; + const char* msg8 = "only support one json tag"; STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; @@ -1666,6 +1681,9 @@ int32_t validateOneTag(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { // invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); // return false; //} + if (pTagField->type == TSDB_DATA_TYPE_JSON) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); + } if ((pTagField->type < TSDB_DATA_TYPE_BOOL) || (pTagField->type > TSDB_DATA_TYPE_UBIGINT)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); @@ -1674,6 +1692,10 @@ int32_t validateOneTag(SSqlCmd* pCmd, TAOS_FIELD* pTagField) { SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); int32_t nLen = 0; + if (numOfTags == 1 && pTagSchema[0].type == TSDB_DATA_TYPE_JSON){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); + } + for (int32_t i = 0; i < numOfTags; ++i) { nLen += pTagSchema[i].bytes; } @@ -1925,20 +1947,34 @@ 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++; + } STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex); - char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName; - tstrncpy(pExpr->base.aliasName, colName, sizeof(pExpr->base.aliasName)); - + if (pSchema->type == TSDB_DATA_TYPE_JSON && pItem->pNode->tokenId == TK_ARROW) { + if (pItem->aliasName){ + tstrncpy(pExpr->base.aliasName, pItem->aliasName, sizeof(pExpr->base.aliasName)); + }else{ + tstrncpy(pExpr->base.aliasName, pItem->pNode->exprToken.z, + pItem->pNode->exprToken.n + 1 < sizeof(pExpr->base.aliasName) ? pItem->pNode->exprToken.n + 1 : sizeof(pExpr->base.aliasName)); + } + }else{ + char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName; + tstrncpy(pExpr->base.aliasName, colName, sizeof(pExpr->base.aliasName)); + } SColumnList ids = {0}; ids.num = 1; ids.ids[0] = *pIndex; - if (pIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX || pIndex->columnIndex == TSDB_UD_COLUMN_INDEX || + if (pIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX || pIndex->columnIndex <= TSDB_UD_COLUMN_INDEX || pIndex->columnIndex >= tscGetNumOfColumns(pTableMeta)) { ids.num = 0; } @@ -2095,6 +2131,10 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11); } + if(pItem->aliasName != NULL && validateColumnName(pItem->aliasName) != TSDB_CODE_SUCCESS){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11); + } + int32_t type = pItem->pNode->type; if (type == SQL_NODE_SQLFUNCTION) { hasAgg = true; @@ -2279,6 +2319,9 @@ 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"; + const char* msg6 = "select name is too long than 64, please use alias name"; int32_t startPos = (int32_t)tscNumOfExprs(pQueryInfo); int32_t tokenId = pItem->pNode->tokenId; @@ -2318,13 +2361,29 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC, getNewResColId(pCmd)); - // 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) { + tVariantAssign(&pExpr->base.param[pExpr->base.numOfParams++], &pItem->pNode->value); + }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); + if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0){ // if select from subquery, pToken should be jtag->'location'. like (select jtag->'location' from (select jtag->'location' from jsons1);) + pToken = &pItem->pNode->exprToken; + }else{ + pToken = &left->columnName; + } + + tSqlExpr* right = pItem->pNode->pRight; + if(right == NULL || right->type != SQL_NODE_VALUE || 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); } @@ -2371,6 +2430,14 @@ 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); + } + if (pSchema->type == TSDB_DATA_TYPE_JSON && tokenId == TK_ARROW && pItem->pNode->exprToken.n >= TSDB_COL_NAME_LEN){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); + } + addProjectQueryCol(pQueryInfo, startPos, &index, pItem, getNewResColId(pCmd)); pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; } @@ -3754,6 +3821,9 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd const char* msg6 = "tags not allowed for table query"; const char* msg7 = "not support group by expression"; const char* msg8 = "normal column can only locate at the end of group by clause"; + const char* msg9 = "json tag must be use ->'key'"; + const char* msg10 = "non json column can not use ->'key'"; + const char* msg11 = "group by json->'key' is too long"; // todo : handle two tables situation STableMetaInfo* pTableMetaInfo = NULL; @@ -3789,13 +3859,18 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd size_t num = taosArrayGetSize(pList); for (int32_t i = 0; i < num; ++i) { - tVariantListItem * pItem = taosArrayGet(pList, i); - tVariant* pVar = &pItem->pVar; - - SStrToken token = {pVar->nLen, pVar->nType, pVar->pz}; - - if (pVar->nType != TSDB_DATA_TYPE_BINARY){ - return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); + CommonItem * pItem = taosArrayGet(pList, i); + SStrToken token = {0}; + if(pItem->isJsonExp){ + assert(pItem->jsonExp->tokenId == TK_ARROW); + token = pItem->jsonExp->pLeft->columnName; + }else { + token.n = pItem->pVar.nLen; + token.z = pItem->pVar.pz; + token.type = pItem->pVar.nType; + if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); + } } SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -3818,6 +3893,13 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); } + if (pSchema->type == TSDB_DATA_TYPE_JSON && !pItem->isJsonExp){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9); + } + if (pSchema->type != TSDB_DATA_TYPE_JSON && pItem->isJsonExp){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg10); + } + int32_t numOfCols = tscGetNumOfColumns(pTableMeta); bool groupTag = (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols); @@ -3832,9 +3914,17 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd } SColIndex colIndex = { .colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId, }; - strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name)); + if(pItem->isJsonExp) { + if(pItem->jsonExp->exprToken.n >= tListLen(colIndex.name)){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11); + } + tstrncpy(colIndex.name, pItem->jsonExp->exprToken.z, pItem->jsonExp->exprToken.n + 1); + }else{ + tstrncpy(colIndex.name, pSchema->name, tListLen(colIndex.name)); + } + taosArrayPush(pGroupExpr->columnInfo, &colIndex); - + index.columnIndex = relIndex; tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); } else { @@ -3844,7 +3934,7 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd } tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); - + SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name)); @@ -3863,7 +3953,7 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd for(int32_t i = 0; i < num; ++i) { SColIndex* pIndex = taosArrayGet(pGroupExpr->columnInfo, i); if (TSDB_COL_IS_NORMAL_COL(pIndex->flag) && i != num - 1) { - return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); } } @@ -4190,8 +4280,17 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS return checkAndSetJoinCondInfo(pCmd, pQueryInfo, pExpr->pRight); } + tSqlExpr* pLeft = pExpr->pLeft; + tSqlExpr* pRight = pExpr->pRight; + if(pLeft->tokenId == TK_ARROW){ + pLeft = pLeft->pLeft; + } + if(pRight->tokenId == TK_ARROW){ + pRight = pRight->pLeft; + } + SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pExpr->pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } @@ -4207,6 +4306,9 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS (*leftNode)->uid = pTableMetaInfo->pTableMeta->id.uid; (*leftNode)->tagColId = pTagSchema1->colId; + if(pExpr->pLeft->tokenId == TK_ARROW) { + tstrncpy((*leftNode)->tagJsonKeyName, pExpr->pLeft->pRight->value.pz, TSDB_MAX_JSON_KEY_LEN + 1); + } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; @@ -4225,7 +4327,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS int16_t leftIdx = index.tableIndex; index = (SColumnIndex)COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pExpr->pRight->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(&pRight->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } @@ -4241,6 +4343,9 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS (*rightNode)->uid = pTableMetaInfo->pTableMeta->id.uid; (*rightNode)->tagColId = pTagSchema2->colId; + if(pExpr->pRight->tokenId == TK_ARROW) { + tstrncpy((*rightNode)->tagJsonKeyName, pExpr->pRight->pRight->value.pz, TSDB_MAX_JSON_KEY_LEN + 1); + } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; @@ -4297,6 +4402,7 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer return TSDB_CODE_TSC_INVALID_OPERATION; } + if (pExpr->tokenId == TK_ARROW) {pExpr = pExpr->pLeft;} SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; @@ -4451,7 +4557,7 @@ static void exchangeExpr(tSqlExpr* pExpr) { tSqlExpr* pLeft = pExpr->pLeft; tSqlExpr* pRight = pExpr->pRight; - if (pRight->tokenId == TK_ID && (pLeft->tokenId == TK_INTEGER || pLeft->tokenId == TK_FLOAT || + if ((pRight->tokenId == TK_ID || pRight->tokenId == TK_ARROW) && (pLeft->tokenId == TK_INTEGER || pLeft->tokenId == TK_FLOAT || pLeft->tokenId == TK_STRING || pLeft->tokenId == TK_BOOL)) { /* * exchange value of the left handside and the value of the right-handside @@ -4488,8 +4594,28 @@ static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr const char* msg3 = "join column must have same type"; const char* msg4 = "self join is not allowed"; const char* msg5 = "join table must be the same type(table to table, super table to super table)"; + const char* msg6 = "tag json key must be string"; + const char* msg7 = "tag json key in json must be same"; + const char* msg8 = "tag json key is too long, no more than 256 bytes"; tSqlExpr* pRight = pExpr->pRight; + if(pRight->tokenId == TK_ARROW){ + if(!IS_VAR_DATA_TYPE(pExpr->pLeft->pRight->value.nType) || pExpr->pLeft->pRight->value.nType != pExpr->pRight->pRight->value.nType){ + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6); + return false; + } + if(pExpr->pLeft->pRight->value.nLen > TSDB_MAX_JSON_KEY_LEN){ + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg8); + return false; + } + if(pExpr->pLeft->pRight->value.nLen != pExpr->pRight->pRight->value.nLen + || strncmp(pExpr->pLeft->pRight->value.pz, pExpr->pRight->pRight->value.pz, pExpr->pRight->pRight->value.nLen) != 0){ + invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); + return false; + } + + pRight = pExpr->pRight->pLeft; + } if (pRight->tokenId != TK_ID) { return true; @@ -4566,13 +4692,13 @@ static int32_t validateNullExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t const char* msg = "only support is [not] null"; tSqlExpr* pRight = pExpr->pRight; - if (pRight->tokenId == TK_NULL && (!(pExpr->tokenId == TK_ISNULL || pExpr->tokenId == TK_NOTNULL))) { + SSchema* pSchema = tscGetTableSchema(pTableMeta); + if (pRight->tokenId == TK_NULL && pSchema[index].type != TSDB_DATA_TYPE_JSON && (!(pExpr->tokenId == TK_ISNULL || pExpr->tokenId == TK_NOTNULL))) { return invalidOperationMsg(msgBuf, msg); } if (pRight->tokenId == TK_STRING) { - SSchema* pSchema = tscGetTableSchema(pTableMeta); - if (IS_VAR_DATA_TYPE(pSchema[index].type)) { + if (IS_VAR_DATA_TYPE(pSchema[index].type) || pSchema[index].type == TSDB_DATA_TYPE_JSON) { return TSDB_CODE_SUCCESS; } @@ -4610,7 +4736,7 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t } SSchema* pSchema = tscGetTableSchema(pTableMeta); - if ((!isTablenameToken(&pLeft->columnName)) && !IS_VAR_DATA_TYPE(pSchema[index].type)) { + if ((pLeft->tokenId != TK_ARROW) && (!isTablenameToken(&pLeft->columnName)) && !IS_VAR_DATA_TYPE(pSchema[index].type)) { return invalidOperationMsg(msgBuf, msg2); } } @@ -4618,6 +4744,59 @@ static int32_t validateLikeExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t return TSDB_CODE_SUCCESS; } +// check for match expression +static int32_t validateJsonTagExpr(tSqlExpr* pExpr, char* msgBuf) { + const char* msg1 = "not support json tag column filter"; + const char* msg2 = "tag json key is invalidate"; + const char* msg3 = "tag json key must be string"; + const char* msg4 = "in operation not support in tag json"; + + tSqlExpr* pLeft = pExpr->pLeft; + tSqlExpr* pRight = pExpr->pRight; + + if (pExpr->tokenId == TK_CONTAINS) { + if (pRight != NULL && !IS_VAR_DATA_TYPE(pRight->value.nType)) + return invalidOperationMsg(msgBuf, msg3); + + if (pRight != NULL && (pRight->value.nLen > TSDB_MAX_JSON_KEY_LEN || pRight->value.nLen <= 0)) + return invalidOperationMsg(msgBuf, msg2); + } else if(pExpr->tokenId == TK_IN){ + return invalidOperationMsg(msgBuf, msg4); + } else { + if (pLeft != NULL && pLeft->tokenId == TK_ID && pExpr->tokenId != TK_ISNULL && pExpr->tokenId != TK_NOTNULL) { + return invalidOperationMsg(msgBuf, msg1); + } + + if (pLeft != NULL && pLeft->tokenId == TK_ARROW) { + if (pLeft->pRight && !IS_VAR_DATA_TYPE(pLeft->pRight->value.nType)) + return invalidOperationMsg(msgBuf, msg3); + if (pLeft->pRight && (pLeft->pRight->value.nLen > TSDB_MAX_JSON_KEY_LEN || pLeft->pRight->value.nLen <= 0)) + return invalidOperationMsg(msgBuf, msg2); + } + + if (pRight->value.nType == TSDB_DATA_TYPE_BINARY){ // json value store by nchar, so need to convert from binary to nchar + if(pRight->value.nLen == INT_BYTES && *(uint32_t*)pRight->value.pz == TSDB_DATA_JSON_null){ + return TSDB_CODE_SUCCESS; + } + if(pRight->value.nLen == 0){ + pRight->value.nType = TSDB_DATA_TYPE_NCHAR; + return TSDB_CODE_SUCCESS; + } + char newData[TSDB_MAX_JSON_TAGS_LEN] = {0}; + int len = 0; + if(!taosMbsToUcs4(pRight->value.pz, pRight->value.nLen, newData, TSDB_MAX_JSON_TAGS_LEN, &len)){ + tscError("json where condition mbsToUcs4 error"); + } + pRight->value.pz = realloc(pRight->value.pz, len); + memcpy(pRight->value.pz, newData, len); + pRight->value.nLen = len; + pRight->value.nType = TSDB_DATA_TYPE_NCHAR; + } + } + + return TSDB_CODE_SUCCESS; +} + // check for match expression static int32_t validateMatchExpr(tSqlExpr* pExpr, STableMeta* pTableMeta, int32_t index, char* msgBuf) { const char* msg1 = "regular expression string should be less than %d characters"; @@ -4686,10 +4865,24 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql tSqlExpr* pLeft = (*pExpr)->pLeft; tSqlExpr* pRight = (*pExpr)->pRight; + SStrToken* colName = NULL; + if(pLeft->tokenId == TK_ARROW){ + colName = &(pLeft->pLeft->columnName); + if (pRight->tokenId == TK_NULL && (*pExpr)->tokenId == TK_EQ) { + // transform for json->'key'=null + pRight->tokenId = TK_STRING; + pRight->value.nType = TSDB_DATA_TYPE_BINARY; + pRight->value.nLen = INT_BYTES; + pRight->value.pz = calloc(INT_BYTES, 1); + *(uint32_t*)pRight->value.pz = TSDB_DATA_JSON_null; + } + }else{ + colName = &(pLeft->columnName); + } int32_t ret = TSDB_CODE_SUCCESS; SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { + if (getColumnIndexByName(colName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } @@ -4798,7 +4991,15 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (pRight != NULL && pRight->tokenId == TK_ID) { // join on tag columns for stable query + // check for json tag operation -> and ? + if (pSchema->type == TSDB_DATA_TYPE_JSON){ + code = validateJsonTagExpr(*pExpr, tscGetErrorMsgPayload(pCmd)); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + + if (pRight != NULL && (pRight->tokenId == TK_ID || pRight->tokenId == TK_ARROW)) { // join on tag columns for stable query if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -4814,7 +5015,10 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql // 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)) { + if ((*pExpr)->tokenId == TK_NE && (pSchema->type != TSDB_DATA_TYPE_BINARY + && pSchema->type != TSDB_DATA_TYPE_NCHAR + && pSchema->type != TSDB_DATA_TYPE_BOOL + && pSchema->type != TSDB_DATA_TYPE_JSON)) { handleNeOptr(&rexpr, *pExpr); *pExpr = rexpr; } @@ -4965,6 +5169,9 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* tSqlExpr* pLeft = (*pExpr)->pLeft; SColumnIndex index = COLUMN_INDEX_INITIALIZER; + if(pLeft->tokenId == TK_ARROW) { + pLeft = pLeft->pLeft; + } if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return; } @@ -5289,7 +5496,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE SArray* colList = taosArrayInit(10, sizeof(SColIndex)); ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL); //if (ret == TSDB_CODE_SUCCESS) { - // ret = filterInitFromTree(p, &pQueryInfo->tagFilter, (int32_t)taosArrayGetSize(colList)); + // ret = filterInitFromTree(p, &pQueryInfo->tagFilter, (int32_t)taosArrayGetSize(colList), NULL); //} SBufferWriter bw = tbufInitWriter(NULL, false); @@ -5476,7 +5683,8 @@ _ret: -int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { +int32_t +validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -5883,7 +6091,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq const char* msg0 = "only one column allowed in orderby"; const char* msg1 = "invalid column name in orderby clause"; const char* msg2 = "too many order by columns"; - const char* msg3 = "only primary timestamp/tbname/first tag in groupby clause allowed"; + const char* msg3 = "only primary timestamp/column in groupby clause allowed as order column"; const char* msg4 = "only tag in groupby clause allowed in order clause"; const char* msg5 = "only primary timestamp/column in top/bottom function allowed as order column"; const char* msg6 = "only primary timestamp allowed as the second order column"; @@ -5893,6 +6101,8 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq const char* msg10 = "not support distinct mixed with order by"; const char* msg11 = "not support order with udf"; const char* msg12 = "order by tags not supported with diff/derivative/csum/mavg"; + const char* msg13 = "order by json tag, key is too long"; + const char* msg14 = "order by json tag, must be json->'key'"; setDefaultOrderInfo(pQueryInfo); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -5929,14 +6139,24 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq return invalidOperationMsg(pMsgBuf, msg10); } - // handle the first part of order by - tVariant* pVar = taosArrayGet(pSortOrder, 0); + SStrToken columnName = {0}; + CommonItem* pItem = taosArrayGet(pSortOrder, 0); + if (pItem->isJsonExp){ + assert(pItem->jsonExp->tokenId == TK_ARROW); + columnName = pItem->jsonExp->pLeft->columnName; + }else{ + // handle the first part of order by + tVariant* pVar = &pItem->pVar; - if (pVar->nType != TSDB_DATA_TYPE_BINARY){ - return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); + if (pVar->nType != TSDB_DATA_TYPE_BINARY){ + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + columnName.n = pVar->nLen; + columnName.type = pVar->nType; + columnName.z = pVar->pz; } - SStrToken columnName = {pVar->nLen, pVar->nType, pVar->pz}; SColumnIndex index = COLUMN_INDEX_INITIALIZER; bool udf = false; @@ -5970,7 +6190,21 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0); if (relTagIndex == pColIndex->colIndex) { - orderByTags = true; + if (tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, pColIndex->colId)->type == TSDB_DATA_TYPE_JSON){ + if(!pItem->isJsonExp){ + return invalidOperationMsg(pMsgBuf, msg14); + } + if(pItem->jsonExp->exprToken.n >= sizeof(pColIndex->name)){ + return invalidOperationMsg(pMsgBuf, msg13); + } + if(strncmp(pColIndex->name, pItem->jsonExp->exprToken.z, pItem->jsonExp->exprToken.n) == 0){ + orderByTags = true; + }else{ + orderByTags = false; + } + }else{ + orderByTags = true; + } } } else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { // order by tbname // it is a tag column @@ -6005,10 +6239,10 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); + CommonItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->groupbyExpr.orderType = p1->sortOrder; } else if (orderByGroupbyCol) { - tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); + CommonItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->groupbyExpr.orderType = p1->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; @@ -6029,12 +6263,12 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq return invalidOperationMsg(pMsgBuf, msg5); } - tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); + CommonItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = p1->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; return TSDB_CODE_SUCCESS; } else { - tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); + CommonItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); if (udf) { return invalidOperationMsg(pMsgBuf, msg11); @@ -6060,7 +6294,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } } } else { - tVariantListItem *pItem = taosArrayGet(pSqlNode->pSortOrder, 0); + pItem = taosArrayGet(pSqlNode->pSortOrder, 0); if (orderByTags) { pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); pQueryInfo->groupbyExpr.orderType = pItem->sortOrder; @@ -6078,9 +6312,18 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } } + SStrToken cname = {0}; pItem = taosArrayGet(pSqlNode->pSortOrder, 1); - tVariant* pVar2 = &pItem->pVar; - SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz}; + if (pItem->isJsonExp){ + assert(pItem->jsonExp->tokenId == TK_ARROW); + cname = pItem->jsonExp->pLeft->columnName; + }else{ + tVariant* pVar = &pItem->pVar; + + cname.n = pVar->nLen; + cname.type = pVar->nType; + cname.z = pVar->pz; + } if (getColumnIndexByName(&cname, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(pMsgBuf, msg1); } @@ -6088,8 +6331,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidOperationMsg(pMsgBuf, msg6); } else { - tVariantListItem* p1 = taosArrayGet(pSortOrder, 1); - pQueryInfo->order.order = p1->sortOrder; + pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; } } @@ -6119,7 +6361,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq return invalidOperationMsg(pMsgBuf, msg11); } - tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); + CommonItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->groupbyExpr.orderIndex = pSchema[index.columnIndex].colId; pQueryInfo->groupbyExpr.orderType = p1->sortOrder; } @@ -6145,7 +6387,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq } } - tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); + pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; @@ -6156,7 +6398,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq return invalidOperationMsg(pMsgBuf, msg11); } - tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); + pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; } else { @@ -6172,7 +6414,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq return invalidOperationMsg(pMsgBuf, msg11); } - tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); + pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; } @@ -6209,6 +6451,8 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { const char* msg23 = "only column length coulbe be modified"; const char* msg24 = "invalid binary/nchar column length"; + const char* msg25 = "json type error, should be string"; + int32_t code = TSDB_CODE_SUCCESS; SSqlCmd* pCmd = &pSql->cmd; @@ -6368,22 +6612,32 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { tVariantListItem* pItem = taosArrayGet(pVarList, 1); SSchema* pTagsSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, columnIndex.columnIndex); - if (IS_VAR_DATA_TYPE(pTagsSchema->type) && (pItem->pVar.nLen > pTagsSchema->bytes * TSDB_NCHAR_SIZE)) { + if (IS_VAR_DATA_TYPE(pTagsSchema->type) && (pItem->pVar.nLen > pTagsSchema->bytes)) { return invalidOperationMsg(pMsg, msg14); } + SKVRowBuilder kvRowBuilder = {0}; + if (pTagsSchema->type == TSDB_DATA_TYPE_JSON) { + if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { + tscError("json type error, should be string"); + return invalidOperationMsg(pMsg, msg25); + } + if (pItem->pVar.nType > TSDB_MAX_JSON_TAGS_LEN / TSDB_NCHAR_SIZE) { + tscError("json tag too long"); + return invalidOperationMsg(pMsg, msg14); + } - pAlterSQL->tagData.data = calloc(1, pTagsSchema->bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE); + if (tdInitKVRowBuilder(&kvRowBuilder) < 0) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } - if (tVariantDump(&pItem->pVar, pAlterSQL->tagData.data, pTagsSchema->type, true) != TSDB_CODE_SUCCESS) { - return invalidOperationMsg(pMsg, msg13); - } - - pAlterSQL->tagData.dataLen = pTagsSchema->bytes; + int8_t tagVal = TSDB_DATA_JSON_PLACEHOLDER; + tdAddColToKVRow(&kvRowBuilder, pTagsSchema->colId, pTagsSchema->type, &tagVal, false); - // validate the length of binary - if ((pTagsSchema->type == TSDB_DATA_TYPE_BINARY || pTagsSchema->type == TSDB_DATA_TYPE_NCHAR) && - varDataTLen(pAlterSQL->tagData.data) > pTagsSchema->bytes) { - return invalidOperationMsg(pMsg, msg14); + code = parseJsontoTagData(pItem->pVar.pz, &kvRowBuilder, pMsg, pTagsSchema->colId); + if (code != TSDB_CODE_SUCCESS) { + tdDestroyKVRowBuilder(&kvRowBuilder); + return code; + } } int32_t schemaLen = sizeof(STColumn) * numOfTags; @@ -6419,15 +6673,32 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { d += sizeof(STColumn); } - // copy the tag value to pMsg body - pItem = taosArrayGet(pVarList, 1); - tVariantDump(&pItem->pVar, pUpdateMsg->data + schemaLen, pTagsSchema->type, true); - + if (pTagsSchema->type == TSDB_DATA_TYPE_JSON){ + SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder); + tdDestroyKVRowBuilder(&kvRowBuilder); + if (row == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + tdSortKVRowByColIdx(row); + + kvRowCpy(pUpdateMsg->data + schemaLen, row); + free(row); + }else{ + // copy the tag value to pMsg body + if (tVariantDump(&pItem->pVar, pUpdateMsg->data + schemaLen, pTagsSchema->type, true) + != TSDB_CODE_SUCCESS){ + return invalidOperationMsg(pMsg, msg13); + } + } + int32_t len = 0; - if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) { + if(pTagsSchema->type == TSDB_DATA_TYPE_JSON){ + len = kvRowLen(pUpdateMsg->data + schemaLen); + }else if (!IS_VAR_DATA_TYPE(pTagsSchema->type)) { len = tDataTypes[pTagsSchema->type].bytes; } else { len = varDataTLen(pUpdateMsg->data + schemaLen); + if(len > pTagsSchema->bytes) return invalidOperationMsg(pMsg, msg14); } pUpdateMsg->tagValLen = htonl(len); // length may be changed after dump data @@ -7210,12 +7481,18 @@ static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } -static bool tagColumnInGroupby(SGroupbyExpr* pGroupbyExpr, int16_t columnId) { +static bool tagColumnInGroupby(SGroupbyExpr* pGroupbyExpr, int16_t columnId, int16_t type, char* name) { for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, j); - - if (columnId == pColIndex->colId && TSDB_COL_IS_TAG(pColIndex->flag )) { - return true; + + if (type == TSDB_DATA_TYPE_JSON && name != NULL){ + if (columnId == pColIndex->colId && strncmp(pColIndex->name, name, tListLen(pColIndex->name)) == 0 && TSDB_COL_IS_TAG(pColIndex->flag )) { + return true; + } + }else{ + if (columnId == pColIndex->colId && TSDB_COL_IS_TAG(pColIndex->flag )) { + return true; + } } } @@ -7250,7 +7527,7 @@ static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) { continue; } - if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->base.colInfo.colId)) { + if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->base.colInfo.colId, pExpr->base.resType, pExpr->base.param[0].pz)) { allInGroupby = false; break; } @@ -7427,16 +7704,23 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo SColumnIndex index = {.tableIndex = pQueryInfo->groupbyExpr.tableIndex, .columnIndex = colIndex}; SExprInfo* pExpr = tscExprInsert(pQueryInfo, pos, f, &index, s->type, s->bytes, getNewResColId(pCmd), s->bytes, true); - - memset(pExpr->base.aliasName, 0, sizeof(pExpr->base.aliasName)); - tstrncpy(pExpr->base.aliasName, s->name, sizeof(pExpr->base.aliasName)); - tstrncpy(pExpr->base.token, s->name, sizeof(pExpr->base.aliasName)); - - pExpr->base.colInfo.flag = TSDB_COL_TAG; - // NOTE: tag column does not add to source column list SColumnList ids = createColumnList(1, 0, pColIndex->colIndex); - insertResultField(pQueryInfo, pos, &ids, s->bytes, (int8_t)s->type, s->name, pExpr); + insertResultField(pQueryInfo, pos, &ids, s->bytes, (int8_t)s->type, pColIndex->name, pExpr); + pExpr->base.colInfo.flag = TSDB_COL_TAG; + memset(pExpr->base.aliasName, 0, sizeof(pExpr->base.aliasName)); + tstrncpy(pExpr->base.aliasName, pColIndex->name, sizeof(pExpr->base.aliasName)); + tstrncpy(pExpr->base.token, pColIndex->name, sizeof(pExpr->base.token)); + if(s->type == TSDB_DATA_TYPE_JSON){ + SStrToken t0 = {.z = pColIndex->name}; + getJsonKey(&t0); + tVariantCreateFromBinary(&(pExpr->base.param[pExpr->base.numOfParams]), t0.z, + t0.n, TSDB_DATA_TYPE_BINARY); + pExpr->base.numOfParams++; + assert(t0.n < strlen(pColIndex->name)); + memmove(pColIndex->name, t0.z, t0.n); + pColIndex->name[t0.n] = '\0'; + } } else { // if this query is "group by" normal column, time window query is not allowed if (isTimeWindowQuery(pQueryInfo)) { @@ -7951,6 +8235,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { const char* msg4 = "illegal value or data overflow"; const char* msg5 = "tags number not matched"; const char* msg6 = "create table only from super table is allowed"; + const char* msg7 = "json type error, should be string"; SSqlCmd* pCmd = &pSql->cmd; @@ -8075,7 +8360,6 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { pItem->pVar.i64 = convertTimePrecision(pItem->pVar.i64, TSDB_TIME_PRECISION_NANO, tinfo.precision); } } - ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true); // check again after the convert since it may be converted from binary to nchar. @@ -8092,7 +8376,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal); + tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal, false); findColumnIndex = true; break; @@ -8114,7 +8398,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { SSchema* pSchema = &pTagSchema[i]; tVariantListItem* pItem = taosArrayGet(pValList, i); - char tagVal[TSDB_MAX_TAGS_LEN]; + char tagVal[TSDB_MAX_TAGS_LEN] = {0}; if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) { if (pItem->pVar.nLen > pSchema->bytes) { tdDestroyKVRowBuilder(&kvRowBuilder); @@ -8130,8 +8414,6 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { pItem->pVar.i64 = convertTimePrecision(pItem->pVar.i64, TSDB_TIME_PRECISION_NANO, tinfo.precision); } } - - ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true); // check again after the convert since it may be converted from binary to nchar. @@ -8148,7 +8430,31 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4); } - tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal); + tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal, false); + } + } + + // encode json tag string + if(schemaSize == 1 && pTagSchema[0].type == TSDB_DATA_TYPE_JSON){ + if (valSize != schemaSize) { + tdDestroyKVRowBuilder(&kvRowBuilder); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); + } + tVariantListItem* pItem = taosArrayGet(pValList, 0); + if(pItem->pVar.nType != TSDB_DATA_TYPE_BINARY){ + tscError("json type error, should be string"); + tdDestroyKVRowBuilder(&kvRowBuilder); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); + } + if(pItem->pVar.nLen > TSDB_MAX_JSON_TAGS_LEN/TSDB_NCHAR_SIZE){ + tscError("json tag too long"); + tdDestroyKVRowBuilder(&kvRowBuilder); + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); + } + ret = parseJsontoTagData(pItem->pVar.pz, &kvRowBuilder, tscGetErrorMsgPayload(pCmd), pTagSchema[0].colId); + if (ret != TSDB_CODE_SUCCESS) { + tdDestroyKVRowBuilder(&kvRowBuilder); + return ret; } } @@ -9517,6 +9823,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS assert(pSqlExpr->pRight == NULL); if (pSqlExpr->type == SQL_NODE_VALUE) { + if(pSqlExpr->value.nType == -1){ + return TSDB_CODE_TSC_INVALID_VALUE; + } int32_t ret = TSDB_CODE_SUCCESS; *pExpr = calloc(1, sizeof(tExprNode)); (*pExpr)->nodeType = TSQL_NODE_VALUE; @@ -9664,7 +9973,10 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS // NOTE: binary|nchar data allows the >|< type filter if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) { if (pRight != NULL && pRight->nodeType == TSQL_NODE_VALUE) { - if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL && pLeft->pSchema->type == TSDB_DATA_TYPE_BOOL) { + if (pLeft->_node.optr == TSDB_RELATION_ARROW){ + pLeft = pLeft->_node.pLeft; + } + if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL && (pLeft->pSchema->type == TSDB_DATA_TYPE_BOOL || pLeft->pSchema->type == TSDB_DATA_TYPE_JSON)) { return TSDB_CODE_TSC_INVALID_OPERATION; } } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 896b5361435d78de1551d5bc9e0da61a19fd2e55..35582973c2af7b214d3054807d31a897c7256191 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -832,7 +832,7 @@ static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, return TSDB_CODE_TSC_INVALID_TABLE_NAME; } - if (validateColumn && !tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) { + if (validateColumn && !tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId)) { tscError("0x%"PRIx64" table schema is not matched with parsed sql", id); return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -1510,7 +1510,8 @@ int tscEstimateCreateTableMsgLength(SSqlObj *pSql, SSqlInfo *pInfo) { SCreateTableSql *pCreateTableInfo = pInfo->pCreateTableInfo; if (pCreateTableInfo->type == TSQL_CREATE_TABLE_FROM_STABLE) { int32_t numOfTables = (int32_t)taosArrayGetSize(pInfo->pCreateTableInfo->childTableInfo); - size += numOfTables * (sizeof(SCreateTableMsg) + TSDB_MAX_TAGS_LEN); + size += numOfTables * (sizeof(SCreateTableMsg) + + ((TSDB_MAX_TAGS_LEN > TSDB_MAX_JSON_TAGS_LEN)?TSDB_MAX_TAGS_LEN:TSDB_MAX_JSON_TAGS_LEN)); } else { size += sizeof(SSchema) * (pCmd->numOfCols + pCmd->count); } @@ -1632,9 +1633,6 @@ int tscEstimateAlterTableMsgLength(SSqlCmd *pCmd) { } int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - char *pMsg; - int msgLen = 0; - SSqlCmd *pCmd = &pSql->cmd; SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd); @@ -1663,14 +1661,7 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pSchema++; } - pMsg = (char *)pSchema; - pAlterTableMsg->tagValLen = htonl(pAlterInfo->tagData.dataLen); - if (pAlterInfo->tagData.dataLen > 0) { - memcpy(pMsg, pAlterInfo->tagData.data, pAlterInfo->tagData.dataLen); - } - pMsg += pAlterInfo->tagData.dataLen; - - msgLen = (int32_t)(pMsg - (char*)pAlterTableMsg); + int msgLen = sizeof(SAlterTableMsg) + sizeof(SSchema) * tscNumOfFields(pQueryInfo); pCmd->payloadLen = msgLen; pCmd->msgType = TSDB_MSG_TYPE_CM_ALTER_TABLE; @@ -1872,7 +1863,9 @@ int tscProcessRetrieveGlobalMergeRsp(SSqlObj *pSql) { uint64_t localQueryId = pSql->self; qTableQuery(pQueryInfo->pQInfo, &localQueryId); - convertQueryResult(pRes, pQueryInfo, pSql->self, true); + bool convertJson = true; + if (pQueryInfo->isStddev == true) convertJson = false; + convertQueryResult(pRes, pQueryInfo, pSql->self, true, convertJson); code = pRes->code; if (pRes->code == TSDB_CODE_SUCCESS) { diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 6abdab4880f837c505eeba10b0dd9af6c1b86974..d27fa15bf13b0f7ca15e4cb92b447f8d51b842ef 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -445,7 +445,7 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { // revise the length for binary and nchar fields if (f[j].type == TSDB_DATA_TYPE_BINARY) { f[j].bytes -= VARSTR_HEADER_SIZE; - } else if (f[j].type == TSDB_DATA_TYPE_NCHAR) { + } else if (f[j].type == TSDB_DATA_TYPE_NCHAR || f[j].type == TSDB_DATA_TYPE_JSON) { f[j].bytes = (f[j].bytes - VARSTR_HEADER_SIZE)/TSDB_NCHAR_SIZE; } diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 3014b874feb58da4ba9e40e835d85a833048d6a6..3e81b2fe64e1e9cce96837be1fcf6cf445d464c2 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -227,6 +227,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { if (skipped) { slot = 0; stackidx = 0; + tVariantDestroy(&tag); continue; } @@ -334,6 +335,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { } if (mergeDone) { + tVariantDestroy(&tag); break; } @@ -341,6 +343,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { stackidx = 0; skipRemainValue(mainCtx->p->pTSBuf, &tag); + tVariantDestroy(&tag); } stackidx = 0; @@ -633,16 +636,21 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { // set the join condition tag column info, todo extract method if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { assert(pQueryInfo->tagCond.joinInfo.hasJoin); + pExpr->base.numOfParams = 0; // the value is 0 by default. just make sure. + // add json tag key, if there is no json tag key, just hold place. + tVariantCreateFromBinary(&(pExpr->base.param[pExpr->base.numOfParams]), pQueryInfo->tagCond.joinInfo.joinTables[0]->tagJsonKeyName, + strlen(pQueryInfo->tagCond.joinInfo.joinTables[0]->tagJsonKeyName), TSDB_DATA_TYPE_BINARY); + pExpr->base.numOfParams++; int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid); // set the tag column id for executor to extract correct tag value - tVariant* pVariant = &pExpr->base.param[0]; + tVariant* pVariant = &pExpr->base.param[pExpr->base.numOfParams]; pVariant->i64 = colId; pVariant->nType = TSDB_DATA_TYPE_BIGINT; pVariant->nLen = sizeof(int64_t); - pExpr->base.numOfParams = 1; + pExpr->base.numOfParams++; } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { @@ -729,8 +737,15 @@ int32_t tagValCompar(const void* p1, const void* p2) { const STidTags* t1 = (const STidTags*) varDataVal(p1); const STidTags* t2 = (const STidTags*) varDataVal(p2); - __compar_fn_t func = getComparFunc(t1->padding, 0); + if (t1->padding == TSDB_DATA_TYPE_JSON){ + bool canReturn = true; + int32_t result = jsonCompareUnit(t1->tag, t2->tag, &canReturn); + if(canReturn) return result; + __compar_fn_t func = getComparFunc(t1->tag[0], 0); + return func(t1->tag + CHAR_BYTES, t2->tag + CHAR_BYTES); + } + __compar_fn_t func = getComparFunc(t1->padding, 0); return func(t1->tag, t2->tag); } @@ -821,16 +836,21 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* SSchema colSchema = {.type = TSDB_DATA_TYPE_BINARY, .bytes = 1}; SColumnIndex index = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); + SExprInfo *pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_TS_COMP, &index, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); // set the tags value for ts_comp function if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - SExprInfo *pExpr = tscExprGet(pQueryInfo, 0); - int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); - pExpr->base.param[0].i64 = tagColId; - pExpr->base.param[0].nLen = sizeof(int64_t); - pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; - pExpr->base.numOfParams = 1; + pExpr->base.numOfParams = 0; // the value is 0 by default. just make sure. + // add json tag key, if there is no json tag key, just hold place. + tVariantCreateFromBinary(&(pExpr->base.param[pExpr->base.numOfParams]), pSupporter->tagCond.joinInfo.joinTables[0]->tagJsonKeyName, + strlen(pSupporter->tagCond.joinInfo.joinTables[0]->tagJsonKeyName), TSDB_DATA_TYPE_BINARY); + pExpr->base.numOfParams++; + + int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); + pExpr->base.param[pExpr->base.numOfParams].i64 = tagColId; + pExpr->base.param[pExpr->base.numOfParams].nLen = sizeof(int64_t); + pExpr->base.param[pExpr->base.numOfParams].nType = TSDB_DATA_TYPE_BIGINT; + pExpr->base.numOfParams++; } // add the filter tag column @@ -2012,7 +2032,12 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter // set get tags query type TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY); - tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TID_TAG, &colIndex, &s1, TSDB_COL_TAG, getNewResColId(pCmd)); + SExprInfo* pExpr = tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TID_TAG, &colIndex, &s1, TSDB_COL_TAG, getNewResColId(pCmd)); + if(strlen(pTagCond->joinInfo.joinTables[0]->tagJsonKeyName) > 0){ + tVariantCreateFromBinary(&(pExpr->base.param[pExpr->base.numOfParams]), pTagCond->joinInfo.joinTables[0]->tagJsonKeyName, + strlen(pTagCond->joinInfo.joinTables[0]->tagJsonKeyName), TSDB_DATA_TYPE_BINARY); + pExpr->base.numOfParams++; + } size_t numOfCols = taosArrayGetSize(pNewQueryInfo->colList); tscDebug( @@ -2025,15 +2050,6 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter SColumnIndex colIndex = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX}; tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &colIndex, &colSchema, TSDB_COL_NORMAL, getNewResColId(pCmd)); - // set the tags value for ts_comp function - SExprInfo *pExpr = tscExprGet(pNewQueryInfo, 0); - - if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); - pExpr->base.param->i64 = tagColId; - pExpr->base.numOfParams = 1; - } - // add the filter tag column if (pSupporter->colList != NULL) { size_t s = taosArrayGetSize(pSupporter->colList); @@ -2427,6 +2443,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0); tscInitQueryInfo(pNewQueryInfo); + pNewQueryInfo->isStddev = true; // for json tag // add the group cond pNewQueryInfo->groupbyExpr = pQueryInfo->groupbyExpr; @@ -2490,6 +2507,10 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { } SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG, getNewResColId(pCmd)); + if (schema->type == TSDB_DATA_TYPE_JSON){ + p->base.numOfParams = pExpr->base.numOfParams; + tVariantAssign(&p->base.param[0], &pExpr->base.param[0]); + } p->base.resColId = pExpr->base.resColId; } else if (pExpr->base.functionId == TSDB_FUNC_PRJ) { int32_t num = (int32_t) taosArrayGetSize(pNewQueryInfo->groupbyExpr.columnInfo); @@ -3681,7 +3702,9 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql) { int32_t type = pInfo->field.type; int32_t bytes = pInfo->field.bytes; - if (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR) { + if (pQueryInfo->isStddev && type == TSDB_DATA_TYPE_JSON){ // for json tag compare in the second round of stddev + pRes->tsrow[j] = pRes->urow[i]; + }else if (!IS_VAR_DATA_TYPE(type) && type != TSDB_DATA_TYPE_JSON) { pRes->tsrow[j] = isNull(pRes->urow[i], type) ? NULL : pRes->urow[i]; } else { pRes->tsrow[j] = isNull(pRes->urow[i], type) ? NULL : varDataVal(pRes->urow[i]); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index e6c4e12e34cee28b0402fe3104d298a4080e6e1c..c5f3a1cdaffd48acc7f0091c63c164d58484bc09 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -29,6 +29,7 @@ #include "tsclient.h" #include "ttimer.h" #include "ttokendef.h" +#include "cJSON.h" #ifdef HTTP_EMBEDDED #include "httpInt.h" @@ -109,6 +110,7 @@ int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *le n = bufSize + escapeSize; break; case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_JSON: if (bufSize < 0) { tscError("invalid buf size"); return TSDB_CODE_TSC_INVALID_VALUE; @@ -732,34 +734,33 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } -static void setResRawPtrImpl(SSqlRes* pRes, SInternalField* pInfo, int32_t i, bool convertNchar) { +static void setResRawPtrImpl(SSqlRes* pRes, SInternalField* pInfo, int32_t i, bool convertNchar, bool convertJson) { // generated the user-defined column result if (pInfo->pExpr->pExpr == NULL && TSDB_COL_IS_UD_COL(pInfo->pExpr->base.colInfo.flag)) { - if (pInfo->pExpr->base.param[1].nType == TSDB_DATA_TYPE_NULL) { + if (pInfo->pExpr->base.param[0].nType == TSDB_DATA_TYPE_NULL) { setNullN(pRes->urow[i], pInfo->field.type, pInfo->field.bytes, (int32_t) pRes->numOfRows); } else { if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR || pInfo->field.type == TSDB_DATA_TYPE_BINARY) { - assert(pInfo->pExpr->base.param[1].nLen <= pInfo->field.bytes); + assert(pInfo->pExpr->base.param[0].nLen <= pInfo->field.bytes); for (int32_t k = 0; k < pRes->numOfRows; ++k) { char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; - memcpy(varDataVal(p), pInfo->pExpr->base.param[1].pz, pInfo->pExpr->base.param[1].nLen); - varDataSetLen(p, pInfo->pExpr->base.param[1].nLen); + memcpy(varDataVal(p), pInfo->pExpr->base.param[0].pz, pInfo->pExpr->base.param[0].nLen); + varDataSetLen(p, pInfo->pExpr->base.param[0].nLen); } } else { for (int32_t k = 0; k < pRes->numOfRows; ++k) { char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; - memcpy(p, &pInfo->pExpr->base.param[1].i64, pInfo->field.bytes); + memcpy(p, &pInfo->pExpr->base.param[0].i64, pInfo->field.bytes); } } } - } else if (convertNchar && pInfo->field.type == TSDB_DATA_TYPE_NCHAR) { + } else if (convertNchar && (pInfo->field.type == TSDB_DATA_TYPE_NCHAR)) { // convert unicode to native code in a temporary buffer extra one byte for terminated symbol char* buffer = realloc(pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); - if(buffer == NULL) - return ; + if (buffer == NULL) return; pRes->buffer[i] = buffer; // string terminated char for binary data memset(pRes->buffer[i], 0, pInfo->field.bytes * pRes->numOfRows); @@ -783,8 +784,63 @@ static void setResRawPtrImpl(SSqlRes* pRes, SInternalField* pInfo, int32_t i, bo p += pInfo->field.bytes; } - memcpy(pRes->urow[i], pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + }else if (pInfo->field.type == TSDB_DATA_TYPE_JSON) { + if (convertJson){ + // convert unicode to native code in a temporary buffer extra one byte for terminated symbol + char* buffer = realloc(pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + if (buffer == NULL) return; + pRes->buffer[i] = buffer; + // string terminated char for binary data + memset(pRes->buffer[i], 0, pInfo->field.bytes * pRes->numOfRows); + + char* p = pRes->urow[i]; + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* dst = pRes->buffer[i] + k * pInfo->field.bytes; + char type = *p; + char* realData = p + CHAR_BYTES; + if (type == TSDB_DATA_TYPE_JSON && isNull(realData, TSDB_DATA_TYPE_JSON)) { + memcpy(dst, realData, varDataTLen(realData)); + } else if (type == TSDB_DATA_TYPE_BINARY) { + assert(*(uint32_t*)varDataVal(realData) == TSDB_DATA_JSON_null); // json null value + assert(varDataLen(realData) == INT_BYTES); + sprintf(varDataVal(dst), "%s", "null"); + varDataSetLen(dst, strlen(varDataVal(dst))); + }else if (type == TSDB_DATA_TYPE_JSON) { + int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), varDataVal(dst)); + varDataSetLen(dst, length); + if (length == 0) { + tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p); + } + }else if (type == TSDB_DATA_TYPE_NCHAR) { // value -> "value" + *(char*)varDataVal(dst) = '\"'; + int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), POINTER_SHIFT(varDataVal(dst), CHAR_BYTES)); + *(char*)(POINTER_SHIFT(varDataVal(dst), length + CHAR_BYTES)) = '\"'; + varDataSetLen(dst, length + CHAR_BYTES*2); + if (length == 0) { + tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p); + } + }else if (type == TSDB_DATA_TYPE_DOUBLE) { + double jsonVd = *(double*)(realData); + sprintf(varDataVal(dst), "%.9lf", jsonVd); + varDataSetLen(dst, strlen(varDataVal(dst))); + }else if (type == TSDB_DATA_TYPE_BIGINT) { + int64_t jsonVd = *(int64_t*)(realData); + sprintf(varDataVal(dst), "%" PRId64, jsonVd); + varDataSetLen(dst, strlen(varDataVal(dst))); + }else if (type == TSDB_DATA_TYPE_BOOL) { + sprintf(varDataVal(dst), "%s", (*((char *)realData) == 1) ? "true" : "false"); + varDataSetLen(dst, strlen(varDataVal(dst))); + }else { + assert(0); + } + + p += pInfo->field.bytes; + } + memcpy(pRes->urow[i], pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + }else{ + // if convertJson is false, json data as raw data used for stddev for the second round + } } if (convertNchar) { @@ -792,6 +848,10 @@ static void setResRawPtrImpl(SSqlRes* pRes, SInternalField* pInfo, int32_t i, bo } } +void tscJson2String(char *src, char* dst){ + +} + void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo, bool converted) { assert(pRes->numOfCols > 0); if (pRes->numOfRows == 0) { @@ -805,11 +865,11 @@ void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo, bool converted) { pRes->length[i] = pInfo->field.bytes; offset += pInfo->field.bytes; - setResRawPtrImpl(pRes, pInfo, i, converted ? false : true); + setResRawPtrImpl(pRes, pInfo, i, converted ? false : true, true); } } -void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock, bool convertNchar) { +void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock, bool convertNchar, bool convertJson) { assert(pRes->numOfCols > 0); for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { @@ -820,7 +880,7 @@ void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBloc pRes->urow[i] = pColData->pData; pRes->length[i] = pInfo->field.bytes; - setResRawPtrImpl(pRes, pInfo, i, convertNchar); + setResRawPtrImpl(pRes, pInfo, i, convertNchar, convertJson); /* // generated the user-defined column result if (pInfo->pExpr->pExpr == NULL && TSDB_COL_IS_UD_COL(pInfo->pExpr->base.ColName.flag)) { @@ -876,17 +936,6 @@ void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBloc } } -static SColumnInfo* extractColumnInfoFromResult(SArray* pTableCols) { - int32_t numOfCols = (int32_t) taosArrayGetSize(pTableCols); - SColumnInfo* pColInfo = calloc(numOfCols, sizeof(SColumnInfo)); - for(int32_t i = 0; i < numOfCols; ++i) { - SColumn* pCol = taosArrayGetP(pTableCols, i); - pColInfo[i] = pCol->info;//[index].type; - } - - return pColInfo; -} - typedef struct SDummyInputInfo { SSDataBlock *block; STableQueryInfo *pTableQueryInfo; @@ -1276,14 +1325,14 @@ SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUp return pOperator; } -void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar) { +void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo, uint64_t objId, bool convertNchar, bool convertJson) { // set the correct result SSDataBlock* p = pQueryInfo->pQInfo->runtimeEnv.outputBuf; pRes->numOfRows = (p != NULL)? p->info.rows: 0; if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) { tscCreateResPointerInfo(pRes, pQueryInfo); - tscSetResRawPtrRv(pRes, pQueryInfo, p, convertNchar); + tscSetResRawPtrRv(pRes, pQueryInfo, p, convertNchar, convertJson); } tscDebug("0x%"PRIx64" retrieve result in pRes, numOfRows:%d", objId, pRes->numOfRows); @@ -1317,8 +1366,6 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue // handle the following query process if (px->pQInfo == NULL) { - SColumnInfo* pColumnInfo = extractColumnInfoFromResult(px->colList); - STableMeta* pTableMeta = tscGetMetaInfo(px, 0)->pTableMeta; SSchema* pSchema = tscGetTableSchema(pTableMeta); @@ -1433,7 +1480,6 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue px->pQInfo->runtimeEnv.udfIsCopy = true; px->pQInfo->runtimeEnv.pUdfInfo = pUdfInfo; - tfree(pColumnInfo); tfree(schema); // set the pRuntimeEnv for pSourceOperator @@ -1442,7 +1488,7 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue uint64_t qId = pSql->self; qTableQuery(px->pQInfo, &qId); - convertQueryResult(pOutput, px, pSql->self, false); + convertQueryResult(pOutput, px, pSql->self, false, false); } static void tscDestroyResPointerInfo(SSqlRes* pRes) { @@ -3093,12 +3139,12 @@ void tscIncStreamExecutionCount(void* pStream) { ps->num += 1; } -bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId, int32_t numOfParams) { +bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId) { if (pTableMetaInfo->pTableMeta == NULL) { return false; } - if (colId == TSDB_TBNAME_COLUMN_INDEX || (colId <= TSDB_UD_COLUMN_INDEX && numOfParams == 2)) { + if (colId == TSDB_TBNAME_COLUMN_INDEX || colId <= TSDB_UD_COLUMN_INDEX) { return true; } @@ -5391,3 +5437,152 @@ char* cloneCurrentDBName(SSqlObj* pSql) { return p; } +int parseJsontoTagData(char* json, SKVRowBuilder* kvRowBuilder, char* errMsg, int16_t startColId){ + // set json NULL data + uint8_t nullTypeVal[CHAR_BYTES + VARSTR_HEADER_SIZE + INT_BYTES] = {0}; + uint32_t jsonNULL = TSDB_DATA_JSON_NULL; + int jsonIndex = startColId + 1; + char nullTypeKey[VARSTR_HEADER_SIZE + INT_BYTES] = {0}; + varDataSetLen(nullTypeKey, INT_BYTES); + nullTypeVal[0] = TSDB_DATA_TYPE_JSON; + varDataSetLen(nullTypeVal + CHAR_BYTES, INT_BYTES); + *(uint32_t*)(varDataVal(nullTypeKey)) = jsonNULL; + tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_NCHAR, nullTypeKey, false); // add json null type + if (strtrim(json) == 0 || strcasecmp(json, "null") == 0){ + *(uint32_t*)(varDataVal(nullTypeVal + CHAR_BYTES)) = jsonNULL; + tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_NCHAR, nullTypeVal, true); // add json null value + return TSDB_CODE_SUCCESS; + } + int32_t jsonNotNull = TSDB_DATA_JSON_NOT_NULL; + *(uint32_t*)(varDataVal(nullTypeVal + CHAR_BYTES)) = jsonNotNull; + tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_NCHAR, nullTypeVal, true); // add json type + + // set json real data + cJSON *root = cJSON_Parse(json); + if (root == NULL){ + tscError("json parse error"); + return tscSQLSyntaxErrMsg(errMsg, "json parse error", NULL); + } + + int size = cJSON_GetArraySize(root); + if(!cJSON_IsObject(root)){ + tscError("json error invalide value"); + return tscSQLSyntaxErrMsg(errMsg, "json error invalide value", NULL); + } + + int retCode = 0; + SHashObj* keyHash = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, false); + for(int i = 0; i < size; i++) { + cJSON* item = cJSON_GetArrayItem(root, i); + if (!item) { + tscError("json inner error:%d", i); + retCode = tscSQLSyntaxErrMsg(errMsg, "json inner error", NULL); + goto end; + } + + char *jsonKey = item->string; + if(!isValidateTag(jsonKey)){ + tscError("json key not validate"); + retCode = tscSQLSyntaxErrMsg(errMsg, "json key not validate", NULL); + goto end; + } + if(strlen(jsonKey) > TSDB_MAX_JSON_KEY_LEN){ + tscError("json key too long error"); + retCode = tscSQLSyntaxErrMsg(errMsg, "json key too long, more than 256", NULL); + goto end; + } + if(strlen(jsonKey) == 0 || taosHashGet(keyHash, jsonKey, strlen(jsonKey)) != NULL){ + continue; + } + + // json key encode by binary + char tagKey[TSDB_MAX_JSON_KEY_LEN + VARSTR_HEADER_SIZE] = {0}; + strncpy(varDataVal(tagKey), jsonKey, strlen(jsonKey)); + int32_t outLen = (int32_t)strlen(jsonKey); + taosHashPut(keyHash, jsonKey, outLen, &outLen, CHAR_BYTES); // add key to hash to remove dumplicate, value is useless + + varDataSetLen(tagKey, outLen); + tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_NCHAR, tagKey, false); // add json key + + if(item->type == cJSON_String){ // add json value format: type|data + char *jsonValue = item->valuestring; + outLen = 0; + char tagVal[TSDB_MAX_JSON_TAGS_LEN] = {0}; + *tagVal = jsonType2DbType(0, item->type); // type + char* tagData = POINTER_SHIFT(tagVal,CHAR_BYTES); + if (!taosMbsToUcs4(jsonValue, strlen(jsonValue), varDataVal(tagData), + TSDB_MAX_JSON_TAGS_LEN - CHAR_BYTES - VARSTR_HEADER_SIZE, &outLen)) { + tscError("json string error:%s|%s", strerror(errno), jsonValue); + retCode = tscSQLSyntaxErrMsg(errMsg, "serizelize json error", NULL); + goto end; + } + + varDataSetLen(tagData, outLen); + tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_NCHAR, tagVal, true); + }else if(item->type == cJSON_Number){ + char tagVal[LONG_BYTES + CHAR_BYTES] = {0}; + *tagVal = jsonType2DbType(item->valuedouble, item->type); // type + char* tagData = POINTER_SHIFT(tagVal,CHAR_BYTES); + if(*tagVal == TSDB_DATA_TYPE_DOUBLE) *((double *)tagData) = item->valuedouble; + else if(*tagVal == TSDB_DATA_TYPE_BIGINT) *((int64_t *)tagData) = item->valueint; + tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_BIGINT, tagVal, true); + }else if(item->type == cJSON_True || item->type == cJSON_False){ + char tagVal[CHAR_BYTES + CHAR_BYTES] = {0}; + *tagVal = jsonType2DbType((double)(item->valueint), item->type); // type + char* tagData = POINTER_SHIFT(tagVal,CHAR_BYTES); + *tagData = (char)(item->valueint); + tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_BOOL, tagVal, true); + }else if(item->type == cJSON_NULL){ + char tagVal[CHAR_BYTES + VARSTR_HEADER_SIZE + INT_BYTES] = {0}; + *tagVal = jsonType2DbType(0, item->type); // type + int32_t* tagData = POINTER_SHIFT(tagVal,CHAR_BYTES); + varDataSetLen(tagData, INT_BYTES); + *(uint32_t*)(varDataVal(tagData)) = TSDB_DATA_JSON_null; + tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_BINARY, tagVal, true); + } + else{ + retCode = tscSQLSyntaxErrMsg(errMsg, "invalidate json value", NULL); + goto end; + } + } + + if(taosHashGetSize(keyHash) == 0){ // set json NULL true + *(uint32_t*)(varDataVal(nullTypeVal + CHAR_BYTES)) = jsonNULL; + memcpy(POINTER_SHIFT(kvRowBuilder->buf, kvRowBuilder->pColIdx[2].offset), nullTypeVal, CHAR_BYTES + VARSTR_HEADER_SIZE + INT_BYTES); + } + +end: + taosHashCleanup(keyHash); + cJSON_Delete(root); + return retCode; +} + +int8_t jsonType2DbType(double data, int jsonType){ + switch(jsonType){ + case cJSON_Number: + if (data - (int64_t)data > 0) return TSDB_DATA_TYPE_DOUBLE; else return TSDB_DATA_TYPE_BIGINT; + case cJSON_String: + return TSDB_DATA_TYPE_NCHAR; + case cJSON_NULL: + return TSDB_DATA_TYPE_BINARY; + case cJSON_True: + case cJSON_False: + return TSDB_DATA_TYPE_BOOL; + } + return TSDB_DATA_TYPE_NULL; +} + +// get key from json->'key' +void getJsonKey(SStrToken *t0){ + while(true){ + t0->n = tGetToken(t0->z, &t0->type); + if (t0->type == TK_STRING){ + t0->z++; + t0->n -= 2; + break; + }else if (t0->type == TK_ILLEGAL){ + assert(0); + } + t0->z += t0->n; + } +} diff --git a/src/common/inc/tdataformat.h b/src/common/inc/tdataformat.h index 98134c2433b690239cf33608dce92ad3fbbcee62..c9359d821d1adb8571bf14cb8c413b41a99a9b42 100644 --- a/src/common/inc/tdataformat.h +++ b/src/common/inc/tdataformat.h @@ -547,7 +547,7 @@ void tdDestroyKVRowBuilder(SKVRowBuilder *pBuilder); void tdResetKVRowBuilder(SKVRowBuilder *pBuilder); SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder); -static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, int8_t type, void *value) { +static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, int8_t type, void *value, bool isJumpJsonVType) { if (pBuilder->nCols >= pBuilder->tCols) { pBuilder->tCols *= 2; SColIdx* pColIdx = (SColIdx *)realloc((void *)(pBuilder->pColIdx), sizeof(SColIdx) * pBuilder->tCols); @@ -560,9 +560,14 @@ static FORCE_INLINE int tdAddColToKVRow(SKVRowBuilder *pBuilder, int16_t colId, pBuilder->nCols++; - int tlen = IS_VAR_DATA_TYPE(type) ? varDataTLen(value) : TYPE_BYTES[type]; + char* jumpType = (char*)value; + if(isJumpJsonVType) jumpType += CHAR_BYTES; + int tlen = IS_VAR_DATA_TYPE(type) ? varDataTLen(jumpType) : TYPE_BYTES[type]; + if(isJumpJsonVType) tlen += CHAR_BYTES; // add type size + if (tlen > pBuilder->alloc - pBuilder->size) { while (tlen > pBuilder->alloc - pBuilder->size) { + assert(pBuilder->alloc > 0); pBuilder->alloc *= 2; } void* buf = realloc(pBuilder->buf, pBuilder->alloc); diff --git a/src/common/inc/tvariant.h b/src/common/inc/tvariant.h index 03b17bdc463d6b5d0f812eafa723c886964d35fc..31bc7a247ad9851aa48d99a3c6eec31e90313972 100644 --- a/src/common/inc/tvariant.h +++ b/src/common/inc/tvariant.h @@ -25,7 +25,7 @@ extern "C" { // variant, each number/string/field_id has a corresponding struct during parsing sql typedef struct tVariant { - uint32_t nType; + int32_t nType; // change uint to int, because in tVariantCreate() pVar->nType = -1; // -1 means error type int32_t nLen; // only used for string, for number, it is useless union { int64_t i64; diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index cc2bb8803badc2aae2e80200691be0439bac3afe..36da3817824f1c03dc0bc19492e23d25799945cc 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -117,11 +117,12 @@ void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) { doExprTreeDestroy(&pNode, fp); } else if (pNode->nodeType == TSQL_NODE_VALUE) { tVariantDestroy(pNode->pVal); + tfree(pNode->pVal); } else if (pNode->nodeType == TSQL_NODE_COL) { tfree(pNode->pSchema); } - free(pNode); + tfree(pNode); } static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { @@ -138,12 +139,12 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { } } else if ((*pExpr)->nodeType == TSQL_NODE_VALUE) { tVariantDestroy((*pExpr)->pVal); - free((*pExpr)->pVal); + tfree((*pExpr)->pVal); } else if ((*pExpr)->nodeType == TSQL_NODE_COL) { - free((*pExpr)->pSchema); + tfree((*pExpr)->pSchema); } - free(*pExpr); + tfree(*pExpr); *pExpr = NULL; } @@ -288,7 +289,7 @@ static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) { tVariant* pVal = expr->pVal; tbufWriteUint32(bw, pVal->nType); - if (pVal->nType == TSDB_DATA_TYPE_BINARY) { + if (pVal->nType == TSDB_DATA_TYPE_BINARY || pVal->nType == TSDB_DATA_TYPE_NCHAR) { tbufWriteInt32(bw, pVal->nLen); tbufWrite(bw, pVal->pz, pVal->nLen); } else { @@ -349,7 +350,7 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) { pExpr->pVal = pVal; pVal->nType = tbufReadUint32(br); - if (pVal->nType == TSDB_DATA_TYPE_BINARY) { + if (pVal->nType == TSDB_DATA_TYPE_BINARY || pVal->nType == TSDB_DATA_TYPE_NCHAR) { tbufReadToBuffer(br, &pVal->nLen, sizeof(pVal->nLen)); pVal->pz = calloc(1, pVal->nLen + 1); tbufReadToBuffer(br, pVal->pz, pVal->nLen); diff --git a/src/common/src/tname.c b/src/common/src/tname.c index c0951cba700fbea2d992da147620cf65bd1f75b9..5d7e8ce54219a1d9d36a7ac21997bb18712a286b 100644 --- a/src/common/src/tname.c +++ b/src/common/src/tname.c @@ -4,6 +4,7 @@ #include "tname.h" #include "ttoken.h" #include "tvariant.h" +#include "tglobal.h" #define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS) #define VALIDNUMOFTAGS(x) ((x) >= 0 && (x) <= TSDB_MAX_TAGS) @@ -251,6 +252,9 @@ static bool doValidateSchema(SSchema* pSchema, int32_t numOfCols, int32_t maxLen int32_t rowLen = 0; for (int32_t i = 0; i < numOfCols; ++i) { + if (pSchema[i].type == TSDB_DATA_TYPE_JSON && numOfCols != 1){ + return false; + } // 1. valid types if (!isValidDataType(pSchema[i].type)) { return false; @@ -301,8 +305,12 @@ bool tIsValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_t numOfTag if (!doValidateSchema(pSchema, numOfCols, TSDB_MAX_BYTES_PER_ROW)) { return false; } + int32_t maxTagLen = TSDB_MAX_TAGS_LEN; + if (numOfTags == 1 && pSchema[numOfCols].type == TSDB_DATA_TYPE_JSON){ + maxTagLen = TSDB_MAX_JSON_TAGS_LEN; + } - if (!doValidateSchema(&pSchema[numOfCols], numOfTags, TSDB_MAX_TAGS_LEN)) { + if (!doValidateSchema(&pSchema[numOfCols], numOfTags, maxTagLen)) { return false; } diff --git a/src/common/src/ttypes.c b/src/common/src/ttypes.c index 08bfc2e9aa6f0b9337d484c725f2737cbbacaac0..81bc9c7275b07cf41dc1305e4db807e1b2b839a0 100644 --- a/src/common/src/ttypes.c +++ b/src/common/src/ttypes.c @@ -18,7 +18,7 @@ #include "ttokendef.h" #include "tscompression.h" -const int32_t TYPE_BYTES[15] = { +const int32_t TYPE_BYTES[16] = { -1, // TSDB_DATA_TYPE_NULL sizeof(int8_t), // TSDB_DATA_TYPE_BOOL sizeof(int8_t), // TSDB_DATA_TYPE_TINYINT @@ -34,6 +34,7 @@ const int32_t TYPE_BYTES[15] = { sizeof(uint16_t), // TSDB_DATA_TYPE_USMALLINT sizeof(uint32_t), // TSDB_DATA_TYPE_UINT sizeof(uint64_t), // TSDB_DATA_TYPE_UBIGINT + sizeof(int8_t), // TSDB_DATA_TYPE_JSON }; #define DO_STATICS(__sum, __min, __max, __minIndex, __maxIndex, _list, _index) \ @@ -367,8 +368,8 @@ static void getStatics_nchr(const void *pData, int32_t numOfRow, int64_t *min, i *maxIndex = 0; } -tDataTypeDescriptor tDataTypes[15] = { - {TSDB_DATA_TYPE_NULL, 6, 1, "NOTYPE", 0, 0, NULL, NULL, NULL}, +tDataTypeDescriptor tDataTypes[16] = { + {TSDB_DATA_TYPE_NULL, 6, 1, "NOTYPE", 0, 0, NULL, NULL, NULL}, {TSDB_DATA_TYPE_BOOL, 4, CHAR_BYTES, "BOOL", false, true, tsCompressBool, tsDecompressBool, getStatics_bool}, {TSDB_DATA_TYPE_TINYINT, 7, CHAR_BYTES, "TINYINT", INT8_MIN, INT8_MAX, tsCompressTinyint, tsDecompressTinyint, getStatics_i8}, {TSDB_DATA_TYPE_SMALLINT, 8, SHORT_BYTES, "SMALLINT", INT16_MIN, INT16_MAX, tsCompressSmallint, tsDecompressSmallint, getStatics_i16}, @@ -376,13 +377,14 @@ tDataTypeDescriptor tDataTypes[15] = { {TSDB_DATA_TYPE_BIGINT, 6, LONG_BYTES, "BIGINT", INT64_MIN, INT64_MAX, tsCompressBigint, tsDecompressBigint, getStatics_i64}, {TSDB_DATA_TYPE_FLOAT, 5, FLOAT_BYTES, "FLOAT", 0, 0, tsCompressFloat, tsDecompressFloat, getStatics_f}, {TSDB_DATA_TYPE_DOUBLE, 6, DOUBLE_BYTES, "DOUBLE", 0, 0, tsCompressDouble, tsDecompressDouble, getStatics_d}, - {TSDB_DATA_TYPE_BINARY, 6, 0, "BINARY", 0, 0, tsCompressString, tsDecompressString, getStatics_bin}, + {TSDB_DATA_TYPE_BINARY, 6, 0, "BINARY", 0, 0, tsCompressString, tsDecompressString, getStatics_bin}, {TSDB_DATA_TYPE_TIMESTAMP, 9, LONG_BYTES, "TIMESTAMP", INT64_MIN, INT64_MAX, tsCompressTimestamp, tsDecompressTimestamp, getStatics_i64}, - {TSDB_DATA_TYPE_NCHAR, 5, 8, "NCHAR", 0, 0, tsCompressString, tsDecompressString, getStatics_nchr}, + {TSDB_DATA_TYPE_NCHAR, 5, 8, "NCHAR", 0, 0, tsCompressString, tsDecompressString, getStatics_nchr}, {TSDB_DATA_TYPE_UTINYINT, 16, CHAR_BYTES, "TINYINT UNSIGNED", 0, UINT8_MAX, tsCompressTinyint, tsDecompressTinyint, getStatics_u8}, {TSDB_DATA_TYPE_USMALLINT, 17, SHORT_BYTES, "SMALLINT UNSIGNED", 0, UINT16_MAX, tsCompressSmallint, tsDecompressSmallint, getStatics_u16}, {TSDB_DATA_TYPE_UINT, 12, INT_BYTES, "INT UNSIGNED", 0, UINT32_MAX, tsCompressInt, tsDecompressInt, getStatics_u32}, {TSDB_DATA_TYPE_UBIGINT, 15, LONG_BYTES, "BIGINT UNSIGNED", 0, UINT64_MAX, tsCompressBigint, tsDecompressBigint, getStatics_u64}, + {TSDB_DATA_TYPE_JSON,4, TSDB_MAX_JSON_TAGS_LEN, "JSON", 0, 0, tsCompressString, tsDecompressString, getStatics_nchr}, }; char tTokenTypeSwitcher[13] = { @@ -428,7 +430,7 @@ FORCE_INLINE void* getDataMax(int32_t type) { bool isValidDataType(int32_t type) { - return type >= TSDB_DATA_TYPE_NULL && type <= TSDB_DATA_TYPE_UBIGINT; + return type >= TSDB_DATA_TYPE_NULL && type <= TSDB_DATA_TYPE_JSON; } void setVardataNull(void* val, int32_t type) { @@ -438,6 +440,9 @@ void setVardataNull(void* val, int32_t type) { } else if (type == TSDB_DATA_TYPE_NCHAR) { varDataSetLen(val, sizeof(int32_t)); *(uint32_t*) varDataVal(val) = TSDB_DATA_NCHAR_NULL; + } else if (type == TSDB_DATA_TYPE_JSON) { + varDataSetLen(val, sizeof(int32_t)); + *(uint32_t*) varDataVal(val) = TSDB_DATA_JSON_NULL; } else { assert(0); } @@ -505,6 +510,7 @@ void setNullN(void *val, int32_t type, int32_t bytes, int32_t numOfElems) { break; case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_JSON: for (int32_t i = 0; i < numOfElems; ++i) { setVardataNull(POINTER_SHIFT(val, i * bytes), type); } diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c index f22e3da28b331d455f5f4d73251c37072e1f69fc..68ed5c5c109cdfacb5ffac50e4f424ec431b78a0 100644 --- a/src/common/src/tvariant.c +++ b/src/common/src/tvariant.c @@ -158,7 +158,7 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32 pVar->dKey = GET_FLOAT_VAL(pz); break; } - case TSDB_DATA_TYPE_NCHAR: { // here we get the nchar length from raw binary bits length + case TSDB_DATA_TYPE_NCHAR:{ // here we get the nchar length from raw binary bits length size_t lenInwchar = len / TSDB_NCHAR_SIZE; pVar->wpz = calloc(1, (lenInwchar + 1) * TSDB_NCHAR_SIZE); @@ -167,7 +167,13 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32 break; } - case TSDB_DATA_TYPE_BINARY: { // todo refactor, extract a method + case TSDB_DATA_TYPE_JSON:{ + pVar->pz = calloc(len + 2, sizeof(char)); + memcpy(pVar->pz, pz, len); + pVar->nLen = (int32_t)len; + break; + } + case TSDB_DATA_TYPE_BINARY:{ pVar->pz = calloc(len + 1, sizeof(char)); memcpy(pVar->pz, pz, len); pVar->nLen = (int32_t)len; @@ -185,7 +191,7 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32 void tVariantDestroy(tVariant *pVar) { if (pVar == NULL) return; - if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR) { + if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR || pVar->nType == TSDB_DATA_TYPE_JSON) { tfree(pVar->pz); pVar->nLen = 0; } @@ -210,11 +216,41 @@ bool tVariantIsValid(tVariant *pVar) { return isValidDataType(pVar->nType); } +bool tVariantTypeMatch(tVariant *pVar, int8_t dbType){ + switch (dbType) { + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: { + if(pVar->nType != TSDB_DATA_TYPE_BINARY && pVar->nType != TSDB_DATA_TYPE_NCHAR){ + return false; + } + break; + } + + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_UTINYINT: + case TSDB_DATA_TYPE_USMALLINT: + case TSDB_DATA_TYPE_UINT: + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_UBIGINT: + case TSDB_DATA_TYPE_FLOAT: + case TSDB_DATA_TYPE_DOUBLE:{ + if(pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR){ + return false; + } + break; + } + } + return true; +} + void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { if (pSrc == NULL || pDst == NULL) return; pDst->nType = pSrc->nType; - if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR) { + if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR || pSrc->nType == TSDB_DATA_TYPE_JSON) { int32_t len = pSrc->nLen + TSDB_NCHAR_SIZE; char* p = realloc(pDst->pz, len); assert(p); @@ -249,7 +285,7 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { } } - if (pDst->nType != TSDB_DATA_TYPE_POINTER_ARRAY && pDst->nType != TSDB_DATA_TYPE_VALUE_ARRAY) { + if (pDst->nType != TSDB_DATA_TYPE_POINTER_ARRAY && pDst->nType != TSDB_DATA_TYPE_VALUE_ARRAY && isValidDataType(pDst->nType)) { // if pDst->nType=-1, core dump. eg: where intcolumn=999999999999999999999999999 pDst->nLen = tDataTypes[pDst->nType].bytes; } } @@ -267,7 +303,7 @@ int32_t tVariantCompare(const tVariant* p1, const tVariant* p2) { return 1; } - if (p1->nType == TSDB_DATA_TYPE_BINARY || p1->nType == TSDB_DATA_TYPE_NCHAR) { + if (p1->nType == TSDB_DATA_TYPE_BINARY || p1->nType == TSDB_DATA_TYPE_NCHAR || p1->nType == TSDB_DATA_TYPE_JSON) { if (p1->nLen == p2->nLen) { return memcmp(p1->pz, p2->pz, p1->nLen); } else { @@ -815,7 +851,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc break; } - case TSDB_DATA_TYPE_BINARY: { + case TSDB_DATA_TYPE_BINARY:{ if (!includeLengthPrefix) { if (pVariant->nType == TSDB_DATA_TYPE_NULL) { *(uint8_t*) payload = TSDB_DATA_BINARY_NULL; @@ -852,7 +888,7 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc } break; } - case TSDB_DATA_TYPE_NCHAR: { + case TSDB_DATA_TYPE_NCHAR:{ int32_t newlen = 0; if (!includeLengthPrefix) { if (pVariant->nType == TSDB_DATA_TYPE_NULL) { @@ -888,6 +924,16 @@ int32_t tVariantDumpEx(tVariant *pVariant, char *payload, int16_t type, bool inc break; } + case TSDB_DATA_TYPE_JSON:{ + if (pVariant->nType == TSDB_DATA_TYPE_BINARY){ + *((int8_t *)payload) = TSDB_DATA_JSON_PLACEHOLDER; + } else if (pVariant->nType == TSDB_DATA_TYPE_JSON){ // select * from stable, set tag type to json,from setTagValue/tag_project_function + memcpy(payload, pVariant->pz, pVariant->nLen); + }else { + return -1; + } + break; + } } return 0; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/JsonTagTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/JsonTagTest.java new file mode 100644 index 0000000000000000000000000000000000000000..afba0398752f1fd6c23dd7874301be27616fdab2 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/JsonTagTest.java @@ -0,0 +1,1169 @@ +package com.taosdata.jdbc; + +import com.google.common.collect.Lists; +import org.checkerframework.checker.units.qual.A; +import org.junit.*; +import org.junit.runners.MethodSorters; + +import java.sql.*; +import java.util.List; + +/** + * test json tag + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class JsonTagTest { + private static String dbname = "json_tag_test"; + private static Connection connection; + private static Statement statement; + private static final String superSql = "create table if not exists jsons1(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)"; + private static final String[] sql = { + "insert into jsons1_1 using jsons1 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(now, 1, false, 'json1', '你是') (1591060608000, 23, true, '等等', 'json')", + "insert into jsons1_2 using jsons1 tags('{\"tag1\":5,\"tag2\":\"beijing\"}') values (1591060628000, 2, true, 'json2', 'sss')", + "insert into jsons1_3 using jsons1 tags('{\"tag1\":false,\"tag2\":\"beijing\"}') values (1591060668000, 3, false, 'json3', 'efwe')", + "insert into jsons1_4 using jsons1 tags('{\"tag1\":null,\"tag2\":\"shanghai\",\"tag3\":\"hello\"}') values (1591060728000, 4, true, 'json4', '323sd')", + "insert into jsons1_5 using jsons1 tags('{\"tag1\":1.232, \"tag2\":null}') values(1591060928000, 1, false, '你就会', 'ewe')", + "insert into jsons1_6 using jsons1 tags('{\"tag1\":11,\"tag2\":\"\",\"tag2\":null}') values(1591061628000, 11, false, '你就会','')", + "insert into jsons1_7 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '你就会', 'dws')", + // test duplicate key using the first one. + "CREATE TABLE if not exists jsons1_8 using jsons1 tags('{\"tag1\":null, \"tag1\":true, \"tag1\":45, \"1tag$\":2, \" \":90}')", + + }; + + private static final String[] invalidJsonInsertSql = { + // test empty json string, save as tag is NULL + "insert into jsons1_9 using jsons1 tags('\t') values (1591062328000, 24, NULL, '你就会', '2sdw')", + }; + + private static final String[] invalidJsonCreateSql = { + "CREATE TABLE if not exists jsons1_10 using jsons1 tags('')", + "CREATE TABLE if not exists jsons1_11 using jsons1 tags(' ')", + "CREATE TABLE if not exists jsons1_12 using jsons1 tags('{}')", + "CREATE TABLE if not exists jsons1_13 using jsons1 tags('null')", + }; + + // test invalidate json + private static final String[] errorJsonInsertSql = { + "CREATE TABLE if not exists jsons1_14 using jsons1 tags('\"efwewf\"')", + "CREATE TABLE if not exists jsons1_14 using jsons1 tags('3333')", + "CREATE TABLE if not exists jsons1_14 using jsons1 tags('33.33')", + "CREATE TABLE if not exists jsons1_14 using jsons1 tags('false')", + "CREATE TABLE if not exists jsons1_14 using jsons1 tags('[1,true]')", + "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{222}')", + "CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"fe\"}')", + }; + + private static final String[] errorSelectSql = { + "select * from jsons1 where jtag->tag1='beijing'", + "select * from jsons1 where jtag->'location'", + "select * from jsons1 where jtag->''", + "select * from jsons1 where jtag->''=9", + "select -> from jsons1", + "select ? from jsons1", + "select * from jsons1 where contains", + "select * from jsons1 where jtag->", + "select jtag->location from jsons1", + "select jtag contains location from jsons1", + "select * from jsons1 where jtag contains location", + "select * from jsons1 where jtag contains ''", + "select * from jsons1 where jtag contains 'location'='beijing'", + // test where with json tag + "select * from jsons1_1 where jtag is not null", + "select * from jsons1 where jtag='{\"tag1\":11,\"tag2\":\"\"}'", + "select * from jsons1 where jtag->'tag1'={}" + }; + + @Test + public void case01_InsertTest() throws SQLException { + for (String sql : sql) { + statement.execute(sql); + } + for (String sql : invalidJsonInsertSql) { + statement.execute(sql); + } + for (String sql : invalidJsonCreateSql) { + statement.execute(sql); + } + } + + @Test + public void case02_InvalidJsonInsertTest() { + int count = 0; + for (String sql : errorJsonInsertSql) { + try { + statement.execute(sql); + } catch (SQLException e) { + count++; + } + } + Assert.assertEquals(errorJsonInsertSql.length, count); + } + + // test invalidate json key, key must can be printed assic char + @Test(expected = SQLException.class) + public void case02_ArrayErrorTest() throws SQLException { + statement.execute("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"tag1\":[1,true]}')"); + } + + @Test(expected = SQLException.class) + public void case02_EmptyKeyErrorTest() throws SQLException { + statement.execute("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"\":\"fff\"}')"); + } + + @Test(expected = SQLException.class) + public void case02_EmptyValueErrorTest() throws SQLException { + statement.execute("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"tag1\":{}}')"); + } + + @Test(expected = SQLException.class) + public void case02_AbnormalKeyErrorTest1() throws SQLException { + statement.execute("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"。loc\":\"fff\"}')"); + } + + @Test(expected = SQLException.class) + public void case02_AbnormalKeyErrorTest2() throws SQLException { + statement.execute("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"\t\":\"fff\"}')"); + } + + @Test(expected = SQLException.class) + public void case02_AbnormalKeyErrorTest3() throws SQLException { + statement.execute("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"试试\":\"fff\"}')"); + } + + @Test + public void case03_AlterTag() throws SQLException { + statement.execute("ALTER TABLE jsons1_1 SET TAG jtag='{\"tag1\":\"femail\",\"tag2\":35,\"tag3\":true}'"); + } + + @Test(expected = SQLException.class) + public void case03_AddTagErrorTest() throws SQLException { + statement.execute("ALTER STABLE jsons1 add tag tag2 nchar(20)"); + } + + @Test(expected = SQLException.class) + public void case03_dropTagErrorTest() throws SQLException { + statement.execute("ALTER STABLE jsons1 drop tag jtag"); + } + + @Test(expected = SQLException.class) + public void case03_AlterTagErrorTest() throws SQLException { + statement.execute("ALTER TABLE jsons1_1 SET TAG jtag=4"); + } + + // test error syntax + @Test + public void case04_SelectErrorTest() { + int count = 0; + for (String sql : errorSelectSql) { + try { + statement.execute(sql); + } catch (SQLException e) { + count++; + } + } + Assert.assertEquals(errorSelectSql.length, count); + } + + // test select normal column + @Test + public void case04_select01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select dataint from jsons1"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(sql.length + invalidJsonInsertSql.length, count); + close(resultSet); + } + + // test select json tag + @Test + public void case04_select02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(sql.length + invalidJsonInsertSql.length, count); + close(resultSet); + } + + @Test + public void case04_select03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag from jsons1"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(sql.length + invalidJsonInsertSql.length + invalidJsonCreateSql.length, count); + close(resultSet); + } + + @Test + public void case04_select04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag from jsons1 where jtag is null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(invalidJsonInsertSql.length + invalidJsonCreateSql.length, count); + close(resultSet); + } + + @Test + public void case04_select05() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag from jsons1 where jtag is not null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(sql.length, count); + close(resultSet); + } + + @Test + public void case04_select06() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag from jsons1_8"); + resultSet.next(); + String result = resultSet.getString(1); + Assert.assertEquals("{\"tag1\":null,\"1tag$\":2,\" \":90}", result); + close(resultSet); + } + + @Test + public void case04_select07() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag from jsons1_1"); + resultSet.next(); + String result = resultSet.getString(1); + Assert.assertEquals("{\"tag1\":\"femail\",\"tag2\":35,\"tag3\":true}", result); + close(resultSet); + } + + // test jtag is NULL + @Test + public void case04_select08() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag from jsons1_9"); + resultSet.next(); + String result = resultSet.getString(1); + Assert.assertNull(result); + close(resultSet); + } + + // test select json tag->'key', value is string + @Test + public void case04_select09() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag1' from jsons1_1"); + resultSet.next(); + String result = resultSet.getString(1); + Assert.assertEquals("\"femail\"", result); + close(resultSet); + } + + @Test + public void case04_select10() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag2' from jsons1_6"); + resultSet.next(); + String result = resultSet.getString(1); + Assert.assertEquals("\"\"", result); + close(resultSet); + } + + // test select json tag->'key', value is int + @Test + public void case04_select11() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag2' from jsons1_1"); + resultSet.next(); + String string = resultSet.getString(1); + Assert.assertEquals("35", string); + close(resultSet); + } + + // test select json tag->'key', value is bool + @Test + public void case04_select12() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag3' from jsons1_1"); + resultSet.next(); + String string = resultSet.getString(1); + Assert.assertEquals("true", string); + close(resultSet); + } + + // test select json tag->'key', value is null + @Test + public void case04_select13() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag1' from jsons1_4"); + resultSet.next(); + String string = resultSet.getString(1); + Assert.assertEquals("null", string); + close(resultSet); + } + + // test select json tag->'key', value is double + @Test + public void case04_select14() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag1' from jsons1_5"); + resultSet.next(); + String string = resultSet.getString(1); + Assert.assertEquals("1.232000000", string); + close(resultSet); + } + + // test select json tag->'key', key is not exist + @Test + public void case04_select15() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag10' from jsons1_4"); + resultSet.next(); + String string = resultSet.getString(1); + Assert.assertNull(string); + close(resultSet); + } + + @Test + public void case04_select16() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag1' from jsons1"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(sql.length + invalidJsonCreateSql.length + invalidJsonInsertSql.length, count); + close(resultSet); + } + + @Test + public void case04_select17() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag1' from jsons1"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(sql.length + invalidJsonCreateSql.length + invalidJsonInsertSql.length, count); + close(resultSet); + } + + // where json value is string + @Test + public void case04_select19() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag2'='beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case04_select20() throws SQLException { + ResultSet resultSet = statement.executeQuery("select dataint,tbname,jtag->'tag1',jtag from jsons1 where jtag->'tag2'='beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case04_select21() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'='beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test + public void case04_select23() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'='收到货'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case05_symbolOperation01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag2'>'beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case05_symbolOperation02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag2'>='beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(3, count); + close(resultSet); + } + + @Test + public void case05_symbolOperation03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag2'<'beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case05_symbolOperation04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag2'<='beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(4, count); + close(resultSet); + } + + @Test + public void case05_symbolOperation05() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag2'!='beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(3, count); + close(resultSet); + } + + @Test + public void case05_symbolOperation06() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag2'=''"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + // where json value is int + @Test + public void case06_selectValue01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=5"); + int count = 0; + while (resultSet.next()) { + System.out.println(resultSet.getString(1)); + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case06_selectValue02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'<54"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(3, count); + close(resultSet); + } + + @Test + public void case06_selectValue03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'<=11"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(3, count); + close(resultSet); + } + + @Test + public void case06_selectValue04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'>4"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case06_selectValue05() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'>=5"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case06_selectValue06() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'!=5"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case06_selectValue07() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'!=55"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(3, count); + close(resultSet); + } + + @Test + public void case06_selectValue08() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=10"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + // where json value is double + @Test + public void case07_selectValue01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=1.232"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case07_doubleOperation01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'<1.232"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test + public void case07_doubleOperation02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'<=1.232"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case07_doubleOperation03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'>1.23"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(3, count); + close(resultSet); + } + + @Test + public void case07_doubleOperation04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'>=1.232"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(3, count); + close(resultSet); + } + + @Test + public void case07_doubleOperation05() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'!=1.232"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case07_doubleOperation06() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'!=3.232"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(3, count); + close(resultSet); + } + + @Test(expected = SQLException.class) + public void case07_doubleOperation07() throws SQLException { + statement.executeQuery("select * from jsons1 where jtag->'tag1'/0=3"); + } + + @Test(expected = SQLException.class) + public void case07_doubleOperation08() throws SQLException { + statement.executeQuery("select * from jsons1 where jtag->'tag1'/5=1"); + } + + @Test + public void case08_boolOperation01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=true"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test + public void case08_boolOperation02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=false"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case08_boolOperation03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'!=false"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test(expected = SQLException.class) + public void case08_boolOperation04() throws SQLException { + statement.executeQuery("select * from jsons1 where jtag->'tag1'>false"); + } + + // where json value is null + @Test + public void case09_select01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case09_select02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag is null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case09_select03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag is not null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(8, count); + close(resultSet); + } + + @Test + public void case09_select04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag_no_exist'=3"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test + public void case09_select05() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1' is null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(invalidJsonInsertSql.length, count); + close(resultSet); + } + + @Test + public void case09_select06() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag4' is null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(sql.length + invalidJsonInsertSql.length, count); + close(resultSet); + } + + @Test + public void case09_select07() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag3' is not null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(4, count); + close(resultSet); + } + + // test ? + @Test + public void case09_select10() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag contains 'tag1'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(8, count); + close(resultSet); + } + + @Test + public void case09_select11() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag contains 'tag3'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(4, count); + close(resultSet); + } + + @Test + public void case09_select12() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag contains 'tag_no_exist'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + // test json tag in where condition with and/or + @Test + public void case10_selectAndOr01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case10_selectAndOr02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=false or jtag->'tag2'='beijing'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case10_selectAndOr03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='shanghai'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test + public void case10_selectAndOr04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'=13 or jtag->'tag2'>35"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test + public void case10_selectAndOr05() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1' is not null and jtag contains 'tag3'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(4, count); + close(resultSet); + } + + @Test + public void case10_selectAndOr06() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1'='femail' and jtag contains 'tag3'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + // test with tbname/normal column + @Test + public void case11_selectTbName01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where tbname = 'jsons1_1'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case11_selectTbName02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case11_selectTbName03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3' and dataint=3"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test + public void case11_selectTbName04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3' and dataint=23"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + // test where condition like + @Test + public void case12_selectWhere01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select *,tbname from jsons1 where jtag->'tag2' like 'bei%'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case12_selectWhere02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select *,tbname from jsons1 where jtag->'tag1' like 'fe%' and jtag->'tag2' is not null"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + // test where condition in no support in + @Test(expected = SQLException.class) + public void case12_selectWhere03() throws SQLException { + statement.executeQuery("select * from jsons1 where jtag->'tag1' in ('beijing')"); + } + + // test where condition match + @Test + public void case12_selectWhere04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1' match 'ma'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case12_selectWhere05() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1' match 'ma$'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + @Test + public void case12_selectWhere06() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag2' match 'jing$'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(2, count); + close(resultSet); + } + + @Test + public void case12_selectWhere07() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from jsons1 where jtag->'tag1' match '收到'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + // test distinct + @Test + public void case13_selectDistinct01() throws SQLException { + statement.execute("insert into jsons1_14 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '你就会', 'dws')"); + } + + @Test + public void case13_selectDistinct02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select distinct jtag->'tag1' from jsons1"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(8, count); + close(resultSet); + } + + @Test + public void case13_selectDistinct03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select distinct jtag from jsons1"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(9, count); + close(resultSet); + } + + // test dumplicate key with normal colomn + @Test + public void case14_selectDump01() throws SQLException { + statement.execute("INSERT INTO jsons1_15 using jsons1 tags('{\"tbname\":\"tt\",\"databool\":true,\"datastr\":\"是是是\"}') values(1591060828000, 4, false, 'jjsf', \"你就会\")"); + } + + @Test + public void case14_selectDump02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select *,tbname,jtag from jsons1 where jtag->'datastr' match '是' and datastr match 'js'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(1, count); + close(resultSet); + } + + @Test + public void case14_selectDump03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select tbname,jtag->'tbname' from jsons1 where jtag->'tbname'='tt' and tbname='jsons1_14'"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(0, count); + close(resultSet); + } + + // test join + @Test + public void case15_selectJoin01() throws SQLException { + statement.execute("create table if not exists jsons2(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)"); + statement.execute("insert into jsons2_1 using jsons2 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 2, false, 'json2', '你是2')"); + statement.execute("insert into jsons2_2 using jsons2 tags('{\"tag1\":5,\"tag2\":null}') values (1591060628000, 2, true, 'json2', 'sss')"); + + statement.execute("create table if not exists jsons3(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)"); + statement.execute("insert into jsons3_1 using jsons3 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 3, false, 'json3', '你是3')"); + statement.execute("insert into jsons3_2 using jsons3 tags('{\"tag1\":5,\"tag2\":\"beijing\"}') values (1591060638000, 2, true, 'json3', 'sss')"); + } + + // TODO check result + @Test + public void case15_selectJoin02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select 'sss',33,a.jtag->'tag3' from jsons2 a,jsons3 b where a.ts=b.ts and a.jtag->'tag1'=b.jtag->'tag1'"); + + close(resultSet); + } + + // test group by & order by json tag + // TODO check other result + @Test + public void case16_selectGroupOrder01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag1' desc"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(8, count); + close(resultSet); + } + + @Test + public void case16_selectGroupOrder02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag1' asc"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(8, count); + close(resultSet); + } + + // test stddev with group by json tag + // TODO check result + @Test + public void case17_selectStddev01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select stddev(dataint) from jsons1 group by jtag->'tag1'"); + String s = ""; + int count = 0; + while (resultSet.next()) { + count++; + s = resultSet.getString(2); + + } + Assert.assertEquals(8, count); + Assert.assertEquals("\"femail\"", s); + close(resultSet); + } + + // subquery with json tag + @Test + public void case18_selectSubquery01() throws SQLException { + ResultSet resultSet = statement.executeQuery("select * from (select jtag, dataint from jsons1)"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(11, count); + close(resultSet); + } + + @Test + public void case18_selectSubquery02() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag1' from (select jtag->'tag1', dataint from jsons1)"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(11, count); + close(resultSet); + } + + @Test + public void case18_selectSubquery03() throws SQLException { + ResultSet resultSet = statement.executeQuery("select jtag->'tag1' from (select jtag->'tag1', dataint from jsons1)"); + ResultSetMetaData metaData = resultSet.getMetaData(); + String columnName = metaData.getColumnName(1); + Assert.assertEquals("jtag->'tag1'", columnName); + close(resultSet); + } + + @Test + public void case18_selectSubquery04() throws SQLException { + ResultSet resultSet = statement.executeQuery("select ts,tbname,jtag->'tag1' from (select jtag->'tag1',tbname,ts from jsons1 order by ts)"); + int count = 0; + while (resultSet.next()) { + count++; + } + Assert.assertEquals(11, count); + close(resultSet); + } + + private void close(ResultSet resultSet) { + try { + if (null != resultSet) { + resultSet.close(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @BeforeClass + public static void beforeClass() { + String host = "127.0.0.1"; + final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + try { + connection = DriverManager.getConnection(url); + statement = connection.createStatement(); + statement.execute("drop database if exists " + dbname); + statement.execute("create database if not exists " + dbname); + statement.execute("use " + dbname); + statement.execute(superSql); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @AfterClass + public static void afterClass() { + try { + if (null != statement) { + statement.execute("drop database " + dbname); + statement.close(); + } + if (null != connection) { + connection.close(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + } +} diff --git a/src/connector/python/taos/bind.py b/src/connector/python/taos/bind.py index 083ddc99aea8dc6f39b1f22ac5f77d2584a2fe69..05659714ef86da3bda383bfe7d7b25403848637f 100644 --- a/src/connector/python/taos/bind.py +++ b/src/connector/python/taos/bind.py @@ -124,6 +124,21 @@ class TaosBind(ctypes.Structure): self.buffer_length = length self.length = pointer(c_size_t(self.buffer_length)) + def json(self, value): + buffer = None + length = 0 + if isinstance(value, str): + bytes = value.encode("utf-8") + buffer = create_string_buffer(bytes) + length = len(bytes) + else: + buffer = value + length = len(value) + self.buffer_type = FieldType.C_JSON + self.buffer = cast(buffer, c_void_p) + self.buffer_length = length + self.length = pointer(c_size_t(self.buffer_length)) + def tinyint_unsigned(self, value): self.buffer_type = FieldType.C_TINYINT_UNSIGNED self.buffer = cast(pointer(c_uint8(value)), c_void_p) @@ -356,6 +371,11 @@ class TaosMultiBind(ctypes.Structure): self.buffer_type = FieldType.C_NCHAR self._str_to_buffer(values) + def json(self, values): + # type: (list[str]) -> None + self.buffer_type = FieldType.C_JSON + self._str_to_buffer(values) + def tinyint_unsigned(self, values): self.buffer_type = FieldType.C_TINYINT_UNSIGNED self.buffer_length = sizeof(c_uint8) diff --git a/src/connector/python/taos/constants.py b/src/connector/python/taos/constants.py index 8ad5b69fc099718fa4f4b8c08cf689b17663eae0..34044a15fc0cd73323552f1b4b8c280d6cad5a9b 100644 --- a/src/connector/python/taos/constants.py +++ b/src/connector/python/taos/constants.py @@ -25,6 +25,7 @@ class FieldType(object): C_SMALLINT_UNSIGNED = 12 C_INT_UNSIGNED = 13 C_BIGINT_UNSIGNED = 14 + C_JSON = 15 # NULL value definition # NOTE: These values should change according to C definition in tsdb.h C_BOOL_NULL = 0x02 diff --git a/src/connector/python/taos/cursor.py b/src/connector/python/taos/cursor.py index 5d21ff95af5d81367e7143d001cc688d90877b67..a8d82bea2ea188f8a08d6603dd33735ea0a0a5af 100644 --- a/src/connector/python/taos/cursor.py +++ b/src/connector/python/taos/cursor.py @@ -188,6 +188,9 @@ class TaosCursor(object): if dataType.upper() == "NCHAR": if self._description[col][1] == FieldType.C_NCHAR: return True + if dataType.upper() == "JSON": + if self._description[col][1] == FieldType.C_JSON: + return True return False diff --git a/src/connector/python/taos/field.py b/src/connector/python/taos/field.py index f6fa28e8336fa53a137ce7bd9a25b99a32263f1b..a6d64422e238b46b096a5ae62c42566666f226ad 100644 --- a/src/connector/python/taos/field.py +++ b/src/connector/python/taos/field.py @@ -207,6 +207,7 @@ CONVERT_FUNC = { FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python, + FieldType.C_JSON: _crow_nchar_to_python, } CONVERT_FUNC_BLOCK = { @@ -224,6 +225,7 @@ CONVERT_FUNC_BLOCK = { FieldType.C_SMALLINT_UNSIGNED: _crow_smallint_unsigned_to_python, FieldType.C_INT_UNSIGNED: _crow_int_unsigned_to_python, FieldType.C_BIGINT_UNSIGNED: _crow_bigint_unsigned_to_python, + FieldType.C_JSON: _crow_nchar_to_python_block, } # Corresponding TAOS_FIELD structure in C diff --git a/src/dnode/src/dnodeMain.c b/src/dnode/src/dnodeMain.c index bc6631284593c74e12842b4c6ea9994d099c3dd9..420f462051687c72019d7c0697a23c940e4b8ae0 100644 --- a/src/dnode/src/dnodeMain.c +++ b/src/dnode/src/dnodeMain.c @@ -170,7 +170,6 @@ int32_t dnodeInitSystem() { taosResolveCRC(); taosInitGlobalCfg(); taosReadGlobalLogCfg(); - taosSetCoreDump(); dnodeInitTmr(); if (dnodeCreateDir(tsLogDir) < 0) { @@ -190,6 +189,7 @@ int32_t dnodeInitSystem() { return -1; } + taosSetCoreDump(); dInfo("start to initialize TDengine"); taosInitNotes(); diff --git a/src/inc/taos.h b/src/inc/taos.h index 910ec8c7d83b1f01ce4b14dcdcc718cc0fdbc1f9..2b74f9c1844641ccef5ad1fb8e9d25a4d3262ecc 100644 --- a/src/inc/taos.h +++ b/src/inc/taos.h @@ -46,6 +46,7 @@ typedef void **TAOS_ROW; #define TSDB_DATA_TYPE_USMALLINT 12 // 2 bytes #define TSDB_DATA_TYPE_UINT 13 // 4 bytes #define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes +#define TSDB_DATA_TYPE_JSON 15 // json string typedef enum { TSDB_OPTION_LOCALE, diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index f05d1466371f32358e3442f53735028b20641d16..b7c628a1189c1c9f368d4079de6a2e1078e2cfa8 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -39,7 +39,7 @@ extern "C" { #define TSKEY_INITIAL_VAL INT64_MIN // Bytes for each type. -extern const int32_t TYPE_BYTES[15]; +extern const int32_t TYPE_BYTES[16]; // TODO: replace and remove code below #define CHAR_BYTES sizeof(char) @@ -70,6 +70,11 @@ extern const int32_t TYPE_BYTES[15]; #define TSDB_DATA_DOUBLE_NULL 0x7FFFFF0000000000L // an NAN #define TSDB_DATA_NCHAR_NULL 0xFFFFFFFF #define TSDB_DATA_BINARY_NULL 0xFF +#define TSDB_DATA_JSON_PLACEHOLDER 0x7F +#define TSDB_DATA_JSON_NULL 0xFFFFFFFF +#define TSDB_DATA_JSON_null 0xFFFFFFFE +#define TSDB_DATA_JSON_NOT_NULL 0x01 +#define TSDB_DATA_JSON_CAN_NOT_COMPARE 0x7FFFFFFF #define TSDB_DATA_UTINYINT_NULL 0xFF #define TSDB_DATA_USMALLINT_NULL 0xFFFF @@ -176,6 +181,9 @@ do { \ #define TSDB_RELATION_MATCH 14 #define TSDB_RELATION_NMATCH 15 +#define TSDB_RELATION_CONTAINS 16 +#define TSDB_RELATION_ARROW 17 + #define TSDB_BINARY_OP_ADD 30 #define TSDB_BINARY_OP_SUBTRACT 31 #define TSDB_BINARY_OP_MULTIPLY 32 @@ -222,8 +230,11 @@ do { \ */ #define TSDB_MAX_BYTES_PER_ROW 49151 #define TSDB_MAX_TAGS_LEN 16384 +#define TSDB_MAX_JSON_TAGS_LEN (4096*TSDB_NCHAR_SIZE + 2 + 1) // 2->var_header_len 1->type #define TSDB_MAX_TAGS 128 #define TSDB_MAX_TAG_CONDITIONS 1024 +#define TSDB_MAX_JSON_KEY_LEN 256 +#define TSDB_MAX_JSON_KEY_MD5_LEN 16 #define TSDB_AUTH_LEN 16 #define TSDB_KEY_LEN 16 diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 39498ab3aa71b2a23acb979aae72f5950ae11690..8700cf246a91655c307bbb4c3c2c111d3271fc67 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -250,48 +250,48 @@ int32_t* taosGetErrno(); #define TSDB_CODE_VND_INVALID_TSDB_STATE TAOS_DEF_ERROR_CODE(0, 0x0514) //"Invalid tsdb state" // tsdb -#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID" -#define TSDB_CODE_TDB_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x0601) //"Invalid table type" -#define TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION TAOS_DEF_ERROR_CODE(0, 0x0602) //"Invalid table schema version" -#define TSDB_CODE_TDB_TABLE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0603) //"Table already exists" -#define TSDB_CODE_TDB_INVALID_CONFIG TAOS_DEF_ERROR_CODE(0, 0x0604) //"Invalid configuration" -#define TSDB_CODE_TDB_INIT_FAILED TAOS_DEF_ERROR_CODE(0, 0x0605) //"Tsdb init failed" -#define TSDB_CODE_TDB_NO_DISKSPACE TAOS_DEF_ERROR_CODE(0, 0x0606) //"No diskspace for tsdb" -#define TSDB_CODE_TDB_NO_DISK_PERMISSIONS TAOS_DEF_ERROR_CODE(0, 0x0607) //"No permission for disk files" -#define TSDB_CODE_TDB_FILE_CORRUPTED TAOS_DEF_ERROR_CODE(0, 0x0608) //"Data file(s) corrupted" -#define TSDB_CODE_TDB_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0609) //"Out of memory" -#define TSDB_CODE_TDB_TAG_VER_OUT_OF_DATE TAOS_DEF_ERROR_CODE(0, 0x060A) //"Tag too old" -#define TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE TAOS_DEF_ERROR_CODE(0, 0x060B) //"Timestamp data out of range" -#define TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP TAOS_DEF_ERROR_CODE(0, 0x060C) //"Submit message is messed up" -#define TSDB_CODE_TDB_INVALID_ACTION TAOS_DEF_ERROR_CODE(0, 0x060D) //"Invalid operation" -#define TSDB_CODE_TDB_INVALID_CREATE_TB_MSG TAOS_DEF_ERROR_CODE(0, 0x060E) //"Invalid creation of table" -#define TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM TAOS_DEF_ERROR_CODE(0, 0x060F) //"No table data in memory skiplist" -#define TSDB_CODE_TDB_FILE_ALREADY_EXISTS TAOS_DEF_ERROR_CODE(0, 0x0610) //"File already exists" -#define TSDB_CODE_TDB_TABLE_RECONFIGURE TAOS_DEF_ERROR_CODE(0, 0x0611) //"Need to reconfigure table" -#define TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO TAOS_DEF_ERROR_CODE(0, 0x0612) //"Invalid information to create table" -#define TSDB_CODE_TDB_NO_AVAIL_DISK TAOS_DEF_ERROR_CODE(0, 0x0613) //"No available disk" -#define TSDB_CODE_TDB_MESSED_MSG TAOS_DEF_ERROR_CODE(0, 0x0614) //"TSDB messed message" -#define TSDB_CODE_TDB_IVLD_TAG_VAL TAOS_DEF_ERROR_CODE(0, 0x0615) //"TSDB invalid tag value" -#define TSDB_CODE_TDB_NO_CACHE_LAST_ROW TAOS_DEF_ERROR_CODE(0, 0x0616) //"TSDB no cache last row data" -#define TSDB_CODE_TDB_INCOMPLETE_DFILESET TAOS_DEF_ERROR_CODE(0, 0x0617) //"TSDB incomplete DFileSet" +#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID") +#define TSDB_CODE_TDB_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x0601) //"Invalid table type") +#define TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION TAOS_DEF_ERROR_CODE(0, 0x0602) //"Invalid table schema version") +#define TSDB_CODE_TDB_TABLE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0603) //"Table already exists") +#define TSDB_CODE_TDB_INVALID_CONFIG TAOS_DEF_ERROR_CODE(0, 0x0604) //"Invalid configuration") +#define TSDB_CODE_TDB_INIT_FAILED TAOS_DEF_ERROR_CODE(0, 0x0605) //"Tsdb init failed") +#define TSDB_CODE_TDB_NO_DISKSPACE TAOS_DEF_ERROR_CODE(0, 0x0606) //"No diskspace for tsdb") +#define TSDB_CODE_TDB_NO_DISK_PERMISSIONS TAOS_DEF_ERROR_CODE(0, 0x0607) //"No permission for disk files") +#define TSDB_CODE_TDB_FILE_CORRUPTED TAOS_DEF_ERROR_CODE(0, 0x0608) //"Data file(s) corrupted") +#define TSDB_CODE_TDB_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0609) //"Out of memory") +#define TSDB_CODE_TDB_TAG_VER_OUT_OF_DATE TAOS_DEF_ERROR_CODE(0, 0x060A) //"Tag too old") +#define TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE TAOS_DEF_ERROR_CODE(0, 0x060B) //"Timestamp data out of range") +#define TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP TAOS_DEF_ERROR_CODE(0, 0x060C) //"Submit message is messed up") +#define TSDB_CODE_TDB_INVALID_ACTION TAOS_DEF_ERROR_CODE(0, 0x060D) //"Invalid operation") +#define TSDB_CODE_TDB_INVALID_CREATE_TB_MSG TAOS_DEF_ERROR_CODE(0, 0x060E) //"Invalid creation of table") +#define TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM TAOS_DEF_ERROR_CODE(0, 0x060F) //"No table data in memory skiplist") +#define TSDB_CODE_TDB_FILE_ALREADY_EXISTS TAOS_DEF_ERROR_CODE(0, 0x0610) //"File already exists") +#define TSDB_CODE_TDB_TABLE_RECONFIGURE TAOS_DEF_ERROR_CODE(0, 0x0611) //"Need to reconfigure table") +#define TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO TAOS_DEF_ERROR_CODE(0, 0x0612) //"Invalid information to create table") +#define TSDB_CODE_TDB_NO_AVAIL_DISK TAOS_DEF_ERROR_CODE(0, 0x0613) //"No available disk") +#define TSDB_CODE_TDB_MESSED_MSG TAOS_DEF_ERROR_CODE(0, 0x0614) //"TSDB messed message") +#define TSDB_CODE_TDB_IVLD_TAG_VAL TAOS_DEF_ERROR_CODE(0, 0x0615) //"TSDB invalid tag value") +#define TSDB_CODE_TDB_NO_CACHE_LAST_ROW TAOS_DEF_ERROR_CODE(0, 0x0616) //"TSDB no cache last row data") +#define TSDB_CODE_TDB_INCOMPLETE_DFILESET TAOS_DEF_ERROR_CODE(0, 0x0617) //"TSDB incomplete DFileSet") +#define TSDB_CODE_TDB_NO_JSON_TAG_KEY TAOS_DEF_ERROR_CODE(0, 0x0618) //"TSDB no tag json key") // query -#define TSDB_CODE_QRY_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0700) //"Invalid handle" -#define TSDB_CODE_QRY_INVALID_MSG TAOS_DEF_ERROR_CODE(0, 0x0701) //"Invalid message" // failed to validate the sql expression msg by vnode -#define TSDB_CODE_QRY_NO_DISKSPACE TAOS_DEF_ERROR_CODE(0, 0x0702) //"No diskspace for query" -#define TSDB_CODE_QRY_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0703) //"System out of memory" -#define TSDB_CODE_QRY_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0704) //"Unexpected generic error in query" -#define TSDB_CODE_QRY_DUP_JOIN_KEY TAOS_DEF_ERROR_CODE(0, 0x0705) //"Duplicated join key" -#define TSDB_CODE_QRY_EXCEED_TAGS_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0706) //"Tag condition too many" -#define TSDB_CODE_QRY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0707) //"Query not ready" -#define TSDB_CODE_QRY_HAS_RSP TAOS_DEF_ERROR_CODE(0, 0x0708) //"Query should response" -#define TSDB_CODE_QRY_IN_EXEC TAOS_DEF_ERROR_CODE(0, 0x0709) //"Multiple retrieval of this query" -#define TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW TAOS_DEF_ERROR_CODE(0, 0x070A) //"Too many time window in query" -#define TSDB_CODE_QRY_NOT_ENOUGH_BUFFER TAOS_DEF_ERROR_CODE(0, 0x070B) //"Query buffer limit has reached" -#define TSDB_CODE_QRY_INCONSISTAN TAOS_DEF_ERROR_CODE(0, 0x070C) //"File inconsistency in replica" -#define TSDB_CODE_QRY_SYS_ERROR TAOS_DEF_ERROR_CODE(0, 0x070D) //"System error" -#define TSDB_CODE_QRY_INVALID_TIME_CONDITION TAOS_DEF_ERROR_CODE(0, 0x070E) //"invalid time condition" - +#define TSDB_CODE_QRY_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0700) //"Invalid handle") +#define TSDB_CODE_QRY_INVALID_MSG TAOS_DEF_ERROR_CODE(0, 0x0701) //"Invalid message") // failed to validate the sql expression msg by vnode +#define TSDB_CODE_QRY_NO_DISKSPACE TAOS_DEF_ERROR_CODE(0, 0x0702) //"No diskspace for query") +#define TSDB_CODE_QRY_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0703) //"System out of memory") +#define TSDB_CODE_QRY_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0704) //"Unexpected generic error in query") +#define TSDB_CODE_QRY_DUP_JOIN_KEY TAOS_DEF_ERROR_CODE(0, 0x0705) //"Duplicated join key") +#define TSDB_CODE_QRY_EXCEED_TAGS_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0706) //"Tag condition too many") +#define TSDB_CODE_QRY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0707) //"Query not ready") +#define TSDB_CODE_QRY_HAS_RSP TAOS_DEF_ERROR_CODE(0, 0x0708) //"Query should response") +#define TSDB_CODE_QRY_IN_EXEC TAOS_DEF_ERROR_CODE(0, 0x0709) //"Multiple retrieval of this query") +#define TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW TAOS_DEF_ERROR_CODE(0, 0x070A) //"Too many time window in query") +#define TSDB_CODE_QRY_NOT_ENOUGH_BUFFER TAOS_DEF_ERROR_CODE(0, 0x070B) //"Query buffer limit has reached") +#define TSDB_CODE_QRY_INCONSISTAN TAOS_DEF_ERROR_CODE(0, 0x070C) //"File inconsistency in replica") +#define TSDB_CODE_QRY_SYS_ERROR TAOS_DEF_ERROR_CODE(0, 0x070D) //"System error") +#define TSDB_CODE_QRY_INVALID_TIME_CONDITION TAOS_DEF_ERROR_CODE(0, 0x070E) //"invalid time condition") // grant #define TSDB_CODE_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0800) //"License expired" diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index 1db66f0387b02c3d02f50eef04110b23ce2d9e64..9dc76466aadbe9781dbdd727a524a32f8103650f 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -412,7 +412,7 @@ typedef struct SColIndex { int16_t colId; // column id int16_t colIndex; // column index in colList if it is a normal column or index in tagColList if a tag uint16_t flag; // denote if it is a tag or a normal column - char name[TSDB_COL_NAME_LEN + TSDB_TABLE_NAME_LEN + 1]; + char name[TSDB_COL_NAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_MAX_JSON_KEY_LEN + 4 + 1]; // 4 meams ->'' for json tag } SColIndex; typedef struct SColumnFilterInfo { diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index f98e7eec31f9cea99505bada1e0e3e8729b8d139..a44e958be4345d4aa131cab8f616e0460624e8c1 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -118,7 +118,7 @@ typedef struct { void tsdbClearTableCfg(STableCfg *config); -void *tsdbGetTableTagVal(const void *pTable, int32_t colId, int16_t type, int16_t bytes); +void *tsdbGetTableTagVal(const void *pTable, int32_t colId, int16_t type); char *tsdbGetTableName(void *pTable); #define TSDB_TABLEID(_table) ((STableId*) (_table)) @@ -418,10 +418,14 @@ int tsdbCompact(STsdbRepo *pRepo); // no problem return true bool tsdbNoProblem(STsdbRepo* pRepo); - // unit of walSize: MB int tsdbCheckWal(STsdbRepo *pRepo, uint32_t walSize); +// for json tag +void* getJsonTagValueElment(void* data, char* key, int32_t keyLen, char* out, int16_t bytes); +void getJsonTagValueAll(void* data, void* dst, int16_t bytes); +char* parseTagDatatoJson(void *p); + #ifdef __cplusplus } #endif diff --git a/src/inc/ttokendef.h b/src/inc/ttokendef.h index 4b6602b4124fe5e16c60700aebf3a1a2d55c77fd..3e639c878c5bd101418a9177ec5c5409a5d65838 100644 --- a/src/inc/ttokendef.h +++ b/src/inc/ttokendef.h @@ -28,195 +28,195 @@ #define TK_TIMESTAMP 10 #define TK_BINARY 11 #define TK_NCHAR 12 -#define TK_OR 13 -#define TK_AND 14 -#define TK_NOT 15 -#define TK_EQ 16 -#define TK_NE 17 -#define TK_ISNULL 18 -#define TK_NOTNULL 19 -#define TK_IS 20 -#define TK_LIKE 21 -#define TK_MATCH 22 -#define TK_NMATCH 23 -#define TK_GLOB 24 -#define TK_BETWEEN 25 -#define TK_IN 26 -#define TK_GT 27 -#define TK_GE 28 -#define TK_LT 29 -#define TK_LE 30 -#define TK_BITAND 31 -#define TK_BITOR 32 -#define TK_LSHIFT 33 -#define TK_RSHIFT 34 -#define TK_PLUS 35 -#define TK_MINUS 36 -#define TK_DIVIDE 37 -#define TK_TIMES 38 -#define TK_STAR 39 -#define TK_SLASH 40 -#define TK_REM 41 -#define TK_CONCAT 42 -#define TK_UMINUS 43 -#define TK_UPLUS 44 -#define TK_BITNOT 45 -#define TK_SHOW 46 -#define TK_DATABASES 47 -#define TK_TOPICS 48 -#define TK_FUNCTIONS 49 -#define TK_MNODES 50 -#define TK_DNODES 51 -#define TK_ACCOUNTS 52 -#define TK_USERS 53 -#define TK_MODULES 54 -#define TK_QUERIES 55 -#define TK_CONNECTIONS 56 -#define TK_STREAMS 57 -#define TK_VARIABLES 58 -#define TK_SCORES 59 -#define TK_GRANTS 60 -#define TK_VNODES 61 -#define TK_DOT 62 -#define TK_CREATE 63 -#define TK_TABLE 64 -#define TK_STABLE 65 -#define TK_DATABASE 66 -#define TK_TABLES 67 -#define TK_STABLES 68 -#define TK_VGROUPS 69 -#define TK_DROP 70 -#define TK_TOPIC 71 -#define TK_FUNCTION 72 -#define TK_DNODE 73 -#define TK_USER 74 -#define TK_ACCOUNT 75 -#define TK_USE 76 -#define TK_DESCRIBE 77 -#define TK_DESC 78 -#define TK_ALTER 79 -#define TK_PASS 80 -#define TK_PRIVILEGE 81 -#define TK_LOCAL 82 -#define TK_COMPACT 83 -#define TK_LP 84 -#define TK_RP 85 -#define TK_IF 86 -#define TK_EXISTS 87 -#define TK_AS 88 -#define TK_OUTPUTTYPE 89 -#define TK_AGGREGATE 90 -#define TK_BUFSIZE 91 -#define TK_PPS 92 -#define TK_TSERIES 93 -#define TK_DBS 94 -#define TK_STORAGE 95 -#define TK_QTIME 96 -#define TK_CONNS 97 -#define TK_STATE 98 -#define TK_COMMA 99 -#define TK_KEEP 100 -#define TK_CACHE 101 -#define TK_REPLICA 102 -#define TK_QUORUM 103 -#define TK_DAYS 104 -#define TK_MINROWS 105 -#define TK_MAXROWS 106 -#define TK_BLOCKS 107 -#define TK_CTIME 108 -#define TK_WAL 109 -#define TK_FSYNC 110 -#define TK_COMP 111 -#define TK_PRECISION 112 -#define TK_UPDATE 113 -#define TK_CACHELAST 114 -#define TK_PARTITIONS 115 -#define TK_UNSIGNED 116 -#define TK_TAGS 117 -#define TK_USING 118 -#define TK_NULL 119 -#define TK_NOW 120 -#define TK_SELECT 121 -#define TK_UNION 122 -#define TK_ALL 123 -#define TK_DISTINCT 124 -#define TK_FROM 125 -#define TK_VARIABLE 126 -#define TK_RANGE 127 -#define TK_INTERVAL 128 -#define TK_EVERY 129 -#define TK_SESSION 130 -#define TK_STATE_WINDOW 131 -#define TK_FILL 132 -#define TK_SLIDING 133 -#define TK_ORDER 134 -#define TK_BY 135 -#define TK_ASC 136 -#define TK_GROUP 137 -#define TK_HAVING 138 -#define TK_LIMIT 139 -#define TK_OFFSET 140 -#define TK_SLIMIT 141 -#define TK_SOFFSET 142 -#define TK_WHERE 143 -#define TK_RESET 144 -#define TK_QUERY 145 -#define TK_SYNCDB 146 -#define TK_ADD 147 -#define TK_COLUMN 148 -#define TK_MODIFY 149 -#define TK_TAG 150 -#define TK_CHANGE 151 -#define TK_SET 152 -#define TK_KILL 153 -#define TK_CONNECTION 154 -#define TK_STREAM 155 -#define TK_COLON 156 -#define TK_ABORT 157 -#define TK_AFTER 158 -#define TK_ATTACH 159 -#define TK_BEFORE 160 -#define TK_BEGIN 161 -#define TK_CASCADE 162 -#define TK_CLUSTER 163 -#define TK_CONFLICT 164 -#define TK_COPY 165 -#define TK_DEFERRED 166 -#define TK_DELIMITERS 167 -#define TK_DETACH 168 -#define TK_EACH 169 -#define TK_END 170 -#define TK_EXPLAIN 171 -#define TK_FAIL 172 -#define TK_FOR 173 -#define TK_IGNORE 174 -#define TK_IMMEDIATE 175 -#define TK_INITIALLY 176 -#define TK_INSTEAD 177 -#define TK_KEY 178 -#define TK_OF 179 -#define TK_RAISE 180 -#define TK_REPLACE 181 -#define TK_RESTRICT 182 -#define TK_ROW 183 -#define TK_STATEMENT 184 -#define TK_TRIGGER 185 -#define TK_VIEW 186 -#define TK_IPTOKEN 187 -#define TK_SEMI 188 -#define TK_NONE 189 -#define TK_PREV 190 -#define TK_LINEAR 191 -#define TK_IMPORT 192 -#define TK_TBNAME 193 -#define TK_JOIN 194 -#define TK_INSERT 195 -#define TK_INTO 196 -#define TK_VALUES 197 -#define TK_FILE 198 - - - +#define TK_JSON 13 +#define TK_OR 14 +#define TK_AND 15 +#define TK_NOT 16 +#define TK_EQ 17 +#define TK_NE 18 +#define TK_ISNULL 19 +#define TK_NOTNULL 20 +#define TK_IS 21 +#define TK_LIKE 22 +#define TK_MATCH 23 +#define TK_NMATCH 24 +#define TK_CONTAINS 25 +#define TK_GLOB 26 +#define TK_BETWEEN 27 +#define TK_IN 28 +#define TK_GT 29 +#define TK_GE 30 +#define TK_LT 31 +#define TK_LE 32 +#define TK_BITAND 33 +#define TK_BITOR 34 +#define TK_LSHIFT 35 +#define TK_RSHIFT 36 +#define TK_PLUS 37 +#define TK_MINUS 38 +#define TK_DIVIDE 39 +#define TK_TIMES 40 +#define TK_STAR 41 +#define TK_SLASH 42 +#define TK_REM 43 +#define TK_CONCAT 44 +#define TK_UMINUS 45 +#define TK_UPLUS 46 +#define TK_BITNOT 47 +#define TK_ARROW 48 +#define TK_SHOW 49 +#define TK_DATABASES 50 +#define TK_TOPICS 51 +#define TK_FUNCTIONS 52 +#define TK_MNODES 53 +#define TK_DNODES 54 +#define TK_ACCOUNTS 55 +#define TK_USERS 56 +#define TK_MODULES 57 +#define TK_QUERIES 58 +#define TK_CONNECTIONS 59 +#define TK_STREAMS 60 +#define TK_VARIABLES 61 +#define TK_SCORES 62 +#define TK_GRANTS 63 +#define TK_VNODES 64 +#define TK_DOT 65 +#define TK_CREATE 66 +#define TK_TABLE 67 +#define TK_STABLE 68 +#define TK_DATABASE 69 +#define TK_TABLES 70 +#define TK_STABLES 71 +#define TK_VGROUPS 72 +#define TK_DROP 73 +#define TK_TOPIC 74 +#define TK_FUNCTION 75 +#define TK_DNODE 76 +#define TK_USER 77 +#define TK_ACCOUNT 78 +#define TK_USE 79 +#define TK_DESCRIBE 80 +#define TK_DESC 81 +#define TK_ALTER 82 +#define TK_PASS 83 +#define TK_PRIVILEGE 84 +#define TK_LOCAL 85 +#define TK_COMPACT 86 +#define TK_LP 87 +#define TK_RP 88 +#define TK_IF 89 +#define TK_EXISTS 90 +#define TK_AS 91 +#define TK_OUTPUTTYPE 92 +#define TK_AGGREGATE 93 +#define TK_BUFSIZE 94 +#define TK_PPS 95 +#define TK_TSERIES 96 +#define TK_DBS 97 +#define TK_STORAGE 98 +#define TK_QTIME 99 +#define TK_CONNS 100 +#define TK_STATE 101 +#define TK_COMMA 102 +#define TK_KEEP 103 +#define TK_CACHE 104 +#define TK_REPLICA 105 +#define TK_QUORUM 106 +#define TK_DAYS 107 +#define TK_MINROWS 108 +#define TK_MAXROWS 109 +#define TK_BLOCKS 110 +#define TK_CTIME 111 +#define TK_WAL 112 +#define TK_FSYNC 113 +#define TK_COMP 114 +#define TK_PRECISION 115 +#define TK_UPDATE 116 +#define TK_CACHELAST 117 +#define TK_PARTITIONS 118 +#define TK_UNSIGNED 119 +#define TK_TAGS 120 +#define TK_USING 121 +#define TK_NULL 122 +#define TK_NOW 123 +#define TK_SELECT 124 +#define TK_UNION 125 +#define TK_ALL 126 +#define TK_DISTINCT 127 +#define TK_FROM 128 +#define TK_VARIABLE 129 +#define TK_RANGE 130 +#define TK_INTERVAL 131 +#define TK_EVERY 132 +#define TK_SESSION 133 +#define TK_STATE_WINDOW 134 +#define TK_FILL 135 +#define TK_SLIDING 136 +#define TK_ORDER 137 +#define TK_BY 138 +#define TK_ASC 139 +#define TK_GROUP 140 +#define TK_HAVING 141 +#define TK_LIMIT 142 +#define TK_OFFSET 143 +#define TK_SLIMIT 144 +#define TK_SOFFSET 145 +#define TK_WHERE 146 +#define TK_RESET 147 +#define TK_QUERY 148 +#define TK_SYNCDB 149 +#define TK_ADD 150 +#define TK_COLUMN 151 +#define TK_MODIFY 152 +#define TK_TAG 153 +#define TK_CHANGE 154 +#define TK_SET 155 +#define TK_KILL 156 +#define TK_CONNECTION 157 +#define TK_STREAM 158 +#define TK_COLON 159 +#define TK_ABORT 160 +#define TK_AFTER 161 +#define TK_ATTACH 162 +#define TK_BEFORE 163 +#define TK_BEGIN 164 +#define TK_CASCADE 165 +#define TK_CLUSTER 166 +#define TK_CONFLICT 167 +#define TK_COPY 168 +#define TK_DEFERRED 169 +#define TK_DELIMITERS 170 +#define TK_DETACH 171 +#define TK_EACH 172 +#define TK_END 173 +#define TK_EXPLAIN 174 +#define TK_FAIL 175 +#define TK_FOR 176 +#define TK_IGNORE 177 +#define TK_IMMEDIATE 178 +#define TK_INITIALLY 179 +#define TK_INSTEAD 180 +#define TK_KEY 181 +#define TK_OF 182 +#define TK_RAISE 183 +#define TK_REPLACE 184 +#define TK_RESTRICT 185 +#define TK_ROW 186 +#define TK_STATEMENT 187 +#define TK_TRIGGER 188 +#define TK_VIEW 189 +#define TK_IPTOKEN 190 +#define TK_SEMI 191 +#define TK_NONE 192 +#define TK_PREV 193 +#define TK_LINEAR 194 +#define TK_IMPORT 195 +#define TK_TBNAME 196 +#define TK_JOIN 197 +#define TK_INSERT 198 +#define TK_INTO 199 +#define TK_VALUES 200 +#define TK_FILE 201 #define TK_SPACE 300 diff --git a/src/inc/ttype.h b/src/inc/ttype.h index 095b593ab7d1fb74effd7991feeeb60f54cbc1b8..ff2fac5b72d9181a3cb0cd8afaf3ea5053da5484 100644 --- a/src/inc/ttype.h +++ b/src/inc/ttype.h @@ -200,6 +200,8 @@ static FORCE_INLINE bool isNull(const void *val, int32_t type) { return *(uint32_t *)val == TSDB_DATA_FLOAT_NULL; case TSDB_DATA_TYPE_DOUBLE: return *(uint64_t *)val == TSDB_DATA_DOUBLE_NULL; + case TSDB_DATA_TYPE_JSON: + return varDataLen(val) == sizeof(int32_t) && *(uint32_t *) varDataVal(val) == TSDB_DATA_JSON_NULL; case TSDB_DATA_TYPE_NCHAR: return varDataLen(val) == sizeof(int32_t) && *(uint32_t*) varDataVal(val) == TSDB_DATA_NCHAR_NULL; case TSDB_DATA_TYPE_BINARY: @@ -230,10 +232,10 @@ typedef struct tDataTypeDescriptor { int (*decompFunc)(const char *const input, int compressedSize, const int nelements, char *const output, int outputSize, char algorithm, char *const buffer, int bufferSize); void (*statisFunc)(const void *pData, int32_t numofrow, int64_t *min, int64_t *max, int64_t *sum, - int16_t *minindex, int16_t *maxindex, int16_t *numofnull); + int16_t *minindex, int16_t *maxindex, int16_t *numofnull); } tDataTypeDescriptor; -extern tDataTypeDescriptor tDataTypes[15]; +extern tDataTypeDescriptor tDataTypes[16]; bool isValidDataType(int32_t type); diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index e3e86e518690c8c4f773471b93bdb381a5bb8dc1..47d39cc0ca3bdf33716782d1dfbac55e9fc7b477 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -509,6 +509,7 @@ static void dumpFieldToFile(FILE* fp, const char* val, TAOS_FIELD* field, int32_ break; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_JSON: memcpy(buf, val, length); buf[length] = 0; fprintf(fp, "\'%s\'", buf); @@ -692,6 +693,7 @@ static void printField(const char* val, TAOS_FIELD* field, int width, int32_t le break; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_JSON: shellPrintNChar(val, length, width); break; case TSDB_DATA_TYPE_TIMESTAMP: @@ -805,7 +807,8 @@ static int calcColWidth(TAOS_FIELD* field, int precision) { return MAX(field->bytes, width); } - case TSDB_DATA_TYPE_NCHAR: { + case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_JSON:{ int16_t bytes = field->bytes * TSDB_NCHAR_SIZE; if (bytes > tsMaxBinaryDisplayWidth) { return MAX(tsMaxBinaryDisplayWidth, width); diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c index ed60ba42caa4a882f21b511aa8009d10d52dad52..b93d85140c230ae5b010a3559fed9488cc6b0b9f 100644 --- a/src/plugins/monitor/src/monMain.c +++ b/src/plugins/monitor/src/monMain.c @@ -21,7 +21,6 @@ #include "tlog.h" #include "ttimer.h" #include "tutil.h" -#include "tscUtil.h" #include "tsclient.h" #include "dnode.h" #include "vnode.h" diff --git a/src/plugins/taosadapter b/src/plugins/taosadapter index f108f5240918d0eec90debd1ff469c98ff0f25ac..88346a2e4e2e9282d2ec8b8c5264ca1ec23698a1 160000 --- a/src/plugins/taosadapter +++ b/src/plugins/taosadapter @@ -1 +1 @@ -Subproject commit f108f5240918d0eec90debd1ff469c98ff0f25ac +Subproject commit 88346a2e4e2e9282d2ec8b8c5264ca1ec23698a1 diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index be0f6aee59de760088c8f10b9d1a5dca79882edd..5a0f16c462c26c03e6a5312495fc49f32e83c66c 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -204,7 +204,7 @@ typedef struct SQLFunctionCtx { SResultRowCellInfo *resultInfo; - int16_t colId; + int16_t colId; // used for user-specified constant value SExtTagsInfo tagInfo; SPoint1 start; SPoint1 end; diff --git a/src/query/inc/qFilter.h b/src/query/inc/qFilter.h index e10d7fdfb4f65bb2d9ed2d14ba3e2d04f9d76706..fe9ef0f47f1e4cf353f9dfbd0e9956e7690debfe 100644 --- a/src/query/inc/qFilter.h +++ b/src/query/inc/qFilter.h @@ -105,6 +105,7 @@ typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const v 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 int32_t (*filer_get_col_from_name)(void *, int32_t, char*, void **); typedef struct SFilterRangeCompare { int64_t s; @@ -237,11 +238,12 @@ typedef struct SFilterInfo { uint32_t blkGroupNum; uint32_t *blkUnits; int8_t *blkUnitRes; - + void *pTable; + SFilterPCtx pctx; } SFilterInfo; -#define FILTER_NO_MERGE_DATA_TYPE(t) ((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR) +#define FILTER_NO_MERGE_DATA_TYPE(t) ((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR || (t) == TSDB_DATA_TYPE_JSON) #define FILTER_NO_MERGE_OPTR(o) ((o) == TSDB_RELATION_ISNULL || (o) == TSDB_RELATION_NOTNULL || (o) == FILTER_DUMMY_EMPTY_OPTR) #define MR_EMPTY_RES(ctx) (ctx->rs == NULL) @@ -286,6 +288,7 @@ typedef struct SFilterInfo { #define FILTER_GET_COL_FIELD_DATA(fi, ri) ((char *)(fi)->data + ((SSchema *)((fi)->desc))->bytes * (ri)) #define FILTER_GET_VAL_FIELD_TYPE(fi) (((tVariant *)((fi)->desc))->nType) #define FILTER_GET_VAL_FIELD_DATA(fi) ((char *)(fi)->data) +#define FILTER_GET_JSON_VAL_FIELD_DATA(fi) ((char *)(fi)->desc) #define FILTER_GET_TYPE(fl) ((fl) & FLD_TYPE_MAX) #define FILTER_GROUP_UNIT(i, g, uid) ((i)->units + (g)->unitIdxs[uid]) @@ -298,6 +301,7 @@ typedef struct SFilterInfo { #define FILTER_UNIT_COL_SIZE(i, u) FILTER_GET_COL_FIELD_SIZE(FILTER_UNIT_LEFT_FIELD(i, u)) #define FILTER_UNIT_COL_ID(i, u) FILTER_GET_COL_FIELD_ID(FILTER_UNIT_LEFT_FIELD(i, u)) #define FILTER_UNIT_VAL_DATA(i, u) FILTER_GET_VAL_FIELD_DATA(FILTER_UNIT_RIGHT_FIELD(i, u)) +#define FILTER_UNIT_JSON_VAL_DATA(i, u) FILTER_GET_JSON_VAL_FIELD_DATA(FILTER_UNIT_RIGHT_FIELD(i, u)) #define FILTER_UNIT_COL_IDX(u) ((u)->left.idx) #define FILTER_UNIT_OPTR(u) ((u)->compare.optr) #define FILTER_UNIT_COMP_FUNC(u) ((u)->compare.func) @@ -324,6 +328,7 @@ typedef struct SFilterInfo { 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, void *param, filer_get_col_from_id fp); +extern int32_t filterSetJsonColFieldData(SFilterInfo *info, void *param, filer_get_col_from_name 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); diff --git a/src/query/inc/qSqlparser.h b/src/query/inc/qSqlparser.h index eb3a06e01d7034ebe4ee474574aa077dcbb5e87e..2c70767aba7e9b8d6822663b96538d4ff83da87c 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -79,6 +79,15 @@ typedef struct tVariantListItem { uint8_t sortOrder; } tVariantListItem; +typedef struct CommonItem { + union { + tVariant pVar; + struct tSqlExpr *jsonExp; + }; + bool isJsonExp; + uint8_t sortOrder; +} CommonItem; + typedef struct SIntervalVal { int32_t token; SStrToken interval; @@ -161,7 +170,6 @@ typedef struct SAlterTableInfo { SStrToken name; int16_t tableType; int16_t type; - STagData tagData; SArray *pAddColumns; // SArray SArray *varList; // set t=val or: change src dst, SArray } SAlterTableInfo; @@ -278,6 +286,7 @@ typedef struct tSqlExprItem { bool distinct; } tSqlExprItem; +SArray *commonItemAppend(SArray *pList, tVariant *pVar, tSqlExpr *jsonExp, bool isJsonExp, uint8_t sortOrder); SArray *tVariantListAppend(SArray *pList, tVariant *pVar, uint8_t sortOrder); SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int32_t index); diff --git a/src/query/inc/qTableMeta.h b/src/query/inc/qTableMeta.h index 422fdd13a6a6b17d63c35880eab27cad5272621a..d47189691ebbe2c4ec3ad55dd72306686586a56e 100644 --- a/src/query/inc/qTableMeta.h +++ b/src/query/inc/qTableMeta.h @@ -28,6 +28,7 @@ typedef struct STblCond { typedef struct SJoinNode { uint64_t uid; int16_t tagColId; + char tagJsonKeyName[TSDB_MAX_JSON_KEY_LEN + 1]; // for tag json key SArray* tsJoin; SArray* tagJoin; } SJoinNode; @@ -165,6 +166,7 @@ typedef struct SQueryInfo { bool stateWindow; bool globalMerge; bool multigroupResult; + bool isStddev; } SQueryInfo; /** diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h index ce607f0fe20a2743579e99e71ddf78fc2e1dbcdc..0882df77c2a8bc38560269ce093568fd96467dae 100644 --- a/src/query/inc/qUtil.h +++ b/src/query/inc/qUtil.h @@ -106,5 +106,4 @@ int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo); int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv *pRuntimeEnv, int32_t* offset); int32_t initUdfInfo(SUdfInfo* pUdfInfo); - #endif // TDENGINE_QUERYUTIL_H diff --git a/src/query/inc/sql.y b/src/query/inc/sql.y index 30441334210727a87f8e1a042981be89b8de22ef..1c7290a5306209c17ff70ab02a5f757493139205 100644 --- a/src/query/inc/sql.y +++ b/src/query/inc/sql.y @@ -6,12 +6,12 @@ %default_type {SStrToken} %extra_argument {SSqlInfo* pInfo} -%fallback ID BOOL TINYINT SMALLINT INTEGER BIGINT FLOAT DOUBLE STRING TIMESTAMP BINARY NCHAR. +%fallback ID BOOL TINYINT SMALLINT INTEGER BIGINT FLOAT DOUBLE STRING TIMESTAMP BINARY NCHAR JSON. %left OR. %left AND. %right NOT. -%left EQ NE ISNULL NOTNULL IS LIKE MATCH NMATCH GLOB BETWEEN IN. +%left EQ NE ISNULL NOTNULL IS LIKE MATCH NMATCH CONTAINS GLOB BETWEEN IN. %left GT GE LT LE. %left BITAND BITOR LSHIFT RSHIFT. %left PLUS MINUS. @@ -19,6 +19,7 @@ %left STAR SLASH REM. %left CONCAT. %right UMINUS UPLUS BITNOT. +%right ARROW. %include { #include @@ -630,25 +631,33 @@ sliding_opt(K) ::= . {K.n = 0; K.z = NULL; K.type = 0 %type sortlist {SArray*} %destructor sortlist {taosArrayDestroy($$);} -%type sortitem {tVariant} -%destructor sortitem {tVariantDestroy(&$$);} - orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} sortlist(A) ::= sortlist(X) COMMA item(Y) sortorder(Z). { - A = tVariantListAppend(X, &Y, Z); + A = commonItemAppend(X, &Y, NULL, false, Z); +} + +sortlist(A) ::= sortlist(X) COMMA arrow(Y) sortorder(Z). { + A = commonItemAppend(X, NULL, Y, true, Z); } sortlist(A) ::= item(Y) sortorder(Z). { - A = tVariantListAppend(NULL, &Y, Z); + A = commonItemAppend(NULL, &Y, NULL, false, Z); +} + +sortlist(A) ::= arrow(Y) sortorder(Z). { + A = commonItemAppend(NULL, NULL, Y, true, Z); } %type item {tVariant} -item(A) ::= ids(X) cpxName(Y). { +item(A) ::= ID(X). { toTSDBType(X.type); - X.n += Y.n; - + tVariantCreate(&A, &X, true); +} +item(A) ::= ID(X) DOT ID(Y). { + toTSDBType(X.type); + X.n += (1+Y.n); tVariantCreate(&A, &X, true); } @@ -667,11 +676,19 @@ groupby_opt(A) ::= . { A = 0;} groupby_opt(A) ::= GROUP BY grouplist(X). { A = X;} grouplist(A) ::= grouplist(X) COMMA item(Y). { - A = tVariantListAppend(X, &Y, -1); + A = commonItemAppend(X, &Y, NULL, false, -1); +} + +grouplist(A) ::= grouplist(X) COMMA arrow(Y). { + A = commonItemAppend(X, NULL, Y, true, -1); } grouplist(A) ::= item(X). { - A = tVariantListAppend(NULL, &X, -1); + A = commonItemAppend(NULL, &X, NULL, false, -1); +} + +grouplist(A) ::= arrow(X). { + A = commonItemAppend(NULL, NULL, X, true, -1); } //having clause, ignore the input condition in having @@ -765,6 +782,18 @@ expr(A) ::= expr(X) LIKE expr(Y). {A = tSqlExprCreate(X, Y, TK_LIKE); } expr(A) ::= expr(X) MATCH expr(Y). {A = tSqlExprCreate(X, Y, TK_MATCH); } expr(A) ::= expr(X) NMATCH expr(Y). {A = tSqlExprCreate(X, Y, TK_NMATCH); } +// contains expression +expr(A) ::= ID(X) CONTAINS STRING(Y). { tSqlExpr* S = tSqlExprCreateIdValue(pInfo, &X, TK_ID); tSqlExpr* M = tSqlExprCreateIdValue(pInfo, &Y, TK_STRING); A = tSqlExprCreate(S, M, TK_CONTAINS); } +expr(A) ::= ID(X) DOT ID(Y) CONTAINS STRING(Z). { X.n += (1+Y.n); tSqlExpr* S = tSqlExprCreateIdValue(pInfo, &X, TK_ID); tSqlExpr* M = tSqlExprCreateIdValue(pInfo, &Z, TK_STRING); A = tSqlExprCreate(S, M, TK_CONTAINS); } + +// arrow expression +%type arrow {tSqlExpr*} +%destructor arrow {tSqlExprDestroy($$);} +arrow(A) ::= ID(X) ARROW STRING(Y). {tSqlExpr* S = tSqlExprCreateIdValue(pInfo, &X, TK_ID); tSqlExpr* M = tSqlExprCreateIdValue(pInfo, &Y, TK_STRING); A = tSqlExprCreate(S, M, TK_ARROW); } +arrow(A) ::= ID(X) DOT ID(Y) ARROW STRING(Z). {X.n += (1+Y.n); tSqlExpr* S = tSqlExprCreateIdValue(pInfo, &X, TK_ID); tSqlExpr* M = tSqlExprCreateIdValue(pInfo, &Z, TK_STRING); A = tSqlExprCreate(S, M, TK_ARROW); } + +expr(A) ::= arrow(X). {A = X;} + //in expression expr(A) ::= expr(X) IN LP exprlist(Y) RP. {A = tSqlExprCreate(X, (tSqlExpr*)Y, TK_IN); } diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 5e7a748095008d074b2a5045dc9afc443630007a..16d2f16aeb4cf62569f74c2e0f36706b0292af2d 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -2929,8 +2929,7 @@ static void date_col_output_function(SQLFunctionCtx *pCtx) { } static void col_project_function(SQLFunctionCtx *pCtx) { - // the number of output rows should not affect the final number of rows, so set it to be 0 - if (pCtx->numOfParams == 2) { + if (pCtx->colId <= TSDB_UD_COLUMN_INDEX && pCtx->colId > TSDB_RES_COL_ID) { // user-specified constant value return; } @@ -2964,6 +2963,7 @@ static void tag_project_function(SQLFunctionCtx *pCtx) { assert(pCtx->inputBytes == pCtx->outputBytes); tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->outputType, true); + char* data = pCtx->pOutput; pCtx->pOutput += pCtx->outputBytes; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index b83926414f39bec3ac2c3d1d94459d0f6d27ea37..6e0eb373ac96c84e3e5eecf6f1bcf9aabf336f09 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -30,6 +30,9 @@ #include "tscompression.h" #include "qScript.h" #include "tscLog.h" +#include "cJSON.h" +#include "tsdbMeta.h" +#include "tscUtil.h" #define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN) #define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN) @@ -134,6 +137,14 @@ do { \ } \ } while (0) +#define GET_JSON_KEY(exprInfo) \ +char* param = NULL; \ +int32_t paramLen = 0; \ +if(exprInfo->base.numOfParams > 0){ \ + param = exprInfo->base.param[0].pz; \ + paramLen = exprInfo->base.param[0].nLen; \ +} + uint64_t queryHandleId = 0; int32_t getMaximumIdleDurationSec() { @@ -1205,7 +1216,7 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type); for(int32_t j = 0; j < pBlock->info.rows; ++j) { char* dst = p->pData + j * p->info.bytes; - tVariantDump(&pOperator->pExpr[i].base.param[1], dst, p->info.type, true); + tVariantDump(&pOperator->pExpr[i].base.param[0], dst, p->info.type, true); } } } @@ -1445,33 +1456,34 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc } static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pSDataBlock, int32_t tableGroupId) { - STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*) pOperatorInfo->info; + STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*)pOperatorInfo->info; SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; int32_t numOfOutput = pOperatorInfo->numOfOutput; SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); - bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); int32_t prevIndex = pResultRowInfo->curPos; TSKEY* tsCols = NULL; if (pSDataBlock->pDataBlock != NULL) { SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, 0); - tsCols = (int64_t*) pColDataInfo->pData; + tsCols = (int64_t*)pColDataInfo->pData; assert(tsCols[0] == pSDataBlock->info.window.skey && tsCols[pSDataBlock->info.rows - 1] == pSDataBlock->info.window.ekey); } - int32_t startPos = ascQuery? 0 : (pSDataBlock->info.rows - 1); - TSKEY ts = getStartTsKey(pQueryAttr, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows); + int32_t startPos = ascQuery ? 0 : (pSDataBlock->info.rows - 1); + TSKEY ts = getStartTsKey(pQueryAttr, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows); STimeWindow win = getActiveTimeWindow(pResultRowInfo, ts, pQueryAttr); + bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); SResultRow* pResult = NULL; - int32_t ret = setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.tid, &win, masterScan, &pResult, tableGroupId, pInfo->pCtx, - numOfOutput, pInfo->rowCellInfoOffset); + int32_t ret = setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.tid, &win, masterScan, &pResult, + tableGroupId, pInfo->pCtx, numOfOutput, pInfo->rowCellInfoOffset); if (ret != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -1487,7 +1499,8 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul for (int32_t j = prevIndex; j < curIndex; ++j) { // previous time window may be all closed already. SResultRow* pRes = getResultRow(pResultRowInfo, j); if (pRes->closed) { - assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && resultRowInterpolated(pRes, RESULT_ROW_END_INTERP)); + assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && + resultRowInterpolated(pRes, RESULT_ROW_END_INTERP)); continue; } @@ -1509,8 +1522,8 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul } // restore current time window - ret = setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.tid, &win, masterScan, &pResult, tableGroupId, pInfo->pCtx, - numOfOutput, pInfo->rowCellInfoOffset); + ret = setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.tid, &win, masterScan, &pResult, + tableGroupId, pInfo->pCtx, numOfOutput, pInfo->rowCellInfoOffset); if (ret != TSDB_CODE_SUCCESS) { longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -1529,8 +1542,8 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul } // null data, failed to allocate more memory buffer - int32_t code = setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.tid, &nextWin, masterScan, &pResult, tableGroupId, - pInfo->pCtx, numOfOutput, pInfo->rowCellInfoOffset); + int32_t code = setResultOutputBufByKey(pRuntimeEnv, pResultRowInfo, pSDataBlock->info.tid, &nextWin, masterScan, + &pResult, tableGroupId, pInfo->pCtx, numOfOutput, pInfo->rowCellInfoOffset); if (code != TSDB_CODE_SUCCESS || pResult == NULL) { longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -1540,20 +1553,18 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul // window start(end) key interpolation doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &nextWin, startPos, forwardStep); - doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &nextWin, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput); + doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &nextWin, startPos, forwardStep, tsCols, pSDataBlock->info.rows, + numOfOutput); } if (pQueryAttr->timeWindowInterpo) { - int32_t rowIndex = ascQuery? (pSDataBlock->info.rows-1):0; + int32_t rowIndex = ascQuery ? (pSDataBlock->info.rows - 1) : 0; saveDataBlockLastRow(pRuntimeEnv, &pSDataBlock->info, pSDataBlock->pDataBlock, rowIndex); } updateResultRowInfoActiveIndex(pResultRowInfo, pQueryAttr, pRuntimeEnv->current->lastKey); } - - - static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; STableQueryInfo* item = pRuntimeEnv->current; @@ -1902,6 +1913,7 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr pCtx->ptsOutputBuf = NULL; + pCtx->colId = pIndex->colId; pCtx->outputBytes = pSqlExpr->resBytes; pCtx->outputType = pSqlExpr->resType; @@ -2158,7 +2170,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf } case OP_MultiwayMergeSort: { - pRuntimeEnv->proot = createMultiwaySortOperatorInfo(pRuntimeEnv, pQueryAttr->pExpr1, pQueryAttr->numOfOutput, 4096, merger); + pRuntimeEnv->proot = createMultiwaySortOperatorInfo(pRuntimeEnv, pQueryAttr->pExpr1, pQueryAttr->numOfOutput, 200, merger); // TD-10899 break; } @@ -2931,7 +2943,7 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock static SColumnInfo* doGetTagColumnInfoById(SColumnInfo* pTagColList, int32_t numOfTags, int16_t colId); -static void doSetTagValueInParam(void* pTable, int32_t tagColId, tVariant *tag, int16_t type, int16_t bytes); +static void doSetTagValueInParam(void* pTable, char* param, int32_t paraLen, int32_t tagColId, tVariant *tag, int16_t type, int16_t bytes); static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock) { SQLFunctionCtx* pCtx = pTableScanInfo->pCtx; @@ -3008,19 +3020,22 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa if (pQueryAttr->stableQuery) { // todo refactor SExprInfo* pExprInfo = &pTableScanInfo->pExpr[0]; - int16_t tagId = (int16_t)pExprInfo->base.param[0].i64; + int16_t tagId = (int16_t)pExprInfo->base.param[1].i64; SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagId); // compare tag first tVariant t = {0}; - doSetTagValueInParam(pRuntimeEnv->current->pTable, tagId, &t, pColInfo->type, pColInfo->bytes); + GET_JSON_KEY(pExprInfo) + doSetTagValueInParam(pRuntimeEnv->current->pTable, param, paramLen, tagId, &t, pColInfo->type, pColInfo->bytes); setTimestampListJoinInfo(pRuntimeEnv, &t, pRuntimeEnv->current); STSElem elem = tsBufGetElem(pRuntimeEnv->pTsBuf); if (!tsBufIsValidElem(&elem) || (tsBufIsValidElem(&elem) && (tVariantCompare(&t, elem.tag) != 0))) { (*status) = BLK_DATA_DISCARD; + tVariantDestroy(&t); return TSDB_CODE_SUCCESS; } + tVariantDestroy(&t); } } @@ -3208,7 +3223,7 @@ int32_t binarySearchForKey(char *pValue, int num, TSKEY key, int order) { * set tag value in SQLFunctionCtx * e.g.,tag information into input buffer */ -static void doSetTagValueInParam(void* pTable, int32_t tagColId, tVariant *tag, int16_t type, int16_t bytes) { +static void doSetTagValueInParam(void* pTable, char* param, int32_t paramLen, int32_t tagColId, tVariant *tag, int16_t type, int16_t bytes) { tVariantDestroy(tag); char* val = NULL; @@ -3216,7 +3231,7 @@ static void doSetTagValueInParam(void* pTable, int32_t tagColId, tVariant *tag, val = tsdbGetTableName(pTable); assert(val != NULL); } else { - val = tsdbGetTableTagVal(pTable, tagColId, type, bytes); + val = tsdbGetTableTagVal(pTable, tagColId, type); } if (val == NULL || isNull(val, type)) { @@ -3224,11 +3239,19 @@ static void doSetTagValueInParam(void* pTable, int32_t tagColId, tVariant *tag, return; } - if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { + if (IS_VAR_DATA_TYPE(type)) { int32_t maxLen = bytes - VARSTR_HEADER_SIZE; int32_t len = (varDataLen(val) > maxLen)? maxLen:varDataLen(val); tVariantCreateFromBinary(tag, varDataVal(val), len, type); //tVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type); + } else if(type == TSDB_DATA_TYPE_JSON){ + char jsonVal[TSDB_MAX_JSON_TAGS_LEN] = {0}; + if(param){ + getJsonTagValueElment(pTable, param, paramLen, jsonVal, bytes); + }else{ + getJsonTagValueAll(val, jsonVal, TSDB_MAX_JSON_TAGS_LEN); + } + tVariantCreateFromBinary(tag, jsonVal, bytes, type); } else { tVariantCreateFromBinary(tag, val, bytes, type); } @@ -3254,12 +3277,12 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt SExprInfo* pExprInfo = &pExpr[0]; if (pQueryAttr->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP && pQueryAttr->stableQuery) { - assert(pExprInfo->base.numOfParams == 1); + assert(pExprInfo->base.numOfParams == 2); - int16_t tagColId = (int16_t)pExprInfo->base.param[0].i64; + int16_t tagColId = (int16_t)pExprInfo->base.param[1].i64; SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId); - - doSetTagValueInParam(pTable, tagColId, &pCtx[0].tag, pColInfo->type, pColInfo->bytes); + GET_JSON_KEY(pExprInfo) + doSetTagValueInParam(pTable, param, paramLen, tagColId, &pCtx[0].tag, pColInfo->type, pColInfo->bytes); return; } else { // set tag value, by which the results are aggregated. @@ -3275,7 +3298,8 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt } // todo use tag column index to optimize performance - doSetTagValueInParam(pTable, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->base.resType, + GET_JSON_KEY(pLocalExprInfo) + doSetTagValueInParam(pTable, param, paramLen, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->base.resType, pLocalExprInfo->base.resBytes); if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resType) @@ -3894,20 +3918,21 @@ void setCtxTagForJoin(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExpr if (pQueryAttr->stableQuery && (pRuntimeEnv->pTsBuf != NULL) && (pExpr->functionId == TSDB_FUNC_TS || pExpr->functionId == TSDB_FUNC_PRJ) && (pExpr->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { - assert(pExpr->numOfParams == 1); + assert(pExpr->numOfParams == 2); - int16_t tagColId = (int16_t)pExprInfo->base.param[0].i64; + int16_t tagColId = (int16_t)pExprInfo->base.param[1].i64; SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId); - doSetTagValueInParam(pTable, tagColId, &pCtx->tag, pColInfo->type, pColInfo->bytes); + GET_JSON_KEY(pExprInfo) + doSetTagValueInParam(pTable, param, paramLen, tagColId, &pCtx->tag, pColInfo->type, pColInfo->bytes); int16_t tagType = pCtx[0].tag.nType; - if (tagType == TSDB_DATA_TYPE_BINARY || tagType == TSDB_DATA_TYPE_NCHAR) { + if (tagType == TSDB_DATA_TYPE_BINARY || tagType == TSDB_DATA_TYPE_NCHAR || tagType == TSDB_DATA_TYPE_JSON) { qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%s", GET_QID(pRuntimeEnv), - pExprInfo->base.param[0].i64, pCtx[0].tag.pz); + pExprInfo->base.param[1].i64, pCtx[0].tag.pz); } else { qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%" PRId64, GET_QID(pRuntimeEnv), - pExprInfo->base.param[0].i64, pCtx[0].tag.i64); + pExprInfo->base.param[1].i64, pCtx[0].tag.i64); } } } @@ -3925,7 +3950,7 @@ int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, // failed to find data with the specified tag value and vnodeId if (!tsBufIsValidElem(&elem)) { - if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) { + if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR || pTag->nType == TSDB_DATA_TYPE_JSON) { qError("QInfo:0x%"PRIx64" failed to find tag:%s in ts_comp", GET_QID(pRuntimeEnv), pTag->pz); } else { qError("QInfo:0x%"PRIx64" failed to find tag:%" PRId64 " in ts_comp", GET_QID(pRuntimeEnv), pTag->i64); @@ -3936,7 +3961,7 @@ int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, // Keep the cursor info of current table pTableQueryInfo->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf); - if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) { + if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR || pTag->nType == TSDB_DATA_TYPE_JSON) { qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); } else { qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); @@ -3944,7 +3969,7 @@ int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, } else { tsBufSetCursor(pRuntimeEnv->pTsBuf, &pTableQueryInfo->cur); - if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) { + if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR || pTag->nType == TSDB_DATA_TYPE_JSON) { qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); } else { qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); @@ -5340,7 +5365,7 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, pInfo->multiGroupResults = groupResultMixedUp; pInfo->pMerge = param; - pInfo->bufCapacity = 4096; + pInfo->bufCapacity = 200; // TD-10899 pInfo->udfInfo = pUdfInfo; pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pInfo->bufCapacity * pInfo->resultRowFactor); pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); @@ -7427,7 +7452,16 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) { if (pExprInfo->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { data = tsdbGetTableName(item->pTable); } else { - data = tsdbGetTableTagVal(item->pTable, pExprInfo->base.colInfo.colId, type, bytes); + data = tsdbGetTableTagVal(item->pTable, pExprInfo->base.colInfo.colId, type); + if(type == TSDB_DATA_TYPE_JSON){ + if(pExprInfo->base.numOfParams > 0){ // tag-> operation + getJsonTagValueElment(item->pTable, pExprInfo->base.param[0].pz, pExprInfo->base.param[0].nLen, output, bytes); + }else{ + getJsonTagValueAll(data, output, bytes); + } + count += 1; + continue; + } } doSetTagValueToResultBuf(output, data, type, bytes); @@ -7463,13 +7497,20 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) { type = pExprInfo[j].base.resType; bytes = pExprInfo[j].base.resBytes; + dst = pColInfo->pData + count * pExprInfo[j].base.resBytes; if (pExprInfo[j].base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { data = tsdbGetTableName(item->pTable); } else { - data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.colInfo.colId, type, bytes); + data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.colInfo.colId, type); + if(type == TSDB_DATA_TYPE_JSON){ + if(pExprInfo[j].base.numOfParams > 0){ // tag-> operation + getJsonTagValueElment(item->pTable, pExprInfo[j].base.param[0].pz, pExprInfo[j].base.param[0].nLen, dst, bytes); + }else{ + getJsonTagValueAll(data, dst, bytes); + } + continue; + } } - - dst = pColInfo->pData + count * pExprInfo[j].base.resBytes; doSetTagValueToResultBuf(dst, data, type, bytes); } @@ -8455,8 +8496,8 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp // it is a user-defined constant value column assert(pExprs[i].base.functionId == TSDB_FUNC_PRJ); - type = pExprs[i].base.param[1].nType; - bytes = pExprs[i].base.param[1].nLen; + type = pExprs[i].base.param[0].nType; + bytes = pExprs[i].base.param[0].nLen; if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { bytes += VARSTR_HEADER_SIZE; } diff --git a/src/query/src/qExtbuffer.c b/src/query/src/qExtbuffer.c index ef4b56dc877ca75fe79ac5a345e99e0a3717eff5..cc214b953303e3b10b053bbe0c183eaee520e32a 100644 --- a/src/query/src/qExtbuffer.c +++ b/src/query/src/qExtbuffer.c @@ -367,6 +367,14 @@ static int32_t tsCompareFunc(TSKEY k1, TSKEY k2, int32_t order) { } int32_t columnValueAscendingComparator(char *f1, char *f2, int32_t type, int32_t bytes) { + if (type == TSDB_DATA_TYPE_JSON){ + bool canReturn = true; + int32_t result = jsonCompareUnit(f1, f2, &canReturn); + if(canReturn) return result; + type = *f1; + f1 += CHAR_BYTES; + f2 += CHAR_BYTES; + } switch (type) { case TSDB_DATA_TYPE_INT: DEFAULT_COMP(GET_INT32_VAL(f1), GET_INT32_VAL(f2)); case TSDB_DATA_TYPE_DOUBLE: DEFAULT_DOUBLE_COMP(GET_DOUBLE_VAL(f1), GET_DOUBLE_VAL(f2)); diff --git a/src/query/src/qFilter.c b/src/query/src/qFilter.c index 2ce8a49097af6229c36931cbf3db753c04580674..d5009c85ae3e7813ab0c35a62812e89d3d879ccf 100644 --- a/src/query/src/qFilter.c +++ b/src/query/src/qFilter.c @@ -18,6 +18,7 @@ #include "tcompare.h" #include "hash.h" #include "tscUtil.h" +#include "tsdbMeta.h" OptrStr gOptrStr[] = { {TSDB_RELATION_INVALID, "invalid"}, @@ -36,13 +37,14 @@ OptrStr gOptrStr[] = { {TSDB_RELATION_NOT, "not"}, {TSDB_RELATION_MATCH, "match"}, {TSDB_RELATION_NMATCH, "nmatch"}, + {TSDB_RELATION_CONTAINS, "contains"}, }; static FORCE_INLINE int32_t filterFieldColDescCompare(const void *desc1, const void *desc2) { const SSchema *sch1 = desc1; const SSchema *sch2 = desc2; - return sch1->colId != sch2->colId; + return !(strcmp(sch1->name, sch2->name) == 0 && sch1->colId == sch2->colId); } static FORCE_INLINE int32_t filterFieldValDescCompare(const void *desc1, const void *desc2) { @@ -60,15 +62,23 @@ filter_desc_compare_func gDescCompare [FLD_TYPE_MAX] = { }; bool filterRangeCompGi (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) { + int32_t result = cfunc(maxv, minr); + if (result == TSDB_DATA_JSON_CAN_NOT_COMPARE) return false; return cfunc(maxv, minr) >= 0; } bool filterRangeCompGe (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) { + int32_t result = cfunc(maxv, minr); + if (result == TSDB_DATA_JSON_CAN_NOT_COMPARE) return false; return cfunc(maxv, minr) > 0; } bool filterRangeCompLi (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) { + int32_t result = cfunc(minv, maxr); + if (result == TSDB_DATA_JSON_CAN_NOT_COMPARE) return false; return cfunc(minv, maxr) <= 0; } bool filterRangeCompLe (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) { + int32_t result = cfunc(minv, maxr); + if (result == TSDB_DATA_JSON_CAN_NOT_COMPARE) return false; return cfunc(minv, maxr) < 0; } bool filterRangeCompii (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) { @@ -158,7 +168,8 @@ int8_t filterGetRangeCompFuncFromOptrs(uint8_t optr, uint8_t optr2) { __compar_fn_t gDataCompare[] = {compareInt32Val, compareInt8Val, compareInt16Val, compareInt64Val, compareFloatVal, compareDoubleVal, compareLenPrefixedStr, compareStrPatternComp, compareFindItemInSet, compareWStrPatternComp, compareLenPrefixedWStr, compareUint8Val, compareUint16Val, compareUint32Val, compareUint64Val, - setCompareBytes1, setCompareBytes2, setCompareBytes4, setCompareBytes8, compareStrRegexCompMatch, compareStrRegexCompNMatch + setCompareBytes1, setCompareBytes2, setCompareBytes4, setCompareBytes8, compareStrRegexCompMatch, + compareStrRegexCompNMatch, compareStrContainJson, compareJsonVal }; int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { @@ -196,7 +207,7 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { case TSDB_DATA_TYPE_TIMESTAMP: comparFn = 3; break; case TSDB_DATA_TYPE_FLOAT: comparFn = 4; break; case TSDB_DATA_TYPE_DOUBLE: comparFn = 5; break; - case TSDB_DATA_TYPE_BINARY: { + case TSDB_DATA_TYPE_BINARY:{ if (optr == TSDB_RELATION_MATCH) { comparFn = 19; } else if (optr == TSDB_RELATION_NMATCH) { @@ -212,7 +223,7 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { break; } - case TSDB_DATA_TYPE_NCHAR: { + case TSDB_DATA_TYPE_NCHAR:{ if (optr == TSDB_RELATION_MATCH) { comparFn = 19; } else if (optr == TSDB_RELATION_NMATCH) { @@ -226,6 +237,20 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) { } break; } + case TSDB_DATA_TYPE_JSON:{ + if (optr == TSDB_RELATION_MATCH) { + comparFn = 19; + } else if (optr == TSDB_RELATION_NMATCH) { + comparFn = 20; + } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ + comparFn = 9; + } else if (optr == TSDB_RELATION_CONTAINS) { + comparFn = 21; + } else { + comparFn = 22; + } + break; + } case TSDB_DATA_TYPE_UTINYINT: comparFn = 11; break; case TSDB_DATA_TYPE_USMALLINT: comparFn = 12;break; @@ -846,11 +871,10 @@ static FORCE_INLINE int32_t filterAddColFieldFromField(SFilterInfo *info, SFilte return TSDB_CODE_SUCCESS; } - int32_t filterAddFieldFromNode(SFilterInfo *info, tExprNode *node, SFilterFieldId *fid) { CHK_LRET(node == NULL, TSDB_CODE_QRY_APP_ERROR, "empty node"); CHK_RET(node->nodeType != TSQL_NODE_COL && node->nodeType != TSQL_NODE_VALUE, TSDB_CODE_QRY_APP_ERROR); - + int32_t type; void *v; @@ -1030,6 +1054,12 @@ int32_t filterConvertSetFromBinary(void **q, const char *buf, int32_t len, uint3 switch (tType) { case TSDB_DATA_TYPE_BOOL: + if (sType != TSDB_DATA_TYPE_BOOL && !IS_SIGNED_NUMERIC_TYPE(sType)) { + goto _return; + } + if (tmpVar.i64 > 1 ||tmpVar.i64 < 0) { + goto _return; + } case TSDB_DATA_TYPE_UTINYINT: case TSDB_DATA_TYPE_TINYINT: { if (tVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) { @@ -1147,20 +1177,46 @@ _return: return code; } +static int32_t filterDealJson(SFilterInfo *info, tExprNode* tree, tExprNode** pLeft) { + if((*pLeft)->nodeType == TSQL_NODE_EXPR && (*pLeft)->_node.optr == TSDB_RELATION_ARROW){ // json tag -> operation + assert(info->pTable != NULL); + SSchema* schema = (*pLeft)->_node.pLeft->pSchema; + if((*pLeft)->_node.pRight->pVal->nLen > TSDB_MAX_JSON_KEY_LEN) return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; + char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0}; + jsonKeyMd5((*pLeft)->_node.pRight->pVal->pz, (*pLeft)->_node.pRight->pVal->nLen, keyMd5); + memcpy(schema->name, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN); + (*pLeft) = (*pLeft)->_node.pLeft; // -> operation use left as input + }else if(((*pLeft)->pSchema->type == TSDB_DATA_TYPE_JSON) && + (tree->_node.optr == TSDB_RELATION_ISNULL || tree->_node.optr == TSDB_RELATION_NOTNULL)){ + SSchema* schema = (*pLeft)->pSchema; + char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0}; + uint32_t nullData = TSDB_DATA_JSON_NULL; + jsonKeyMd5(&nullData, INT_BYTES, keyMd5); + memcpy(schema->name, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN); + }else if(tree->_node.optr == TSDB_RELATION_CONTAINS){ + SSchema* schema = (*pLeft)->pSchema; + if(tree->_node.pRight->pVal->nLen > TSDB_MAX_JSON_KEY_LEN) return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH; + char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0}; + jsonKeyMd5(tree->_node.pRight->pVal->pz, tree->_node.pRight->pVal->nLen, keyMd5); + memcpy(schema->name, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN); + } + return TSDB_CODE_SUCCESS; +} int32_t filterAddGroupUnitFromNode(SFilterInfo *info, tExprNode* tree, SArray *group) { + tExprNode* pLeft = tree->_node.pLeft; + int32_t ret = TSDB_CODE_SUCCESS; + if((ret = filterDealJson(info, tree, &pLeft)) != TSDB_CODE_SUCCESS) return ret; SFilterFieldId left = {0}, right = {0}; - - filterAddFieldFromNode(info, tree->_node.pLeft, &left); - - tVariant* var = tree->_node.pRight->pVal; - int32_t type = FILTER_GET_COL_FIELD_TYPE(FILTER_GET_FIELD(info, left)); + filterAddFieldFromNode(info, pLeft, &left); + uint8_t type = FILTER_GET_COL_FIELD_TYPE(FILTER_GET_FIELD(info, left)); int32_t len = 0; uint32_t uidx = 0; - if (tree->_node.optr == TSDB_RELATION_IN && (!IS_VAR_DATA_TYPE(type))) { + if (tree->_node.optr == TSDB_RELATION_IN && !IS_VAR_DATA_TYPE(type) && type != TSDB_DATA_TYPE_JSON) { void *data = NULL; + tVariant* var = tree->_node.pRight->pVal; filterConvertSetFromBinary((void **)&data, var->pz, var->nLen, type, false); CHK_LRET(data == NULL, TSDB_CODE_QRY_APP_ERROR, "failed to convert in param"); @@ -1180,18 +1236,11 @@ int32_t filterAddGroupUnitFromNode(SFilterInfo *info, tExprNode* tree, SArray *g while(p) { void *key = taosHashGetDataKey((SHashObj *)data, p); void *fdata = NULL; - - if (IS_VAR_DATA_TYPE(type)) { - len = (int32_t)taosHashGetDataKeyLen((SHashObj *)data, p); - fdata = malloc(len + VARSTR_HEADER_SIZE); - varDataLen(fdata) = len; - memcpy(varDataVal(fdata), key, len); - len += VARSTR_HEADER_SIZE; - } else { - fdata = malloc(sizeof(int64_t)); - SIMPLE_COPY_VALUES(fdata, key); - len = tDataTypes[type].bytes; - } + + fdata = malloc(sizeof(int64_t)); + SIMPLE_COPY_VALUES(fdata, key); + len = tDataTypes[type].bytes; + filterAddField(info, NULL, &fdata, FLD_TYPE_VALUE, &right, len, true); filterAddUnit(info, TSDB_RELATION_EQUAL, &left, &right, &uidx); @@ -1206,9 +1255,9 @@ int32_t filterAddGroupUnitFromNode(SFilterInfo *info, tExprNode* tree, SArray *g taosHashCleanup(data); } else { - filterAddFieldFromNode(info, tree->_node.pRight, &right); + filterAddFieldFromNode(info, tree->_node.pRight, &right); - filterAddUnit(info, tree->_node.optr, &left, &right, &uidx); + filterAddUnit(info, tree->_node.optr, &left, &right, &uidx); SFilterGroup fgroup = {0}; filterAddUnitToGroup(&fgroup, uidx); @@ -1476,7 +1525,7 @@ int32_t filterTreeToGroup(tExprNode* tree, SFilterInfo *info, SArray* group) { return TSDB_CODE_SUCCESS; } - code = filterAddGroupUnitFromNode(info, tree, group); + code = filterAddGroupUnitFromNode(info, tree, group); _return: @@ -1534,7 +1583,7 @@ void filterDumpInfoToString(SFilterInfo *info, const char *msg, int32_t options) tlen = varDataLen(data); data += VARSTR_HEADER_SIZE; } - converToStr(str + len, type, data, tlen > 32 ? 32 : tlen, &tlen); + if (data) converToStr(str + len, type, data, tlen > 32 ? 32 : tlen, &tlen); } else { strcat(str, "NULL"); } @@ -1815,7 +1864,7 @@ int32_t filterInitValFieldData(SFilterInfo *info) { } else if (type == TSDB_DATA_TYPE_NCHAR) { size_t len = (var->nType == TSDB_DATA_TYPE_BINARY || var->nType == TSDB_DATA_TYPE_NCHAR) ? var->nLen : MAX_NUM_STR_SIZE; fi->data = calloc(1, (len + 1) * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE); - } else { + } else if (type != TSDB_DATA_TYPE_JSON){ if (var->nType == TSDB_DATA_TYPE_VALUE_ARRAY) { //TIME RANGE fi->data = calloc(var->nLen, tDataTypes[type].bytes); for (int32_t a = 0; a < var->nLen; ++a) { @@ -1827,18 +1876,22 @@ int32_t filterInitValFieldData(SFilterInfo *info) { } else { fi->data = calloc(1, sizeof(int64_t)); } + } else{ // type == TSDB_DATA_TYPE_JSON + // fi->data = null; use fi->desc as data, because json value is variable, so use tVariant (fi->desc) } - bool converted = false; - char extInfo = 0; - if (tVariantDumpEx(var, (char*)fi->data, type, true, &converted, &extInfo)) { - if (converted) { - filterHandleValueExtInfo(unit, extInfo); - - continue; + if(type != TSDB_DATA_TYPE_JSON){ + bool converted = false; + char extInfo = 0; + if (tVariantDumpEx(var, (char*)fi->data, type, true, &converted, &extInfo)) { + if (converted) { + filterHandleValueExtInfo(unit, extInfo); + + continue; + } + qError("dump value to type[%d] failed", type); + return TSDB_CODE_TSC_INVALID_OPERATION; } - qError("dump value to type[%d] failed", type); - return TSDB_CODE_TSC_INVALID_OPERATION; } // match/nmatch for nchar type need convert from ucs4 to mbs @@ -1848,7 +1901,14 @@ int32_t filterInitValFieldData(SFilterInfo *info) { int32_t len = taosUcs4ToMbs(varDataVal(fi->data), varDataLen(fi->data), varDataVal(newValData)); varDataSetLen(newValData, len); varDataCopy(fi->data, newValData); + }else if(type == TSDB_DATA_TYPE_JSON && + (unit->compare.optr == TSDB_RELATION_MATCH || unit->compare.optr == TSDB_RELATION_NMATCH)){ + char newValData[TSDB_REGEX_STRING_DEFAULT_LEN * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE] = {0}; + int32_t len = taosUcs4ToMbs(((tVariant*)(fi->desc))->pz, ((tVariant*)(fi->desc))->nLen, newValData); + memcpy(((tVariant*)(fi->desc))->pz, newValData, len); + ((tVariant*)(fi->desc))->nLen = len; } + } return TSDB_CODE_SUCCESS; @@ -1858,6 +1918,8 @@ int32_t filterInitValFieldData(SFilterInfo *info) { bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right) { int32_t ret = func(left, right); + if(ret == TSDB_DATA_JSON_CAN_NOT_COMPARE) return false; + switch (optr) { case TSDB_RELATION_EQUAL: { return ret == 0; @@ -1883,6 +1945,9 @@ bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right) case TSDB_RELATION_MATCH: { return ret == 0; } + case TSDB_RELATION_CONTAINS: { + return ret == 0; + } case TSDB_RELATION_NMATCH: { return ret == 0; } @@ -2569,7 +2634,11 @@ int32_t filterGenerateComInfo(SFilterInfo *info) { info->cunits[i].colId = FILTER_UNIT_COL_ID(info, unit); if (unit->right.type == FLD_TYPE_VALUE) { - info->cunits[i].valData = FILTER_UNIT_VAL_DATA(info, unit); + if(FILTER_UNIT_DATA_TYPE(unit) == TSDB_DATA_TYPE_JSON){ // json value is tVariant + info->cunits[i].valData = FILTER_UNIT_JSON_VAL_DATA(info, unit); + }else{ + info->cunits[i].valData = FILTER_UNIT_VAL_DATA(info, unit); + } } else { info->cunits[i].valData = NULL; } @@ -2647,9 +2716,9 @@ int32_t filterRmUnitByRange(SFilterInfo *info, SDataStatis *pDataStatis, int32_t } } - if (cunit->optr == TSDB_RELATION_ISNULL || cunit->optr == TSDB_RELATION_NOTNULL + if (cunit->optr == TSDB_RELATION_ISNULL || cunit->optr == TSDB_RELATION_NOTNULL || cunit->optr == TSDB_RELATION_IN || cunit->optr == TSDB_RELATION_LIKE || cunit->optr == TSDB_RELATION_MATCH - || cunit->optr == TSDB_RELATION_NOT_EQUAL) { + || cunit->optr == TSDB_RELATION_NOT_EQUAL || cunit->optr == TSDB_RELATION_CONTAINS) { continue; } @@ -2891,7 +2960,18 @@ static FORCE_INLINE bool filterExecuteImplIsNull(void *pinfo, int32_t numOfRows, for (int32_t i = 0; i < numOfRows; ++i) { uint32_t uidx = info->groups[0].unitIdxs[0]; void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i; - (*p)[i] = ((colData == NULL) || isNull(colData, info->cunits[uidx].dataType)); + if(info->cunits[uidx].dataType == TSDB_DATA_TYPE_JSON){ + if (!colData){ // for json->'key' is null + (*p)[i] = 1; + }else if( *(char*)colData == TSDB_DATA_TYPE_JSON){ // for json is null + colData = POINTER_SHIFT(colData, CHAR_BYTES); + (*p)[i] = isNull(colData, info->cunits[uidx].dataType); + }else{ + (*p)[i] = 0; + } + }else{ + (*p)[i] = ((colData == NULL) || isNull(colData, info->cunits[uidx].dataType)); + } if ((*p)[i] == 0) { all = false; } @@ -2914,7 +2994,20 @@ static FORCE_INLINE bool filterExecuteImplNotNull(void *pinfo, int32_t numOfRows for (int32_t i = 0; i < numOfRows; ++i) { uint32_t uidx = info->groups[0].unitIdxs[0]; void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i; - (*p)[i] = ((colData != NULL) && !isNull(colData, info->cunits[uidx].dataType)); + + if(info->cunits[uidx].dataType == TSDB_DATA_TYPE_JSON){ + if (!colData) { // for json->'key' is not null + (*p)[i] = 0; + }else if( *(char*)colData == TSDB_DATA_TYPE_JSON){ // for json is not null + colData = POINTER_SHIFT(colData, CHAR_BYTES); + (*p)[i] = !isNull(colData, info->cunits[uidx].dataType); + }else{ // for json->'key' is not null + (*p)[i] = 1; + } + }else { + (*p)[i] = ((colData != NULL) && !isNull(colData, info->cunits[uidx].dataType)); + } + if ((*p)[i] == 0) { all = false; } @@ -2923,6 +3016,42 @@ static FORCE_INLINE bool filterExecuteImplNotNull(void *pinfo, int32_t numOfRows return all; } +static void doJsonCompare(SFilterComUnit *cunit, int8_t *result, void* colData){ + if(cunit->optr == TSDB_RELATION_MATCH || cunit->optr == TSDB_RELATION_NMATCH){ + uint8_t jsonType = *(char*)colData; + char* realData = POINTER_SHIFT(colData, CHAR_BYTES); + if (jsonType != TSDB_DATA_TYPE_NCHAR){ + *result = false; + }else{ + char *newColData = calloc(cunit->dataSize * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE, 1); + int len = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), varDataVal(newColData)); + varDataSetLen(newColData, len); + tVariant* val = cunit->valData; + char newValData[TSDB_REGEX_STRING_DEFAULT_LEN * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE] = {0}; + assert(val->nLen <= TSDB_REGEX_STRING_DEFAULT_LEN * TSDB_NCHAR_SIZE); + memcpy(varDataVal(newValData), val->pz, val->nLen); + varDataSetLen(newValData, val->nLen); + *result = filterDoCompare(gDataCompare[cunit->func], cunit->optr, newColData, newValData); + tfree(newColData); + } + }else if(cunit->optr == TSDB_RELATION_LIKE){ + uint8_t jsonType = *(char*)colData; + char* realData = POINTER_SHIFT(colData, CHAR_BYTES); + if (jsonType != TSDB_DATA_TYPE_NCHAR){ + *result = false; + }else{ + tVariant* val = cunit->valData; + char* newValData = calloc(val->nLen + VARSTR_HEADER_SIZE, 1); + memcpy(varDataVal(newValData), val->pz, val->nLen); + varDataSetLen(newValData, val->nLen); + *result = filterDoCompare(gDataCompare[cunit->func], cunit->optr, realData, newValData); + tfree(newValData); + } + }else{ + *result = filterDoCompare(gDataCompare[cunit->func], cunit->optr, colData, cunit->valData); + } +} + bool filterExecuteImplRange(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols) { SFilterInfo *info = (SFilterInfo *)pinfo; bool all = true; @@ -2988,6 +3117,8 @@ bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, int8_t** p, SDataStat varDataSetLen(newColData, len); (*p)[i] = filterDoCompare(gDataCompare[info->cunits[uidx].func], info->cunits[uidx].optr, newColData, info->cunits[uidx].valData); tfree(newColData); + }else if(info->cunits[uidx].dataType == TSDB_DATA_TYPE_JSON){ + doJsonCompare(&(info->cunits[uidx]), &(*p)[i], colData); }else{ (*p)[i] = filterDoCompare(gDataCompare[info->cunits[uidx].func], info->cunits[uidx].optr, colData, info->cunits[uidx].valData); } @@ -3000,7 +3131,6 @@ bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, int8_t** p, SDataStat return all; } - bool filterExecuteImpl(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols) { SFilterInfo *info = (SFilterInfo *)pinfo; bool all = true; @@ -3044,6 +3174,8 @@ bool filterExecuteImpl(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis * varDataSetLen(newColData, len); (*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, newColData, cunit->valData); tfree(newColData); + }else if(cunit->dataType == TSDB_DATA_TYPE_JSON){ + doJsonCompare(cunit, &(*p)[i], colData); }else{ (*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, colData, cunit->valData); } @@ -3175,6 +3307,25 @@ int32_t filterSetColFieldData(SFilterInfo *info, void *param, filer_get_col_from return TSDB_CODE_SUCCESS; } +int32_t filterSetJsonColFieldData(SFilterInfo *info, void *param, filer_get_col_from_name 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"); + + if (FILTER_ALL_RES(info) || FILTER_EMPTY_RES(info)) { + return TSDB_CODE_SUCCESS; + } + + 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; + + (*fp)(param, sch->colId, sch->name, &fi->data); + } + + filterUpdateComUnits(info); + + return TSDB_CODE_SUCCESS; +} int32_t filterInitFromTree(tExprNode* tree, void **pinfo, uint32_t options) { int32_t code = TSDB_CODE_SUCCESS; @@ -3195,10 +3346,10 @@ int32_t filterInitFromTree(tExprNode* tree, void **pinfo, uint32_t options) { filterInitUnitsFields(info); code = filterTreeToGroup(tree, info, group); - ERR_JRET(code); filterConvertGroupFromArray(info, group); + taosArrayDestroy(group); ERR_JRET(filterInitValFieldData(info)); @@ -3210,7 +3361,6 @@ int32_t filterInitFromTree(tExprNode* tree, void **pinfo, uint32_t options) { CHK_JMP(FILTER_GET_FLAG(info->status, FI_STATUS_ALL)); if (FILTER_GET_FLAG(info->status, FI_STATUS_EMPTY)) { - taosArrayDestroy(group); return code; } } @@ -3220,15 +3370,11 @@ int32_t filterInitFromTree(tExprNode* tree, void **pinfo, uint32_t options) { filterDumpInfoToString(info, "Final", 0); - taosArrayDestroy(group); - return code; _return: qInfo("No filter, code:%d", code); - taosArrayDestroy(group); - filterFreeInfo(*pinfo); *pinfo = NULL; @@ -3472,7 +3618,7 @@ int32_t filterIsIndexedColumnQuery(SFilterInfo* info, int32_t idxId, bool *res) int32_t optr = FILTER_UNIT_OPTR(info->units); CHK_JMP(optr == TSDB_RELATION_LIKE || optr == TSDB_RELATION_IN || optr == TSDB_RELATION_MATCH - || optr == TSDB_RELATION_ISNULL || optr == TSDB_RELATION_NOTNULL); + || optr == TSDB_RELATION_ISNULL || optr == TSDB_RELATION_NOTNULL || optr == TSDB_RELATION_CONTAINS); *res = true; diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index 1f6de550cfe195b15aafe970dc900681939546e4..64f8eb05d2a1d17f3fa21db3cd489337dc53d53e 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -22,6 +22,7 @@ #include "ttoken.h" #include "ttokendef.h" #include "tutil.h" +#include "tscUtil.h" SSqlInfo qSqlParse(const char *pStr) { void *pParser = ParseAlloc(malloc); @@ -52,7 +53,6 @@ SSqlInfo qSqlParse(const char *pStr) { Parse(pParser, 0, t0, &sqlInfo); goto abort_parse; } - case TK_QUESTION: case TK_ILLEGAL: { snprintf(sqlInfo.msg, tListLen(sqlInfo.msg), "unrecognized token: \"%s\"", t0.z); @@ -387,6 +387,11 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) { pRSub->Expr.paramList = (SArray *)pRight; pExpr->pRight = pRSub; + } else if (optrType == TK_ARROW || optrType == TK_CONTAINS) { + pExpr->tokenId = optrType; + pExpr->pLeft = pLeft; + pExpr->pRight = pRight; + pExpr->type = SQL_NODE_TABLE_COLUMN; } else { pExpr->tokenId = optrType; pExpr->pLeft = pLeft; @@ -522,12 +527,13 @@ void tSqlExprCompact(tSqlExpr** pExpr) { } bool tSqlExprIsLeaf(tSqlExpr* pExpr) { - return (pExpr->pRight == NULL && pExpr->pLeft == NULL) && + return ((pExpr->pRight == NULL && pExpr->pLeft == NULL) && (pExpr->tokenId == 0 || (pExpr->tokenId == TK_ID) || (pExpr->tokenId >= TK_BOOL && pExpr->tokenId <= TK_NCHAR) || (pExpr->tokenId == TK_NULL) || - (pExpr->tokenId == TK_SET)); + (pExpr->tokenId == TK_SET))) || + (pExpr->tokenId == TK_ARROW); } bool tSqlExprIsParentOfLeaf(tSqlExpr* pExpr) { @@ -575,6 +581,24 @@ SArray *tVariantListAppendToken(SArray *pList, SStrToken *pToken, uint8_t order, return pList; } +SArray *commonItemAppend(SArray *pList, tVariant *pVar, tSqlExpr *jsonExp, bool isJsonExp, uint8_t sortOrder){ + if (pList == NULL) { + pList = taosArrayInit(4, sizeof(CommonItem)); + } + + CommonItem item; + item.sortOrder = sortOrder; + item.isJsonExp = isJsonExp; + if(isJsonExp){ + item.jsonExp = jsonExp; + }else{ + item.pVar = *pVar; + } + + taosArrayPush(pList, &item); + return pList; +} + SArray *tVariantListAppend(SArray *pList, tVariant *pVar, uint8_t sortOrder) { if (pList == NULL) { pList = taosArrayInit(4, sizeof(tVariantListItem)); @@ -878,6 +902,15 @@ static void freeVariant(void *pItem) { tVariantDestroy(&p->pVar); } +static void freeCommonItem(void *pItem) { + CommonItem* p = (CommonItem *) pItem; + if (p->isJsonExp){ + tSqlExprDestroy(p->jsonExp); + }else{ + tVariantDestroy(&p->pVar); + } +} + void freeCreateTableInfo(void* p) { SCreatedTableInfo* pInfo = (SCreatedTableInfo*) p; taosArrayDestroy(pInfo->pTagNames); @@ -897,10 +930,10 @@ void destroySqlNode(SSqlNode *pSqlNode) { tSqlExprDestroy(pSqlNode->pWhere); pSqlNode->pWhere = NULL; - taosArrayDestroyEx(pSqlNode->pSortOrder, freeVariant); + taosArrayDestroyEx(pSqlNode->pSortOrder, freeCommonItem); pSqlNode->pSortOrder = NULL; - taosArrayDestroyEx(pSqlNode->pGroupby, freeVariant); + taosArrayDestroyEx(pSqlNode->pGroupby, freeCommonItem); pSqlNode->pGroupby = NULL; pSqlNode->from = destroyRelationInfo(pSqlNode->from); @@ -1015,7 +1048,6 @@ void SqlInfoDestroy(SSqlInfo *pInfo) { } else if (pInfo->type == TSDB_SQL_ALTER_TABLE) { taosArrayDestroyEx(pInfo->pAlterInfo->varList, freeVariant); taosArrayDestroy(pInfo->pAlterInfo->pAddColumns); - tfree(pInfo->pAlterInfo->tagData.data); tfree(pInfo->pAlterInfo); } else if (pInfo->type == TSDB_SQL_COMPACT_VNODE) { tSqlExprListDestroy(pInfo->list); diff --git a/src/query/src/qTsbuf.c b/src/query/src/qTsbuf.c index 9893533a589af0ca7a87dd05628db5059ecbe8eb..acbf094555e72cb72fd096014be8e8a89d700f4c 100644 --- a/src/query/src/qTsbuf.c +++ b/src/query/src/qTsbuf.c @@ -267,7 +267,8 @@ static void writeDataToDisk(STSBuf* pTSBuf) { metaLen += (int32_t)fwrite(&pBlock->tag.nType, 1, sizeof(pBlock->tag.nType), pTSBuf->f); int32_t trueLen = pBlock->tag.nLen; - if (pBlock->tag.nType == TSDB_DATA_TYPE_BINARY || pBlock->tag.nType == TSDB_DATA_TYPE_NCHAR) { + if (pBlock->tag.nType == TSDB_DATA_TYPE_BINARY || pBlock->tag.nType == TSDB_DATA_TYPE_NCHAR || + pBlock->tag.nType == TSDB_DATA_TYPE_JSON) { metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f); metaLen += (int32_t)fwrite(pBlock->tag.pz, 1, (size_t)pBlock->tag.nLen, pTSBuf->f); } else if (pBlock->tag.nType == TSDB_DATA_TYPE_FLOAT) { @@ -349,7 +350,8 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) { // NOTE: mix types tags are not supported size_t sz = 0; - if (pBlock->tag.nType == TSDB_DATA_TYPE_BINARY || pBlock->tag.nType == TSDB_DATA_TYPE_NCHAR) { + if (pBlock->tag.nType == TSDB_DATA_TYPE_BINARY || pBlock->tag.nType == TSDB_DATA_TYPE_NCHAR || + pBlock->tag.nType == TSDB_DATA_TYPE_JSON) { char* tp = realloc(pBlock->tag.pz, pBlock->tag.nLen + 1); assert(tp != NULL); diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index a150f3a717afaa0ddd79a33a9c8be5285c327574..4da6f52d7ae08dcdbc7192c7b89a6fb2733995fe 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -23,6 +23,8 @@ #include "tlosertree.h" #include "queryLog.h" #include "tscompression.h" +#include "tscUtil.h" +#include "cJSON.h" typedef struct SCompSupporter { STableQueryInfo **pTableQueryInfo; @@ -587,4 +589,3 @@ void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDi tfree(outputBuf); } } - diff --git a/src/query/src/sql.c b/src/query/src/sql.c index b06e430139339e7fbe335a3dbb3683bc470b2994..120feeb2046b5539ed8acc8510064919d7289187 100644 --- a/src/query/src/sql.c +++ b/src/query/src/sql.c @@ -1,3 +1,5 @@ +/* This file is automatically generated by Lemon from input grammar +** source file "sql.y". */ /* ** 2000-05-29 ** @@ -22,10 +24,7 @@ ** The following is the concatenation of all %include directives from the ** input grammar file: */ -#include -#include /************ Begin %include sections from the grammar ************************/ - #include #include #include @@ -38,11 +37,212 @@ #include "tutil.h" #include "tvariant.h" /**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ +/* These constants specify the various numeric values for terminal symbols. +***************** Begin token definitions *************************************/ +#ifndef TK_ID +#define TK_ID 1 +#define TK_BOOL 2 +#define TK_TINYINT 3 +#define TK_SMALLINT 4 +#define TK_INTEGER 5 +#define TK_BIGINT 6 +#define TK_FLOAT 7 +#define TK_DOUBLE 8 +#define TK_STRING 9 +#define TK_TIMESTAMP 10 +#define TK_BINARY 11 +#define TK_NCHAR 12 +#define TK_JSON 13 +#define TK_OR 14 +#define TK_AND 15 +#define TK_NOT 16 +#define TK_EQ 17 +#define TK_NE 18 +#define TK_ISNULL 19 +#define TK_NOTNULL 20 +#define TK_IS 21 +#define TK_LIKE 22 +#define TK_MATCH 23 +#define TK_NMATCH 24 +#define TK_CONTAINS 25 +#define TK_GLOB 26 +#define TK_BETWEEN 27 +#define TK_IN 28 +#define TK_GT 29 +#define TK_GE 30 +#define TK_LT 31 +#define TK_LE 32 +#define TK_BITAND 33 +#define TK_BITOR 34 +#define TK_LSHIFT 35 +#define TK_RSHIFT 36 +#define TK_PLUS 37 +#define TK_MINUS 38 +#define TK_DIVIDE 39 +#define TK_TIMES 40 +#define TK_STAR 41 +#define TK_SLASH 42 +#define TK_REM 43 +#define TK_CONCAT 44 +#define TK_UMINUS 45 +#define TK_UPLUS 46 +#define TK_BITNOT 47 +#define TK_ARROW 48 +#define TK_SHOW 49 +#define TK_DATABASES 50 +#define TK_TOPICS 51 +#define TK_FUNCTIONS 52 +#define TK_MNODES 53 +#define TK_DNODES 54 +#define TK_ACCOUNTS 55 +#define TK_USERS 56 +#define TK_MODULES 57 +#define TK_QUERIES 58 +#define TK_CONNECTIONS 59 +#define TK_STREAMS 60 +#define TK_VARIABLES 61 +#define TK_SCORES 62 +#define TK_GRANTS 63 +#define TK_VNODES 64 +#define TK_DOT 65 +#define TK_CREATE 66 +#define TK_TABLE 67 +#define TK_STABLE 68 +#define TK_DATABASE 69 +#define TK_TABLES 70 +#define TK_STABLES 71 +#define TK_VGROUPS 72 +#define TK_DROP 73 +#define TK_TOPIC 74 +#define TK_FUNCTION 75 +#define TK_DNODE 76 +#define TK_USER 77 +#define TK_ACCOUNT 78 +#define TK_USE 79 +#define TK_DESCRIBE 80 +#define TK_DESC 81 +#define TK_ALTER 82 +#define TK_PASS 83 +#define TK_PRIVILEGE 84 +#define TK_LOCAL 85 +#define TK_COMPACT 86 +#define TK_LP 87 +#define TK_RP 88 +#define TK_IF 89 +#define TK_EXISTS 90 +#define TK_AS 91 +#define TK_OUTPUTTYPE 92 +#define TK_AGGREGATE 93 +#define TK_BUFSIZE 94 +#define TK_PPS 95 +#define TK_TSERIES 96 +#define TK_DBS 97 +#define TK_STORAGE 98 +#define TK_QTIME 99 +#define TK_CONNS 100 +#define TK_STATE 101 +#define TK_COMMA 102 +#define TK_KEEP 103 +#define TK_CACHE 104 +#define TK_REPLICA 105 +#define TK_QUORUM 106 +#define TK_DAYS 107 +#define TK_MINROWS 108 +#define TK_MAXROWS 109 +#define TK_BLOCKS 110 +#define TK_CTIME 111 +#define TK_WAL 112 +#define TK_FSYNC 113 +#define TK_COMP 114 +#define TK_PRECISION 115 +#define TK_UPDATE 116 +#define TK_CACHELAST 117 +#define TK_PARTITIONS 118 +#define TK_UNSIGNED 119 +#define TK_TAGS 120 +#define TK_USING 121 +#define TK_NULL 122 +#define TK_NOW 123 +#define TK_SELECT 124 +#define TK_UNION 125 +#define TK_ALL 126 +#define TK_DISTINCT 127 +#define TK_FROM 128 +#define TK_VARIABLE 129 +#define TK_RANGE 130 +#define TK_INTERVAL 131 +#define TK_EVERY 132 +#define TK_SESSION 133 +#define TK_STATE_WINDOW 134 +#define TK_FILL 135 +#define TK_SLIDING 136 +#define TK_ORDER 137 +#define TK_BY 138 +#define TK_ASC 139 +#define TK_GROUP 140 +#define TK_HAVING 141 +#define TK_LIMIT 142 +#define TK_OFFSET 143 +#define TK_SLIMIT 144 +#define TK_SOFFSET 145 +#define TK_WHERE 146 +#define TK_RESET 147 +#define TK_QUERY 148 +#define TK_SYNCDB 149 +#define TK_ADD 150 +#define TK_COLUMN 151 +#define TK_MODIFY 152 +#define TK_TAG 153 +#define TK_CHANGE 154 +#define TK_SET 155 +#define TK_KILL 156 +#define TK_CONNECTION 157 +#define TK_STREAM 158 +#define TK_COLON 159 +#define TK_ABORT 160 +#define TK_AFTER 161 +#define TK_ATTACH 162 +#define TK_BEFORE 163 +#define TK_BEGIN 164 +#define TK_CASCADE 165 +#define TK_CLUSTER 166 +#define TK_CONFLICT 167 +#define TK_COPY 168 +#define TK_DEFERRED 169 +#define TK_DELIMITERS 170 +#define TK_DETACH 171 +#define TK_EACH 172 +#define TK_END 173 +#define TK_EXPLAIN 174 +#define TK_FAIL 175 +#define TK_FOR 176 +#define TK_IGNORE 177 +#define TK_IMMEDIATE 178 +#define TK_INITIALLY 179 +#define TK_INSTEAD 180 +#define TK_KEY 181 +#define TK_OF 182 +#define TK_RAISE 183 +#define TK_REPLACE 184 +#define TK_RESTRICT 185 +#define TK_ROW 186 +#define TK_STATEMENT 187 +#define TK_TRIGGER 188 +#define TK_VIEW 189 +#define TK_IPTOKEN 190 +#define TK_SEMI 191 +#define TK_NONE 192 +#define TK_PREV 193 +#define TK_LINEAR 194 +#define TK_IMPORT 195 +#define TK_TBNAME 196 +#define TK_JOIN 197 +#define TK_INSERT 198 +#define TK_INTO 199 +#define TK_VALUES 200 +#define TK_FILE 201 +#endif +/**************** End token definitions ***************************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. @@ -100,30 +300,30 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 282 +#define YYNOCODE 285 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SStrToken typedef union { int yyinit; ParseTOKENTYPE yy0; - tVariant yy2; - SCreateDbInfo yy10; - int32_t yy40; - SSqlNode* yy68; - SCreatedTableInfo yy72; - SLimitVal yy114; - SRangeVal yy144; - SCreateTableSql* yy170; - SIntervalVal yy280; - int yy281; - SSessionWindowVal yy295; - SArray* yy345; - tSqlExpr* yy418; - SCreateAcctInfo yy427; - SWindowStateVal yy432; + SCreateAcctInfo yy31; + SSqlNode* yy86; + TAOS_FIELD yy103; + tVariant yy176; + tSqlExpr* yy226; + SWindowStateVal yy228; + SArray* yy231; + SCreatedTableInfo yy306; + int32_t yy310; + SSessionWindowVal yy409; + SCreateTableSql* yy422; + SIntervalVal yy430; + SLimitVal yy444; + SRangeVal yy480; SRelationInfo* yy484; - TAOS_FIELD yy487; - int64_t yy525; + int yy502; + SCreateDbInfo yy532; + int64_t yy549; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -139,18 +339,18 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 378 -#define YYNRULE 302 -#define YYNRULE_WITH_ACTION 302 -#define YYNTOKEN 199 -#define YY_MAX_SHIFT 377 -#define YY_MIN_SHIFTREDUCE 593 -#define YY_MAX_SHIFTREDUCE 894 -#define YY_ERROR_ACTION 895 -#define YY_ACCEPT_ACTION 896 -#define YY_NO_ACTION 897 -#define YY_MIN_REDUCE 898 -#define YY_MAX_REDUCE 1199 +#define YYNSTATE 387 +#define YYNRULE 312 +#define YYNRULE_WITH_ACTION 312 +#define YYNTOKEN 202 +#define YY_MAX_SHIFT 386 +#define YY_MIN_SHIFTREDUCE 609 +#define YY_MAX_SHIFTREDUCE 920 +#define YY_ERROR_ACTION 921 +#define YY_ACCEPT_ACTION 922 +#define YY_NO_ACTION 923 +#define YY_MIN_REDUCE 924 +#define YY_MAX_REDUCE 1235 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -217,297 +417,309 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (790) +#define YY_ACTTAB_COUNT (831) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 244, 644, 376, 237, 1053, 23, 213, 728, 1075, 645, - /* 10 */ 680, 896, 377, 59, 60, 250, 63, 64, 1175, 1053, - /* 20 */ 258, 53, 52, 51, 644, 62, 334, 67, 65, 68, - /* 30 */ 66, 158, 645, 336, 174, 58, 57, 354, 353, 56, - /* 40 */ 55, 54, 59, 60, 252, 63, 64, 1052, 1053, 258, - /* 50 */ 53, 52, 51, 296, 62, 334, 67, 65, 68, 66, - /* 60 */ 1023, 1066, 1021, 1022, 58, 57, 1195, 1024, 56, 55, - /* 70 */ 54, 1025, 255, 1026, 1027, 58, 57, 1072, 280, 56, - /* 80 */ 55, 54, 59, 60, 165, 63, 64, 38, 84, 258, - /* 90 */ 53, 52, 51, 90, 62, 334, 67, 65, 68, 66, - /* 100 */ 1066, 287, 286, 644, 58, 57, 332, 29, 56, 55, - /* 110 */ 54, 645, 59, 61, 831, 63, 64, 240, 1039, 258, - /* 120 */ 53, 52, 51, 644, 62, 334, 67, 65, 68, 66, - /* 130 */ 45, 645, 239, 213, 58, 57, 1050, 850, 56, 55, - /* 140 */ 54, 60, 1047, 63, 64, 1176, 281, 258, 53, 52, - /* 150 */ 51, 165, 62, 334, 67, 65, 68, 66, 38, 308, - /* 160 */ 39, 95, 58, 57, 796, 797, 56, 55, 54, 594, - /* 170 */ 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, - /* 180 */ 605, 606, 607, 156, 1066, 238, 63, 64, 768, 251, - /* 190 */ 258, 53, 52, 51, 254, 62, 334, 67, 65, 68, - /* 200 */ 66, 241, 364, 248, 332, 58, 57, 1050, 210, 56, - /* 210 */ 55, 54, 256, 44, 330, 371, 370, 329, 328, 327, - /* 220 */ 369, 326, 325, 324, 368, 323, 367, 366, 1123, 16, - /* 230 */ 306, 15, 165, 24, 6, 1015, 1003, 1004, 1005, 1006, - /* 240 */ 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1016, 1017, - /* 250 */ 216, 165, 257, 846, 211, 213, 835, 224, 838, 837, - /* 260 */ 841, 840, 99, 141, 140, 139, 223, 1176, 257, 846, - /* 270 */ 339, 90, 835, 772, 838, 272, 841, 56, 55, 54, - /* 280 */ 67, 65, 68, 66, 276, 275, 235, 236, 58, 57, - /* 290 */ 335, 765, 56, 55, 54, 1036, 1037, 35, 1040, 259, - /* 300 */ 372, 984, 235, 236, 5, 41, 184, 267, 45, 1122, - /* 310 */ 38, 183, 108, 113, 104, 112, 752, 9, 180, 749, - /* 320 */ 261, 750, 784, 751, 38, 102, 787, 266, 96, 38, - /* 330 */ 319, 279, 836, 82, 839, 69, 125, 119, 130, 217, - /* 340 */ 231, 946, 118, 129, 117, 135, 138, 128, 194, 263, - /* 350 */ 264, 69, 292, 293, 132, 204, 202, 200, 38, 1049, - /* 360 */ 213, 1041, 199, 145, 144, 143, 142, 127, 38, 249, - /* 370 */ 847, 842, 1176, 1050, 343, 38, 38, 843, 1050, 364, - /* 380 */ 844, 44, 38, 371, 370, 83, 847, 842, 369, 375, - /* 390 */ 374, 621, 368, 843, 367, 366, 38, 262, 38, 260, - /* 400 */ 267, 342, 341, 344, 268, 218, 265, 1050, 349, 348, - /* 410 */ 813, 181, 14, 345, 219, 267, 98, 1050, 87, 1038, - /* 420 */ 346, 350, 88, 97, 1050, 1050, 1051, 351, 155, 153, - /* 430 */ 152, 1050, 956, 753, 754, 947, 34, 242, 85, 194, - /* 440 */ 793, 352, 194, 356, 803, 1050, 101, 1050, 804, 1, - /* 450 */ 182, 3, 195, 845, 160, 283, 291, 290, 70, 283, - /* 460 */ 75, 78, 26, 738, 311, 740, 313, 739, 812, 314, - /* 470 */ 869, 848, 833, 643, 18, 81, 17, 39, 39, 70, - /* 480 */ 100, 70, 137, 136, 25, 25, 757, 25, 758, 20, - /* 490 */ 755, 19, 756, 124, 22, 123, 21, 288, 1170, 1169, - /* 500 */ 1168, 233, 79, 76, 234, 214, 215, 727, 289, 1187, - /* 510 */ 834, 220, 212, 221, 222, 1133, 226, 227, 228, 1132, - /* 520 */ 246, 225, 277, 1129, 209, 1128, 247, 355, 48, 1067, - /* 530 */ 157, 1074, 1085, 1064, 154, 1082, 1083, 284, 1115, 1087, - /* 540 */ 159, 164, 1114, 302, 1048, 176, 282, 86, 177, 1046, - /* 550 */ 178, 179, 961, 783, 316, 317, 295, 318, 321, 322, - /* 560 */ 166, 46, 243, 297, 309, 80, 207, 42, 333, 955, - /* 570 */ 340, 1194, 115, 1193, 1190, 185, 347, 1186, 121, 299, - /* 580 */ 77, 167, 50, 307, 1185, 1182, 168, 305, 186, 303, - /* 590 */ 981, 43, 301, 40, 47, 208, 943, 131, 941, 133, - /* 600 */ 134, 939, 938, 298, 269, 197, 198, 935, 934, 933, - /* 610 */ 932, 931, 930, 929, 201, 203, 925, 923, 921, 205, - /* 620 */ 918, 206, 294, 914, 320, 49, 91, 300, 1116, 365, - /* 630 */ 126, 357, 358, 359, 360, 361, 362, 232, 363, 253, - /* 640 */ 315, 373, 894, 270, 271, 893, 273, 274, 229, 892, - /* 650 */ 875, 230, 109, 960, 959, 874, 110, 146, 278, 283, - /* 660 */ 310, 10, 285, 89, 92, 760, 937, 936, 189, 147, - /* 670 */ 188, 982, 187, 190, 191, 193, 928, 192, 148, 927, - /* 680 */ 4, 149, 1019, 920, 30, 983, 919, 175, 171, 169, - /* 690 */ 172, 170, 173, 33, 2, 792, 1029, 73, 790, 789, - /* 700 */ 786, 785, 74, 163, 794, 161, 245, 805, 162, 11, - /* 710 */ 799, 93, 31, 801, 94, 304, 32, 12, 13, 27, - /* 720 */ 312, 103, 28, 101, 106, 36, 658, 693, 691, 690, - /* 730 */ 689, 105, 687, 686, 37, 107, 685, 682, 648, 111, - /* 740 */ 7, 331, 849, 337, 8, 851, 338, 114, 39, 71, - /* 750 */ 72, 116, 120, 730, 729, 726, 122, 674, 672, 664, - /* 760 */ 670, 666, 668, 662, 660, 696, 695, 694, 692, 688, - /* 770 */ 684, 683, 196, 646, 611, 898, 897, 897, 897, 897, - /* 780 */ 897, 897, 897, 897, 897, 897, 897, 897, 150, 151, + /* 0 */ 101, 660, 660, 1153, 660, 1154, 309, 744, 1073, 661, + /* 10 */ 661, 160, 661, 104, 37, 38, 248, 41, 42, 385, + /* 20 */ 239, 261, 31, 30, 29, 922, 386, 40, 341, 45, + /* 30 */ 43, 46, 44, 1062, 1063, 55, 1066, 36, 35, 363, + /* 40 */ 362, 34, 33, 32, 37, 38, 24, 41, 42, 1067, + /* 50 */ 696, 261, 31, 30, 29, 254, 1209, 40, 341, 45, + /* 60 */ 43, 46, 44, 1049, 1078, 1047, 1048, 36, 35, 1101, + /* 70 */ 1050, 34, 33, 32, 1051, 1092, 1052, 1053, 58, 36, + /* 80 */ 35, 290, 289, 34, 33, 32, 37, 38, 51, 41, + /* 90 */ 42, 84, 283, 261, 31, 30, 29, 660, 90, 40, + /* 100 */ 341, 45, 43, 46, 44, 661, 384, 383, 637, 36, + /* 110 */ 35, 211, 212, 34, 33, 32, 37, 39, 852, 41, + /* 120 */ 42, 1209, 1209, 261, 31, 30, 29, 1075, 337, 40, + /* 130 */ 341, 45, 43, 46, 44, 67, 58, 58, 1098, 36, + /* 140 */ 35, 381, 1010, 34, 33, 32, 610, 611, 612, 613, + /* 150 */ 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, + /* 160 */ 158, 38, 240, 41, 42, 58, 54, 261, 31, 30, + /* 170 */ 29, 812, 813, 40, 341, 45, 43, 46, 44, 284, + /* 180 */ 218, 241, 251, 36, 35, 1076, 1076, 34, 33, 32, + /* 190 */ 1209, 41, 42, 59, 175, 261, 31, 30, 29, 319, + /* 200 */ 264, 40, 341, 45, 43, 46, 44, 34, 33, 32, + /* 210 */ 252, 36, 35, 299, 1076, 34, 33, 32, 66, 335, + /* 220 */ 380, 379, 334, 333, 332, 378, 331, 330, 329, 377, + /* 230 */ 328, 376, 375, 313, 96, 291, 95, 25, 1041, 1029, + /* 240 */ 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, + /* 250 */ 1040, 1042, 1043, 214, 217, 246, 232, 867, 58, 1079, + /* 260 */ 856, 225, 859, 1209, 862, 1211, 1231, 143, 142, 141, + /* 270 */ 224, 373, 232, 867, 348, 90, 856, 265, 859, 263, + /* 280 */ 862, 351, 350, 157, 155, 154, 45, 43, 46, 44, + /* 290 */ 972, 58, 237, 238, 36, 35, 342, 195, 34, 33, + /* 300 */ 32, 800, 858, 352, 861, 803, 219, 1076, 237, 238, + /* 310 */ 1, 183, 67, 5, 61, 185, 1209, 1151, 58, 1152, + /* 320 */ 184, 110, 115, 106, 114, 768, 269, 857, 765, 860, + /* 330 */ 766, 258, 767, 295, 296, 282, 353, 82, 1223, 324, + /* 340 */ 1076, 98, 47, 97, 233, 257, 127, 121, 132, 1164, + /* 350 */ 253, 262, 58, 131, 1079, 137, 140, 130, 47, 275, + /* 360 */ 266, 267, 784, 354, 134, 58, 58, 1076, 279, 278, + /* 370 */ 294, 293, 66, 340, 380, 379, 832, 868, 863, 378, + /* 380 */ 205, 203, 201, 377, 864, 376, 375, 200, 147, 146, + /* 390 */ 145, 144, 214, 868, 863, 13, 339, 355, 1065, 100, + /* 400 */ 864, 1076, 1209, 271, 1212, 268, 214, 358, 357, 58, + /* 410 */ 359, 360, 214, 260, 1076, 1076, 1209, 58, 1212, 244, + /* 420 */ 345, 220, 1209, 1201, 1212, 270, 865, 1200, 1199, 103, + /* 430 */ 235, 1209, 236, 1209, 831, 6, 181, 1209, 1209, 1163, + /* 440 */ 1209, 83, 1209, 215, 292, 769, 770, 216, 788, 221, + /* 450 */ 213, 866, 255, 1209, 361, 222, 1079, 1209, 1076, 1209, + /* 460 */ 1209, 223, 365, 227, 228, 1209, 1076, 1092, 229, 226, + /* 470 */ 210, 1209, 1092, 1209, 1209, 1064, 982, 270, 1209, 1209, + /* 480 */ 1209, 270, 129, 195, 242, 99, 973, 337, 182, 243, + /* 490 */ 3, 196, 1077, 195, 373, 781, 87, 88, 809, 819, + /* 500 */ 85, 820, 339, 75, 78, 15, 754, 14, 316, 344, + /* 510 */ 756, 318, 162, 70, 755, 48, 895, 869, 259, 312, + /* 520 */ 59, 10, 59, 659, 70, 102, 871, 120, 70, 119, + /* 530 */ 9, 9, 343, 286, 286, 81, 17, 9, 16, 773, + /* 540 */ 771, 774, 772, 139, 138, 79, 76, 19, 126, 18, + /* 550 */ 125, 21, 26, 20, 249, 1160, 1159, 280, 855, 250, + /* 560 */ 364, 159, 1100, 1111, 1108, 1109, 1093, 743, 1113, 287, + /* 570 */ 161, 166, 305, 1143, 1142, 1141, 177, 1074, 178, 1140, + /* 580 */ 156, 1072, 179, 180, 987, 321, 322, 323, 326, 174, + /* 590 */ 327, 68, 208, 64, 338, 981, 349, 799, 1230, 117, + /* 600 */ 298, 167, 245, 300, 302, 1090, 80, 1229, 314, 1226, + /* 610 */ 186, 356, 168, 77, 28, 169, 1222, 310, 123, 1221, + /* 620 */ 1218, 187, 308, 1007, 306, 65, 170, 172, 60, 69, + /* 630 */ 304, 209, 171, 173, 969, 133, 967, 135, 136, 301, + /* 640 */ 965, 964, 272, 198, 199, 961, 960, 959, 958, 957, + /* 650 */ 956, 955, 297, 202, 204, 951, 949, 947, 27, 206, + /* 660 */ 944, 207, 940, 325, 374, 285, 128, 86, 91, 303, + /* 670 */ 366, 367, 234, 368, 369, 371, 256, 370, 320, 372, + /* 680 */ 382, 920, 273, 274, 230, 231, 919, 276, 277, 918, + /* 690 */ 986, 985, 111, 112, 901, 281, 900, 286, 315, 11, + /* 700 */ 89, 963, 962, 52, 954, 190, 189, 1008, 148, 188, + /* 710 */ 191, 192, 194, 193, 149, 150, 953, 2, 151, 1045, + /* 720 */ 1009, 4, 946, 53, 176, 945, 776, 288, 92, 808, + /* 730 */ 73, 806, 1055, 805, 802, 801, 74, 165, 810, 163, + /* 740 */ 247, 821, 164, 22, 815, 93, 62, 817, 94, 307, + /* 750 */ 343, 311, 23, 63, 12, 49, 317, 50, 103, 674, + /* 760 */ 105, 56, 107, 108, 57, 109, 709, 707, 706, 705, + /* 770 */ 703, 702, 701, 698, 336, 664, 113, 7, 892, 890, + /* 780 */ 870, 893, 891, 8, 346, 872, 347, 116, 71, 59, + /* 790 */ 746, 72, 118, 122, 745, 124, 742, 690, 688, 680, + /* 800 */ 686, 682, 684, 678, 676, 712, 711, 710, 708, 704, + /* 810 */ 700, 699, 197, 662, 627, 924, 923, 923, 923, 923, + /* 820 */ 923, 923, 923, 923, 923, 923, 923, 923, 923, 152, + /* 830 */ 153, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 247, 1, 201, 202, 251, 269, 269, 5, 201, 9, - /* 10 */ 5, 199, 200, 13, 14, 247, 16, 17, 281, 251, - /* 20 */ 20, 21, 22, 23, 1, 25, 26, 27, 28, 29, - /* 30 */ 30, 201, 9, 15, 256, 35, 36, 35, 36, 39, - /* 40 */ 40, 41, 13, 14, 247, 16, 17, 251, 251, 20, - /* 50 */ 21, 22, 23, 275, 25, 26, 27, 28, 29, 30, - /* 60 */ 225, 249, 227, 228, 35, 36, 251, 232, 39, 40, - /* 70 */ 41, 236, 208, 238, 239, 35, 36, 270, 266, 39, - /* 80 */ 40, 41, 13, 14, 201, 16, 17, 201, 88, 20, - /* 90 */ 21, 22, 23, 84, 25, 26, 27, 28, 29, 30, - /* 100 */ 249, 271, 272, 1, 35, 36, 86, 84, 39, 40, - /* 110 */ 41, 9, 13, 14, 85, 16, 17, 266, 0, 20, - /* 120 */ 21, 22, 23, 1, 25, 26, 27, 28, 29, 30, - /* 130 */ 121, 9, 246, 269, 35, 36, 250, 119, 39, 40, - /* 140 */ 41, 14, 201, 16, 17, 281, 85, 20, 21, 22, - /* 150 */ 23, 201, 25, 26, 27, 28, 29, 30, 201, 276, - /* 160 */ 99, 278, 35, 36, 128, 129, 39, 40, 41, 47, - /* 170 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 180 */ 58, 59, 60, 61, 249, 63, 16, 17, 39, 248, - /* 190 */ 20, 21, 22, 23, 208, 25, 26, 27, 28, 29, - /* 200 */ 30, 266, 92, 246, 86, 35, 36, 250, 269, 39, - /* 210 */ 40, 41, 62, 100, 101, 102, 103, 104, 105, 106, - /* 220 */ 107, 108, 109, 110, 111, 112, 113, 114, 278, 148, - /* 230 */ 280, 150, 201, 46, 84, 225, 226, 227, 228, 229, + /* 0 */ 212, 1, 1, 280, 1, 282, 283, 5, 204, 9, + /* 10 */ 9, 204, 9, 212, 14, 15, 1, 17, 18, 204, + /* 20 */ 205, 21, 22, 23, 24, 202, 203, 27, 28, 29, + /* 30 */ 30, 31, 32, 245, 246, 247, 248, 37, 38, 37, + /* 40 */ 38, 41, 42, 43, 14, 15, 272, 17, 18, 248, + /* 50 */ 5, 21, 22, 23, 24, 251, 282, 27, 28, 29, + /* 60 */ 30, 31, 32, 228, 254, 230, 231, 37, 38, 204, + /* 70 */ 235, 41, 42, 43, 239, 252, 241, 242, 204, 37, + /* 80 */ 38, 274, 275, 41, 42, 43, 14, 15, 87, 17, + /* 90 */ 18, 91, 269, 21, 22, 23, 24, 1, 87, 27, + /* 100 */ 28, 29, 30, 31, 32, 9, 70, 71, 72, 37, + /* 110 */ 38, 272, 272, 41, 42, 43, 14, 15, 88, 17, + /* 120 */ 18, 282, 282, 21, 22, 23, 24, 253, 89, 27, + /* 130 */ 28, 29, 30, 31, 32, 124, 204, 204, 273, 37, + /* 140 */ 38, 226, 227, 41, 42, 43, 50, 51, 52, 53, + /* 150 */ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + /* 160 */ 64, 15, 66, 17, 18, 204, 87, 21, 22, 23, + /* 170 */ 24, 131, 132, 27, 28, 29, 30, 31, 32, 88, + /* 180 */ 272, 249, 249, 37, 38, 253, 253, 41, 42, 43, + /* 190 */ 282, 17, 18, 102, 259, 21, 22, 23, 24, 120, + /* 200 */ 73, 27, 28, 29, 30, 31, 32, 41, 42, 43, + /* 210 */ 249, 37, 38, 278, 253, 41, 42, 43, 103, 104, + /* 220 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 230 */ 115, 116, 117, 279, 280, 277, 282, 49, 228, 229, /* 240 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - /* 250 */ 63, 201, 1, 2, 269, 269, 5, 70, 7, 5, - /* 260 */ 9, 7, 209, 76, 77, 78, 79, 281, 1, 2, - /* 270 */ 83, 84, 5, 124, 7, 145, 9, 39, 40, 41, - /* 280 */ 27, 28, 29, 30, 154, 155, 35, 36, 35, 36, - /* 290 */ 39, 99, 39, 40, 41, 242, 243, 244, 245, 208, - /* 300 */ 223, 224, 35, 36, 64, 65, 66, 201, 121, 278, - /* 310 */ 201, 71, 72, 73, 74, 75, 2, 125, 212, 5, - /* 320 */ 70, 7, 5, 9, 201, 209, 9, 70, 278, 201, - /* 330 */ 90, 144, 5, 146, 7, 84, 64, 65, 66, 269, - /* 340 */ 153, 207, 148, 71, 150, 73, 74, 75, 214, 35, - /* 350 */ 36, 84, 35, 36, 82, 64, 65, 66, 201, 250, - /* 360 */ 269, 245, 71, 72, 73, 74, 75, 80, 201, 246, - /* 370 */ 119, 120, 281, 250, 246, 201, 201, 126, 250, 92, - /* 380 */ 126, 100, 201, 102, 103, 209, 119, 120, 107, 67, - /* 390 */ 68, 69, 111, 126, 113, 114, 201, 147, 201, 149, - /* 400 */ 201, 151, 152, 246, 147, 269, 149, 250, 151, 152, - /* 410 */ 78, 212, 84, 246, 269, 201, 88, 250, 85, 243, - /* 420 */ 246, 246, 85, 252, 250, 250, 212, 246, 64, 65, - /* 430 */ 66, 250, 207, 119, 120, 207, 84, 120, 267, 214, - /* 440 */ 85, 246, 214, 246, 85, 250, 118, 250, 85, 210, - /* 450 */ 211, 205, 206, 126, 99, 122, 35, 36, 99, 122, - /* 460 */ 99, 99, 99, 85, 85, 85, 85, 85, 136, 117, - /* 470 */ 85, 85, 1, 85, 148, 84, 150, 99, 99, 99, - /* 480 */ 99, 99, 80, 81, 99, 99, 5, 99, 7, 148, - /* 490 */ 5, 150, 7, 148, 148, 150, 150, 274, 269, 269, - /* 500 */ 269, 269, 140, 142, 269, 269, 269, 116, 274, 251, - /* 510 */ 39, 269, 269, 269, 269, 241, 269, 269, 269, 241, - /* 520 */ 241, 269, 201, 241, 269, 241, 241, 241, 268, 249, - /* 530 */ 201, 201, 201, 265, 62, 201, 201, 249, 279, 201, - /* 540 */ 201, 201, 279, 201, 249, 253, 203, 203, 201, 201, - /* 550 */ 201, 201, 201, 126, 201, 201, 273, 201, 201, 201, - /* 560 */ 264, 201, 273, 273, 134, 139, 201, 201, 201, 201, - /* 570 */ 201, 201, 201, 201, 201, 201, 201, 201, 201, 273, - /* 580 */ 141, 263, 138, 137, 201, 201, 262, 132, 201, 131, - /* 590 */ 201, 201, 130, 201, 201, 201, 201, 201, 201, 201, - /* 600 */ 201, 201, 201, 133, 201, 201, 201, 201, 201, 201, - /* 610 */ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, - /* 620 */ 201, 201, 127, 201, 91, 143, 203, 203, 203, 115, - /* 630 */ 98, 97, 53, 94, 96, 57, 95, 203, 93, 203, - /* 640 */ 203, 86, 5, 156, 5, 5, 156, 5, 203, 5, - /* 650 */ 102, 203, 209, 213, 213, 101, 209, 204, 145, 122, - /* 660 */ 117, 84, 99, 123, 99, 85, 203, 203, 216, 204, - /* 670 */ 220, 222, 221, 219, 217, 215, 203, 218, 204, 203, - /* 680 */ 205, 204, 240, 203, 84, 224, 203, 254, 259, 261, - /* 690 */ 258, 260, 257, 255, 210, 85, 240, 99, 126, 126, - /* 700 */ 5, 5, 84, 99, 85, 84, 1, 85, 84, 135, - /* 710 */ 85, 84, 99, 85, 84, 84, 99, 135, 84, 84, - /* 720 */ 117, 80, 84, 118, 72, 89, 5, 9, 5, 5, - /* 730 */ 5, 88, 5, 5, 89, 88, 5, 5, 87, 80, - /* 740 */ 84, 15, 85, 26, 84, 119, 61, 150, 99, 16, - /* 750 */ 16, 150, 150, 5, 5, 85, 150, 5, 5, 5, - /* 760 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - /* 770 */ 5, 5, 99, 87, 62, 0, 282, 282, 282, 282, - /* 780 */ 282, 282, 282, 282, 282, 282, 282, 282, 21, 21, - /* 790 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 800 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 810 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 820 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 830 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 840 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 850 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 860 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 870 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 880 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 890 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 900 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 910 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 920 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 930 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 940 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 950 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 960 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 970 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, - /* 980 */ 282, 282, 282, 282, 282, 282, 282, 282, 282, + /* 250 */ 240, 241, 242, 272, 66, 250, 1, 2, 204, 254, + /* 260 */ 5, 73, 7, 282, 9, 284, 254, 79, 80, 81, + /* 270 */ 82, 95, 1, 2, 86, 87, 5, 150, 7, 152, + /* 280 */ 9, 154, 155, 67, 68, 69, 29, 30, 31, 32, + /* 290 */ 210, 204, 37, 38, 37, 38, 41, 217, 41, 42, + /* 300 */ 43, 5, 5, 249, 7, 9, 272, 253, 37, 38, + /* 310 */ 213, 214, 124, 67, 68, 69, 282, 280, 204, 282, + /* 320 */ 74, 75, 76, 77, 78, 2, 73, 5, 5, 7, + /* 330 */ 7, 211, 9, 37, 38, 147, 249, 149, 254, 93, + /* 340 */ 253, 280, 87, 282, 156, 211, 67, 68, 69, 244, + /* 350 */ 250, 211, 204, 74, 254, 76, 77, 78, 87, 148, + /* 360 */ 37, 38, 41, 249, 85, 204, 204, 253, 157, 158, + /* 370 */ 37, 38, 103, 25, 105, 106, 81, 122, 123, 110, + /* 380 */ 67, 68, 69, 114, 129, 116, 117, 74, 75, 76, + /* 390 */ 77, 78, 272, 122, 123, 87, 48, 249, 0, 91, + /* 400 */ 129, 253, 282, 150, 284, 152, 272, 154, 155, 204, + /* 410 */ 249, 249, 272, 65, 253, 253, 282, 204, 284, 123, + /* 420 */ 16, 272, 282, 272, 284, 204, 129, 272, 272, 121, + /* 430 */ 272, 282, 272, 282, 139, 87, 215, 282, 282, 244, + /* 440 */ 282, 212, 282, 272, 277, 122, 123, 272, 127, 272, + /* 450 */ 272, 129, 250, 282, 249, 272, 254, 282, 253, 282, + /* 460 */ 282, 272, 249, 272, 272, 282, 253, 252, 272, 272, + /* 470 */ 272, 282, 252, 282, 282, 246, 210, 204, 282, 282, + /* 480 */ 282, 204, 83, 217, 269, 255, 210, 89, 215, 269, + /* 490 */ 208, 209, 215, 217, 95, 102, 88, 88, 88, 88, + /* 500 */ 270, 88, 48, 102, 102, 151, 88, 153, 88, 25, + /* 510 */ 88, 88, 102, 102, 88, 102, 88, 88, 1, 65, + /* 520 */ 102, 128, 102, 88, 102, 102, 122, 151, 102, 153, + /* 530 */ 102, 102, 48, 125, 125, 87, 151, 102, 153, 5, + /* 540 */ 5, 7, 7, 83, 84, 143, 145, 151, 151, 153, + /* 550 */ 153, 151, 271, 153, 244, 244, 244, 204, 41, 244, + /* 560 */ 244, 204, 204, 204, 204, 204, 252, 119, 204, 252, + /* 570 */ 204, 204, 204, 281, 281, 281, 256, 252, 204, 281, + /* 580 */ 65, 204, 204, 204, 204, 204, 204, 204, 204, 260, + /* 590 */ 204, 204, 204, 204, 204, 204, 204, 129, 204, 204, + /* 600 */ 276, 267, 276, 276, 276, 268, 142, 204, 137, 204, + /* 610 */ 204, 204, 266, 144, 141, 265, 204, 140, 204, 204, + /* 620 */ 204, 204, 135, 204, 134, 204, 264, 262, 204, 204, + /* 630 */ 133, 204, 263, 261, 204, 204, 204, 204, 204, 136, + /* 640 */ 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + /* 650 */ 204, 204, 130, 204, 204, 204, 204, 204, 146, 204, + /* 660 */ 204, 204, 204, 94, 118, 206, 101, 206, 206, 206, + /* 670 */ 100, 56, 206, 97, 99, 98, 206, 60, 206, 96, + /* 680 */ 89, 5, 159, 5, 206, 206, 5, 159, 5, 5, + /* 690 */ 216, 216, 212, 212, 105, 148, 104, 125, 120, 87, + /* 700 */ 126, 206, 206, 87, 206, 219, 223, 225, 207, 224, + /* 710 */ 222, 220, 218, 221, 207, 207, 206, 213, 207, 243, + /* 720 */ 227, 208, 206, 258, 257, 206, 88, 102, 102, 88, + /* 730 */ 102, 129, 243, 129, 5, 5, 87, 102, 88, 87, + /* 740 */ 1, 88, 87, 138, 88, 87, 102, 88, 87, 87, + /* 750 */ 48, 1, 138, 102, 87, 87, 120, 87, 121, 5, + /* 760 */ 83, 92, 91, 75, 92, 91, 9, 5, 5, 5, + /* 770 */ 5, 5, 5, 5, 16, 90, 83, 87, 9, 9, + /* 780 */ 88, 9, 9, 87, 28, 122, 64, 153, 17, 102, + /* 790 */ 5, 17, 153, 153, 5, 153, 88, 5, 5, 5, + /* 800 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 810 */ 5, 5, 102, 90, 65, 0, 285, 285, 285, 285, + /* 820 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 22, + /* 830 */ 22, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 840 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 850 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 860 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 870 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 880 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 890 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 900 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 910 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 920 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 930 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 940 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 950 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 960 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 970 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 980 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 990 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 1000 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 1010 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 1020 */ 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + /* 1030 */ 285, 285, 285, }; -#define YY_SHIFT_COUNT (377) +#define YY_SHIFT_COUNT (386) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (775) +#define YY_SHIFT_MAX (815) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 187, 113, 113, 281, 281, 20, 251, 267, 267, 23, - /* 10 */ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - /* 20 */ 102, 102, 102, 0, 122, 267, 314, 314, 314, 9, - /* 30 */ 9, 102, 102, 36, 102, 118, 102, 102, 102, 102, - /* 40 */ 287, 20, 110, 110, 5, 790, 790, 790, 267, 267, - /* 50 */ 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - /* 60 */ 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - /* 70 */ 314, 314, 314, 317, 317, 2, 2, 2, 2, 2, - /* 80 */ 2, 2, 102, 102, 102, 149, 102, 102, 102, 9, - /* 90 */ 9, 102, 102, 102, 102, 332, 332, 192, 9, 102, - /* 100 */ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - /* 110 */ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - /* 120 */ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - /* 130 */ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - /* 140 */ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - /* 150 */ 102, 102, 102, 102, 102, 102, 102, 472, 472, 472, - /* 160 */ 427, 427, 427, 427, 472, 472, 426, 439, 430, 444, - /* 170 */ 446, 455, 458, 462, 470, 495, 482, 472, 472, 472, - /* 180 */ 533, 533, 514, 20, 20, 472, 472, 532, 534, 579, - /* 190 */ 539, 538, 578, 541, 545, 514, 5, 472, 472, 555, - /* 200 */ 555, 472, 555, 472, 555, 472, 472, 790, 790, 29, - /* 210 */ 69, 69, 99, 69, 127, 170, 240, 253, 253, 253, - /* 220 */ 253, 253, 253, 272, 291, 40, 40, 40, 40, 250, - /* 230 */ 257, 130, 328, 238, 238, 254, 327, 322, 364, 61, - /* 240 */ 333, 337, 421, 355, 359, 363, 361, 362, 378, 379, - /* 250 */ 380, 381, 382, 352, 385, 386, 471, 150, 18, 388, - /* 260 */ 81, 194, 326, 481, 485, 341, 345, 391, 346, 402, - /* 270 */ 637, 487, 639, 640, 490, 642, 644, 548, 554, 513, - /* 280 */ 537, 543, 577, 540, 580, 600, 563, 565, 610, 598, - /* 290 */ 572, 573, 695, 696, 618, 619, 621, 622, 624, 625, - /* 300 */ 604, 627, 628, 630, 705, 631, 613, 574, 617, 582, - /* 310 */ 634, 543, 635, 603, 638, 605, 641, 636, 643, 652, - /* 320 */ 721, 645, 647, 718, 723, 724, 725, 727, 728, 731, - /* 330 */ 732, 651, 726, 659, 656, 657, 626, 660, 717, 685, - /* 340 */ 733, 597, 601, 649, 649, 649, 649, 734, 602, 606, - /* 350 */ 649, 649, 649, 748, 749, 670, 649, 752, 753, 754, - /* 360 */ 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, - /* 370 */ 765, 766, 673, 686, 767, 768, 712, 775, + /* 0 */ 188, 115, 115, 269, 269, 39, 255, 271, 271, 271, + /* 10 */ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + /* 20 */ 3, 3, 15, 15, 0, 96, 271, 271, 271, 271, + /* 30 */ 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + /* 40 */ 271, 271, 271, 271, 271, 271, 271, 271, 323, 323, + /* 50 */ 323, 11, 11, 40, 3, 398, 3, 3, 3, 3, + /* 60 */ 399, 39, 15, 15, 176, 176, 45, 831, 831, 831, + /* 70 */ 323, 323, 323, 296, 296, 2, 2, 2, 2, 2, + /* 80 */ 2, 2, 3, 3, 3, 321, 3, 3, 3, 11, + /* 90 */ 11, 3, 3, 3, 3, 295, 295, 295, 295, 393, + /* 100 */ 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, + /* 110 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + /* 120 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + /* 130 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + /* 140 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + /* 150 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 515, + /* 160 */ 515, 515, 468, 468, 468, 468, 515, 464, 469, 471, + /* 170 */ 473, 477, 487, 490, 497, 503, 522, 512, 515, 515, + /* 180 */ 515, 569, 569, 546, 39, 39, 515, 515, 565, 570, + /* 190 */ 615, 576, 575, 617, 577, 583, 546, 45, 515, 515, + /* 200 */ 591, 591, 515, 591, 515, 591, 515, 515, 831, 831, + /* 210 */ 30, 72, 72, 102, 72, 146, 174, 246, 257, 257, + /* 220 */ 257, 257, 257, 257, 279, 313, 42, 42, 42, 42, + /* 230 */ 127, 253, 348, 211, 308, 166, 166, 297, 322, 36, + /* 240 */ 216, 91, 408, 409, 333, 410, 411, 413, 454, 401, + /* 250 */ 402, 418, 420, 422, 423, 426, 79, 428, 429, 484, + /* 260 */ 517, 404, 435, 354, 376, 385, 534, 535, 396, 397, + /* 270 */ 448, 400, 460, 676, 523, 678, 681, 528, 683, 684, + /* 280 */ 589, 592, 547, 572, 578, 612, 574, 638, 616, 625, + /* 290 */ 626, 641, 628, 602, 604, 729, 730, 649, 650, 652, + /* 300 */ 653, 655, 656, 635, 658, 659, 661, 739, 662, 644, + /* 310 */ 605, 702, 750, 651, 614, 667, 578, 668, 636, 670, + /* 320 */ 637, 677, 669, 671, 688, 754, 672, 674, 757, 762, + /* 330 */ 763, 764, 765, 766, 767, 768, 685, 758, 693, 769, + /* 340 */ 770, 690, 692, 772, 773, 663, 696, 756, 722, 771, + /* 350 */ 634, 639, 687, 687, 687, 687, 774, 640, 642, 687, + /* 360 */ 687, 687, 785, 789, 708, 687, 792, 793, 794, 795, + /* 370 */ 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, + /* 380 */ 806, 710, 723, 807, 808, 749, 815, }; -#define YY_REDUCE_COUNT (208) -#define YY_REDUCE_MIN (-264) -#define YY_REDUCE_MAX (484) +#define YY_REDUCE_COUNT (209) +#define YY_REDUCE_MIN (-277) +#define YY_REDUCE_MAX (519) static const short yy_reduce_ofst[] = { - /* 0 */ -188, 10, 10, -165, -165, 53, -136, -14, 91, -170, - /* 10 */ -114, -50, -117, -43, 123, 128, 157, 167, 174, 175, - /* 20 */ 181, 195, 197, -193, -199, -263, -247, -232, -203, -149, - /* 30 */ -65, 31, 50, -222, -59, 116, 106, 199, 214, 109, - /* 40 */ 134, 176, 225, 228, 77, 171, 239, 246, -264, -61, - /* 50 */ -15, 70, 136, 145, 229, 230, 231, 232, 235, 236, - /* 60 */ 237, 242, 243, 244, 245, 247, 248, 249, 252, 255, - /* 70 */ -204, -185, 258, 223, 234, 274, 278, 279, 282, 284, - /* 80 */ 285, 286, 321, 329, 330, 260, 331, 334, 335, 280, - /* 90 */ 288, 338, 339, 340, 342, 259, 263, 292, 295, 347, - /* 100 */ 348, 349, 350, 351, 353, 354, 356, 357, 358, 360, - /* 110 */ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - /* 120 */ 375, 376, 377, 383, 384, 387, 389, 390, 392, 393, - /* 130 */ 394, 395, 396, 397, 398, 399, 400, 401, 403, 404, - /* 140 */ 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - /* 150 */ 415, 416, 417, 418, 419, 420, 422, 343, 344, 423, - /* 160 */ 283, 289, 290, 306, 424, 425, 268, 296, 318, 324, - /* 170 */ 428, 431, 429, 432, 435, 438, 433, 434, 436, 437, - /* 180 */ 440, 441, 442, 443, 447, 445, 448, 449, 451, 450, - /* 190 */ 452, 454, 457, 459, 460, 456, 461, 463, 464, 453, - /* 200 */ 465, 473, 474, 476, 477, 480, 483, 484, 475, + /* 0 */ -177, 10, 10, -165, -165, -212, 120, 134, 140, -19, + /* 10 */ -193, -68, -67, -39, 54, 87, 114, 148, 161, 162, + /* 20 */ 205, 213, -277, -46, -135, -185, -226, -161, -160, -92, + /* 30 */ 34, 149, 151, 155, 156, 158, 160, 171, 175, 177, + /* 40 */ 178, 183, 189, 191, 192, 196, 197, 198, 5, 100, + /* 50 */ 202, 215, 220, -65, -196, -199, 221, 273, 277, -126, + /* 60 */ 80, 229, 37, 61, 266, 276, -85, 230, 97, 282, + /* 70 */ -190, 12, 84, -42, 167, 105, 195, 310, 311, 312, + /* 80 */ 315, 316, 353, 357, 358, 281, 359, 360, 361, 314, + /* 90 */ 317, 364, 366, 367, 368, 292, 293, 294, 298, 320, + /* 100 */ 325, 374, 377, 378, 379, 380, 381, 382, 383, 384, + /* 110 */ 386, 387, 388, 389, 390, 391, 392, 394, 395, 403, + /* 120 */ 405, 406, 407, 412, 414, 415, 416, 417, 419, 421, + /* 130 */ 424, 425, 427, 430, 431, 432, 433, 434, 436, 437, + /* 140 */ 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, + /* 150 */ 449, 450, 451, 452, 453, 455, 456, 457, 458, 459, + /* 160 */ 461, 462, 324, 326, 327, 328, 463, 337, 334, 346, + /* 170 */ 350, 362, 369, 365, 372, 329, 465, 467, 466, 470, + /* 180 */ 472, 474, 475, 476, 480, 481, 478, 479, 482, 485, + /* 190 */ 483, 486, 488, 491, 492, 494, 489, 493, 495, 496, + /* 200 */ 501, 507, 498, 508, 510, 511, 516, 519, 504, 513, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 895, 1018, 957, 1028, 944, 954, 1178, 1178, 1178, 895, - /* 10 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 20 */ 895, 895, 895, 1076, 915, 1178, 895, 895, 895, 895, - /* 30 */ 895, 895, 895, 1100, 895, 954, 895, 895, 895, 895, - /* 40 */ 964, 954, 964, 964, 895, 1071, 1002, 1020, 895, 895, - /* 50 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 60 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 70 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 80 */ 895, 895, 895, 895, 895, 1078, 1084, 1081, 895, 895, - /* 90 */ 895, 1086, 895, 895, 895, 1119, 1119, 1069, 895, 895, - /* 100 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 110 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 120 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 130 */ 895, 942, 895, 940, 895, 895, 895, 895, 895, 895, - /* 140 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 150 */ 895, 895, 895, 895, 895, 895, 913, 917, 917, 917, - /* 160 */ 895, 895, 895, 895, 917, 917, 1126, 1130, 1112, 1124, - /* 170 */ 1120, 1107, 1105, 1103, 1111, 1096, 1134, 917, 917, 917, - /* 180 */ 962, 962, 958, 954, 954, 917, 917, 980, 978, 976, - /* 190 */ 968, 974, 970, 972, 966, 945, 895, 917, 917, 952, - /* 200 */ 952, 917, 952, 917, 952, 917, 917, 1002, 1020, 895, - /* 210 */ 1135, 1125, 895, 1177, 1165, 1164, 895, 1173, 1172, 1171, - /* 220 */ 1163, 1162, 1161, 895, 895, 1157, 1160, 1159, 1158, 895, - /* 230 */ 895, 895, 895, 1167, 1166, 895, 895, 895, 895, 895, - /* 240 */ 895, 895, 1093, 895, 895, 895, 1131, 1127, 895, 895, - /* 250 */ 895, 895, 895, 895, 895, 895, 895, 1137, 895, 895, - /* 260 */ 895, 895, 895, 895, 895, 895, 895, 1030, 895, 895, - /* 270 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 280 */ 1068, 895, 895, 895, 895, 895, 1080, 1079, 895, 895, - /* 290 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 300 */ 895, 895, 895, 895, 895, 895, 1121, 895, 1113, 895, - /* 310 */ 895, 1042, 895, 895, 895, 895, 895, 895, 895, 895, - /* 320 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 330 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 340 */ 895, 895, 895, 1196, 1191, 1192, 1189, 895, 895, 895, - /* 350 */ 1188, 1183, 1184, 895, 895, 895, 1181, 895, 895, 895, - /* 360 */ 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, - /* 370 */ 895, 895, 986, 895, 924, 922, 895, 895, + /* 0 */ 921, 1044, 983, 1054, 970, 980, 1214, 1214, 1214, 1214, + /* 10 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 20 */ 921, 921, 921, 921, 1102, 941, 921, 921, 921, 921, + /* 30 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 40 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 50 */ 921, 921, 921, 1126, 921, 980, 921, 921, 921, 921, + /* 60 */ 990, 980, 921, 921, 990, 990, 921, 1097, 1028, 1046, + /* 70 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 80 */ 921, 921, 921, 921, 921, 1104, 1110, 1107, 921, 921, + /* 90 */ 921, 1112, 921, 921, 921, 1148, 1148, 1148, 1148, 1095, + /* 100 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 110 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 120 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 130 */ 921, 921, 921, 968, 921, 966, 921, 921, 921, 921, + /* 140 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 150 */ 921, 921, 921, 921, 921, 921, 921, 921, 939, 943, + /* 160 */ 943, 943, 921, 921, 921, 921, 943, 1157, 1161, 1138, + /* 170 */ 1155, 1149, 1133, 1131, 1129, 1137, 1122, 1165, 943, 943, + /* 180 */ 943, 988, 988, 984, 980, 980, 943, 943, 1006, 1004, + /* 190 */ 1002, 994, 1000, 996, 998, 992, 971, 921, 943, 943, + /* 200 */ 978, 978, 943, 978, 943, 978, 943, 943, 1028, 1046, + /* 210 */ 921, 1166, 1156, 921, 1213, 1196, 1195, 921, 1204, 1203, + /* 220 */ 1202, 1194, 1193, 1192, 921, 921, 1188, 1191, 1190, 1189, + /* 230 */ 921, 921, 1168, 921, 921, 1198, 1197, 921, 921, 921, + /* 240 */ 921, 921, 921, 921, 1119, 921, 921, 921, 1144, 1162, + /* 250 */ 1158, 921, 921, 921, 921, 921, 921, 921, 921, 1169, + /* 260 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 270 */ 1056, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 280 */ 921, 921, 921, 1094, 921, 921, 921, 921, 921, 1106, + /* 290 */ 1105, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 300 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 1150, + /* 310 */ 921, 1145, 921, 1139, 921, 921, 1068, 921, 921, 921, + /* 320 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 330 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 340 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 350 */ 921, 921, 1232, 1227, 1228, 1225, 921, 921, 921, 1224, + /* 360 */ 1219, 1220, 921, 921, 921, 1217, 921, 921, 921, 921, + /* 370 */ 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + /* 380 */ 921, 1012, 921, 950, 948, 921, 921, }; /********** End of lemon-generated parsing tables *****************************/ @@ -540,6 +752,7 @@ static const YYCODETYPE yyFallback[] = { 1, /* TIMESTAMP => ID */ 1, /* BINARY => ID */ 1, /* NCHAR => ID */ + 1, /* JSON => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* NOT => nothing */ @@ -551,6 +764,7 @@ static const YYCODETYPE yyFallback[] = { 1, /* LIKE => ID */ 1, /* MATCH => ID */ 1, /* NMATCH => ID */ + 0, /* CONTAINS => nothing */ 1, /* GLOB => ID */ 0, /* BETWEEN => nothing */ 0, /* IN => nothing */ @@ -573,6 +787,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* UMINUS => nothing */ 0, /* UPLUS => nothing */ 0, /* BITNOT => nothing */ + 0, /* ARROW => nothing */ 0, /* SHOW => nothing */ 0, /* DATABASES => nothing */ 0, /* TOPICS => nothing */ @@ -779,6 +994,7 @@ typedef struct yyParser yyParser; #ifndef NDEBUG #include +#include static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ @@ -826,275 +1042,278 @@ static const char *const yyTokenName[] = { /* 10 */ "TIMESTAMP", /* 11 */ "BINARY", /* 12 */ "NCHAR", - /* 13 */ "OR", - /* 14 */ "AND", - /* 15 */ "NOT", - /* 16 */ "EQ", - /* 17 */ "NE", - /* 18 */ "ISNULL", - /* 19 */ "NOTNULL", - /* 20 */ "IS", - /* 21 */ "LIKE", - /* 22 */ "MATCH", - /* 23 */ "NMATCH", - /* 24 */ "GLOB", - /* 25 */ "BETWEEN", - /* 26 */ "IN", - /* 27 */ "GT", - /* 28 */ "GE", - /* 29 */ "LT", - /* 30 */ "LE", - /* 31 */ "BITAND", - /* 32 */ "BITOR", - /* 33 */ "LSHIFT", - /* 34 */ "RSHIFT", - /* 35 */ "PLUS", - /* 36 */ "MINUS", - /* 37 */ "DIVIDE", - /* 38 */ "TIMES", - /* 39 */ "STAR", - /* 40 */ "SLASH", - /* 41 */ "REM", - /* 42 */ "CONCAT", - /* 43 */ "UMINUS", - /* 44 */ "UPLUS", - /* 45 */ "BITNOT", - /* 46 */ "SHOW", - /* 47 */ "DATABASES", - /* 48 */ "TOPICS", - /* 49 */ "FUNCTIONS", - /* 50 */ "MNODES", - /* 51 */ "DNODES", - /* 52 */ "ACCOUNTS", - /* 53 */ "USERS", - /* 54 */ "MODULES", - /* 55 */ "QUERIES", - /* 56 */ "CONNECTIONS", - /* 57 */ "STREAMS", - /* 58 */ "VARIABLES", - /* 59 */ "SCORES", - /* 60 */ "GRANTS", - /* 61 */ "VNODES", - /* 62 */ "DOT", - /* 63 */ "CREATE", - /* 64 */ "TABLE", - /* 65 */ "STABLE", - /* 66 */ "DATABASE", - /* 67 */ "TABLES", - /* 68 */ "STABLES", - /* 69 */ "VGROUPS", - /* 70 */ "DROP", - /* 71 */ "TOPIC", - /* 72 */ "FUNCTION", - /* 73 */ "DNODE", - /* 74 */ "USER", - /* 75 */ "ACCOUNT", - /* 76 */ "USE", - /* 77 */ "DESCRIBE", - /* 78 */ "DESC", - /* 79 */ "ALTER", - /* 80 */ "PASS", - /* 81 */ "PRIVILEGE", - /* 82 */ "LOCAL", - /* 83 */ "COMPACT", - /* 84 */ "LP", - /* 85 */ "RP", - /* 86 */ "IF", - /* 87 */ "EXISTS", - /* 88 */ "AS", - /* 89 */ "OUTPUTTYPE", - /* 90 */ "AGGREGATE", - /* 91 */ "BUFSIZE", - /* 92 */ "PPS", - /* 93 */ "TSERIES", - /* 94 */ "DBS", - /* 95 */ "STORAGE", - /* 96 */ "QTIME", - /* 97 */ "CONNS", - /* 98 */ "STATE", - /* 99 */ "COMMA", - /* 100 */ "KEEP", - /* 101 */ "CACHE", - /* 102 */ "REPLICA", - /* 103 */ "QUORUM", - /* 104 */ "DAYS", - /* 105 */ "MINROWS", - /* 106 */ "MAXROWS", - /* 107 */ "BLOCKS", - /* 108 */ "CTIME", - /* 109 */ "WAL", - /* 110 */ "FSYNC", - /* 111 */ "COMP", - /* 112 */ "PRECISION", - /* 113 */ "UPDATE", - /* 114 */ "CACHELAST", - /* 115 */ "PARTITIONS", - /* 116 */ "UNSIGNED", - /* 117 */ "TAGS", - /* 118 */ "USING", - /* 119 */ "NULL", - /* 120 */ "NOW", - /* 121 */ "SELECT", - /* 122 */ "UNION", - /* 123 */ "ALL", - /* 124 */ "DISTINCT", - /* 125 */ "FROM", - /* 126 */ "VARIABLE", - /* 127 */ "RANGE", - /* 128 */ "INTERVAL", - /* 129 */ "EVERY", - /* 130 */ "SESSION", - /* 131 */ "STATE_WINDOW", - /* 132 */ "FILL", - /* 133 */ "SLIDING", - /* 134 */ "ORDER", - /* 135 */ "BY", - /* 136 */ "ASC", - /* 137 */ "GROUP", - /* 138 */ "HAVING", - /* 139 */ "LIMIT", - /* 140 */ "OFFSET", - /* 141 */ "SLIMIT", - /* 142 */ "SOFFSET", - /* 143 */ "WHERE", - /* 144 */ "RESET", - /* 145 */ "QUERY", - /* 146 */ "SYNCDB", - /* 147 */ "ADD", - /* 148 */ "COLUMN", - /* 149 */ "MODIFY", - /* 150 */ "TAG", - /* 151 */ "CHANGE", - /* 152 */ "SET", - /* 153 */ "KILL", - /* 154 */ "CONNECTION", - /* 155 */ "STREAM", - /* 156 */ "COLON", - /* 157 */ "ABORT", - /* 158 */ "AFTER", - /* 159 */ "ATTACH", - /* 160 */ "BEFORE", - /* 161 */ "BEGIN", - /* 162 */ "CASCADE", - /* 163 */ "CLUSTER", - /* 164 */ "CONFLICT", - /* 165 */ "COPY", - /* 166 */ "DEFERRED", - /* 167 */ "DELIMITERS", - /* 168 */ "DETACH", - /* 169 */ "EACH", - /* 170 */ "END", - /* 171 */ "EXPLAIN", - /* 172 */ "FAIL", - /* 173 */ "FOR", - /* 174 */ "IGNORE", - /* 175 */ "IMMEDIATE", - /* 176 */ "INITIALLY", - /* 177 */ "INSTEAD", - /* 178 */ "KEY", - /* 179 */ "OF", - /* 180 */ "RAISE", - /* 181 */ "REPLACE", - /* 182 */ "RESTRICT", - /* 183 */ "ROW", - /* 184 */ "STATEMENT", - /* 185 */ "TRIGGER", - /* 186 */ "VIEW", - /* 187 */ "IPTOKEN", - /* 188 */ "SEMI", - /* 189 */ "NONE", - /* 190 */ "PREV", - /* 191 */ "LINEAR", - /* 192 */ "IMPORT", - /* 193 */ "TBNAME", - /* 194 */ "JOIN", - /* 195 */ "INSERT", - /* 196 */ "INTO", - /* 197 */ "VALUES", - /* 198 */ "FILE", - /* 199 */ "program", - /* 200 */ "cmd", - /* 201 */ "ids", - /* 202 */ "dbPrefix", - /* 203 */ "cpxName", - /* 204 */ "ifexists", - /* 205 */ "alter_db_optr", - /* 206 */ "alter_topic_optr", - /* 207 */ "acct_optr", - /* 208 */ "exprlist", - /* 209 */ "ifnotexists", - /* 210 */ "db_optr", - /* 211 */ "topic_optr", - /* 212 */ "typename", - /* 213 */ "bufsize", - /* 214 */ "pps", - /* 215 */ "tseries", - /* 216 */ "dbs", - /* 217 */ "streams", - /* 218 */ "storage", - /* 219 */ "qtime", - /* 220 */ "users", - /* 221 */ "conns", - /* 222 */ "state", - /* 223 */ "intitemlist", - /* 224 */ "intitem", - /* 225 */ "keep", - /* 226 */ "cache", - /* 227 */ "replica", - /* 228 */ "quorum", - /* 229 */ "days", - /* 230 */ "minrows", - /* 231 */ "maxrows", - /* 232 */ "blocks", - /* 233 */ "ctime", - /* 234 */ "wal", - /* 235 */ "fsync", - /* 236 */ "comp", - /* 237 */ "prec", - /* 238 */ "update", - /* 239 */ "cachelast", - /* 240 */ "partitions", - /* 241 */ "signed", - /* 242 */ "create_table_args", - /* 243 */ "create_stable_args", - /* 244 */ "create_table_list", - /* 245 */ "create_from_stable", - /* 246 */ "columnlist", - /* 247 */ "tagitemlist", - /* 248 */ "tagNamelist", - /* 249 */ "select", - /* 250 */ "column", - /* 251 */ "tagitem", - /* 252 */ "selcollist", - /* 253 */ "from", - /* 254 */ "where_opt", - /* 255 */ "range_option", - /* 256 */ "interval_option", - /* 257 */ "sliding_opt", - /* 258 */ "session_option", - /* 259 */ "windowstate_option", - /* 260 */ "fill_opt", - /* 261 */ "groupby_opt", - /* 262 */ "having_opt", - /* 263 */ "orderby_opt", - /* 264 */ "slimit_opt", - /* 265 */ "limit_opt", - /* 266 */ "union", - /* 267 */ "sclp", - /* 268 */ "distinct", - /* 269 */ "expr", - /* 270 */ "as", - /* 271 */ "tablelist", - /* 272 */ "sub", - /* 273 */ "tmvar", - /* 274 */ "timestamp", - /* 275 */ "intervalKey", - /* 276 */ "sortlist", - /* 277 */ "sortitem", - /* 278 */ "item", - /* 279 */ "sortorder", - /* 280 */ "grouplist", - /* 281 */ "expritem", + /* 13 */ "JSON", + /* 14 */ "OR", + /* 15 */ "AND", + /* 16 */ "NOT", + /* 17 */ "EQ", + /* 18 */ "NE", + /* 19 */ "ISNULL", + /* 20 */ "NOTNULL", + /* 21 */ "IS", + /* 22 */ "LIKE", + /* 23 */ "MATCH", + /* 24 */ "NMATCH", + /* 25 */ "CONTAINS", + /* 26 */ "GLOB", + /* 27 */ "BETWEEN", + /* 28 */ "IN", + /* 29 */ "GT", + /* 30 */ "GE", + /* 31 */ "LT", + /* 32 */ "LE", + /* 33 */ "BITAND", + /* 34 */ "BITOR", + /* 35 */ "LSHIFT", + /* 36 */ "RSHIFT", + /* 37 */ "PLUS", + /* 38 */ "MINUS", + /* 39 */ "DIVIDE", + /* 40 */ "TIMES", + /* 41 */ "STAR", + /* 42 */ "SLASH", + /* 43 */ "REM", + /* 44 */ "CONCAT", + /* 45 */ "UMINUS", + /* 46 */ "UPLUS", + /* 47 */ "BITNOT", + /* 48 */ "ARROW", + /* 49 */ "SHOW", + /* 50 */ "DATABASES", + /* 51 */ "TOPICS", + /* 52 */ "FUNCTIONS", + /* 53 */ "MNODES", + /* 54 */ "DNODES", + /* 55 */ "ACCOUNTS", + /* 56 */ "USERS", + /* 57 */ "MODULES", + /* 58 */ "QUERIES", + /* 59 */ "CONNECTIONS", + /* 60 */ "STREAMS", + /* 61 */ "VARIABLES", + /* 62 */ "SCORES", + /* 63 */ "GRANTS", + /* 64 */ "VNODES", + /* 65 */ "DOT", + /* 66 */ "CREATE", + /* 67 */ "TABLE", + /* 68 */ "STABLE", + /* 69 */ "DATABASE", + /* 70 */ "TABLES", + /* 71 */ "STABLES", + /* 72 */ "VGROUPS", + /* 73 */ "DROP", + /* 74 */ "TOPIC", + /* 75 */ "FUNCTION", + /* 76 */ "DNODE", + /* 77 */ "USER", + /* 78 */ "ACCOUNT", + /* 79 */ "USE", + /* 80 */ "DESCRIBE", + /* 81 */ "DESC", + /* 82 */ "ALTER", + /* 83 */ "PASS", + /* 84 */ "PRIVILEGE", + /* 85 */ "LOCAL", + /* 86 */ "COMPACT", + /* 87 */ "LP", + /* 88 */ "RP", + /* 89 */ "IF", + /* 90 */ "EXISTS", + /* 91 */ "AS", + /* 92 */ "OUTPUTTYPE", + /* 93 */ "AGGREGATE", + /* 94 */ "BUFSIZE", + /* 95 */ "PPS", + /* 96 */ "TSERIES", + /* 97 */ "DBS", + /* 98 */ "STORAGE", + /* 99 */ "QTIME", + /* 100 */ "CONNS", + /* 101 */ "STATE", + /* 102 */ "COMMA", + /* 103 */ "KEEP", + /* 104 */ "CACHE", + /* 105 */ "REPLICA", + /* 106 */ "QUORUM", + /* 107 */ "DAYS", + /* 108 */ "MINROWS", + /* 109 */ "MAXROWS", + /* 110 */ "BLOCKS", + /* 111 */ "CTIME", + /* 112 */ "WAL", + /* 113 */ "FSYNC", + /* 114 */ "COMP", + /* 115 */ "PRECISION", + /* 116 */ "UPDATE", + /* 117 */ "CACHELAST", + /* 118 */ "PARTITIONS", + /* 119 */ "UNSIGNED", + /* 120 */ "TAGS", + /* 121 */ "USING", + /* 122 */ "NULL", + /* 123 */ "NOW", + /* 124 */ "SELECT", + /* 125 */ "UNION", + /* 126 */ "ALL", + /* 127 */ "DISTINCT", + /* 128 */ "FROM", + /* 129 */ "VARIABLE", + /* 130 */ "RANGE", + /* 131 */ "INTERVAL", + /* 132 */ "EVERY", + /* 133 */ "SESSION", + /* 134 */ "STATE_WINDOW", + /* 135 */ "FILL", + /* 136 */ "SLIDING", + /* 137 */ "ORDER", + /* 138 */ "BY", + /* 139 */ "ASC", + /* 140 */ "GROUP", + /* 141 */ "HAVING", + /* 142 */ "LIMIT", + /* 143 */ "OFFSET", + /* 144 */ "SLIMIT", + /* 145 */ "SOFFSET", + /* 146 */ "WHERE", + /* 147 */ "RESET", + /* 148 */ "QUERY", + /* 149 */ "SYNCDB", + /* 150 */ "ADD", + /* 151 */ "COLUMN", + /* 152 */ "MODIFY", + /* 153 */ "TAG", + /* 154 */ "CHANGE", + /* 155 */ "SET", + /* 156 */ "KILL", + /* 157 */ "CONNECTION", + /* 158 */ "STREAM", + /* 159 */ "COLON", + /* 160 */ "ABORT", + /* 161 */ "AFTER", + /* 162 */ "ATTACH", + /* 163 */ "BEFORE", + /* 164 */ "BEGIN", + /* 165 */ "CASCADE", + /* 166 */ "CLUSTER", + /* 167 */ "CONFLICT", + /* 168 */ "COPY", + /* 169 */ "DEFERRED", + /* 170 */ "DELIMITERS", + /* 171 */ "DETACH", + /* 172 */ "EACH", + /* 173 */ "END", + /* 174 */ "EXPLAIN", + /* 175 */ "FAIL", + /* 176 */ "FOR", + /* 177 */ "IGNORE", + /* 178 */ "IMMEDIATE", + /* 179 */ "INITIALLY", + /* 180 */ "INSTEAD", + /* 181 */ "KEY", + /* 182 */ "OF", + /* 183 */ "RAISE", + /* 184 */ "REPLACE", + /* 185 */ "RESTRICT", + /* 186 */ "ROW", + /* 187 */ "STATEMENT", + /* 188 */ "TRIGGER", + /* 189 */ "VIEW", + /* 190 */ "IPTOKEN", + /* 191 */ "SEMI", + /* 192 */ "NONE", + /* 193 */ "PREV", + /* 194 */ "LINEAR", + /* 195 */ "IMPORT", + /* 196 */ "TBNAME", + /* 197 */ "JOIN", + /* 198 */ "INSERT", + /* 199 */ "INTO", + /* 200 */ "VALUES", + /* 201 */ "FILE", + /* 202 */ "program", + /* 203 */ "cmd", + /* 204 */ "ids", + /* 205 */ "dbPrefix", + /* 206 */ "cpxName", + /* 207 */ "ifexists", + /* 208 */ "alter_db_optr", + /* 209 */ "alter_topic_optr", + /* 210 */ "acct_optr", + /* 211 */ "exprlist", + /* 212 */ "ifnotexists", + /* 213 */ "db_optr", + /* 214 */ "topic_optr", + /* 215 */ "typename", + /* 216 */ "bufsize", + /* 217 */ "pps", + /* 218 */ "tseries", + /* 219 */ "dbs", + /* 220 */ "streams", + /* 221 */ "storage", + /* 222 */ "qtime", + /* 223 */ "users", + /* 224 */ "conns", + /* 225 */ "state", + /* 226 */ "intitemlist", + /* 227 */ "intitem", + /* 228 */ "keep", + /* 229 */ "cache", + /* 230 */ "replica", + /* 231 */ "quorum", + /* 232 */ "days", + /* 233 */ "minrows", + /* 234 */ "maxrows", + /* 235 */ "blocks", + /* 236 */ "ctime", + /* 237 */ "wal", + /* 238 */ "fsync", + /* 239 */ "comp", + /* 240 */ "prec", + /* 241 */ "update", + /* 242 */ "cachelast", + /* 243 */ "partitions", + /* 244 */ "signed", + /* 245 */ "create_table_args", + /* 246 */ "create_stable_args", + /* 247 */ "create_table_list", + /* 248 */ "create_from_stable", + /* 249 */ "columnlist", + /* 250 */ "tagitemlist", + /* 251 */ "tagNamelist", + /* 252 */ "select", + /* 253 */ "column", + /* 254 */ "tagitem", + /* 255 */ "selcollist", + /* 256 */ "from", + /* 257 */ "where_opt", + /* 258 */ "range_option", + /* 259 */ "interval_option", + /* 260 */ "sliding_opt", + /* 261 */ "session_option", + /* 262 */ "windowstate_option", + /* 263 */ "fill_opt", + /* 264 */ "groupby_opt", + /* 265 */ "having_opt", + /* 266 */ "orderby_opt", + /* 267 */ "slimit_opt", + /* 268 */ "limit_opt", + /* 269 */ "union", + /* 270 */ "sclp", + /* 271 */ "distinct", + /* 272 */ "expr", + /* 273 */ "as", + /* 274 */ "tablelist", + /* 275 */ "sub", + /* 276 */ "tmvar", + /* 277 */ "timestamp", + /* 278 */ "intervalKey", + /* 279 */ "sortlist", + /* 280 */ "item", + /* 281 */ "sortorder", + /* 282 */ "arrow", + /* 283 */ "grouplist", + /* 284 */ "expritem", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -1319,91 +1538,101 @@ static const char *const yyRuleName[] = { /* 214 */ "orderby_opt ::=", /* 215 */ "orderby_opt ::= ORDER BY sortlist", /* 216 */ "sortlist ::= sortlist COMMA item sortorder", - /* 217 */ "sortlist ::= item sortorder", - /* 218 */ "item ::= ids cpxName", - /* 219 */ "sortorder ::= ASC", - /* 220 */ "sortorder ::= DESC", - /* 221 */ "sortorder ::=", - /* 222 */ "groupby_opt ::=", - /* 223 */ "groupby_opt ::= GROUP BY grouplist", - /* 224 */ "grouplist ::= grouplist COMMA item", - /* 225 */ "grouplist ::= item", - /* 226 */ "having_opt ::=", - /* 227 */ "having_opt ::= HAVING expr", - /* 228 */ "limit_opt ::=", - /* 229 */ "limit_opt ::= LIMIT signed", - /* 230 */ "limit_opt ::= LIMIT signed OFFSET signed", - /* 231 */ "limit_opt ::= LIMIT signed COMMA signed", - /* 232 */ "slimit_opt ::=", - /* 233 */ "slimit_opt ::= SLIMIT signed", - /* 234 */ "slimit_opt ::= SLIMIT signed SOFFSET signed", - /* 235 */ "slimit_opt ::= SLIMIT signed COMMA signed", - /* 236 */ "where_opt ::=", - /* 237 */ "where_opt ::= WHERE expr", - /* 238 */ "expr ::= LP expr RP", - /* 239 */ "expr ::= ID", - /* 240 */ "expr ::= ID DOT ID", - /* 241 */ "expr ::= ID DOT STAR", - /* 242 */ "expr ::= INTEGER", - /* 243 */ "expr ::= MINUS INTEGER", - /* 244 */ "expr ::= PLUS INTEGER", - /* 245 */ "expr ::= FLOAT", - /* 246 */ "expr ::= MINUS FLOAT", - /* 247 */ "expr ::= PLUS FLOAT", - /* 248 */ "expr ::= STRING", - /* 249 */ "expr ::= NOW", - /* 250 */ "expr ::= VARIABLE", - /* 251 */ "expr ::= PLUS VARIABLE", - /* 252 */ "expr ::= MINUS VARIABLE", - /* 253 */ "expr ::= BOOL", - /* 254 */ "expr ::= NULL", - /* 255 */ "expr ::= ID LP exprlist RP", - /* 256 */ "expr ::= ID LP STAR RP", - /* 257 */ "expr ::= expr IS NULL", - /* 258 */ "expr ::= expr IS NOT NULL", - /* 259 */ "expr ::= expr LT expr", - /* 260 */ "expr ::= expr GT expr", - /* 261 */ "expr ::= expr LE expr", - /* 262 */ "expr ::= expr GE expr", - /* 263 */ "expr ::= expr NE expr", - /* 264 */ "expr ::= expr EQ expr", - /* 265 */ "expr ::= expr BETWEEN expr AND expr", - /* 266 */ "expr ::= expr AND expr", - /* 267 */ "expr ::= expr OR expr", - /* 268 */ "expr ::= expr PLUS expr", - /* 269 */ "expr ::= expr MINUS expr", - /* 270 */ "expr ::= expr STAR expr", - /* 271 */ "expr ::= expr SLASH expr", - /* 272 */ "expr ::= expr REM expr", - /* 273 */ "expr ::= expr LIKE expr", - /* 274 */ "expr ::= expr MATCH expr", - /* 275 */ "expr ::= expr NMATCH expr", - /* 276 */ "expr ::= expr IN LP exprlist RP", - /* 277 */ "exprlist ::= exprlist COMMA expritem", - /* 278 */ "exprlist ::= expritem", - /* 279 */ "expritem ::= expr", - /* 280 */ "expritem ::=", - /* 281 */ "cmd ::= RESET QUERY CACHE", - /* 282 */ "cmd ::= SYNCDB ids REPLICA", - /* 283 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", - /* 284 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", - /* 285 */ "cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist", - /* 286 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", - /* 287 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", - /* 288 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", - /* 289 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", - /* 290 */ "cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist", - /* 291 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", - /* 292 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", - /* 293 */ "cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist", - /* 294 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", - /* 295 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", - /* 296 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", - /* 297 */ "cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem", - /* 298 */ "cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist", - /* 299 */ "cmd ::= KILL CONNECTION INTEGER", - /* 300 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", - /* 301 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", + /* 217 */ "sortlist ::= sortlist COMMA arrow sortorder", + /* 218 */ "sortlist ::= item sortorder", + /* 219 */ "sortlist ::= arrow sortorder", + /* 220 */ "item ::= ID", + /* 221 */ "item ::= ID DOT ID", + /* 222 */ "sortorder ::= ASC", + /* 223 */ "sortorder ::= DESC", + /* 224 */ "sortorder ::=", + /* 225 */ "groupby_opt ::=", + /* 226 */ "groupby_opt ::= GROUP BY grouplist", + /* 227 */ "grouplist ::= grouplist COMMA item", + /* 228 */ "grouplist ::= grouplist COMMA arrow", + /* 229 */ "grouplist ::= item", + /* 230 */ "grouplist ::= arrow", + /* 231 */ "having_opt ::=", + /* 232 */ "having_opt ::= HAVING expr", + /* 233 */ "limit_opt ::=", + /* 234 */ "limit_opt ::= LIMIT signed", + /* 235 */ "limit_opt ::= LIMIT signed OFFSET signed", + /* 236 */ "limit_opt ::= LIMIT signed COMMA signed", + /* 237 */ "slimit_opt ::=", + /* 238 */ "slimit_opt ::= SLIMIT signed", + /* 239 */ "slimit_opt ::= SLIMIT signed SOFFSET signed", + /* 240 */ "slimit_opt ::= SLIMIT signed COMMA signed", + /* 241 */ "where_opt ::=", + /* 242 */ "where_opt ::= WHERE expr", + /* 243 */ "expr ::= LP expr RP", + /* 244 */ "expr ::= ID", + /* 245 */ "expr ::= ID DOT ID", + /* 246 */ "expr ::= ID DOT STAR", + /* 247 */ "expr ::= INTEGER", + /* 248 */ "expr ::= MINUS INTEGER", + /* 249 */ "expr ::= PLUS INTEGER", + /* 250 */ "expr ::= FLOAT", + /* 251 */ "expr ::= MINUS FLOAT", + /* 252 */ "expr ::= PLUS FLOAT", + /* 253 */ "expr ::= STRING", + /* 254 */ "expr ::= NOW", + /* 255 */ "expr ::= VARIABLE", + /* 256 */ "expr ::= PLUS VARIABLE", + /* 257 */ "expr ::= MINUS VARIABLE", + /* 258 */ "expr ::= BOOL", + /* 259 */ "expr ::= NULL", + /* 260 */ "expr ::= ID LP exprlist RP", + /* 261 */ "expr ::= ID LP STAR RP", + /* 262 */ "expr ::= expr IS NULL", + /* 263 */ "expr ::= expr IS NOT NULL", + /* 264 */ "expr ::= expr LT expr", + /* 265 */ "expr ::= expr GT expr", + /* 266 */ "expr ::= expr LE expr", + /* 267 */ "expr ::= expr GE expr", + /* 268 */ "expr ::= expr NE expr", + /* 269 */ "expr ::= expr EQ expr", + /* 270 */ "expr ::= expr BETWEEN expr AND expr", + /* 271 */ "expr ::= expr AND expr", + /* 272 */ "expr ::= expr OR expr", + /* 273 */ "expr ::= expr PLUS expr", + /* 274 */ "expr ::= expr MINUS expr", + /* 275 */ "expr ::= expr STAR expr", + /* 276 */ "expr ::= expr SLASH expr", + /* 277 */ "expr ::= expr REM expr", + /* 278 */ "expr ::= expr LIKE expr", + /* 279 */ "expr ::= expr MATCH expr", + /* 280 */ "expr ::= expr NMATCH expr", + /* 281 */ "expr ::= ID CONTAINS STRING", + /* 282 */ "expr ::= ID DOT ID CONTAINS STRING", + /* 283 */ "arrow ::= ID ARROW STRING", + /* 284 */ "arrow ::= ID DOT ID ARROW STRING", + /* 285 */ "expr ::= arrow", + /* 286 */ "expr ::= expr IN LP exprlist RP", + /* 287 */ "exprlist ::= exprlist COMMA expritem", + /* 288 */ "exprlist ::= expritem", + /* 289 */ "expritem ::= expr", + /* 290 */ "expritem ::=", + /* 291 */ "cmd ::= RESET QUERY CACHE", + /* 292 */ "cmd ::= SYNCDB ids REPLICA", + /* 293 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", + /* 294 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", + /* 295 */ "cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist", + /* 296 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", + /* 297 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", + /* 298 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", + /* 299 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", + /* 300 */ "cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist", + /* 301 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", + /* 302 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", + /* 303 */ "cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist", + /* 304 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", + /* 305 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", + /* 306 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", + /* 307 */ "cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem", + /* 308 */ "cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist", + /* 309 */ "cmd ::= KILL CONNECTION INTEGER", + /* 310 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", + /* 311 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", }; #endif /* NDEBUG */ @@ -1529,61 +1758,57 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 208: /* exprlist */ - case 252: /* selcollist */ - case 267: /* sclp */ + case 211: /* exprlist */ + case 255: /* selcollist */ + case 270: /* sclp */ { -tSqlExprListDestroy((yypminor->yy345)); +tSqlExprListDestroy((yypminor->yy231)); } break; - case 223: /* intitemlist */ - case 225: /* keep */ - case 246: /* columnlist */ - case 247: /* tagitemlist */ - case 248: /* tagNamelist */ - case 260: /* fill_opt */ - case 261: /* groupby_opt */ - case 263: /* orderby_opt */ - case 276: /* sortlist */ - case 280: /* grouplist */ -{ -taosArrayDestroy((yypminor->yy345)); -} - break; - case 244: /* create_table_list */ + case 226: /* intitemlist */ + case 228: /* keep */ + case 249: /* columnlist */ + case 250: /* tagitemlist */ + case 251: /* tagNamelist */ + case 263: /* fill_opt */ + case 264: /* groupby_opt */ + case 266: /* orderby_opt */ + case 279: /* sortlist */ + case 283: /* grouplist */ { -destroyCreateTableSql((yypminor->yy170)); +taosArrayDestroy((yypminor->yy231)); } break; - case 249: /* select */ + case 247: /* create_table_list */ { -destroySqlNode((yypminor->yy68)); +destroyCreateTableSql((yypminor->yy422)); } break; - case 253: /* from */ - case 271: /* tablelist */ - case 272: /* sub */ + case 252: /* select */ { -destroyRelationInfo((yypminor->yy484)); +destroySqlNode((yypminor->yy86)); } break; - case 254: /* where_opt */ - case 262: /* having_opt */ - case 269: /* expr */ - case 274: /* timestamp */ - case 281: /* expritem */ + case 256: /* from */ + case 274: /* tablelist */ + case 275: /* sub */ { -tSqlExprDestroy((yypminor->yy418)); +destroyRelationInfo((yypminor->yy484)); } break; - case 266: /* union */ + case 257: /* where_opt */ + case 265: /* having_opt */ + case 272: /* expr */ + case 277: /* timestamp */ + case 282: /* arrow */ + case 284: /* expritem */ { -destroyAllSqlNode((yypminor->yy345)); +tSqlExprDestroy((yypminor->yy226)); } break; - case 277: /* sortitem */ + case 269: /* union */ { -tVariantDestroy(&(yypminor->yy2)); +destroyAllSqlNode((yypminor->yy231)); } break; /********* End destructor definitions *****************************************/ @@ -1750,7 +1975,7 @@ static YYACTIONTYPE yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ - assert( i>=0 && i=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) ); return yy_action[i]; } }while(1); @@ -1872,308 +2097,318 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 199, /* (0) program ::= cmd */ - 200, /* (1) cmd ::= SHOW DATABASES */ - 200, /* (2) cmd ::= SHOW TOPICS */ - 200, /* (3) cmd ::= SHOW FUNCTIONS */ - 200, /* (4) cmd ::= SHOW MNODES */ - 200, /* (5) cmd ::= SHOW DNODES */ - 200, /* (6) cmd ::= SHOW ACCOUNTS */ - 200, /* (7) cmd ::= SHOW USERS */ - 200, /* (8) cmd ::= SHOW MODULES */ - 200, /* (9) cmd ::= SHOW QUERIES */ - 200, /* (10) cmd ::= SHOW CONNECTIONS */ - 200, /* (11) cmd ::= SHOW STREAMS */ - 200, /* (12) cmd ::= SHOW VARIABLES */ - 200, /* (13) cmd ::= SHOW SCORES */ - 200, /* (14) cmd ::= SHOW GRANTS */ - 200, /* (15) cmd ::= SHOW VNODES */ - 200, /* (16) cmd ::= SHOW VNODES ids */ - 202, /* (17) dbPrefix ::= */ - 202, /* (18) dbPrefix ::= ids DOT */ - 203, /* (19) cpxName ::= */ - 203, /* (20) cpxName ::= DOT ids */ - 200, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ - 200, /* (22) cmd ::= SHOW CREATE STABLE ids cpxName */ - 200, /* (23) cmd ::= SHOW CREATE DATABASE ids */ - 200, /* (24) cmd ::= SHOW dbPrefix TABLES */ - 200, /* (25) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - 200, /* (26) cmd ::= SHOW dbPrefix STABLES */ - 200, /* (27) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - 200, /* (28) cmd ::= SHOW dbPrefix VGROUPS */ - 200, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ - 200, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ - 200, /* (31) cmd ::= DROP DATABASE ifexists ids */ - 200, /* (32) cmd ::= DROP TOPIC ifexists ids */ - 200, /* (33) cmd ::= DROP FUNCTION ids */ - 200, /* (34) cmd ::= DROP DNODE ids */ - 200, /* (35) cmd ::= DROP USER ids */ - 200, /* (36) cmd ::= DROP ACCOUNT ids */ - 200, /* (37) cmd ::= USE ids */ - 200, /* (38) cmd ::= DESCRIBE ids cpxName */ - 200, /* (39) cmd ::= DESC ids cpxName */ - 200, /* (40) cmd ::= ALTER USER ids PASS ids */ - 200, /* (41) cmd ::= ALTER USER ids PRIVILEGE ids */ - 200, /* (42) cmd ::= ALTER DNODE ids ids */ - 200, /* (43) cmd ::= ALTER DNODE ids ids ids */ - 200, /* (44) cmd ::= ALTER LOCAL ids */ - 200, /* (45) cmd ::= ALTER LOCAL ids ids */ - 200, /* (46) cmd ::= ALTER DATABASE ids alter_db_optr */ - 200, /* (47) cmd ::= ALTER TOPIC ids alter_topic_optr */ - 200, /* (48) cmd ::= ALTER ACCOUNT ids acct_optr */ - 200, /* (49) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - 200, /* (50) cmd ::= COMPACT VNODES IN LP exprlist RP */ - 201, /* (51) ids ::= ID */ - 201, /* (52) ids ::= STRING */ - 204, /* (53) ifexists ::= IF EXISTS */ - 204, /* (54) ifexists ::= */ - 209, /* (55) ifnotexists ::= IF NOT EXISTS */ - 209, /* (56) ifnotexists ::= */ - 200, /* (57) cmd ::= CREATE DNODE ids */ - 200, /* (58) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - 200, /* (59) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - 200, /* (60) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - 200, /* (61) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - 200, /* (62) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - 200, /* (63) cmd ::= CREATE USER ids PASS ids */ - 213, /* (64) bufsize ::= */ - 213, /* (65) bufsize ::= BUFSIZE INTEGER */ - 214, /* (66) pps ::= */ - 214, /* (67) pps ::= PPS INTEGER */ - 215, /* (68) tseries ::= */ - 215, /* (69) tseries ::= TSERIES INTEGER */ - 216, /* (70) dbs ::= */ - 216, /* (71) dbs ::= DBS INTEGER */ - 217, /* (72) streams ::= */ - 217, /* (73) streams ::= STREAMS INTEGER */ - 218, /* (74) storage ::= */ - 218, /* (75) storage ::= STORAGE INTEGER */ - 219, /* (76) qtime ::= */ - 219, /* (77) qtime ::= QTIME INTEGER */ - 220, /* (78) users ::= */ - 220, /* (79) users ::= USERS INTEGER */ - 221, /* (80) conns ::= */ - 221, /* (81) conns ::= CONNS INTEGER */ - 222, /* (82) state ::= */ - 222, /* (83) state ::= STATE ids */ - 207, /* (84) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - 223, /* (85) intitemlist ::= intitemlist COMMA intitem */ - 223, /* (86) intitemlist ::= intitem */ - 224, /* (87) intitem ::= INTEGER */ - 225, /* (88) keep ::= KEEP intitemlist */ - 226, /* (89) cache ::= CACHE INTEGER */ - 227, /* (90) replica ::= REPLICA INTEGER */ - 228, /* (91) quorum ::= QUORUM INTEGER */ - 229, /* (92) days ::= DAYS INTEGER */ - 230, /* (93) minrows ::= MINROWS INTEGER */ - 231, /* (94) maxrows ::= MAXROWS INTEGER */ - 232, /* (95) blocks ::= BLOCKS INTEGER */ - 233, /* (96) ctime ::= CTIME INTEGER */ - 234, /* (97) wal ::= WAL INTEGER */ - 235, /* (98) fsync ::= FSYNC INTEGER */ - 236, /* (99) comp ::= COMP INTEGER */ - 237, /* (100) prec ::= PRECISION STRING */ - 238, /* (101) update ::= UPDATE INTEGER */ - 239, /* (102) cachelast ::= CACHELAST INTEGER */ - 240, /* (103) partitions ::= PARTITIONS INTEGER */ - 210, /* (104) db_optr ::= */ - 210, /* (105) db_optr ::= db_optr cache */ - 210, /* (106) db_optr ::= db_optr replica */ - 210, /* (107) db_optr ::= db_optr quorum */ - 210, /* (108) db_optr ::= db_optr days */ - 210, /* (109) db_optr ::= db_optr minrows */ - 210, /* (110) db_optr ::= db_optr maxrows */ - 210, /* (111) db_optr ::= db_optr blocks */ - 210, /* (112) db_optr ::= db_optr ctime */ - 210, /* (113) db_optr ::= db_optr wal */ - 210, /* (114) db_optr ::= db_optr fsync */ - 210, /* (115) db_optr ::= db_optr comp */ - 210, /* (116) db_optr ::= db_optr prec */ - 210, /* (117) db_optr ::= db_optr keep */ - 210, /* (118) db_optr ::= db_optr update */ - 210, /* (119) db_optr ::= db_optr cachelast */ - 211, /* (120) topic_optr ::= db_optr */ - 211, /* (121) topic_optr ::= topic_optr partitions */ - 205, /* (122) alter_db_optr ::= */ - 205, /* (123) alter_db_optr ::= alter_db_optr replica */ - 205, /* (124) alter_db_optr ::= alter_db_optr quorum */ - 205, /* (125) alter_db_optr ::= alter_db_optr keep */ - 205, /* (126) alter_db_optr ::= alter_db_optr blocks */ - 205, /* (127) alter_db_optr ::= alter_db_optr comp */ - 205, /* (128) alter_db_optr ::= alter_db_optr update */ - 205, /* (129) alter_db_optr ::= alter_db_optr cachelast */ - 206, /* (130) alter_topic_optr ::= alter_db_optr */ - 206, /* (131) alter_topic_optr ::= alter_topic_optr partitions */ - 212, /* (132) typename ::= ids */ - 212, /* (133) typename ::= ids LP signed RP */ - 212, /* (134) typename ::= ids UNSIGNED */ - 241, /* (135) signed ::= INTEGER */ - 241, /* (136) signed ::= PLUS INTEGER */ - 241, /* (137) signed ::= MINUS INTEGER */ - 200, /* (138) cmd ::= CREATE TABLE create_table_args */ - 200, /* (139) cmd ::= CREATE TABLE create_stable_args */ - 200, /* (140) cmd ::= CREATE STABLE create_stable_args */ - 200, /* (141) cmd ::= CREATE TABLE create_table_list */ - 244, /* (142) create_table_list ::= create_from_stable */ - 244, /* (143) create_table_list ::= create_table_list create_from_stable */ - 242, /* (144) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - 243, /* (145) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - 245, /* (146) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - 245, /* (147) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - 248, /* (148) tagNamelist ::= tagNamelist COMMA ids */ - 248, /* (149) tagNamelist ::= ids */ - 242, /* (150) create_table_args ::= ifnotexists ids cpxName AS select */ - 246, /* (151) columnlist ::= columnlist COMMA column */ - 246, /* (152) columnlist ::= column */ - 250, /* (153) column ::= ids typename */ - 247, /* (154) tagitemlist ::= tagitemlist COMMA tagitem */ - 247, /* (155) tagitemlist ::= tagitem */ - 251, /* (156) tagitem ::= INTEGER */ - 251, /* (157) tagitem ::= FLOAT */ - 251, /* (158) tagitem ::= STRING */ - 251, /* (159) tagitem ::= BOOL */ - 251, /* (160) tagitem ::= NULL */ - 251, /* (161) tagitem ::= NOW */ - 251, /* (162) tagitem ::= MINUS INTEGER */ - 251, /* (163) tagitem ::= MINUS FLOAT */ - 251, /* (164) tagitem ::= PLUS INTEGER */ - 251, /* (165) tagitem ::= PLUS FLOAT */ - 249, /* (166) select ::= SELECT selcollist from where_opt range_option interval_option sliding_opt session_option windowstate_option fill_opt groupby_opt having_opt orderby_opt slimit_opt limit_opt */ - 249, /* (167) select ::= LP select RP */ - 266, /* (168) union ::= select */ - 266, /* (169) union ::= union UNION ALL select */ - 200, /* (170) cmd ::= union */ - 249, /* (171) select ::= SELECT selcollist */ - 267, /* (172) sclp ::= selcollist COMMA */ - 267, /* (173) sclp ::= */ - 252, /* (174) selcollist ::= sclp distinct expr as */ - 252, /* (175) selcollist ::= sclp STAR */ - 270, /* (176) as ::= AS ids */ - 270, /* (177) as ::= ids */ - 270, /* (178) as ::= */ - 268, /* (179) distinct ::= DISTINCT */ - 268, /* (180) distinct ::= */ - 253, /* (181) from ::= FROM tablelist */ - 253, /* (182) from ::= FROM sub */ - 272, /* (183) sub ::= LP union RP */ - 272, /* (184) sub ::= LP union RP ids */ - 272, /* (185) sub ::= sub COMMA LP union RP ids */ - 271, /* (186) tablelist ::= ids cpxName */ - 271, /* (187) tablelist ::= ids cpxName ids */ - 271, /* (188) tablelist ::= tablelist COMMA ids cpxName */ - 271, /* (189) tablelist ::= tablelist COMMA ids cpxName ids */ - 273, /* (190) tmvar ::= VARIABLE */ - 274, /* (191) timestamp ::= INTEGER */ - 274, /* (192) timestamp ::= MINUS INTEGER */ - 274, /* (193) timestamp ::= PLUS INTEGER */ - 274, /* (194) timestamp ::= STRING */ - 274, /* (195) timestamp ::= NOW */ - 274, /* (196) timestamp ::= NOW PLUS VARIABLE */ - 274, /* (197) timestamp ::= NOW MINUS VARIABLE */ - 255, /* (198) range_option ::= */ - 255, /* (199) range_option ::= RANGE LP timestamp COMMA timestamp RP */ - 256, /* (200) interval_option ::= intervalKey LP tmvar RP */ - 256, /* (201) interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ - 256, /* (202) interval_option ::= */ - 275, /* (203) intervalKey ::= INTERVAL */ - 275, /* (204) intervalKey ::= EVERY */ - 258, /* (205) session_option ::= */ - 258, /* (206) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - 259, /* (207) windowstate_option ::= */ - 259, /* (208) windowstate_option ::= STATE_WINDOW LP ids RP */ - 260, /* (209) fill_opt ::= */ - 260, /* (210) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - 260, /* (211) fill_opt ::= FILL LP ID RP */ - 257, /* (212) sliding_opt ::= SLIDING LP tmvar RP */ - 257, /* (213) sliding_opt ::= */ - 263, /* (214) orderby_opt ::= */ - 263, /* (215) orderby_opt ::= ORDER BY sortlist */ - 276, /* (216) sortlist ::= sortlist COMMA item sortorder */ - 276, /* (217) sortlist ::= item sortorder */ - 278, /* (218) item ::= ids cpxName */ - 279, /* (219) sortorder ::= ASC */ - 279, /* (220) sortorder ::= DESC */ - 279, /* (221) sortorder ::= */ - 261, /* (222) groupby_opt ::= */ - 261, /* (223) groupby_opt ::= GROUP BY grouplist */ - 280, /* (224) grouplist ::= grouplist COMMA item */ - 280, /* (225) grouplist ::= item */ - 262, /* (226) having_opt ::= */ - 262, /* (227) having_opt ::= HAVING expr */ - 265, /* (228) limit_opt ::= */ - 265, /* (229) limit_opt ::= LIMIT signed */ - 265, /* (230) limit_opt ::= LIMIT signed OFFSET signed */ - 265, /* (231) limit_opt ::= LIMIT signed COMMA signed */ - 264, /* (232) slimit_opt ::= */ - 264, /* (233) slimit_opt ::= SLIMIT signed */ - 264, /* (234) slimit_opt ::= SLIMIT signed SOFFSET signed */ - 264, /* (235) slimit_opt ::= SLIMIT signed COMMA signed */ - 254, /* (236) where_opt ::= */ - 254, /* (237) where_opt ::= WHERE expr */ - 269, /* (238) expr ::= LP expr RP */ - 269, /* (239) expr ::= ID */ - 269, /* (240) expr ::= ID DOT ID */ - 269, /* (241) expr ::= ID DOT STAR */ - 269, /* (242) expr ::= INTEGER */ - 269, /* (243) expr ::= MINUS INTEGER */ - 269, /* (244) expr ::= PLUS INTEGER */ - 269, /* (245) expr ::= FLOAT */ - 269, /* (246) expr ::= MINUS FLOAT */ - 269, /* (247) expr ::= PLUS FLOAT */ - 269, /* (248) expr ::= STRING */ - 269, /* (249) expr ::= NOW */ - 269, /* (250) expr ::= VARIABLE */ - 269, /* (251) expr ::= PLUS VARIABLE */ - 269, /* (252) expr ::= MINUS VARIABLE */ - 269, /* (253) expr ::= BOOL */ - 269, /* (254) expr ::= NULL */ - 269, /* (255) expr ::= ID LP exprlist RP */ - 269, /* (256) expr ::= ID LP STAR RP */ - 269, /* (257) expr ::= expr IS NULL */ - 269, /* (258) expr ::= expr IS NOT NULL */ - 269, /* (259) expr ::= expr LT expr */ - 269, /* (260) expr ::= expr GT expr */ - 269, /* (261) expr ::= expr LE expr */ - 269, /* (262) expr ::= expr GE expr */ - 269, /* (263) expr ::= expr NE expr */ - 269, /* (264) expr ::= expr EQ expr */ - 269, /* (265) expr ::= expr BETWEEN expr AND expr */ - 269, /* (266) expr ::= expr AND expr */ - 269, /* (267) expr ::= expr OR expr */ - 269, /* (268) expr ::= expr PLUS expr */ - 269, /* (269) expr ::= expr MINUS expr */ - 269, /* (270) expr ::= expr STAR expr */ - 269, /* (271) expr ::= expr SLASH expr */ - 269, /* (272) expr ::= expr REM expr */ - 269, /* (273) expr ::= expr LIKE expr */ - 269, /* (274) expr ::= expr MATCH expr */ - 269, /* (275) expr ::= expr NMATCH expr */ - 269, /* (276) expr ::= expr IN LP exprlist RP */ - 208, /* (277) exprlist ::= exprlist COMMA expritem */ - 208, /* (278) exprlist ::= expritem */ - 281, /* (279) expritem ::= expr */ - 281, /* (280) expritem ::= */ - 200, /* (281) cmd ::= RESET QUERY CACHE */ - 200, /* (282) cmd ::= SYNCDB ids REPLICA */ - 200, /* (283) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - 200, /* (284) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - 200, /* (285) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ - 200, /* (286) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - 200, /* (287) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - 200, /* (288) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - 200, /* (289) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - 200, /* (290) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ - 200, /* (291) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - 200, /* (292) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - 200, /* (293) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ - 200, /* (294) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - 200, /* (295) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - 200, /* (296) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - 200, /* (297) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ - 200, /* (298) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ - 200, /* (299) cmd ::= KILL CONNECTION INTEGER */ - 200, /* (300) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - 200, /* (301) cmd ::= KILL QUERY INTEGER COLON INTEGER */ + 202, /* (0) program ::= cmd */ + 203, /* (1) cmd ::= SHOW DATABASES */ + 203, /* (2) cmd ::= SHOW TOPICS */ + 203, /* (3) cmd ::= SHOW FUNCTIONS */ + 203, /* (4) cmd ::= SHOW MNODES */ + 203, /* (5) cmd ::= SHOW DNODES */ + 203, /* (6) cmd ::= SHOW ACCOUNTS */ + 203, /* (7) cmd ::= SHOW USERS */ + 203, /* (8) cmd ::= SHOW MODULES */ + 203, /* (9) cmd ::= SHOW QUERIES */ + 203, /* (10) cmd ::= SHOW CONNECTIONS */ + 203, /* (11) cmd ::= SHOW STREAMS */ + 203, /* (12) cmd ::= SHOW VARIABLES */ + 203, /* (13) cmd ::= SHOW SCORES */ + 203, /* (14) cmd ::= SHOW GRANTS */ + 203, /* (15) cmd ::= SHOW VNODES */ + 203, /* (16) cmd ::= SHOW VNODES ids */ + 205, /* (17) dbPrefix ::= */ + 205, /* (18) dbPrefix ::= ids DOT */ + 206, /* (19) cpxName ::= */ + 206, /* (20) cpxName ::= DOT ids */ + 203, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ + 203, /* (22) cmd ::= SHOW CREATE STABLE ids cpxName */ + 203, /* (23) cmd ::= SHOW CREATE DATABASE ids */ + 203, /* (24) cmd ::= SHOW dbPrefix TABLES */ + 203, /* (25) cmd ::= SHOW dbPrefix TABLES LIKE ids */ + 203, /* (26) cmd ::= SHOW dbPrefix STABLES */ + 203, /* (27) cmd ::= SHOW dbPrefix STABLES LIKE ids */ + 203, /* (28) cmd ::= SHOW dbPrefix VGROUPS */ + 203, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ + 203, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ + 203, /* (31) cmd ::= DROP DATABASE ifexists ids */ + 203, /* (32) cmd ::= DROP TOPIC ifexists ids */ + 203, /* (33) cmd ::= DROP FUNCTION ids */ + 203, /* (34) cmd ::= DROP DNODE ids */ + 203, /* (35) cmd ::= DROP USER ids */ + 203, /* (36) cmd ::= DROP ACCOUNT ids */ + 203, /* (37) cmd ::= USE ids */ + 203, /* (38) cmd ::= DESCRIBE ids cpxName */ + 203, /* (39) cmd ::= DESC ids cpxName */ + 203, /* (40) cmd ::= ALTER USER ids PASS ids */ + 203, /* (41) cmd ::= ALTER USER ids PRIVILEGE ids */ + 203, /* (42) cmd ::= ALTER DNODE ids ids */ + 203, /* (43) cmd ::= ALTER DNODE ids ids ids */ + 203, /* (44) cmd ::= ALTER LOCAL ids */ + 203, /* (45) cmd ::= ALTER LOCAL ids ids */ + 203, /* (46) cmd ::= ALTER DATABASE ids alter_db_optr */ + 203, /* (47) cmd ::= ALTER TOPIC ids alter_topic_optr */ + 203, /* (48) cmd ::= ALTER ACCOUNT ids acct_optr */ + 203, /* (49) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ + 203, /* (50) cmd ::= COMPACT VNODES IN LP exprlist RP */ + 204, /* (51) ids ::= ID */ + 204, /* (52) ids ::= STRING */ + 207, /* (53) ifexists ::= IF EXISTS */ + 207, /* (54) ifexists ::= */ + 212, /* (55) ifnotexists ::= IF NOT EXISTS */ + 212, /* (56) ifnotexists ::= */ + 203, /* (57) cmd ::= CREATE DNODE ids */ + 203, /* (58) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ + 203, /* (59) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ + 203, /* (60) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ + 203, /* (61) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ + 203, /* (62) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ + 203, /* (63) cmd ::= CREATE USER ids PASS ids */ + 216, /* (64) bufsize ::= */ + 216, /* (65) bufsize ::= BUFSIZE INTEGER */ + 217, /* (66) pps ::= */ + 217, /* (67) pps ::= PPS INTEGER */ + 218, /* (68) tseries ::= */ + 218, /* (69) tseries ::= TSERIES INTEGER */ + 219, /* (70) dbs ::= */ + 219, /* (71) dbs ::= DBS INTEGER */ + 220, /* (72) streams ::= */ + 220, /* (73) streams ::= STREAMS INTEGER */ + 221, /* (74) storage ::= */ + 221, /* (75) storage ::= STORAGE INTEGER */ + 222, /* (76) qtime ::= */ + 222, /* (77) qtime ::= QTIME INTEGER */ + 223, /* (78) users ::= */ + 223, /* (79) users ::= USERS INTEGER */ + 224, /* (80) conns ::= */ + 224, /* (81) conns ::= CONNS INTEGER */ + 225, /* (82) state ::= */ + 225, /* (83) state ::= STATE ids */ + 210, /* (84) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ + 226, /* (85) intitemlist ::= intitemlist COMMA intitem */ + 226, /* (86) intitemlist ::= intitem */ + 227, /* (87) intitem ::= INTEGER */ + 228, /* (88) keep ::= KEEP intitemlist */ + 229, /* (89) cache ::= CACHE INTEGER */ + 230, /* (90) replica ::= REPLICA INTEGER */ + 231, /* (91) quorum ::= QUORUM INTEGER */ + 232, /* (92) days ::= DAYS INTEGER */ + 233, /* (93) minrows ::= MINROWS INTEGER */ + 234, /* (94) maxrows ::= MAXROWS INTEGER */ + 235, /* (95) blocks ::= BLOCKS INTEGER */ + 236, /* (96) ctime ::= CTIME INTEGER */ + 237, /* (97) wal ::= WAL INTEGER */ + 238, /* (98) fsync ::= FSYNC INTEGER */ + 239, /* (99) comp ::= COMP INTEGER */ + 240, /* (100) prec ::= PRECISION STRING */ + 241, /* (101) update ::= UPDATE INTEGER */ + 242, /* (102) cachelast ::= CACHELAST INTEGER */ + 243, /* (103) partitions ::= PARTITIONS INTEGER */ + 213, /* (104) db_optr ::= */ + 213, /* (105) db_optr ::= db_optr cache */ + 213, /* (106) db_optr ::= db_optr replica */ + 213, /* (107) db_optr ::= db_optr quorum */ + 213, /* (108) db_optr ::= db_optr days */ + 213, /* (109) db_optr ::= db_optr minrows */ + 213, /* (110) db_optr ::= db_optr maxrows */ + 213, /* (111) db_optr ::= db_optr blocks */ + 213, /* (112) db_optr ::= db_optr ctime */ + 213, /* (113) db_optr ::= db_optr wal */ + 213, /* (114) db_optr ::= db_optr fsync */ + 213, /* (115) db_optr ::= db_optr comp */ + 213, /* (116) db_optr ::= db_optr prec */ + 213, /* (117) db_optr ::= db_optr keep */ + 213, /* (118) db_optr ::= db_optr update */ + 213, /* (119) db_optr ::= db_optr cachelast */ + 214, /* (120) topic_optr ::= db_optr */ + 214, /* (121) topic_optr ::= topic_optr partitions */ + 208, /* (122) alter_db_optr ::= */ + 208, /* (123) alter_db_optr ::= alter_db_optr replica */ + 208, /* (124) alter_db_optr ::= alter_db_optr quorum */ + 208, /* (125) alter_db_optr ::= alter_db_optr keep */ + 208, /* (126) alter_db_optr ::= alter_db_optr blocks */ + 208, /* (127) alter_db_optr ::= alter_db_optr comp */ + 208, /* (128) alter_db_optr ::= alter_db_optr update */ + 208, /* (129) alter_db_optr ::= alter_db_optr cachelast */ + 209, /* (130) alter_topic_optr ::= alter_db_optr */ + 209, /* (131) alter_topic_optr ::= alter_topic_optr partitions */ + 215, /* (132) typename ::= ids */ + 215, /* (133) typename ::= ids LP signed RP */ + 215, /* (134) typename ::= ids UNSIGNED */ + 244, /* (135) signed ::= INTEGER */ + 244, /* (136) signed ::= PLUS INTEGER */ + 244, /* (137) signed ::= MINUS INTEGER */ + 203, /* (138) cmd ::= CREATE TABLE create_table_args */ + 203, /* (139) cmd ::= CREATE TABLE create_stable_args */ + 203, /* (140) cmd ::= CREATE STABLE create_stable_args */ + 203, /* (141) cmd ::= CREATE TABLE create_table_list */ + 247, /* (142) create_table_list ::= create_from_stable */ + 247, /* (143) create_table_list ::= create_table_list create_from_stable */ + 245, /* (144) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ + 246, /* (145) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ + 248, /* (146) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ + 248, /* (147) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ + 251, /* (148) tagNamelist ::= tagNamelist COMMA ids */ + 251, /* (149) tagNamelist ::= ids */ + 245, /* (150) create_table_args ::= ifnotexists ids cpxName AS select */ + 249, /* (151) columnlist ::= columnlist COMMA column */ + 249, /* (152) columnlist ::= column */ + 253, /* (153) column ::= ids typename */ + 250, /* (154) tagitemlist ::= tagitemlist COMMA tagitem */ + 250, /* (155) tagitemlist ::= tagitem */ + 254, /* (156) tagitem ::= INTEGER */ + 254, /* (157) tagitem ::= FLOAT */ + 254, /* (158) tagitem ::= STRING */ + 254, /* (159) tagitem ::= BOOL */ + 254, /* (160) tagitem ::= NULL */ + 254, /* (161) tagitem ::= NOW */ + 254, /* (162) tagitem ::= MINUS INTEGER */ + 254, /* (163) tagitem ::= MINUS FLOAT */ + 254, /* (164) tagitem ::= PLUS INTEGER */ + 254, /* (165) tagitem ::= PLUS FLOAT */ + 252, /* (166) select ::= SELECT selcollist from where_opt range_option interval_option sliding_opt session_option windowstate_option fill_opt groupby_opt having_opt orderby_opt slimit_opt limit_opt */ + 252, /* (167) select ::= LP select RP */ + 269, /* (168) union ::= select */ + 269, /* (169) union ::= union UNION ALL select */ + 203, /* (170) cmd ::= union */ + 252, /* (171) select ::= SELECT selcollist */ + 270, /* (172) sclp ::= selcollist COMMA */ + 270, /* (173) sclp ::= */ + 255, /* (174) selcollist ::= sclp distinct expr as */ + 255, /* (175) selcollist ::= sclp STAR */ + 273, /* (176) as ::= AS ids */ + 273, /* (177) as ::= ids */ + 273, /* (178) as ::= */ + 271, /* (179) distinct ::= DISTINCT */ + 271, /* (180) distinct ::= */ + 256, /* (181) from ::= FROM tablelist */ + 256, /* (182) from ::= FROM sub */ + 275, /* (183) sub ::= LP union RP */ + 275, /* (184) sub ::= LP union RP ids */ + 275, /* (185) sub ::= sub COMMA LP union RP ids */ + 274, /* (186) tablelist ::= ids cpxName */ + 274, /* (187) tablelist ::= ids cpxName ids */ + 274, /* (188) tablelist ::= tablelist COMMA ids cpxName */ + 274, /* (189) tablelist ::= tablelist COMMA ids cpxName ids */ + 276, /* (190) tmvar ::= VARIABLE */ + 277, /* (191) timestamp ::= INTEGER */ + 277, /* (192) timestamp ::= MINUS INTEGER */ + 277, /* (193) timestamp ::= PLUS INTEGER */ + 277, /* (194) timestamp ::= STRING */ + 277, /* (195) timestamp ::= NOW */ + 277, /* (196) timestamp ::= NOW PLUS VARIABLE */ + 277, /* (197) timestamp ::= NOW MINUS VARIABLE */ + 258, /* (198) range_option ::= */ + 258, /* (199) range_option ::= RANGE LP timestamp COMMA timestamp RP */ + 259, /* (200) interval_option ::= intervalKey LP tmvar RP */ + 259, /* (201) interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ + 259, /* (202) interval_option ::= */ + 278, /* (203) intervalKey ::= INTERVAL */ + 278, /* (204) intervalKey ::= EVERY */ + 261, /* (205) session_option ::= */ + 261, /* (206) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + 262, /* (207) windowstate_option ::= */ + 262, /* (208) windowstate_option ::= STATE_WINDOW LP ids RP */ + 263, /* (209) fill_opt ::= */ + 263, /* (210) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + 263, /* (211) fill_opt ::= FILL LP ID RP */ + 260, /* (212) sliding_opt ::= SLIDING LP tmvar RP */ + 260, /* (213) sliding_opt ::= */ + 266, /* (214) orderby_opt ::= */ + 266, /* (215) orderby_opt ::= ORDER BY sortlist */ + 279, /* (216) sortlist ::= sortlist COMMA item sortorder */ + 279, /* (217) sortlist ::= sortlist COMMA arrow sortorder */ + 279, /* (218) sortlist ::= item sortorder */ + 279, /* (219) sortlist ::= arrow sortorder */ + 280, /* (220) item ::= ID */ + 280, /* (221) item ::= ID DOT ID */ + 281, /* (222) sortorder ::= ASC */ + 281, /* (223) sortorder ::= DESC */ + 281, /* (224) sortorder ::= */ + 264, /* (225) groupby_opt ::= */ + 264, /* (226) groupby_opt ::= GROUP BY grouplist */ + 283, /* (227) grouplist ::= grouplist COMMA item */ + 283, /* (228) grouplist ::= grouplist COMMA arrow */ + 283, /* (229) grouplist ::= item */ + 283, /* (230) grouplist ::= arrow */ + 265, /* (231) having_opt ::= */ + 265, /* (232) having_opt ::= HAVING expr */ + 268, /* (233) limit_opt ::= */ + 268, /* (234) limit_opt ::= LIMIT signed */ + 268, /* (235) limit_opt ::= LIMIT signed OFFSET signed */ + 268, /* (236) limit_opt ::= LIMIT signed COMMA signed */ + 267, /* (237) slimit_opt ::= */ + 267, /* (238) slimit_opt ::= SLIMIT signed */ + 267, /* (239) slimit_opt ::= SLIMIT signed SOFFSET signed */ + 267, /* (240) slimit_opt ::= SLIMIT signed COMMA signed */ + 257, /* (241) where_opt ::= */ + 257, /* (242) where_opt ::= WHERE expr */ + 272, /* (243) expr ::= LP expr RP */ + 272, /* (244) expr ::= ID */ + 272, /* (245) expr ::= ID DOT ID */ + 272, /* (246) expr ::= ID DOT STAR */ + 272, /* (247) expr ::= INTEGER */ + 272, /* (248) expr ::= MINUS INTEGER */ + 272, /* (249) expr ::= PLUS INTEGER */ + 272, /* (250) expr ::= FLOAT */ + 272, /* (251) expr ::= MINUS FLOAT */ + 272, /* (252) expr ::= PLUS FLOAT */ + 272, /* (253) expr ::= STRING */ + 272, /* (254) expr ::= NOW */ + 272, /* (255) expr ::= VARIABLE */ + 272, /* (256) expr ::= PLUS VARIABLE */ + 272, /* (257) expr ::= MINUS VARIABLE */ + 272, /* (258) expr ::= BOOL */ + 272, /* (259) expr ::= NULL */ + 272, /* (260) expr ::= ID LP exprlist RP */ + 272, /* (261) expr ::= ID LP STAR RP */ + 272, /* (262) expr ::= expr IS NULL */ + 272, /* (263) expr ::= expr IS NOT NULL */ + 272, /* (264) expr ::= expr LT expr */ + 272, /* (265) expr ::= expr GT expr */ + 272, /* (266) expr ::= expr LE expr */ + 272, /* (267) expr ::= expr GE expr */ + 272, /* (268) expr ::= expr NE expr */ + 272, /* (269) expr ::= expr EQ expr */ + 272, /* (270) expr ::= expr BETWEEN expr AND expr */ + 272, /* (271) expr ::= expr AND expr */ + 272, /* (272) expr ::= expr OR expr */ + 272, /* (273) expr ::= expr PLUS expr */ + 272, /* (274) expr ::= expr MINUS expr */ + 272, /* (275) expr ::= expr STAR expr */ + 272, /* (276) expr ::= expr SLASH expr */ + 272, /* (277) expr ::= expr REM expr */ + 272, /* (278) expr ::= expr LIKE expr */ + 272, /* (279) expr ::= expr MATCH expr */ + 272, /* (280) expr ::= expr NMATCH expr */ + 272, /* (281) expr ::= ID CONTAINS STRING */ + 272, /* (282) expr ::= ID DOT ID CONTAINS STRING */ + 282, /* (283) arrow ::= ID ARROW STRING */ + 282, /* (284) arrow ::= ID DOT ID ARROW STRING */ + 272, /* (285) expr ::= arrow */ + 272, /* (286) expr ::= expr IN LP exprlist RP */ + 211, /* (287) exprlist ::= exprlist COMMA expritem */ + 211, /* (288) exprlist ::= expritem */ + 284, /* (289) expritem ::= expr */ + 284, /* (290) expritem ::= */ + 203, /* (291) cmd ::= RESET QUERY CACHE */ + 203, /* (292) cmd ::= SYNCDB ids REPLICA */ + 203, /* (293) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + 203, /* (294) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + 203, /* (295) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ + 203, /* (296) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + 203, /* (297) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + 203, /* (298) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + 203, /* (299) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + 203, /* (300) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ + 203, /* (301) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + 203, /* (302) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + 203, /* (303) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ + 203, /* (304) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + 203, /* (305) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + 203, /* (306) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + 203, /* (307) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ + 203, /* (308) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ + 203, /* (309) cmd ::= KILL CONNECTION INTEGER */ + 203, /* (310) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + 203, /* (311) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -2396,91 +2631,101 @@ static const signed char yyRuleInfoNRhs[] = { 0, /* (214) orderby_opt ::= */ -3, /* (215) orderby_opt ::= ORDER BY sortlist */ -4, /* (216) sortlist ::= sortlist COMMA item sortorder */ - -2, /* (217) sortlist ::= item sortorder */ - -2, /* (218) item ::= ids cpxName */ - -1, /* (219) sortorder ::= ASC */ - -1, /* (220) sortorder ::= DESC */ - 0, /* (221) sortorder ::= */ - 0, /* (222) groupby_opt ::= */ - -3, /* (223) groupby_opt ::= GROUP BY grouplist */ - -3, /* (224) grouplist ::= grouplist COMMA item */ - -1, /* (225) grouplist ::= item */ - 0, /* (226) having_opt ::= */ - -2, /* (227) having_opt ::= HAVING expr */ - 0, /* (228) limit_opt ::= */ - -2, /* (229) limit_opt ::= LIMIT signed */ - -4, /* (230) limit_opt ::= LIMIT signed OFFSET signed */ - -4, /* (231) limit_opt ::= LIMIT signed COMMA signed */ - 0, /* (232) slimit_opt ::= */ - -2, /* (233) slimit_opt ::= SLIMIT signed */ - -4, /* (234) slimit_opt ::= SLIMIT signed SOFFSET signed */ - -4, /* (235) slimit_opt ::= SLIMIT signed COMMA signed */ - 0, /* (236) where_opt ::= */ - -2, /* (237) where_opt ::= WHERE expr */ - -3, /* (238) expr ::= LP expr RP */ - -1, /* (239) expr ::= ID */ - -3, /* (240) expr ::= ID DOT ID */ - -3, /* (241) expr ::= ID DOT STAR */ - -1, /* (242) expr ::= INTEGER */ - -2, /* (243) expr ::= MINUS INTEGER */ - -2, /* (244) expr ::= PLUS INTEGER */ - -1, /* (245) expr ::= FLOAT */ - -2, /* (246) expr ::= MINUS FLOAT */ - -2, /* (247) expr ::= PLUS FLOAT */ - -1, /* (248) expr ::= STRING */ - -1, /* (249) expr ::= NOW */ - -1, /* (250) expr ::= VARIABLE */ - -2, /* (251) expr ::= PLUS VARIABLE */ - -2, /* (252) expr ::= MINUS VARIABLE */ - -1, /* (253) expr ::= BOOL */ - -1, /* (254) expr ::= NULL */ - -4, /* (255) expr ::= ID LP exprlist RP */ - -4, /* (256) expr ::= ID LP STAR RP */ - -3, /* (257) expr ::= expr IS NULL */ - -4, /* (258) expr ::= expr IS NOT NULL */ - -3, /* (259) expr ::= expr LT expr */ - -3, /* (260) expr ::= expr GT expr */ - -3, /* (261) expr ::= expr LE expr */ - -3, /* (262) expr ::= expr GE expr */ - -3, /* (263) expr ::= expr NE expr */ - -3, /* (264) expr ::= expr EQ expr */ - -5, /* (265) expr ::= expr BETWEEN expr AND expr */ - -3, /* (266) expr ::= expr AND expr */ - -3, /* (267) expr ::= expr OR expr */ - -3, /* (268) expr ::= expr PLUS expr */ - -3, /* (269) expr ::= expr MINUS expr */ - -3, /* (270) expr ::= expr STAR expr */ - -3, /* (271) expr ::= expr SLASH expr */ - -3, /* (272) expr ::= expr REM expr */ - -3, /* (273) expr ::= expr LIKE expr */ - -3, /* (274) expr ::= expr MATCH expr */ - -3, /* (275) expr ::= expr NMATCH expr */ - -5, /* (276) expr ::= expr IN LP exprlist RP */ - -3, /* (277) exprlist ::= exprlist COMMA expritem */ - -1, /* (278) exprlist ::= expritem */ - -1, /* (279) expritem ::= expr */ - 0, /* (280) expritem ::= */ - -3, /* (281) cmd ::= RESET QUERY CACHE */ - -3, /* (282) cmd ::= SYNCDB ids REPLICA */ - -7, /* (283) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (284) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - -7, /* (285) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ - -7, /* (286) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - -7, /* (287) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - -8, /* (288) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - -9, /* (289) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - -7, /* (290) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ - -7, /* (291) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (292) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - -7, /* (293) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ - -7, /* (294) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - -7, /* (295) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - -8, /* (296) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - -9, /* (297) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ - -7, /* (298) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ - -3, /* (299) cmd ::= KILL CONNECTION INTEGER */ - -5, /* (300) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - -5, /* (301) cmd ::= KILL QUERY INTEGER COLON INTEGER */ + -4, /* (217) sortlist ::= sortlist COMMA arrow sortorder */ + -2, /* (218) sortlist ::= item sortorder */ + -2, /* (219) sortlist ::= arrow sortorder */ + -1, /* (220) item ::= ID */ + -3, /* (221) item ::= ID DOT ID */ + -1, /* (222) sortorder ::= ASC */ + -1, /* (223) sortorder ::= DESC */ + 0, /* (224) sortorder ::= */ + 0, /* (225) groupby_opt ::= */ + -3, /* (226) groupby_opt ::= GROUP BY grouplist */ + -3, /* (227) grouplist ::= grouplist COMMA item */ + -3, /* (228) grouplist ::= grouplist COMMA arrow */ + -1, /* (229) grouplist ::= item */ + -1, /* (230) grouplist ::= arrow */ + 0, /* (231) having_opt ::= */ + -2, /* (232) having_opt ::= HAVING expr */ + 0, /* (233) limit_opt ::= */ + -2, /* (234) limit_opt ::= LIMIT signed */ + -4, /* (235) limit_opt ::= LIMIT signed OFFSET signed */ + -4, /* (236) limit_opt ::= LIMIT signed COMMA signed */ + 0, /* (237) slimit_opt ::= */ + -2, /* (238) slimit_opt ::= SLIMIT signed */ + -4, /* (239) slimit_opt ::= SLIMIT signed SOFFSET signed */ + -4, /* (240) slimit_opt ::= SLIMIT signed COMMA signed */ + 0, /* (241) where_opt ::= */ + -2, /* (242) where_opt ::= WHERE expr */ + -3, /* (243) expr ::= LP expr RP */ + -1, /* (244) expr ::= ID */ + -3, /* (245) expr ::= ID DOT ID */ + -3, /* (246) expr ::= ID DOT STAR */ + -1, /* (247) expr ::= INTEGER */ + -2, /* (248) expr ::= MINUS INTEGER */ + -2, /* (249) expr ::= PLUS INTEGER */ + -1, /* (250) expr ::= FLOAT */ + -2, /* (251) expr ::= MINUS FLOAT */ + -2, /* (252) expr ::= PLUS FLOAT */ + -1, /* (253) expr ::= STRING */ + -1, /* (254) expr ::= NOW */ + -1, /* (255) expr ::= VARIABLE */ + -2, /* (256) expr ::= PLUS VARIABLE */ + -2, /* (257) expr ::= MINUS VARIABLE */ + -1, /* (258) expr ::= BOOL */ + -1, /* (259) expr ::= NULL */ + -4, /* (260) expr ::= ID LP exprlist RP */ + -4, /* (261) expr ::= ID LP STAR RP */ + -3, /* (262) expr ::= expr IS NULL */ + -4, /* (263) expr ::= expr IS NOT NULL */ + -3, /* (264) expr ::= expr LT expr */ + -3, /* (265) expr ::= expr GT expr */ + -3, /* (266) expr ::= expr LE expr */ + -3, /* (267) expr ::= expr GE expr */ + -3, /* (268) expr ::= expr NE expr */ + -3, /* (269) expr ::= expr EQ expr */ + -5, /* (270) expr ::= expr BETWEEN expr AND expr */ + -3, /* (271) expr ::= expr AND expr */ + -3, /* (272) expr ::= expr OR expr */ + -3, /* (273) expr ::= expr PLUS expr */ + -3, /* (274) expr ::= expr MINUS expr */ + -3, /* (275) expr ::= expr STAR expr */ + -3, /* (276) expr ::= expr SLASH expr */ + -3, /* (277) expr ::= expr REM expr */ + -3, /* (278) expr ::= expr LIKE expr */ + -3, /* (279) expr ::= expr MATCH expr */ + -3, /* (280) expr ::= expr NMATCH expr */ + -3, /* (281) expr ::= ID CONTAINS STRING */ + -5, /* (282) expr ::= ID DOT ID CONTAINS STRING */ + -3, /* (283) arrow ::= ID ARROW STRING */ + -5, /* (284) arrow ::= ID DOT ID ARROW STRING */ + -1, /* (285) expr ::= arrow */ + -5, /* (286) expr ::= expr IN LP exprlist RP */ + -3, /* (287) exprlist ::= exprlist COMMA expritem */ + -1, /* (288) exprlist ::= expritem */ + -1, /* (289) expritem ::= expr */ + 0, /* (290) expritem ::= */ + -3, /* (291) cmd ::= RESET QUERY CACHE */ + -3, /* (292) cmd ::= SYNCDB ids REPLICA */ + -7, /* (293) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + -7, /* (294) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + -7, /* (295) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ + -7, /* (296) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + -7, /* (297) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + -8, /* (298) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + -9, /* (299) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + -7, /* (300) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ + -7, /* (301) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + -7, /* (302) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + -7, /* (303) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ + -7, /* (304) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + -7, /* (305) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + -8, /* (306) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + -9, /* (307) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ + -7, /* (308) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ + -3, /* (309) cmd ::= KILL CONNECTION INTEGER */ + -5, /* (310) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + -5, /* (311) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -2510,54 +2755,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } - yymsp = yypParser->yytos; - } -#endif - } switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -2743,16 +2940,16 @@ static YYACTIONTYPE yy_reduce( break; case 46: /* cmd ::= ALTER DATABASE ids alter_db_optr */ case 47: /* cmd ::= ALTER TOPIC ids alter_topic_optr */ yytestcase(yyruleno==47); -{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy10, &t);} +{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy532, &t);} break; case 48: /* cmd ::= ALTER ACCOUNT ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy427);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy31);} break; case 49: /* cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy427);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy31);} break; case 50: /* cmd ::= COMPACT VNODES IN LP exprlist RP */ -{ setCompactVnodeSql(pInfo, TSDB_SQL_COMPACT_VNODE, yymsp[-1].minor.yy345);} +{ setCompactVnodeSql(pInfo, TSDB_SQL_COMPACT_VNODE, yymsp[-1].minor.yy231);} break; case 51: /* ids ::= ID */ case 52: /* ids ::= STRING */ yytestcase(yyruleno==52); @@ -2774,17 +2971,17 @@ static YYACTIONTYPE yy_reduce( { setDCLSqlElems(pInfo, TSDB_SQL_CREATE_DNODE, 1, &yymsp[0].minor.yy0);} break; case 58: /* cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy427);} +{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy31);} break; case 59: /* cmd ::= CREATE DATABASE ifnotexists ids db_optr */ case 60: /* cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ yytestcase(yyruleno==60); -{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy10, &yymsp[-2].minor.yy0);} +{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy532, &yymsp[-2].minor.yy0);} break; case 61: /* cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ -{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy487, &yymsp[0].minor.yy0, 1);} +{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy103, &yymsp[0].minor.yy0, 1);} break; case 62: /* cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ -{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy487, &yymsp[0].minor.yy0, 2);} +{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy103, &yymsp[0].minor.yy0, 2);} break; case 63: /* cmd ::= CREATE USER ids PASS ids */ { setCreateUserSql(pInfo, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);} @@ -2815,38 +3012,38 @@ static YYACTIONTYPE yy_reduce( break; case 84: /* acct_optr ::= pps tseries storage streams qtime dbs users conns state */ { - yylhsminor.yy427.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; - yylhsminor.yy427.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; - yylhsminor.yy427.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; - yylhsminor.yy427.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; - yylhsminor.yy427.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; - yylhsminor.yy427.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy427.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy427.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; - yylhsminor.yy427.stat = yymsp[0].minor.yy0; + yylhsminor.yy31.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; + yylhsminor.yy31.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; + yylhsminor.yy31.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; + yylhsminor.yy31.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; + yylhsminor.yy31.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; + yylhsminor.yy31.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy31.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy31.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; + yylhsminor.yy31.stat = yymsp[0].minor.yy0; } - yymsp[-8].minor.yy427 = yylhsminor.yy427; + yymsp[-8].minor.yy31 = yylhsminor.yy31; break; case 85: /* intitemlist ::= intitemlist COMMA intitem */ case 154: /* tagitemlist ::= tagitemlist COMMA tagitem */ yytestcase(yyruleno==154); -{ yylhsminor.yy345 = tVariantListAppend(yymsp[-2].minor.yy345, &yymsp[0].minor.yy2, -1); } - yymsp[-2].minor.yy345 = yylhsminor.yy345; +{ yylhsminor.yy231 = tVariantListAppend(yymsp[-2].minor.yy231, &yymsp[0].minor.yy176, -1); } + yymsp[-2].minor.yy231 = yylhsminor.yy231; break; case 86: /* intitemlist ::= intitem */ case 155: /* tagitemlist ::= tagitem */ yytestcase(yyruleno==155); -{ yylhsminor.yy345 = tVariantListAppend(NULL, &yymsp[0].minor.yy2, -1); } - yymsp[0].minor.yy345 = yylhsminor.yy345; +{ yylhsminor.yy231 = tVariantListAppend(NULL, &yymsp[0].minor.yy176, -1); } + yymsp[0].minor.yy231 = yylhsminor.yy231; break; case 87: /* intitem ::= INTEGER */ case 156: /* tagitem ::= INTEGER */ yytestcase(yyruleno==156); case 157: /* tagitem ::= FLOAT */ yytestcase(yyruleno==157); case 158: /* tagitem ::= STRING */ yytestcase(yyruleno==158); case 159: /* tagitem ::= BOOL */ yytestcase(yyruleno==159); -{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy2, &yymsp[0].minor.yy0, true); } - yymsp[0].minor.yy2 = yylhsminor.yy2; +{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy176, &yymsp[0].minor.yy0, true); } + yymsp[0].minor.yy176 = yylhsminor.yy176; break; case 88: /* keep ::= KEEP intitemlist */ -{ yymsp[-1].minor.yy345 = yymsp[0].minor.yy345; } +{ yymsp[-1].minor.yy231 = yymsp[0].minor.yy231; } break; case 89: /* cache ::= CACHE INTEGER */ case 90: /* replica ::= REPLICA INTEGER */ yytestcase(yyruleno==90); @@ -2866,221 +3063,221 @@ static YYACTIONTYPE yy_reduce( { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } break; case 104: /* db_optr ::= */ -{setDefaultCreateDbOption(&yymsp[1].minor.yy10); yymsp[1].minor.yy10.dbType = TSDB_DB_TYPE_DEFAULT;} +{setDefaultCreateDbOption(&yymsp[1].minor.yy532); yymsp[1].minor.yy532.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 105: /* db_optr ::= db_optr cache */ -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 106: /* db_optr ::= db_optr replica */ case 123: /* alter_db_optr ::= alter_db_optr replica */ yytestcase(yyruleno==123); -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 107: /* db_optr ::= db_optr quorum */ case 124: /* alter_db_optr ::= alter_db_optr quorum */ yytestcase(yyruleno==124); -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 108: /* db_optr ::= db_optr days */ -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 109: /* db_optr ::= db_optr minrows */ -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 110: /* db_optr ::= db_optr maxrows */ -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 111: /* db_optr ::= db_optr blocks */ case 126: /* alter_db_optr ::= alter_db_optr blocks */ yytestcase(yyruleno==126); -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 112: /* db_optr ::= db_optr ctime */ -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 113: /* db_optr ::= db_optr wal */ -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 114: /* db_optr ::= db_optr fsync */ -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 115: /* db_optr ::= db_optr comp */ case 127: /* alter_db_optr ::= alter_db_optr comp */ yytestcase(yyruleno==127); -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 116: /* db_optr ::= db_optr prec */ -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.precision = yymsp[0].minor.yy0; } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.precision = yymsp[0].minor.yy0; } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 117: /* db_optr ::= db_optr keep */ case 125: /* alter_db_optr ::= alter_db_optr keep */ yytestcase(yyruleno==125); -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.keep = yymsp[0].minor.yy345; } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.keep = yymsp[0].minor.yy231; } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 118: /* db_optr ::= db_optr update */ case 128: /* alter_db_optr ::= alter_db_optr update */ yytestcase(yyruleno==128); -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 119: /* db_optr ::= db_optr cachelast */ case 129: /* alter_db_optr ::= alter_db_optr cachelast */ yytestcase(yyruleno==129); -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 120: /* topic_optr ::= db_optr */ case 130: /* alter_topic_optr ::= alter_db_optr */ yytestcase(yyruleno==130); -{ yylhsminor.yy10 = yymsp[0].minor.yy10; yylhsminor.yy10.dbType = TSDB_DB_TYPE_TOPIC; } - yymsp[0].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[0].minor.yy532; yylhsminor.yy532.dbType = TSDB_DB_TYPE_TOPIC; } + yymsp[0].minor.yy532 = yylhsminor.yy532; break; case 121: /* topic_optr ::= topic_optr partitions */ case 131: /* alter_topic_optr ::= alter_topic_optr partitions */ yytestcase(yyruleno==131); -{ yylhsminor.yy10 = yymsp[-1].minor.yy10; yylhsminor.yy10.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy10 = yylhsminor.yy10; +{ yylhsminor.yy532 = yymsp[-1].minor.yy532; yylhsminor.yy532.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 122: /* alter_db_optr ::= */ -{ setDefaultCreateDbOption(&yymsp[1].minor.yy10); yymsp[1].minor.yy10.dbType = TSDB_DB_TYPE_DEFAULT;} +{ setDefaultCreateDbOption(&yymsp[1].minor.yy532); yymsp[1].minor.yy532.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 132: /* typename ::= ids */ { yymsp[0].minor.yy0.type = 0; - tSetColumnType (&yylhsminor.yy487, &yymsp[0].minor.yy0); + tSetColumnType (&yylhsminor.yy103, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy487 = yylhsminor.yy487; + yymsp[0].minor.yy103 = yylhsminor.yy103; break; case 133: /* typename ::= ids LP signed RP */ { - if (yymsp[-1].minor.yy525 <= 0) { + if (yymsp[-1].minor.yy549 <= 0) { yymsp[-3].minor.yy0.type = 0; - tSetColumnType(&yylhsminor.yy487, &yymsp[-3].minor.yy0); + tSetColumnType(&yylhsminor.yy103, &yymsp[-3].minor.yy0); } else { - yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy525; // negative value of name length - tSetColumnType(&yylhsminor.yy487, &yymsp[-3].minor.yy0); + yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy549; // negative value of name length + tSetColumnType(&yylhsminor.yy103, &yymsp[-3].minor.yy0); } } - yymsp[-3].minor.yy487 = yylhsminor.yy487; + yymsp[-3].minor.yy103 = yylhsminor.yy103; break; case 134: /* typename ::= ids UNSIGNED */ { yymsp[-1].minor.yy0.type = 0; yymsp[-1].minor.yy0.n = ((yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z); - tSetColumnType (&yylhsminor.yy487, &yymsp[-1].minor.yy0); + tSetColumnType (&yylhsminor.yy103, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy487 = yylhsminor.yy487; + yymsp[-1].minor.yy103 = yylhsminor.yy103; break; case 135: /* signed ::= INTEGER */ -{ yylhsminor.yy525 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[0].minor.yy525 = yylhsminor.yy525; +{ yylhsminor.yy549 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[0].minor.yy549 = yylhsminor.yy549; break; case 136: /* signed ::= PLUS INTEGER */ -{ yymsp[-1].minor.yy525 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy549 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 137: /* signed ::= MINUS INTEGER */ -{ yymsp[-1].minor.yy525 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} +{ yymsp[-1].minor.yy549 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} break; case 141: /* cmd ::= CREATE TABLE create_table_list */ -{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy170;} +{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy422;} break; case 142: /* create_table_list ::= create_from_stable */ { SCreateTableSql* pCreateTable = calloc(1, sizeof(SCreateTableSql)); pCreateTable->childTableInfo = taosArrayInit(4, sizeof(SCreatedTableInfo)); - taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy72); + taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy306); pCreateTable->type = TSQL_CREATE_TABLE_FROM_STABLE; - yylhsminor.yy170 = pCreateTable; + yylhsminor.yy422 = pCreateTable; } - yymsp[0].minor.yy170 = yylhsminor.yy170; + yymsp[0].minor.yy422 = yylhsminor.yy422; break; case 143: /* create_table_list ::= create_table_list create_from_stable */ { - taosArrayPush(yymsp[-1].minor.yy170->childTableInfo, &yymsp[0].minor.yy72); - yylhsminor.yy170 = yymsp[-1].minor.yy170; + taosArrayPush(yymsp[-1].minor.yy422->childTableInfo, &yymsp[0].minor.yy306); + yylhsminor.yy422 = yymsp[-1].minor.yy422; } - yymsp[-1].minor.yy170 = yylhsminor.yy170; + yymsp[-1].minor.yy422 = yylhsminor.yy422; break; case 144: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ { - yylhsminor.yy170 = tSetCreateTableInfo(yymsp[-1].minor.yy345, NULL, NULL, TSQL_CREATE_TABLE); - setSqlInfo(pInfo, yylhsminor.yy170, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy422 = tSetCreateTableInfo(yymsp[-1].minor.yy231, NULL, NULL, TSQL_CREATE_TABLE); + setSqlInfo(pInfo, yylhsminor.yy422, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-4].minor.yy0, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy170 = yylhsminor.yy170; + yymsp[-5].minor.yy422 = yylhsminor.yy422; break; case 145: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ { - yylhsminor.yy170 = tSetCreateTableInfo(yymsp[-5].minor.yy345, yymsp[-1].minor.yy345, NULL, TSQL_CREATE_STABLE); - setSqlInfo(pInfo, yylhsminor.yy170, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy422 = tSetCreateTableInfo(yymsp[-5].minor.yy231, yymsp[-1].minor.yy231, NULL, TSQL_CREATE_STABLE); + setSqlInfo(pInfo, yylhsminor.yy422, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy170 = yylhsminor.yy170; + yymsp[-9].minor.yy422 = yylhsminor.yy422; break; case 146: /* create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; - yylhsminor.yy72 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy345, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); + yylhsminor.yy306 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy231, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy72 = yylhsminor.yy72; + yymsp[-9].minor.yy306 = yylhsminor.yy306; break; case 147: /* create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ { yymsp[-8].minor.yy0.n += yymsp[-7].minor.yy0.n; yymsp[-11].minor.yy0.n += yymsp[-10].minor.yy0.n; - yylhsminor.yy72 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy345, yymsp[-1].minor.yy345, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); + yylhsminor.yy306 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy231, yymsp[-1].minor.yy231, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); } - yymsp[-12].minor.yy72 = yylhsminor.yy72; + yymsp[-12].minor.yy306 = yylhsminor.yy306; break; case 148: /* tagNamelist ::= tagNamelist COMMA ids */ -{taosArrayPush(yymsp[-2].minor.yy345, &yymsp[0].minor.yy0); yylhsminor.yy345 = yymsp[-2].minor.yy345; } - yymsp[-2].minor.yy345 = yylhsminor.yy345; +{taosArrayPush(yymsp[-2].minor.yy231, &yymsp[0].minor.yy0); yylhsminor.yy231 = yymsp[-2].minor.yy231; } + yymsp[-2].minor.yy231 = yylhsminor.yy231; break; case 149: /* tagNamelist ::= ids */ -{yylhsminor.yy345 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy345, &yymsp[0].minor.yy0);} - yymsp[0].minor.yy345 = yylhsminor.yy345; +{yylhsminor.yy231 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy231, &yymsp[0].minor.yy0);} + yymsp[0].minor.yy231 = yylhsminor.yy231; break; case 150: /* create_table_args ::= ifnotexists ids cpxName AS select */ { - yylhsminor.yy170 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy68, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy170, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy422 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy86, TSQL_CREATE_STREAM); + setSqlInfo(pInfo, yylhsminor.yy422, NULL, TSDB_SQL_CREATE_TABLE); yymsp[-3].minor.yy0.n += yymsp[-2].minor.yy0.n; setCreatedTableName(pInfo, &yymsp[-3].minor.yy0, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy170 = yylhsminor.yy170; + yymsp[-4].minor.yy422 = yylhsminor.yy422; break; case 151: /* columnlist ::= columnlist COMMA column */ -{taosArrayPush(yymsp[-2].minor.yy345, &yymsp[0].minor.yy487); yylhsminor.yy345 = yymsp[-2].minor.yy345; } - yymsp[-2].minor.yy345 = yylhsminor.yy345; +{taosArrayPush(yymsp[-2].minor.yy231, &yymsp[0].minor.yy103); yylhsminor.yy231 = yymsp[-2].minor.yy231; } + yymsp[-2].minor.yy231 = yylhsminor.yy231; break; case 152: /* columnlist ::= column */ -{yylhsminor.yy345 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy345, &yymsp[0].minor.yy487);} - yymsp[0].minor.yy345 = yylhsminor.yy345; +{yylhsminor.yy231 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy231, &yymsp[0].minor.yy103);} + yymsp[0].minor.yy231 = yylhsminor.yy231; break; case 153: /* column ::= ids typename */ { - tSetColumnInfo(&yylhsminor.yy487, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy487); + tSetColumnInfo(&yylhsminor.yy103, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy103); } - yymsp[-1].minor.yy487 = yylhsminor.yy487; + yymsp[-1].minor.yy103 = yylhsminor.yy103; break; case 160: /* tagitem ::= NULL */ -{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy2, &yymsp[0].minor.yy0, true); } - yymsp[0].minor.yy2 = yylhsminor.yy2; +{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy176, &yymsp[0].minor.yy0, true); } + yymsp[0].minor.yy176 = yylhsminor.yy176; break; case 161: /* tagitem ::= NOW */ -{ yymsp[0].minor.yy0.type = TSDB_DATA_TYPE_TIMESTAMP; tVariantCreate(&yylhsminor.yy2, &yymsp[0].minor.yy0, true);} - yymsp[0].minor.yy2 = yylhsminor.yy2; +{ yymsp[0].minor.yy0.type = TSDB_DATA_TYPE_TIMESTAMP; tVariantCreate(&yylhsminor.yy176, &yymsp[0].minor.yy0, true);} + yymsp[0].minor.yy176 = yylhsminor.yy176; break; case 162: /* tagitem ::= MINUS INTEGER */ case 163: /* tagitem ::= MINUS FLOAT */ yytestcase(yyruleno==163); @@ -3090,56 +3287,56 @@ static YYACTIONTYPE yy_reduce( yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = yymsp[0].minor.yy0.type; toTSDBType(yymsp[-1].minor.yy0.type); - tVariantCreate(&yylhsminor.yy2, &yymsp[-1].minor.yy0, true); + tVariantCreate(&yylhsminor.yy176, &yymsp[-1].minor.yy0, true); } - yymsp[-1].minor.yy2 = yylhsminor.yy2; + yymsp[-1].minor.yy176 = yylhsminor.yy176; break; case 166: /* select ::= SELECT selcollist from where_opt range_option interval_option sliding_opt session_option windowstate_option fill_opt groupby_opt having_opt orderby_opt slimit_opt limit_opt */ { - yylhsminor.yy68 = tSetQuerySqlNode(&yymsp[-14].minor.yy0, yymsp[-13].minor.yy345, yymsp[-12].minor.yy484, yymsp[-11].minor.yy418, yymsp[-4].minor.yy345, yymsp[-2].minor.yy345, &yymsp[-9].minor.yy280, &yymsp[-7].minor.yy295, &yymsp[-6].minor.yy432, &yymsp[-8].minor.yy0, yymsp[-5].minor.yy345, &yymsp[0].minor.yy114, &yymsp[-1].minor.yy114, yymsp[-3].minor.yy418, &yymsp[-10].minor.yy144); + yylhsminor.yy86 = tSetQuerySqlNode(&yymsp[-14].minor.yy0, yymsp[-13].minor.yy231, yymsp[-12].minor.yy484, yymsp[-11].minor.yy226, yymsp[-4].minor.yy231, yymsp[-2].minor.yy231, &yymsp[-9].minor.yy430, &yymsp[-7].minor.yy409, &yymsp[-6].minor.yy228, &yymsp[-8].minor.yy0, yymsp[-5].minor.yy231, &yymsp[0].minor.yy444, &yymsp[-1].minor.yy444, yymsp[-3].minor.yy226, &yymsp[-10].minor.yy480); } - yymsp[-14].minor.yy68 = yylhsminor.yy68; + yymsp[-14].minor.yy86 = yylhsminor.yy86; break; case 167: /* select ::= LP select RP */ -{yymsp[-2].minor.yy68 = yymsp[-1].minor.yy68;} +{yymsp[-2].minor.yy86 = yymsp[-1].minor.yy86;} break; case 168: /* union ::= select */ -{ yylhsminor.yy345 = setSubclause(NULL, yymsp[0].minor.yy68); } - yymsp[0].minor.yy345 = yylhsminor.yy345; +{ yylhsminor.yy231 = setSubclause(NULL, yymsp[0].minor.yy86); } + yymsp[0].minor.yy231 = yylhsminor.yy231; break; case 169: /* union ::= union UNION ALL select */ -{ yylhsminor.yy345 = appendSelectClause(yymsp[-3].minor.yy345, yymsp[0].minor.yy68); } - yymsp[-3].minor.yy345 = yylhsminor.yy345; +{ yylhsminor.yy231 = appendSelectClause(yymsp[-3].minor.yy231, yymsp[0].minor.yy86); } + yymsp[-3].minor.yy231 = yylhsminor.yy231; break; case 170: /* cmd ::= union */ -{ setSqlInfo(pInfo, yymsp[0].minor.yy345, NULL, TSDB_SQL_SELECT); } +{ setSqlInfo(pInfo, yymsp[0].minor.yy231, NULL, TSDB_SQL_SELECT); } break; case 171: /* select ::= SELECT selcollist */ { - yylhsminor.yy68 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy345, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + yylhsminor.yy86 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy231, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } - yymsp[-1].minor.yy68 = yylhsminor.yy68; + yymsp[-1].minor.yy86 = yylhsminor.yy86; break; case 172: /* sclp ::= selcollist COMMA */ -{yylhsminor.yy345 = yymsp[-1].minor.yy345;} - yymsp[-1].minor.yy345 = yylhsminor.yy345; +{yylhsminor.yy231 = yymsp[-1].minor.yy231;} + yymsp[-1].minor.yy231 = yylhsminor.yy231; break; case 173: /* sclp ::= */ case 214: /* orderby_opt ::= */ yytestcase(yyruleno==214); -{yymsp[1].minor.yy345 = 0;} +{yymsp[1].minor.yy231 = 0;} break; case 174: /* selcollist ::= sclp distinct expr as */ { - yylhsminor.yy345 = tSqlExprListAppend(yymsp[-3].minor.yy345, yymsp[-1].minor.yy418, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); + yylhsminor.yy231 = tSqlExprListAppend(yymsp[-3].minor.yy231, yymsp[-1].minor.yy226, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); } - yymsp[-3].minor.yy345 = yylhsminor.yy345; + yymsp[-3].minor.yy231 = yylhsminor.yy231; break; case 175: /* selcollist ::= sclp STAR */ { tSqlExpr *pNode = tSqlExprCreateIdValue(pInfo, NULL, TK_ALL); - yylhsminor.yy345 = tSqlExprListAppend(yymsp[-1].minor.yy345, pNode, 0, 0); + yylhsminor.yy231 = tSqlExprListAppend(yymsp[-1].minor.yy231, pNode, 0, 0); } - yymsp[-1].minor.yy345 = yylhsminor.yy345; + yymsp[-1].minor.yy231 = yylhsminor.yy231; break; case 176: /* as ::= AS ids */ { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } @@ -3160,13 +3357,13 @@ static YYACTIONTYPE yy_reduce( {yymsp[-1].minor.yy484 = yymsp[0].minor.yy484;} break; case 183: /* sub ::= LP union RP */ -{yymsp[-2].minor.yy484 = addSubqueryElem(NULL, yymsp[-1].minor.yy345, NULL);} +{yymsp[-2].minor.yy484 = addSubqueryElem(NULL, yymsp[-1].minor.yy231, NULL);} break; case 184: /* sub ::= LP union RP ids */ -{yymsp[-3].minor.yy484 = addSubqueryElem(NULL, yymsp[-2].minor.yy345, &yymsp[0].minor.yy0);} +{yymsp[-3].minor.yy484 = addSubqueryElem(NULL, yymsp[-2].minor.yy231, &yymsp[0].minor.yy0);} break; case 185: /* sub ::= sub COMMA LP union RP ids */ -{yylhsminor.yy484 = addSubqueryElem(yymsp[-5].minor.yy484, yymsp[-2].minor.yy345, &yymsp[0].minor.yy0);} +{yylhsminor.yy484 = addSubqueryElem(yymsp[-5].minor.yy484, yymsp[-2].minor.yy231, &yymsp[0].minor.yy0);} yymsp[-5].minor.yy484 = yylhsminor.yy484; break; case 186: /* tablelist ::= ids cpxName */ @@ -3202,69 +3399,69 @@ static YYACTIONTYPE yy_reduce( yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 191: /* timestamp ::= INTEGER */ -{ yylhsminor.yy418 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy418 = yylhsminor.yy418; +{ yylhsminor.yy226 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_INTEGER);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; case 192: /* timestamp ::= MINUS INTEGER */ case 193: /* timestamp ::= PLUS INTEGER */ yytestcase(yyruleno==193); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy418 = tSqlExprCreateTimestamp(&yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy418 = yylhsminor.yy418; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy226 = tSqlExprCreateTimestamp(&yymsp[-1].minor.yy0, TK_INTEGER);} + yymsp[-1].minor.yy226 = yylhsminor.yy226; break; case 194: /* timestamp ::= STRING */ -{ yylhsminor.yy418 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy418 = yylhsminor.yy418; +{ yylhsminor.yy226 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_STRING);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; case 195: /* timestamp ::= NOW */ -{ yylhsminor.yy418 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy418 = yylhsminor.yy418; +{ yylhsminor.yy226 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_NOW); } + yymsp[0].minor.yy226 = yylhsminor.yy226; break; case 196: /* timestamp ::= NOW PLUS VARIABLE */ -{yymsp[-2].minor.yy418 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_PLUS); } +{yymsp[-2].minor.yy226 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_PLUS); } break; case 197: /* timestamp ::= NOW MINUS VARIABLE */ -{yymsp[-2].minor.yy418 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_MINUS); } +{yymsp[-2].minor.yy226 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_MINUS); } break; case 198: /* range_option ::= */ -{yymsp[1].minor.yy144.start = 0; yymsp[1].minor.yy144.end = 0;} +{yymsp[1].minor.yy480.start = 0; yymsp[1].minor.yy480.end = 0;} break; case 199: /* range_option ::= RANGE LP timestamp COMMA timestamp RP */ -{yymsp[-5].minor.yy144.start = yymsp[-3].minor.yy418; yymsp[-5].minor.yy144.end = yymsp[-1].minor.yy418;} +{yymsp[-5].minor.yy480.start = yymsp[-3].minor.yy226; yymsp[-5].minor.yy480.end = yymsp[-1].minor.yy226;} break; case 200: /* interval_option ::= intervalKey LP tmvar RP */ -{yylhsminor.yy280.interval = yymsp[-1].minor.yy0; yylhsminor.yy280.offset.n = 0; yylhsminor.yy280.token = yymsp[-3].minor.yy40;} - yymsp[-3].minor.yy280 = yylhsminor.yy280; +{yylhsminor.yy430.interval = yymsp[-1].minor.yy0; yylhsminor.yy430.offset.n = 0; yylhsminor.yy430.token = yymsp[-3].minor.yy310;} + yymsp[-3].minor.yy430 = yylhsminor.yy430; break; case 201: /* interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ -{yylhsminor.yy280.interval = yymsp[-3].minor.yy0; yylhsminor.yy280.offset = yymsp[-1].minor.yy0; yylhsminor.yy280.token = yymsp[-5].minor.yy40;} - yymsp[-5].minor.yy280 = yylhsminor.yy280; +{yylhsminor.yy430.interval = yymsp[-3].minor.yy0; yylhsminor.yy430.offset = yymsp[-1].minor.yy0; yylhsminor.yy430.token = yymsp[-5].minor.yy310;} + yymsp[-5].minor.yy430 = yylhsminor.yy430; break; case 202: /* interval_option ::= */ -{memset(&yymsp[1].minor.yy280, 0, sizeof(yymsp[1].minor.yy280));} +{memset(&yymsp[1].minor.yy430, 0, sizeof(yymsp[1].minor.yy430));} break; case 203: /* intervalKey ::= INTERVAL */ -{yymsp[0].minor.yy40 = TK_INTERVAL;} +{yymsp[0].minor.yy310 = TK_INTERVAL;} break; case 204: /* intervalKey ::= EVERY */ -{yymsp[0].minor.yy40 = TK_EVERY; } +{yymsp[0].minor.yy310 = TK_EVERY; } break; case 205: /* session_option ::= */ -{yymsp[1].minor.yy295.col.n = 0; yymsp[1].minor.yy295.gap.n = 0;} +{yymsp[1].minor.yy409.col.n = 0; yymsp[1].minor.yy409.gap.n = 0;} break; case 206: /* session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - yymsp[-6].minor.yy295.col = yymsp[-4].minor.yy0; - yymsp[-6].minor.yy295.gap = yymsp[-1].minor.yy0; + yymsp[-6].minor.yy409.col = yymsp[-4].minor.yy0; + yymsp[-6].minor.yy409.gap = yymsp[-1].minor.yy0; } break; case 207: /* windowstate_option ::= */ -{ yymsp[1].minor.yy432.col.n = 0; yymsp[1].minor.yy432.col.z = NULL;} +{ yymsp[1].minor.yy228.col.n = 0; yymsp[1].minor.yy228.col.z = NULL;} break; case 208: /* windowstate_option ::= STATE_WINDOW LP ids RP */ -{ yymsp[-3].minor.yy432.col = yymsp[-1].minor.yy0; } +{ yymsp[-3].minor.yy228.col = yymsp[-1].minor.yy0; } break; case 209: /* fill_opt ::= */ -{ yymsp[1].minor.yy345 = 0; } +{ yymsp[1].minor.yy231 = 0; } break; case 210: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ { @@ -3272,14 +3469,14 @@ static YYACTIONTYPE yy_reduce( toTSDBType(yymsp[-3].minor.yy0.type); tVariantCreate(&A, &yymsp[-3].minor.yy0, true); - tVariantListInsert(yymsp[-1].minor.yy345, &A, -1, 0); - yymsp[-5].minor.yy345 = yymsp[-1].minor.yy345; + tVariantListInsert(yymsp[-1].minor.yy231, &A, -1, 0); + yymsp[-5].minor.yy231 = yymsp[-1].minor.yy231; } break; case 211: /* fill_opt ::= FILL LP ID RP */ { toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-3].minor.yy345 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1, true); + yymsp[-3].minor.yy231 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1, true); } break; case 212: /* sliding_opt ::= SLIDING LP tmvar RP */ @@ -3289,258 +3486,305 @@ static YYACTIONTYPE yy_reduce( {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; } break; case 215: /* orderby_opt ::= ORDER BY sortlist */ -{yymsp[-2].minor.yy345 = yymsp[0].minor.yy345;} +{yymsp[-2].minor.yy231 = yymsp[0].minor.yy231;} break; case 216: /* sortlist ::= sortlist COMMA item sortorder */ { - yylhsminor.yy345 = tVariantListAppend(yymsp[-3].minor.yy345, &yymsp[-1].minor.yy2, yymsp[0].minor.yy281); + yylhsminor.yy231 = commonItemAppend(yymsp[-3].minor.yy231, &yymsp[-1].minor.yy176, NULL, false, yymsp[0].minor.yy502); } - yymsp[-3].minor.yy345 = yylhsminor.yy345; + yymsp[-3].minor.yy231 = yylhsminor.yy231; break; - case 217: /* sortlist ::= item sortorder */ + case 217: /* sortlist ::= sortlist COMMA arrow sortorder */ { - yylhsminor.yy345 = tVariantListAppend(NULL, &yymsp[-1].minor.yy2, yymsp[0].minor.yy281); + yylhsminor.yy231 = commonItemAppend(yymsp[-3].minor.yy231, NULL, yymsp[-1].minor.yy226, true, yymsp[0].minor.yy502); } - yymsp[-1].minor.yy345 = yylhsminor.yy345; + yymsp[-3].minor.yy231 = yylhsminor.yy231; break; - case 218: /* item ::= ids cpxName */ + case 218: /* sortlist ::= item sortorder */ { - toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - - tVariantCreate(&yylhsminor.yy2, &yymsp[-1].minor.yy0, true); + yylhsminor.yy231 = commonItemAppend(NULL, &yymsp[-1].minor.yy176, NULL, false, yymsp[0].minor.yy502); } - yymsp[-1].minor.yy2 = yylhsminor.yy2; + yymsp[-1].minor.yy231 = yylhsminor.yy231; break; - case 219: /* sortorder ::= ASC */ -{ yymsp[0].minor.yy281 = TSDB_ORDER_ASC; } + case 219: /* sortlist ::= arrow sortorder */ +{ + yylhsminor.yy231 = commonItemAppend(NULL, NULL, yymsp[-1].minor.yy226, true, yymsp[0].minor.yy502); +} + yymsp[-1].minor.yy231 = yylhsminor.yy231; break; - case 220: /* sortorder ::= DESC */ -{ yymsp[0].minor.yy281 = TSDB_ORDER_DESC;} + case 220: /* item ::= ID */ +{ + toTSDBType(yymsp[0].minor.yy0.type); + tVariantCreate(&yylhsminor.yy176, &yymsp[0].minor.yy0, true); +} + yymsp[0].minor.yy176 = yylhsminor.yy176; break; - case 221: /* sortorder ::= */ -{ yymsp[1].minor.yy281 = TSDB_ORDER_ASC; } + case 221: /* item ::= ID DOT ID */ +{ + toTSDBType(yymsp[-2].minor.yy0.type); + yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); + tVariantCreate(&yylhsminor.yy176, &yymsp[-2].minor.yy0, true); +} + yymsp[-2].minor.yy176 = yylhsminor.yy176; + break; + case 222: /* sortorder ::= ASC */ +{ yymsp[0].minor.yy502 = TSDB_ORDER_ASC; } + break; + case 223: /* sortorder ::= DESC */ +{ yymsp[0].minor.yy502 = TSDB_ORDER_DESC;} + break; + case 224: /* sortorder ::= */ +{ yymsp[1].minor.yy502 = TSDB_ORDER_ASC; } break; - case 222: /* groupby_opt ::= */ -{ yymsp[1].minor.yy345 = 0;} + case 225: /* groupby_opt ::= */ +{ yymsp[1].minor.yy231 = 0;} + break; + case 226: /* groupby_opt ::= GROUP BY grouplist */ +{ yymsp[-2].minor.yy231 = yymsp[0].minor.yy231;} + break; + case 227: /* grouplist ::= grouplist COMMA item */ +{ + yylhsminor.yy231 = commonItemAppend(yymsp[-2].minor.yy231, &yymsp[0].minor.yy176, NULL, false, -1); +} + yymsp[-2].minor.yy231 = yylhsminor.yy231; break; - case 223: /* groupby_opt ::= GROUP BY grouplist */ -{ yymsp[-2].minor.yy345 = yymsp[0].minor.yy345;} + case 228: /* grouplist ::= grouplist COMMA arrow */ +{ + yylhsminor.yy231 = commonItemAppend(yymsp[-2].minor.yy231, NULL, yymsp[0].minor.yy226, true, -1); +} + yymsp[-2].minor.yy231 = yylhsminor.yy231; break; - case 224: /* grouplist ::= grouplist COMMA item */ + case 229: /* grouplist ::= item */ { - yylhsminor.yy345 = tVariantListAppend(yymsp[-2].minor.yy345, &yymsp[0].minor.yy2, -1); + yylhsminor.yy231 = commonItemAppend(NULL, &yymsp[0].minor.yy176, NULL, false, -1); } - yymsp[-2].minor.yy345 = yylhsminor.yy345; + yymsp[0].minor.yy231 = yylhsminor.yy231; break; - case 225: /* grouplist ::= item */ + case 230: /* grouplist ::= arrow */ { - yylhsminor.yy345 = tVariantListAppend(NULL, &yymsp[0].minor.yy2, -1); + yylhsminor.yy231 = commonItemAppend(NULL, NULL, yymsp[0].minor.yy226, true, -1); } - yymsp[0].minor.yy345 = yylhsminor.yy345; + yymsp[0].minor.yy231 = yylhsminor.yy231; + break; + case 231: /* having_opt ::= */ + case 241: /* where_opt ::= */ yytestcase(yyruleno==241); + case 290: /* expritem ::= */ yytestcase(yyruleno==290); +{yymsp[1].minor.yy226 = 0;} + break; + case 232: /* having_opt ::= HAVING expr */ + case 242: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==242); +{yymsp[-1].minor.yy226 = yymsp[0].minor.yy226;} break; - case 226: /* having_opt ::= */ - case 236: /* where_opt ::= */ yytestcase(yyruleno==236); - case 280: /* expritem ::= */ yytestcase(yyruleno==280); -{yymsp[1].minor.yy418 = 0;} + case 233: /* limit_opt ::= */ + case 237: /* slimit_opt ::= */ yytestcase(yyruleno==237); +{yymsp[1].minor.yy444.limit = -1; yymsp[1].minor.yy444.offset = 0;} break; - case 227: /* having_opt ::= HAVING expr */ - case 237: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==237); -{yymsp[-1].minor.yy418 = yymsp[0].minor.yy418;} + case 234: /* limit_opt ::= LIMIT signed */ + case 238: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==238); +{yymsp[-1].minor.yy444.limit = yymsp[0].minor.yy549; yymsp[-1].minor.yy444.offset = 0;} break; - case 228: /* limit_opt ::= */ - case 232: /* slimit_opt ::= */ yytestcase(yyruleno==232); -{yymsp[1].minor.yy114.limit = -1; yymsp[1].minor.yy114.offset = 0;} + case 235: /* limit_opt ::= LIMIT signed OFFSET signed */ +{ yymsp[-3].minor.yy444.limit = yymsp[-2].minor.yy549; yymsp[-3].minor.yy444.offset = yymsp[0].minor.yy549;} break; - case 229: /* limit_opt ::= LIMIT signed */ - case 233: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==233); -{yymsp[-1].minor.yy114.limit = yymsp[0].minor.yy525; yymsp[-1].minor.yy114.offset = 0;} + case 236: /* limit_opt ::= LIMIT signed COMMA signed */ +{ yymsp[-3].minor.yy444.limit = yymsp[0].minor.yy549; yymsp[-3].minor.yy444.offset = yymsp[-2].minor.yy549;} break; - case 230: /* limit_opt ::= LIMIT signed OFFSET signed */ -{ yymsp[-3].minor.yy114.limit = yymsp[-2].minor.yy525; yymsp[-3].minor.yy114.offset = yymsp[0].minor.yy525;} + case 239: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ +{yymsp[-3].minor.yy444.limit = yymsp[-2].minor.yy549; yymsp[-3].minor.yy444.offset = yymsp[0].minor.yy549;} break; - case 231: /* limit_opt ::= LIMIT signed COMMA signed */ -{ yymsp[-3].minor.yy114.limit = yymsp[0].minor.yy525; yymsp[-3].minor.yy114.offset = yymsp[-2].minor.yy525;} + case 240: /* slimit_opt ::= SLIMIT signed COMMA signed */ +{yymsp[-3].minor.yy444.limit = yymsp[0].minor.yy549; yymsp[-3].minor.yy444.offset = yymsp[-2].minor.yy549;} break; - case 234: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ -{yymsp[-3].minor.yy114.limit = yymsp[-2].minor.yy525; yymsp[-3].minor.yy114.offset = yymsp[0].minor.yy525;} + case 243: /* expr ::= LP expr RP */ +{yylhsminor.yy226 = yymsp[-1].minor.yy226; yylhsminor.yy226->exprToken.z = yymsp[-2].minor.yy0.z; yylhsminor.yy226->exprToken.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 235: /* slimit_opt ::= SLIMIT signed COMMA signed */ -{yymsp[-3].minor.yy114.limit = yymsp[0].minor.yy525; yymsp[-3].minor.yy114.offset = yymsp[-2].minor.yy525;} + case 244: /* expr ::= ID */ +{ yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_ID);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 238: /* expr ::= LP expr RP */ -{yylhsminor.yy418 = yymsp[-1].minor.yy418; yylhsminor.yy418->exprToken.z = yymsp[-2].minor.yy0.z; yylhsminor.yy418->exprToken.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 245: /* expr ::= ID DOT ID */ +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ID);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 239: /* expr ::= ID */ -{ yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_ID);} - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 246: /* expr ::= ID DOT STAR */ +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ALL);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 240: /* expr ::= ID DOT ID */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ID);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 247: /* expr ::= INTEGER */ +{ yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_INTEGER);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 241: /* expr ::= ID DOT STAR */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ALL);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 248: /* expr ::= MINUS INTEGER */ + case 249: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==249); +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_INTEGER);} + yymsp[-1].minor.yy226 = yylhsminor.yy226; break; - case 242: /* expr ::= INTEGER */ -{ yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 250: /* expr ::= FLOAT */ +{ yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_FLOAT);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 243: /* expr ::= MINUS INTEGER */ - case 244: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==244); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy418 = yylhsminor.yy418; + case 251: /* expr ::= MINUS FLOAT */ + case 252: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==252); +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_FLOAT);} + yymsp[-1].minor.yy226 = yylhsminor.yy226; break; - case 245: /* expr ::= FLOAT */ -{ yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_FLOAT);} - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 253: /* expr ::= STRING */ +{ yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_STRING);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 246: /* expr ::= MINUS FLOAT */ - case 247: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==247); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_FLOAT);} - yymsp[-1].minor.yy418 = yylhsminor.yy418; + case 254: /* expr ::= NOW */ +{ yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_NOW); } + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 248: /* expr ::= STRING */ -{ yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 255: /* expr ::= VARIABLE */ +{ yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_VARIABLE);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 249: /* expr ::= NOW */ -{ yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 256: /* expr ::= PLUS VARIABLE */ + case 257: /* expr ::= MINUS VARIABLE */ yytestcase(yyruleno==257); +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_VARIABLE);} + yymsp[-1].minor.yy226 = yylhsminor.yy226; break; - case 250: /* expr ::= VARIABLE */ -{ yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_VARIABLE);} - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 258: /* expr ::= BOOL */ +{ yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_BOOL);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 251: /* expr ::= PLUS VARIABLE */ - case 252: /* expr ::= MINUS VARIABLE */ yytestcase(yyruleno==252); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_VARIABLE);} - yymsp[-1].minor.yy418 = yylhsminor.yy418; + case 259: /* expr ::= NULL */ +{ yylhsminor.yy226 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_NULL);} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 253: /* expr ::= BOOL */ -{ yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_BOOL);} - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 260: /* expr ::= ID LP exprlist RP */ +{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy226 = tSqlExprCreateFunction(yymsp[-1].minor.yy231, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy226 = yylhsminor.yy226; break; - case 254: /* expr ::= NULL */ -{ yylhsminor.yy418 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_NULL);} - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 261: /* expr ::= ID LP STAR RP */ +{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy226 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy226 = yylhsminor.yy226; break; - case 255: /* expr ::= ID LP exprlist RP */ -{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy418 = tSqlExprCreateFunction(yymsp[-1].minor.yy345, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy418 = yylhsminor.yy418; + case 262: /* expr ::= expr IS NULL */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, NULL, TK_ISNULL);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 256: /* expr ::= ID LP STAR RP */ -{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy418 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy418 = yylhsminor.yy418; + case 263: /* expr ::= expr IS NOT NULL */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-3].minor.yy226, NULL, TK_NOTNULL);} + yymsp[-3].minor.yy226 = yylhsminor.yy226; break; - case 257: /* expr ::= expr IS NULL */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, NULL, TK_ISNULL);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 264: /* expr ::= expr LT expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_LT);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 258: /* expr ::= expr IS NOT NULL */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-3].minor.yy418, NULL, TK_NOTNULL);} - yymsp[-3].minor.yy418 = yylhsminor.yy418; + case 265: /* expr ::= expr GT expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_GT);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 259: /* expr ::= expr LT expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_LT);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 266: /* expr ::= expr LE expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_LE);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 260: /* expr ::= expr GT expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_GT);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 267: /* expr ::= expr GE expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_GE);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 261: /* expr ::= expr LE expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_LE);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 268: /* expr ::= expr NE expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_NE);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 262: /* expr ::= expr GE expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_GE);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 269: /* expr ::= expr EQ expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_EQ);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 263: /* expr ::= expr NE expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_NE);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 270: /* expr ::= expr BETWEEN expr AND expr */ +{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy226); yylhsminor.yy226 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy226, yymsp[-2].minor.yy226, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy226, TK_LE), TK_AND);} + yymsp[-4].minor.yy226 = yylhsminor.yy226; break; - case 264: /* expr ::= expr EQ expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_EQ);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 271: /* expr ::= expr AND expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_AND);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 265: /* expr ::= expr BETWEEN expr AND expr */ -{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy418); yylhsminor.yy418 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy418, yymsp[-2].minor.yy418, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy418, TK_LE), TK_AND);} - yymsp[-4].minor.yy418 = yylhsminor.yy418; + case 272: /* expr ::= expr OR expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_OR); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 266: /* expr ::= expr AND expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_AND);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 273: /* expr ::= expr PLUS expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_PLUS); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 267: /* expr ::= expr OR expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_OR); } - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 274: /* expr ::= expr MINUS expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_MINUS); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 268: /* expr ::= expr PLUS expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_PLUS); } - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 275: /* expr ::= expr STAR expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_STAR); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 269: /* expr ::= expr MINUS expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_MINUS); } - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 276: /* expr ::= expr SLASH expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_DIVIDE);} + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 270: /* expr ::= expr STAR expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_STAR); } - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 277: /* expr ::= expr REM expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_REM); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 271: /* expr ::= expr SLASH expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_DIVIDE);} - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 278: /* expr ::= expr LIKE expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_LIKE); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 272: /* expr ::= expr REM expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_REM); } - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 279: /* expr ::= expr MATCH expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_MATCH); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 273: /* expr ::= expr LIKE expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_LIKE); } - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 280: /* expr ::= expr NMATCH expr */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-2].minor.yy226, yymsp[0].minor.yy226, TK_NMATCH); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 274: /* expr ::= expr MATCH expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_MATCH); } - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 281: /* expr ::= ID CONTAINS STRING */ +{ tSqlExpr* S = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ID); tSqlExpr* M = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_STRING); yylhsminor.yy226 = tSqlExprCreate(S, M, TK_CONTAINS); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 275: /* expr ::= expr NMATCH expr */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-2].minor.yy418, yymsp[0].minor.yy418, TK_NMATCH); } - yymsp[-2].minor.yy418 = yylhsminor.yy418; + case 282: /* expr ::= ID DOT ID CONTAINS STRING */ +{ yymsp[-4].minor.yy0.n += (1+yymsp[-2].minor.yy0.n); tSqlExpr* S = tSqlExprCreateIdValue(pInfo, &yymsp[-4].minor.yy0, TK_ID); tSqlExpr* M = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_STRING); yylhsminor.yy226 = tSqlExprCreate(S, M, TK_CONTAINS); } + yymsp[-4].minor.yy226 = yylhsminor.yy226; break; - case 276: /* expr ::= expr IN LP exprlist RP */ -{yylhsminor.yy418 = tSqlExprCreate(yymsp[-4].minor.yy418, (tSqlExpr*)yymsp[-1].minor.yy345, TK_IN); } - yymsp[-4].minor.yy418 = yylhsminor.yy418; + case 283: /* arrow ::= ID ARROW STRING */ +{tSqlExpr* S = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ID); tSqlExpr* M = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_STRING); yylhsminor.yy226 = tSqlExprCreate(S, M, TK_ARROW); } + yymsp[-2].minor.yy226 = yylhsminor.yy226; break; - case 277: /* exprlist ::= exprlist COMMA expritem */ -{yylhsminor.yy345 = tSqlExprListAppend(yymsp[-2].minor.yy345,yymsp[0].minor.yy418,0, 0);} - yymsp[-2].minor.yy345 = yylhsminor.yy345; + case 284: /* arrow ::= ID DOT ID ARROW STRING */ +{yymsp[-4].minor.yy0.n += (1+yymsp[-2].minor.yy0.n); tSqlExpr* S = tSqlExprCreateIdValue(pInfo, &yymsp[-4].minor.yy0, TK_ID); tSqlExpr* M = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_STRING); yylhsminor.yy226 = tSqlExprCreate(S, M, TK_ARROW); } + yymsp[-4].minor.yy226 = yylhsminor.yy226; break; - case 278: /* exprlist ::= expritem */ -{yylhsminor.yy345 = tSqlExprListAppend(0,yymsp[0].minor.yy418,0, 0);} - yymsp[0].minor.yy345 = yylhsminor.yy345; + case 285: /* expr ::= arrow */ + case 289: /* expritem ::= expr */ yytestcase(yyruleno==289); +{yylhsminor.yy226 = yymsp[0].minor.yy226;} + yymsp[0].minor.yy226 = yylhsminor.yy226; break; - case 279: /* expritem ::= expr */ -{yylhsminor.yy418 = yymsp[0].minor.yy418;} - yymsp[0].minor.yy418 = yylhsminor.yy418; + case 286: /* expr ::= expr IN LP exprlist RP */ +{yylhsminor.yy226 = tSqlExprCreate(yymsp[-4].minor.yy226, (tSqlExpr*)yymsp[-1].minor.yy231, TK_IN); } + yymsp[-4].minor.yy226 = yylhsminor.yy226; break; - case 281: /* cmd ::= RESET QUERY CACHE */ + case 287: /* exprlist ::= exprlist COMMA expritem */ +{yylhsminor.yy231 = tSqlExprListAppend(yymsp[-2].minor.yy231,yymsp[0].minor.yy226,0, 0);} + yymsp[-2].minor.yy231 = yylhsminor.yy231; + break; + case 288: /* exprlist ::= expritem */ +{yylhsminor.yy231 = tSqlExprListAppend(0,yymsp[0].minor.yy226,0, 0);} + yymsp[0].minor.yy231 = yylhsminor.yy231; + break; + case 291: /* cmd ::= RESET QUERY CACHE */ { setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} break; - case 282: /* cmd ::= SYNCDB ids REPLICA */ + case 292: /* cmd ::= SYNCDB ids REPLICA */ { setDCLSqlElems(pInfo, TSDB_SQL_SYNC_DB_REPLICA, 1, &yymsp[-1].minor.yy0);} break; - case 283: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + case 293: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy345, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy231, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 284: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + case 294: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3551,21 +3795,21 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 285: /* cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ + case 295: /* cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy345, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy231, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 286: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + case 296: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy345, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy231, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 287: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + case 297: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3576,7 +3820,7 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 288: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + case 298: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3590,33 +3834,33 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 289: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + case 299: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ { yymsp[-6].minor.yy0.n += yymsp[-5].minor.yy0.n; toTSDBType(yymsp[-2].minor.yy0.type); SArray* A = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1, true); - A = tVariantListAppend(A, &yymsp[0].minor.yy2, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy176, -1); SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-6].minor.yy0, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 290: /* cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ + case 300: /* cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy345, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy231, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 291: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + case 301: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy345, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy231, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 292: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + case 302: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3627,21 +3871,21 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 293: /* cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ + case 303: /* cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy345, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy231, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 294: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + case 304: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy345, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy231, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 295: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + case 305: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3652,7 +3896,7 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 296: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + case 306: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3666,32 +3910,32 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 297: /* cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ + case 307: /* cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ { yymsp[-6].minor.yy0.n += yymsp[-5].minor.yy0.n; toTSDBType(yymsp[-2].minor.yy0.type); SArray* A = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1, true); - A = tVariantListAppend(A, &yymsp[0].minor.yy2, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy176, -1); SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-6].minor.yy0, NULL, A, TSDB_ALTER_TABLE_UPDATE_TAG_VAL, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 298: /* cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ + case 308: /* cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy345, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy231, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 299: /* cmd ::= KILL CONNECTION INTEGER */ + case 309: /* cmd ::= KILL CONNECTION INTEGER */ {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &yymsp[0].minor.yy0);} break; - case 300: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ + case 310: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSql(pInfo, TSDB_SQL_KILL_STREAM, &yymsp[-2].minor.yy0);} break; - case 301: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ + case 311: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSql(pInfo, TSDB_SQL_KILL_QUERY, &yymsp[-2].minor.yy0);} break; default: @@ -3862,12 +4106,56 @@ void Parse( } #endif - do{ + while(1){ /* Exit by "break" */ + assert( yypParser->yytos>=yypParser->yystack ); assert( yyact==yypParser->yytos->stateno ); yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ - yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor ParseCTX_PARAM); + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); +#ifndef NDEBUG + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == + (int)(yypParser->yytos - yypParser->yystack)); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=yypParser->yystackEnd ){ + yyStackOverflow(yypParser); + break; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + break; + } + } +#endif + } + yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor ParseCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY @@ -3923,14 +4211,13 @@ void Parse( yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); yymajor = YYNOCODE; }else{ - while( yypParser->yytos >= yypParser->yystack - && (yyact = yy_find_reduce_action( - yypParser->yytos->stateno, - YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE - ){ + while( yypParser->yytos > yypParser->yystack ){ + yyact = yy_find_reduce_action(yypParser->yytos->stateno, + YYERRORSYMBOL); + if( yyact<=YY_MAX_SHIFTREDUCE ) break; yy_pop_parser_stack(yypParser); } - if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ + if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); #ifndef YYNOERRORRECOVERY @@ -3980,7 +4267,7 @@ void Parse( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; diff --git a/src/tsdb/CMakeLists.txt b/src/tsdb/CMakeLists.txt index 0f472cfbfc443e57e538068d28cb3c2c8d228dec..875bb6258125b88399558c75a6169dea67bfdde8 100644 --- a/src/tsdb/CMakeLists.txt +++ b/src/tsdb/CMakeLists.txt @@ -3,9 +3,10 @@ PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) +INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc) AUX_SOURCE_DIRECTORY(src SRC) ADD_LIBRARY(tsdb ${SRC}) -TARGET_LINK_LIBRARIES(tsdb tfs common tutil) +TARGET_LINK_LIBRARIES(tsdb tfs common tutil cJson) IF (TD_TSDB_PLUGINS) TARGET_LINK_LIBRARIES(tsdb tsdbPlugins) diff --git a/src/tsdb/inc/tsdbMeta.h b/src/tsdb/inc/tsdbMeta.h index 0b7af561cda8d9c37201f99c7ab467b4e1598d37..9cdb8a83aa266d04d91e07d515f0acb56703f880 100644 --- a/src/tsdb/inc/tsdbMeta.h +++ b/src/tsdb/inc/tsdbMeta.h @@ -18,6 +18,14 @@ #define TSDB_MAX_TABLE_SCHEMAS 16 +#pragma pack (push,1) +typedef struct jsonMapValue{ + void* table; // STable * + int16_t colId; // the json col ID. +}JsonMapValue; + +#pragma pack (pop) + typedef struct STable { STableId tableId; ETableType type; @@ -28,6 +36,7 @@ typedef struct STable { STSchema* tagSchema; SKVRow tagVal; SSkipList* pIndex; // For TSDB_SUPER_TABLE, it is the skiplist index + SHashObj* jsonKeyMap; // For json tag key {"key":[t1, t2, t3]} void* eventHandler; // TODO void* streamHandler; // TODO TSKEY lastKey; @@ -89,6 +98,8 @@ int16_t tsdbGetLastColumnsIndexByColId(STable* pTable, int16_t colId); int tsdbUpdateLastColSchema(STable *pTable, STSchema *pNewSchema); STSchema* tsdbGetTableLatestSchema(STable *pTable); void tsdbFreeLastColumns(STable* pTable); +int tsdbCompareJsonMapValue(const void* a, const void* b); +void* tsdbGetJsonTagValue(STable* pTable, char* key, int32_t keyLen, int16_t* colId); static FORCE_INLINE int tsdbCompareSchemaVersion(const void *key1, const void *key2) { if (*(int16_t *)key1 < schemaVersion(*(STSchema **)key2)) { diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c index 1bb9733970cf6730366adda7f89ec5f09577df92..18225ab70cde20ab2d18c80b5327bd24be3827df 100644 --- a/src/tsdb/src/tsdbMeta.c +++ b/src/tsdb/src/tsdbMeta.c @@ -13,6 +13,8 @@ * along with this program. If not, see . */ #include "tsdbint.h" +#include "tcompare.h" +#include "tutil.h" #define TSDB_SUPER_TABLE_SL_LEVEL 5 #define DEFAULT_TAG_INDEX_COLUMN 0 @@ -118,11 +120,13 @@ int tsdbCreateTable(STsdbRepo *repo, STableCfg *pCfg) { tsdbWLockRepoMeta(pRepo); if (newSuper) { if (tsdbAddTableToMeta(pRepo, super, true, false) < 0) { + super = NULL; tsdbUnlockRepoMeta(pRepo); goto _err; } } if (tsdbAddTableToMeta(pRepo, table, true, false) < 0) { + table = NULL; tsdbUnlockRepoMeta(pRepo); goto _err; } @@ -200,7 +204,7 @@ _err: return -1; } -void *tsdbGetTableTagVal(const void* pTable, int32_t colId, int16_t type, int16_t bytes) { +void *tsdbGetTableTagVal(const void* pTable, int32_t colId, int16_t type) { // TODO: this function should be changed also STSchema *pSchema = tsdbGetTableTagSchema((STable*) pTable); @@ -209,12 +213,13 @@ void *tsdbGetTableTagVal(const void* pTable, int32_t colId, int16_t type, int16_ return NULL; // No matched tag volumn } - char *val = tdGetKVRowValOfCol(((STable*)pTable)->tagVal, colId); - assert(type == pCol->type); - - // if (val != NULL && IS_VAR_DATA_TYPE(type)) { - // assert(varDataLen(val) < pCol->bytes); - // } + char *val = NULL; + if (pCol->type == TSDB_DATA_TYPE_JSON){ + val = ((STable*)pTable)->tagVal; + }else{ + val = tdGetKVRowValOfCol(((STable*)pTable)->tagVal, colId); + assert(type == pCol->type); + } return val; } @@ -388,7 +393,8 @@ int tsdbUpdateTableTagValue(STsdbRepo *repo, SUpdateTableTagValMsg *pMsg) { TSDB_WUNLOCK_TABLE(pTable->pSuper); } - bool isChangeIndexCol = (pMsg->colId == colColId(schemaColAt(pTable->pSuper->tagSchema, 0))); + bool isChangeIndexCol = (pMsg->colId == colColId(schemaColAt(pTable->pSuper->tagSchema, 0))) + || pMsg->type == TSDB_DATA_TYPE_JSON; // STColumn *pCol = bsearch(&(pMsg->colId), pMsg->data, pMsg->numOfTags, sizeof(STColumn), colIdCompar); // ASSERT(pCol != NULL); @@ -397,7 +403,12 @@ int tsdbUpdateTableTagValue(STsdbRepo *repo, SUpdateTableTagValMsg *pMsg) { tsdbRemoveTableFromIndex(pMeta, pTable); } TSDB_WLOCK_TABLE(pTable); - tdSetKVRowDataOfCol(&(pTable->tagVal), pMsg->colId, pMsg->type, POINTER_SHIFT(pMsg->data, pMsg->schemaLen)); + if (pMsg->type == TSDB_DATA_TYPE_JSON){ + kvRowFree(pTable->tagVal); + pTable->tagVal = tdKVRowDup(POINTER_SHIFT(pMsg->data, pMsg->schemaLen)); + }else{ + tdSetKVRowDataOfCol(&(pTable->tagVal), pMsg->colId, pMsg->type, POINTER_SHIFT(pMsg->data, pMsg->schemaLen)); + } TSDB_WUNLOCK_TABLE(pTable); if (isChangeIndexCol) { tsdbAddTableIntoIndex(pMeta, pTable, false); @@ -850,11 +861,22 @@ static STable *tsdbCreateTableFromCfg(STableCfg *pCfg, bool isSuper, STable *pST } pTable->tagVal = NULL; STColumn *pCol = schemaColAt(pTable->tagSchema, DEFAULT_TAG_INDEX_COLUMN); - pTable->pIndex = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, colType(pCol), (uint8_t)(colBytes(pCol)), NULL, - SL_ALLOW_DUP_KEY, getTagIndexKey); - if (pTable->pIndex == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; + if(pCol->type == TSDB_DATA_TYPE_JSON){ + assert(pTable->tagSchema->numOfCols == 1); + pTable->jsonKeyMap = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + if (pTable->jsonKeyMap == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + tsdbFreeTable(pTable); + return NULL; + } + taosHashSetFreeFp(pTable->jsonKeyMap, taosArrayDestroyForHash); + }else{ + pTable->pIndex = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, colType(pCol), (uint8_t)(colBytes(pCol)), NULL, + SL_ALLOW_DUP_KEY, getTagIndexKey); + if (pTable->pIndex == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + goto _err; + } } } else { pTable->type = pCfg->type; @@ -924,6 +946,7 @@ static void tsdbFreeTable(STable *pTable) { kvRowFree(pTable->tagVal); tSkipListDestroy(pTable->pIndex); + taosHashCleanup(pTable->jsonKeyMap); taosTZfree(pTable->lastRow); tfree(pTable->sql); @@ -1048,16 +1071,92 @@ static void tsdbRemoveTableFromMeta(STsdbRepo *pRepo, STable *pTable, bool rmFro tsdbUnRefTable(pTable); } +void* tsdbGetJsonTagValue(STable* pTable, char* key, int32_t keyLen, int16_t* retColId){ + assert(TABLE_TYPE(pTable) == TSDB_CHILD_TABLE); + STable* superTable= pTable->pSuper; + SArray** data = (SArray**)taosHashGet(superTable->jsonKeyMap, key, keyLen); + if(data == NULL) return NULL; + JsonMapValue jmvalue = {pTable, 0}; + JsonMapValue* p = taosArraySearch(*data, &jmvalue, tsdbCompareJsonMapValue, TD_EQ); + if (p == NULL) return NULL; + int16_t colId = p->colId + 1; + if(retColId) *retColId = p->colId; + return tdGetKVRowValOfCol(pTable->tagVal, colId); +} + +int tsdbCompareJsonMapValue(const void* a, const void* b) { + const JsonMapValue* x = (const JsonMapValue*)a; + const JsonMapValue* y = (const JsonMapValue*)b; + if (x->table > y->table) return 1; + if (x->table < y->table) return -1; + return 0; +} + static int tsdbAddTableIntoIndex(STsdbMeta *pMeta, STable *pTable, bool refSuper) { ASSERT(pTable->type == TSDB_CHILD_TABLE && pTable != NULL); STable *pSTable = tsdbGetTableByUid(pMeta, TABLE_SUID(pTable)); ASSERT(pSTable != NULL); pTable->pSuper = pSTable; + if (refSuper) T_REF_INC(pSTable); - tSkipListPut(pSTable->pIndex, (void *)pTable); + if(pSTable->tagSchema->columns[0].type == TSDB_DATA_TYPE_JSON){ + ASSERT(pSTable->tagSchema->numOfCols == 1); + int16_t nCols = kvRowNCols(pTable->tagVal); + ASSERT(nCols%2 == 1); + // check first + for (int j = 0; j < nCols; ++j) { + if (j != 0 && j % 2 == 0) continue; // jump value + SColIdx *pColIdx = kvRowColIdxAt(pTable->tagVal, j); + void *val = (kvRowColVal(pTable->tagVal, pColIdx)); + if (j == 0) { // json value is the first + int8_t jsonPlaceHolder = *(int8_t *)val; + ASSERT(jsonPlaceHolder == TSDB_DATA_JSON_PLACEHOLDER); + continue; + } + if (j == 1) { + uint32_t jsonNULL = *(uint32_t *)(varDataVal(val)); + ASSERT(jsonNULL == TSDB_DATA_JSON_NULL); + } + + // then insert + char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0}; + jsonKeyMd5(varDataVal(val), varDataLen(val), keyMd5); + SArray *tablistNew = NULL; + SArray **tablist = (SArray **)taosHashGet(pSTable->jsonKeyMap, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN); + if (tablist == NULL) { + tablistNew = taosArrayInit(8, sizeof(JsonMapValue)); + if (tablistNew == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + tsdbError("out of memory when alloc json tag array"); + return -1; + } + if (taosHashPut(pSTable->jsonKeyMap, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN, &tablistNew, sizeof(void *)) < 0) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + tsdbError("out of memory when put json tag array"); + return -1; + } + } else { + tablistNew = *tablist; + } + + JsonMapValue jmvalue = {pTable, pColIdx->colId}; + void* p = taosArraySearch(tablistNew, &jmvalue, tsdbCompareJsonMapValue, TD_EQ); + if (p == NULL) { + p = taosArraySearch(tablistNew, &jmvalue, tsdbCompareJsonMapValue, TD_GE); + if(p == NULL){ + taosArrayPush(tablistNew, &jmvalue); + }else{ + taosArrayInsert(tablistNew, TARRAY_ELEM_IDX(tablistNew, p), &jmvalue); + } + }else{ + tsdbError("insert dumplicate"); + } + } + }else{ + tSkipListPut(pSTable->pIndex, (void *)pTable); + } - if (refSuper) T_REF_INC(pSTable); return 0; } @@ -1067,22 +1166,58 @@ static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable) { STable *pSTable = pTable->pSuper; ASSERT(pSTable != NULL); - char* key = getTagIndexKey(pTable); - SArray *res = tSkipListGet(pSTable->pIndex, key); + if(pSTable->tagSchema->columns[0].type == TSDB_DATA_TYPE_JSON){ + ASSERT(pSTable->tagSchema->numOfCols == 1); + int16_t nCols = kvRowNCols(pTable->tagVal); + ASSERT(nCols%2 == 1); + for (int j = 0; j < nCols; ++j) { + if (j != 0 && j%2 == 0) continue; // jump value + SColIdx * pColIdx = kvRowColIdxAt(pTable->tagVal, j); + void* val = (kvRowColVal(pTable->tagVal, pColIdx)); + if (j == 0){ // json value is the first + int8_t jsonPlaceHolder = *(int8_t*)val; + ASSERT(jsonPlaceHolder == TSDB_DATA_JSON_PLACEHOLDER); + continue; + } + if (j == 1){ + uint32_t jsonNULL = *(uint32_t*)(varDataVal(val)); + ASSERT(jsonNULL == TSDB_DATA_JSON_NULL); + } + + char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0}; + jsonKeyMd5(varDataVal(val), varDataLen(val), keyMd5); + SArray** tablist = (SArray **)taosHashGet(pSTable->jsonKeyMap, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN); + if(tablist == NULL) { + tsdbError("json tag no key error,%d", j); + continue; + } - size_t size = taosArrayGetSize(res); - ASSERT(size > 0); + JsonMapValue jmvalue = {pTable, pColIdx->colId}; + void* p = taosArraySearch(*tablist, &jmvalue, tsdbCompareJsonMapValue, TD_EQ); + if (p == NULL) { + tsdbError("json tag no tableid error,%d", j); + continue; + } + taosArrayRemove(*tablist, TARRAY_ELEM_IDX(*tablist, p)); + } + }else { + char * key = getTagIndexKey(pTable); + SArray *res = tSkipListGet(pSTable->pIndex, key); - for (int32_t i = 0; i < size; ++i) { - SSkipListNode *pNode = taosArrayGetP(res, i); + size_t size = taosArrayGetSize(res); + ASSERT(size > 0); - // STableIndexElem* pElem = (STableIndexElem*) SL_GET_NODE_DATA(pNode); - if ((STable *)SL_GET_NODE_DATA(pNode) == pTable) { // this is the exact what we need - tSkipListRemoveNode(pSTable->pIndex, pNode); + for (int32_t i = 0; i < size; ++i) { + SSkipListNode *pNode = taosArrayGetP(res, i); + + // STableIndexElem* pElem = (STableIndexElem*) SL_GET_NODE_DATA(pNode); + if ((STable *)SL_GET_NODE_DATA(pNode) == pTable) { // this is the exact what we need + tSkipListRemoveNode(pSTable->pIndex, pNode); + } } - } - taosArrayDestroy(res); + taosArrayDestroy(res); + } return 0; } @@ -1320,12 +1455,22 @@ static void *tsdbDecodeTable(void *buf, STable **pRTable) { if (TABLE_TYPE(pTable) == TSDB_SUPER_TABLE) { buf = tdDecodeSchema(buf, &(pTable->tagSchema)); STColumn *pCol = schemaColAt(pTable->tagSchema, DEFAULT_TAG_INDEX_COLUMN); - pTable->pIndex = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, colType(pCol), (uint8_t)(colBytes(pCol)), NULL, + if(pCol->type == TSDB_DATA_TYPE_JSON){ + assert(pTable->tagSchema->numOfCols == 1); + pTable->jsonKeyMap = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + if (pTable->jsonKeyMap == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + tsdbFreeTable(pTable); + return NULL; + } + }else{ + pTable->pIndex = tSkipListCreate(TSDB_SUPER_TABLE_SL_LEVEL, colType(pCol), (uint8_t)(colBytes(pCol)), NULL, SL_ALLOW_DUP_KEY, getTagIndexKey); - if (pTable->pIndex == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - tsdbFreeTable(pTable); - return NULL; + if (pTable->pIndex == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + tsdbFreeTable(pTable); + return NULL; + } } } @@ -1341,13 +1486,29 @@ static void *tsdbDecodeTable(void *buf, STable **pRTable) { return buf; } +static SArray* getJsonTagTableList(STable *pTable){ + uint32_t key = TSDB_DATA_JSON_NULL; + char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0}; + jsonKeyMd5(&key, INT_BYTES, keyMd5); + SArray** tablist = (SArray**)taosHashGet(pTable->jsonKeyMap, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN); + + return *tablist; +} + static int tsdbGetTableEncodeSize(int8_t act, STable *pTable) { int tlen = 0; if (act == TSDB_UPDATE_META) { tlen = sizeof(SListNode) + sizeof(SActObj) + sizeof(SActCont) + tsdbEncodeTable(NULL, pTable) + sizeof(TSCKSUM); } else { if (TABLE_TYPE(pTable) == TSDB_SUPER_TABLE) { - tlen = (int)((sizeof(SListNode) + sizeof(SActObj)) * (SL_SIZE(pTable->pIndex) + 1)); + size_t tableSize = 0; + if(pTable->tagSchema->columns[0].type == TSDB_DATA_TYPE_JSON){ + SArray* tablist = getJsonTagTableList(pTable); + tableSize = taosArrayGetSize(tablist); + }else{ + tableSize = SL_SIZE(pTable->pIndex); + } + tlen = (int)((sizeof(SListNode) + sizeof(SActObj)) * (tableSize + 1)); } else { tlen = sizeof(SListNode) + sizeof(SActObj); } @@ -1387,19 +1548,28 @@ static int tsdbRemoveTableFromStore(STsdbRepo *pRepo, STable *pTable) { void *pBuf = buf; if (TABLE_TYPE(pTable) == TSDB_SUPER_TABLE) { - SSkipListIterator *pIter = tSkipListCreateIter(pTable->pIndex); - if (pIter == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } + if(pTable->tagSchema->columns[0].type == TSDB_DATA_TYPE_JSON){ + SArray* tablist = getJsonTagTableList(pTable); + for (int i = 0; i < taosArrayGetSize(tablist); ++i) { + JsonMapValue* p = taosArrayGet(tablist, i); + ASSERT(TABLE_TYPE((STable *)(p->table)) == TSDB_CHILD_TABLE); + pBuf = tsdbInsertTableAct(pRepo, TSDB_DROP_META, pBuf, p->table); + } + }else { + SSkipListIterator *pIter = tSkipListCreateIter(pTable->pIndex); + if (pIter == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + return -1; + } - while (tSkipListIterNext(pIter)) { - STable *tTable = (STable *)SL_GET_NODE_DATA(tSkipListIterGet(pIter)); - ASSERT(TABLE_TYPE(tTable) == TSDB_CHILD_TABLE); - pBuf = tsdbInsertTableAct(pRepo, TSDB_DROP_META, pBuf, tTable); - } + while (tSkipListIterNext(pIter)) { + STable *tTable = (STable *)SL_GET_NODE_DATA(tSkipListIterGet(pIter)); + ASSERT(TABLE_TYPE(tTable) == TSDB_CHILD_TABLE); + pBuf = tsdbInsertTableAct(pRepo, TSDB_DROP_META, pBuf, tTable); + } - tSkipListDestroyIter(pIter); + tSkipListDestroyIter(pIter); + } } pBuf = tsdbInsertTableAct(pRepo, TSDB_DROP_META, pBuf, pTable); @@ -1410,25 +1580,27 @@ static int tsdbRemoveTableFromStore(STsdbRepo *pRepo, STable *pTable) { static int tsdbRmTableFromMeta(STsdbRepo *pRepo, STable *pTable) { if (TABLE_TYPE(pTable) == TSDB_SUPER_TABLE) { - SSkipListIterator *pIter = tSkipListCreateIter(pTable->pIndex); - if (pIter == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } - tsdbWLockRepoMeta(pRepo); - - while (tSkipListIterNext(pIter)) { - STable *tTable = (STable *)SL_GET_NODE_DATA(tSkipListIterGet(pIter)); - tsdbRemoveTableFromMeta(pRepo, tTable, false, false); + if(pTable->tagSchema->columns[0].type == TSDB_DATA_TYPE_JSON){ + SArray* tablist = getJsonTagTableList(pTable); + for (int i = 0; i < taosArrayGetSize(tablist); ++i) { + JsonMapValue* p = taosArrayGet(tablist, i); + tsdbRemoveTableFromMeta(pRepo, p->table, false, false); + } + }else{ + SSkipListIterator *pIter = tSkipListCreateIter(pTable->pIndex); + if (pIter == NULL) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + return -1; + } + while (tSkipListIterNext(pIter)) { + STable *tTable = (STable *)SL_GET_NODE_DATA(tSkipListIterGet(pIter)); + tsdbRemoveTableFromMeta(pRepo, tTable, false, false); + } + tSkipListDestroyIter(pIter); } - tsdbRemoveTableFromMeta(pRepo, pTable, false, false); - tsdbUnlockRepoMeta(pRepo); - - tSkipListDestroyIter(pIter); - } else { if ((TABLE_TYPE(pTable) == TSDB_STREAM_TABLE) && pTable->cqhandle) pRepo->appH.cqDropFunc(pTable->cqhandle); tsdbRemoveTableFromMeta(pRepo, pTable, true, true); @@ -1511,3 +1683,4 @@ static void tsdbFreeTableSchema(STable *pTable) { taosArrayDestroy(pTable->schema); } } + diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 9b138bbd02b7a88b9bdaddcafbc2d2290d5c3d2e..ca38d10d59348f6f2b9b7d1150d7f21d7bc1a3de 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -26,6 +26,7 @@ #include "tsdbint.h" #include "texpr.h" #include "qFilter.h" +#include "cJSON.h" #define EXTRA_BYTES 2 #define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC) @@ -2673,17 +2674,31 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int } static int32_t getAllTableList(STable* pSuperTable, SArray* list) { - SSkipListIterator* iter = tSkipListCreateIter(pSuperTable->pIndex); - while (tSkipListIterNext(iter)) { - SSkipListNode* pNode = tSkipListIterGet(iter); + STSchema* pTagSchema = tsdbGetTableTagSchema(pSuperTable); + if(pTagSchema && pTagSchema->numOfCols == 1 && pTagSchema->columns[0].type == TSDB_DATA_TYPE_JSON){ + uint32_t key = TSDB_DATA_JSON_NULL; + char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0}; + jsonKeyMd5(&key, INT_BYTES, keyMd5); + SArray** tablist = (SArray**)taosHashGet(pSuperTable->jsonKeyMap, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN); + + for (int i = 0; i < taosArrayGetSize(*tablist); ++i) { + JsonMapValue* p = taosArrayGet(*tablist, i); + STableKeyInfo info = {.pTable = p->table, .lastKey = TSKEY_INITIAL_VAL}; + taosArrayPush(list, &info); + } + }else{ + SSkipListIterator* iter = tSkipListCreateIter(pSuperTable->pIndex); + while (tSkipListIterNext(iter)) { + SSkipListNode* pNode = tSkipListIterGet(iter); - STable* pTable = (STable*) SL_GET_NODE_DATA((SSkipListNode*) pNode); + STable* pTable = (STable*) SL_GET_NODE_DATA((SSkipListNode*) pNode); - STableKeyInfo info = {.pTable = pTable, .lastKey = TSKEY_INITIAL_VAL}; - taosArrayPush(list, &info); - } + STableKeyInfo info = {.pTable = pTable, .lastKey = TSKEY_INITIAL_VAL}; + taosArrayPush(list, &info); + } - tSkipListDestroyIter(iter); + tSkipListDestroyIter(iter); + } return TSDB_CODE_SUCCESS; } @@ -3543,8 +3558,13 @@ static int32_t tableGroupComparFn(const void *p1, const void *p2, const void *pa STColumn* pCol = schemaColAt(pTableGroupSupp->pTagSchema, colIndex); bytes = pCol->bytes; type = pCol->type; - f1 = tdGetKVRowValOfCol(pTable1->tagVal, pCol->colId); - f2 = tdGetKVRowValOfCol(pTable2->tagVal, pCol->colId); + if (type == TSDB_DATA_TYPE_JSON){ + f1 = getJsonTagValueElment(pTable1, pColIndex->name, (int32_t)strlen(pColIndex->name), NULL, TSDB_MAX_JSON_TAGS_LEN); + f2 = getJsonTagValueElment(pTable2, pColIndex->name, (int32_t)strlen(pColIndex->name), NULL, TSDB_MAX_JSON_TAGS_LEN); + }else{ + f1 = tdGetKVRowValOfCol(pTable1->tagVal, pCol->colId); + f2 = tdGetKVRowValOfCol(pTable2->tagVal, pCol->colId); + } } } @@ -3660,6 +3680,7 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, const char* pTagCond, size_t len, STableGroupInfo* pGroupInfo, SColIndex* pColIndex, int32_t numOfCols) { + SArray* res = NULL; if (tsdbRLockRepoMeta(tsdb) < 0) goto _error; STable* pTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid); @@ -3681,7 +3702,7 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons } //NOTE: not add ref count for super table - SArray* res = taosArrayInit(8, sizeof(STableKeyInfo)); + res = taosArrayInit(8, sizeof(STableKeyInfo)); STSchema* pTagSchema = tsdbGetTableTagSchema(pTable); // no tags and tbname condition, all child tables of this stable are involved @@ -3719,20 +3740,28 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons // TODO: more error handling } END_TRY - void *filterInfo = NULL; - + void *filterInfo = calloc(1, sizeof(SFilterInfo)); + ((SFilterInfo*)filterInfo)->pTable = pTable; ret = filterInitFromTree(expr, &filterInfo, 0); + tExprTreeDestroy(expr, NULL); + if (ret != TSDB_CODE_SUCCESS) { terrno = ret; + tsdbUnlockRepoMeta(tsdb); + filterFreeInfo(filterInfo); goto _error; } - tsdbQueryTableList(pTable, res, filterInfo); + ret = tsdbQueryTableList(pTable, res, filterInfo); + if (ret != TSDB_CODE_SUCCESS) { + terrno = ret; + tsdbUnlockRepoMeta(tsdb); + filterFreeInfo(filterInfo); + goto _error; + } filterFreeInfo(filterInfo); - tExprTreeDestroy(expr, NULL); - pGroupInfo->numOfTables = (uint32_t)taosArrayGetSize(res); pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols, skey); @@ -3745,6 +3774,8 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons return ret; _error: + + taosArrayDestroy(res); return terrno; } @@ -4009,22 +4040,257 @@ static void queryIndexlessColumn(SSkipList* pSkipList, void* filterInfo, SArray* tSkipListDestroyIter(iter); } +static FORCE_INLINE int32_t tsdbGetJsonTagDataFromId(void *param, int32_t id, char* name, void **data) { + JsonMapValue* jsonMapV = (JsonMapValue*)(param); + STable* pTable = (STable*)(jsonMapV->table); + + if (id == TSDB_TBNAME_COLUMN_INDEX) { + *data = TABLE_NAME(pTable); + } else { + void* jsonData = tsdbGetJsonTagValue(pTable, name, TSDB_MAX_JSON_KEY_MD5_LEN, NULL); + // jsonData == NULL for ? operation + // if(jsonData != NULL) jsonData += CHAR_BYTES; // jump type + *data = jsonData; + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t queryByJsonTag(STable* pTable, void* filterInfo, SArray* res){ + // get all table in fields, and dumplicate it + SArray* tabList = NULL; + bool needQueryAll = false; + SFilterInfo* info = (SFilterInfo*)filterInfo; + 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; + if (sch->colId == TSDB_TBNAME_COLUMN_INDEX) { + tabList = taosArrayInit(32, sizeof(JsonMapValue)); + getAllTableList(pTable, tabList); // query all table + needQueryAll = true; + break; + } + } + for (uint16_t i = 0; i < info->unitNum; ++i) { // is null operation need query all table + SFilterUnit* unit = &info->units[i]; + if (unit->compare.optr == TSDB_RELATION_ISNULL) { + tabList = taosArrayInit(32, sizeof(JsonMapValue)); + getAllTableList(pTable, tabList); // query all table + needQueryAll = true; + break; + } + } + + for (uint16_t i = 0; i < info->fields[FLD_TYPE_COLUMN].num; ++i) { + if (needQueryAll) break; // query all table + SFilterField* fi = &info->fields[FLD_TYPE_COLUMN].fields[i]; + SSchema* sch = fi->desc; + char* key = sch->name; + + SArray** data = (SArray**)taosHashGet(pTable->jsonKeyMap, key, TSDB_MAX_JSON_KEY_MD5_LEN); + if(data == NULL) continue; + if(tabList == NULL) { + tabList = taosArrayDup(*data); + }else{ + for(int j = 0; j < taosArrayGetSize(*data); j++){ + void* element = taosArrayGet(*data, j); + void* p = taosArraySearch(tabList, element, tsdbCompareJsonMapValue, TD_EQ); + if (p == NULL) { + p = taosArraySearch(tabList, element, tsdbCompareJsonMapValue, TD_GE); + if(p == NULL){ + taosArrayPush(tabList, element); + }else{ + taosArrayInsert(tabList, TARRAY_ELEM_IDX(tabList, p), element); + } + } + } + } + } + if(tabList == NULL){ + tsdbError("json key not exist, no candidate table"); + return TSDB_CODE_SUCCESS; + } + size_t size = taosArrayGetSize(tabList); + int8_t *addToResult = NULL; + for(int i = 0; i < size; i++){ + JsonMapValue* data = taosArrayGet(tabList, i); + filterSetJsonColFieldData(filterInfo, data, tsdbGetJsonTagDataFromId); + bool all = filterExecute(filterInfo, 1, &addToResult, NULL, 0); + + if (all || (addToResult && *addToResult)) { + STableKeyInfo kInfo = {.pTable = (void*)(data->table), .lastKey = TSKEY_INITIAL_VAL}; + taosArrayPush(res, &kInfo); + } + } + tfree(addToResult); + taosArrayDestroy(tabList); + return TSDB_CODE_SUCCESS; +} static int32_t tsdbQueryTableList(STable* pTable, SArray* pRes, void* filterInfo) { STSchema* pTSSchema = pTable->tagSchema; - bool indexQuery = false; - SSkipList *pSkipList = pTable->pIndex; - filterIsIndexedColumnQuery(filterInfo, pTSSchema->columns->colId, &indexQuery); + if(pTSSchema->columns->type == TSDB_DATA_TYPE_JSON){ + return queryByJsonTag(pTable, filterInfo, pRes); + }else{ + bool indexQuery = false; + SSkipList *pSkipList = pTable->pIndex; - if (indexQuery) { - queryIndexedColumn(pSkipList, filterInfo, pRes); - } else { - queryIndexlessColumn(pSkipList, filterInfo, pRes); + filterIsIndexedColumnQuery(filterInfo, pTSSchema->columns->colId, &indexQuery); + + if (indexQuery) { + queryIndexedColumn(pSkipList, filterInfo, pRes); + } else { + queryIndexlessColumn(pSkipList, filterInfo, pRes); + } } return TSDB_CODE_SUCCESS; } +void* getJsonTagValueElment(void* data, char* key, int32_t keyLen, char* dst, int16_t bytes){ + char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0}; + jsonKeyMd5(key, keyLen, keyMd5); + + void* result = tsdbGetJsonTagValue(data, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN, NULL); + if (result == NULL){ // json key no result + if(!dst) return NULL; + *dst = TSDB_DATA_TYPE_JSON; + setNull(dst + CHAR_BYTES, TSDB_DATA_TYPE_JSON, 0); + return dst; + } + + char* realData = POINTER_SHIFT(result, CHAR_BYTES); + if(*(char*)result == TSDB_DATA_TYPE_NCHAR || *(char*)result == TSDB_DATA_TYPE_BINARY) { + assert(varDataTLen(realData) < bytes); + if(!dst) return result; + memcpy(dst, result, CHAR_BYTES + varDataTLen(realData)); + return dst; + }else if (*(char*)result == TSDB_DATA_TYPE_DOUBLE || *(char*)result == TSDB_DATA_TYPE_BIGINT) { + if(!dst) return result; + memcpy(dst, result, CHAR_BYTES + LONG_BYTES); + return dst; + }else if (*(char*)result == TSDB_DATA_TYPE_BOOL) { + if(!dst) return result; + memcpy(dst, result, CHAR_BYTES + CHAR_BYTES); + return dst; + }else { + assert(0); + } + return result; +} + +void getJsonTagValueAll(void* data, void* dst, int16_t bytes) { + char* json = parseTagDatatoJson(data); + char* tagData = POINTER_SHIFT(dst, CHAR_BYTES); + *(char*)dst = TSDB_DATA_TYPE_JSON; + if(json == NULL){ + setNull(tagData, TSDB_DATA_TYPE_JSON, 0); + return; + } + + int32_t length = 0; + if(!taosMbsToUcs4(json, strlen(json), varDataVal(tagData), bytes - VARSTR_HEADER_SIZE - CHAR_BYTES, &length)){ + tsdbError("getJsonTagValueAll mbstoucs4 error! length:%d", length); + } + varDataSetLen(tagData, length); + assert(varDataTLen(tagData) <= bytes); + tfree(json); +} + +char* parseTagDatatoJson(void *p){ + char* string = NULL; + cJSON *json = cJSON_CreateObject(); + if (json == NULL) + { + goto end; + } + + int16_t nCols = kvRowNCols(p); + ASSERT(nCols%2 == 1); + char tagJsonKey[TSDB_MAX_JSON_KEY_LEN + 1] = {0}; + for (int j = 0; j < nCols; ++j) { + SColIdx * pColIdx = kvRowColIdxAt(p, j); + void* val = (kvRowColVal(p, pColIdx)); + if (j == 0){ + int8_t jsonPlaceHolder = *(int8_t*)val; + ASSERT(jsonPlaceHolder == TSDB_DATA_JSON_PLACEHOLDER); + continue; + } + if(j == 1){ + uint32_t jsonNULL = *(uint32_t*)(varDataVal(val)); + ASSERT(jsonNULL == TSDB_DATA_JSON_NULL); + continue; + } + if (j == 2){ + if(*(uint32_t*)(varDataVal(val + CHAR_BYTES)) == TSDB_DATA_JSON_NULL) goto end; + continue; + } + if (j%2 == 1) { // json key encode by binary + ASSERT(varDataLen(val) <= TSDB_MAX_JSON_KEY_LEN); + memset(tagJsonKey, 0, sizeof(tagJsonKey)); + memcpy(tagJsonKey, varDataVal(val), varDataLen(val)); + }else{ // json value + char tagJsonValue[TSDB_MAX_JSON_TAGS_LEN] = {0}; + char* realData = POINTER_SHIFT(val, CHAR_BYTES); + char type = *(char*)val; + if(type == TSDB_DATA_TYPE_BINARY) { + assert(*(uint32_t*)varDataVal(realData) == TSDB_DATA_JSON_null); // json null value + assert(varDataLen(realData) == INT_BYTES); + cJSON* value = cJSON_CreateNull(); + if (value == NULL) + { + goto end; + } + cJSON_AddItemToObject(json, tagJsonKey, value); + }else if(type == TSDB_DATA_TYPE_NCHAR) { + int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), tagJsonValue); + if (length < 0) { + tsdbError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, + (char*)val); + goto end; + } + cJSON* value = cJSON_CreateString(tagJsonValue); + + if (value == NULL) + { + goto end; + } + cJSON_AddItemToObject(json, tagJsonKey, value); + }else if(type == TSDB_DATA_TYPE_DOUBLE){ + double jsonVd = *(double*)(realData); + cJSON* value = cJSON_CreateNumber(jsonVd); + if (value == NULL) + { + goto end; + } + cJSON_AddItemToObject(json, tagJsonKey, value); + }else if(type == TSDB_DATA_TYPE_BIGINT){ + int64_t jsonVd = *(int64_t*)(realData); + cJSON* value = cJSON_CreateNumber((double)jsonVd); + if (value == NULL) + { + goto end; + } + cJSON_AddItemToObject(json, tagJsonKey, value); + }else if (type == TSDB_DATA_TYPE_BOOL) { + char jsonVd = *(char*)(realData); + cJSON* value = cJSON_CreateBool(jsonVd); + if (value == NULL) + { + goto end; + } + cJSON_AddItemToObject(json, tagJsonKey, value); + } + else{ + tsdbError("unsupportted json value"); + } + } + } + string = cJSON_PrintUnformatted(json); +end: + cJSON_Delete(json); + return string; +} diff --git a/src/util/inc/hash.h b/src/util/inc/hash.h index 2a4cbec4dd1fa5d227e181b07ce103c14120a12b..d41c579a58dd149172ee42c94e97b72ab5687548 100644 --- a/src/util/inc/hash.h +++ b/src/util/inc/hash.h @@ -88,6 +88,8 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTyp */ void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp); +void taosHashSetFreeFp(SHashObj *pHashObj, _hash_free_fn_t fp); + /** * return the size of hash table * @param pHashObj diff --git a/src/util/inc/tarray.h b/src/util/inc/tarray.h index 2da74eac820e28206cb3e2b7cb6f2c4fb9f481b8..5587b283a47af6b3ee8b38f1f69e95f4d6f7623b 100644 --- a/src/util/inc/tarray.h +++ b/src/util/inc/tarray.h @@ -178,6 +178,12 @@ void taosArrayClear(SArray* pArray); */ void* taosArrayDestroy(SArray* pArray); +/** + * destroy array list for hash + * @param pArray + */ +void taosArrayDestroyForHash(void* para); + /** * * @param pArray diff --git a/src/util/inc/tcompare.h b/src/util/inc/tcompare.h index 1125516d34c65da1b5d0c47dadd126aa0b1959fa..be62ce0a659d0e07d904cac4f994b4639cd18917 100644 --- a/src/util/inc/tcompare.h +++ b/src/util/inc/tcompare.h @@ -88,6 +88,9 @@ int32_t compareStrRegexCompMatch(const void* pLeft, const void* pRight); int32_t compareStrRegexCompNMatch(const void* pLeft, const void* pRight); int32_t compareFindItemInSet(const void *pLeft, const void* pRight); int32_t compareWStrPatternComp(const void* pLeft, const void* pRight); +int32_t compareStrContainJson(const void* pLeft, const void* pRight); +int32_t compareJsonVal(const void* pLeft, const void* pRight); +int32_t jsonCompareUnit(const char* f1, const char* f2, bool* canReturn); #ifdef __cplusplus } diff --git a/src/util/inc/tutil.h b/src/util/inc/tutil.h index 4443716bca3ea280f50eb0402034dc60ee8b5dc8..dd943e8cc45837c814680c9e63b720ddc0c80010 100644 --- a/src/util/inc/tutil.h +++ b/src/util/inc/tutil.h @@ -47,6 +47,8 @@ int taosCheckVersion(char *input_client_version, char *input_server_version, in char * taosIpStr(uint32_t ipInt); uint32_t ip2uint(const char *const ip_addr); +void jsonKeyMd5(void *pMsg, int msgLen, void *pKey); +bool isValidateTag(char *input); static FORCE_INLINE void taosEncryptPass(uint8_t *inBuf, size_t inLen, char *target) { MD5_CTX context; diff --git a/src/util/src/hash.c b/src/util/src/hash.c index 00de532a95363dc22104b4cc75256ccde0c96c2a..20aa146893298a5b9c3f5a85498494ed29afff66 100644 --- a/src/util/src/hash.c +++ b/src/util/src/hash.c @@ -203,7 +203,13 @@ void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp) { if (pHashObj != NULL && fp != NULL) { pHashObj->equalFp = fp; } -} +} + +void taosHashSetFreeFp(SHashObj *pHashObj, _hash_free_fn_t fp) { + if (pHashObj != NULL && fp != NULL) { + pHashObj->freeFp = fp; + } +} int32_t taosHashGetSize(const SHashObj *pHashObj) { if (!pHashObj) { @@ -611,7 +617,7 @@ void taosHashCleanup(SHashObj *pHashObj) { taosArrayDestroy(pHashObj->pMemBlock); memset(pHashObj, 0, sizeof(SHashObj)); - free(pHashObj); + tfree(pHashObj); } // for profile only diff --git a/src/util/src/tarray.c b/src/util/src/tarray.c index 007ce0682974d06bf506a82d8bbbc809092eb9e4..812cf65a80e928acf918da7c2b3ab82fd55682d6 100644 --- a/src/util/src/tarray.c +++ b/src/util/src/tarray.c @@ -281,13 +281,26 @@ void taosArrayClear(SArray* pArray) { void* taosArrayDestroy(SArray* pArray) { if (pArray) { - free(pArray->pData); - free(pArray); + tfree(pArray->pData); + tfree(pArray); } return NULL; } +void taosArrayDestroyForHash(void* para) { + SArray** ppArray = (SArray**)para; + if(ppArray == NULL) return; + + SArray* pArray = *ppArray; + if (pArray) { + tfree(pArray->pData); + tfree(pArray); + } + + return; +} + void taosArrayDestroyEx(SArray* pArray, void (*fp)(void*)) { if (pArray == NULL) { return; diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 23bb73ff860a2b0c4bd5a81005089910faa7792a..1cfc0c3873a438699c342a7dd4a4b1a8efd32878 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -18,11 +18,12 @@ #define _DEFAULT_SOURCE #include "tcompare.h" -#include "tulog.h" +#include "tvariant.h" #include "hash.h" -#include "regex.h" #include "os.h" +#include "regex.h" #include "ttype.h" +#include "tulog.h" int32_t setCompareBytes1(const void *pLeft, const void *pRight) { return NULL != taosHashGet((SHashObj *)pRight, pLeft, 1) ? 1 : 0; @@ -218,6 +219,36 @@ int32_t compareLenPrefixedWStrDesc(const void* pLeft, const void* pRight) { return compareLenPrefixedWStr(pRight, pLeft); } +int32_t compareJsonVal(const void *pLeft, const void *pRight) { + const tVariant* right = pRight; + if(right->nType != *(char*)pLeft && !(IS_NUMERIC_TYPE(right->nType) && IS_NUMERIC_TYPE(*(char*)pLeft))) + return TSDB_DATA_JSON_CAN_NOT_COMPARE; + + uint8_t type = *(char*)pLeft; + char* realData = POINTER_SHIFT(pLeft, CHAR_BYTES); + if(type == TSDB_DATA_TYPE_BOOL) { + DEFAULT_COMP(GET_INT8_VAL(realData), right->i64); + }else if(type == TSDB_DATA_TYPE_BIGINT){ + DEFAULT_COMP(GET_INT64_VAL(realData), (right->nType == TSDB_DATA_TYPE_BIGINT) ? right->i64 : right->dKey); + }else if(type == TSDB_DATA_TYPE_DOUBLE){ + DEFAULT_DOUBLE_COMP(GET_DOUBLE_VAL(realData), (right->nType == TSDB_DATA_TYPE_DOUBLE) ? right->dKey : right->i64); + }else if(type == TSDB_DATA_TYPE_NCHAR){ + if (varDataLen(realData) != right->nLen) { + return varDataLen(realData) > right->nLen ? 1 : -1; + } + int32_t ret = memcmp(varDataVal(realData), right->pz, right->nLen); + if (ret == 0) { + return ret; + } + return (ret < 0) ? -1 : 1; + }else if(type == TSDB_DATA_TYPE_BINARY) { //json null + return 0; + }else{ + assert(0); + } + return 0; +} + /* * Compare two strings * TSDB_MATCH: Match @@ -405,6 +436,12 @@ int32_t compareStrRegexComp(const void* pLeft, const void* pRight) { return result; } +int32_t compareStrContainJson(const void* pLeft, const void* pRight) { + if(pLeft) return 0; + return 1; +} + + int32_t taosArrayCompareString(const void* a, const void* b) { const char* x = *(const char**)a; const char* y = *(const char**)b; @@ -487,7 +524,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { break; } - case TSDB_DATA_TYPE_NCHAR: { + case TSDB_DATA_TYPE_NCHAR:{ if (optr == TSDB_RELATION_MATCH) { comparFn = compareStrRegexCompMatch; } else if (optr == TSDB_RELATION_NMATCH) { @@ -501,6 +538,20 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) { } break; } + case TSDB_DATA_TYPE_JSON:{ + if (optr == TSDB_RELATION_MATCH) { + comparFn = compareStrRegexCompMatch; + } else if (optr == TSDB_RELATION_NMATCH) { + comparFn = compareStrRegexCompNMatch; + } else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */ + comparFn = compareWStrPatternComp; + } else if (optr == TSDB_RELATION_CONTAINS) { + comparFn = compareStrContainJson; + } else { + comparFn = compareJsonVal; + } + break; + } case TSDB_DATA_TYPE_UTINYINT: comparFn = compareUint8Val; break; case TSDB_DATA_TYPE_USMALLINT: comparFn = compareUint16Val;break; @@ -565,7 +616,48 @@ __compar_fn_t getKeyComparFunc(int32_t keyType, int32_t order) { return comparFn; } +int32_t jsonCompareUnit(const char* f1, const char* f2, bool* canReturn){ + *canReturn = true; + bool f1IsNull = (*f1 == TSDB_DATA_TYPE_JSON && isNull(f1 + CHAR_BYTES, TSDB_DATA_TYPE_JSON)); + bool f2IsNull = (*f2 == TSDB_DATA_TYPE_JSON && isNull(f2 + CHAR_BYTES, TSDB_DATA_TYPE_JSON)); + if(f1IsNull && f2IsNull){ + return 0; + }else if(f1IsNull && !f2IsNull){ + return -1; + }else if(!f1IsNull && f2IsNull){ + return 1; + }else{ + bool f1IsJsonNull = (*f1 == TSDB_DATA_TYPE_BINARY && *(uint32_t*)varDataVal(f1 + CHAR_BYTES) == TSDB_DATA_JSON_null); + bool f2IsJsonNull = (*f2 == TSDB_DATA_TYPE_BINARY && *(uint32_t*)varDataVal(f2 + CHAR_BYTES) == TSDB_DATA_JSON_null); + if(f1IsJsonNull && f2IsJsonNull){ + return 0; + }else if(f1IsJsonNull && !f2IsJsonNull){ + return -1; + }else if(!f1IsJsonNull && f2IsJsonNull) { + return 1; + } + if(*f1 != *f2 && !(IS_NUMERIC_TYPE(*f1) && IS_NUMERIC_TYPE(*f2))) { + return *f1 > *f2 ? 1 : -1; + } + if(*f1 == TSDB_DATA_TYPE_BIGINT && *f2 == TSDB_DATA_TYPE_DOUBLE){ + DEFAULT_COMP(GET_INT64_VAL(f1 + CHAR_BYTES), GET_DOUBLE_VAL(f2 + CHAR_BYTES)); + }else if(*f1 == TSDB_DATA_TYPE_DOUBLE && *f2 == TSDB_DATA_TYPE_BIGINT){ + DEFAULT_COMP(GET_DOUBLE_VAL(f1 + CHAR_BYTES), GET_INT64_VAL(f2 + CHAR_BYTES)); + } + *canReturn = false; + return 0; // meaningless + } +} + int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) { + if (type == TSDB_DATA_TYPE_JSON){ + bool canReturn = true; + int32_t result = jsonCompareUnit(f1, f2, &canReturn); + if(canReturn) return result; + type = *f1; + f1 += CHAR_BYTES; + f2 += CHAR_BYTES; + } switch (type) { case TSDB_DATA_TYPE_INT: DEFAULT_COMP(GET_INT32_VAL(f1), GET_INT32_VAL(f2)); case TSDB_DATA_TYPE_DOUBLE: DEFAULT_DOUBLE_COMP(GET_DOUBLE_VAL(f1), GET_DOUBLE_VAL(f2)); @@ -578,7 +670,7 @@ int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) { case TSDB_DATA_TYPE_USMALLINT: DEFAULT_COMP(GET_UINT16_VAL(f1), GET_UINT16_VAL(f2)); case TSDB_DATA_TYPE_UINT: DEFAULT_COMP(GET_UINT32_VAL(f1), GET_UINT32_VAL(f2)); case TSDB_DATA_TYPE_UBIGINT: DEFAULT_COMP(GET_UINT64_VAL(f1), GET_UINT64_VAL(f2)); - case TSDB_DATA_TYPE_NCHAR: { + case TSDB_DATA_TYPE_NCHAR:{ tstr* t1 = (tstr*) f1; tstr* t2 = (tstr*) f2; diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 2001cb29a043774e8514220d08893750ab7b285c..3853d2e9c7491db68abf4ca9f7d42edd62da5729 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -282,6 +282,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TDB_MESSED_MSG, "TSDB messed message") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVLD_TAG_VAL, "TSDB invalid tag value") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_CACHE_LAST_ROW, "TSDB no cache last row data") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INCOMPLETE_DFILESET, "Incomplete DFileSet") +TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_JSON_TAG_KEY, "TSDB no tag json key") // query TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_QHANDLE, "Invalid handle") @@ -300,7 +301,6 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INCONSISTAN, "File inconsistance in TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_TIME_CONDITION, "One valid time range condition expected") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_SYS_ERROR, "System error") - // grant TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, "License expired") TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_DNODE_LIMITED, "DNode creation limited by licence") diff --git a/src/util/src/ttokenizer.c b/src/util/src/ttokenizer.c index 5eee3adbc3e83e3d26a2bd93e0b564d21cfc6668..5e3aa82ef4740d60f362807a086d50cfdb4aa491 100644 --- a/src/util/src/ttokenizer.c +++ b/src/util/src/ttokenizer.c @@ -44,6 +44,7 @@ static SKeyword keywordTable[] = { {"TIMESTAMP", TK_TIMESTAMP}, {"BINARY", TK_BINARY}, {"NCHAR", TK_NCHAR}, + {"JSON", TK_JSON}, {"OR", TK_OR}, {"AND", TK_AND}, {"NOT", TK_NOT}, @@ -230,7 +231,8 @@ static SKeyword keywordTable[] = { {"OUTPUTTYPE", TK_OUTPUTTYPE}, {"AGGREGATE", TK_AGGREGATE}, {"BUFSIZE", TK_BUFSIZE}, - {"RANGE", TK_RANGE} + {"RANGE", TK_RANGE}, + {"CONTAINS", TK_CONTAINS} }; static const char isIdChar[] = { @@ -312,6 +314,10 @@ uint32_t tGetToken(char* z, uint32_t* tokenId) { *tokenId = TK_COMMENT; return i; } + if (z[1] == '>') { + *tokenId = TK_ARROW; + return 2; + } *tokenId = TK_MINUS; return 1; } diff --git a/src/util/src/tutil.c b/src/util/src/tutil.c index c8172fc0aff010332de7d13071a28303f37cf7f5..c15197b7537601c0f0ca72420a6711547d1ed0ed 100644 --- a/src/util/src/tutil.c +++ b/src/util/src/tutil.c @@ -21,6 +21,11 @@ #include "tulog.h" #include "taoserror.h" +bool isInteger(double x){ + int truncated = (int)x; + return (x == truncated); +} + int32_t strdequote(char *z) { if (z == NULL) { return 0; @@ -105,7 +110,7 @@ size_t strtrim(char *z) { int32_t j = 0; int32_t delta = 0; - while (z[j] == ' ') { + while (isspace(z[j])) { ++j; } @@ -118,9 +123,9 @@ size_t strtrim(char *z) { int32_t stop = 0; while (z[j] != 0) { - if (z[j] == ' ' && stop == 0) { + if (isspace(z[j]) && stop == 0) { stop = j; - } else if (z[j] != ' ' && stop != 0) { + } else if (!isspace(z[j]) && stop != 0) { stop = 0; } @@ -509,6 +514,24 @@ char *taosIpStr(uint32_t ipInt) { return ipStr; } +void jsonKeyMd5(void *pMsg, int msgLen, void *pKey) { + MD5_CTX context; + + MD5Init(&context); + MD5Update(&context, (uint8_t *)pMsg, msgLen); + MD5Final(&context); + + memcpy(pKey, context.digest, sizeof(context.digest)); +} + +bool isValidateTag(char *input) { + if (!input) return false; + for (size_t i = 0; i < strlen(input); ++i) { + if (isprint(input[i]) == 0) return false; + } + return true; +} + FORCE_INLINE float taos_align_get_float(const char* pBuf) { #if __STDC_VERSION__ >= 201112L static_assert(sizeof(float) == sizeof(uint32_t), "sizeof(float) must equal to sizeof(uint32_t)"); diff --git a/tests/develop-test/0-management/3-tag/json_tag.py b/tests/develop-test/0-management/3-tag/json_tag.py new file mode 100644 index 0000000000000000000000000000000000000000..4810ec8b4e2437f5aecbb67a10c8d2ce4e5c55c5 --- /dev/null +++ b/tests/develop-test/0-management/3-tag/json_tag.py @@ -0,0 +1,515 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, db_test.stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import tdLog +from util.cases import tdCases +from util.sql import tdSql + + +class TDTestCase: + def caseDescription(self): + ''' + Json tag test case, include create table with json tag, + select json tag and query with json tag in where condition, + besides, include json tag in group by/order by/join/subquery. + ''' + return + + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + tdSql.prepare() + + print("============== STEP 1 ===== prepare data & validate json string") + tdSql.error("create table if not exists jsons1(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json, tagint int)") + tdSql.error("create table if not exists jsons1(ts timestamp, data json) tags(tagint int)") + tdSql.execute("create table if not exists jsons1(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)") + tdSql.execute("insert into jsons1_1 using jsons1 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 1, false, 'json1', '你是') (1591060608000, 23, true, '等等', 'json')") + tdSql.execute("insert into jsons1_2 using jsons1 tags('{\"tag1\":5,\"tag2\":\"beijing\"}') values (1591060628000, 2, true, 'json2', 'sss')") + tdSql.execute("insert into jsons1_3 using jsons1 tags('{\"tag1\":false,\"tag2\":\"beijing\"}') values (1591060668000, 3, false, 'json3', 'efwe')") + tdSql.execute("insert into jsons1_4 using jsons1 tags('{\"tag1\":null,\"tag2\":\"shanghai\",\"tag3\":\"hello\"}') values (1591060728000, 4, true, 'json4', '323sd')") + tdSql.execute("insert into jsons1_5 using jsons1 tags('{\"tag1\":1.232, \"tag2\":null}') values(1591060928000, 1, false, '你就会', 'ewe')") + tdSql.execute("insert into jsons1_6 using jsons1 tags('{\"tag1\":11,\"tag2\":\"\",\"tag2\":null}') values(1591061628000, 11, false, '你就会','')") + tdSql.execute("insert into jsons1_7 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '你就会', 'dws')") + + # test duplicate key using the first one. elimate empty key + tdSql.execute("CREATE TABLE if not exists jsons1_8 using jsons1 tags('{\"tag1\":null, \"tag1\":true, \"tag1\":45, \"1tag$\":2, \" \":90, \"\":32}')") + tdSql.query("select jtag from jsons1_8") + tdSql.checkData(0, 0, '{"tag1":null,"1tag$":2," ":90}') + + # test empty json string, save as jtag is NULL + tdSql.execute("insert into jsons1_9 using jsons1 tags('\t') values (1591062328000, 24, NULL, '你就会', '2sdw')") + tdSql.execute("CREATE TABLE if not exists jsons1_10 using jsons1 tags('')") + tdSql.execute("CREATE TABLE if not exists jsons1_11 using jsons1 tags(' ')") + tdSql.execute("CREATE TABLE if not exists jsons1_12 using jsons1 tags('{}')") + tdSql.execute("CREATE TABLE if not exists jsons1_13 using jsons1 tags('null')") + + # test invalidate json + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('\"efwewf\"')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('3333')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('33.33')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('false')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('[1,true]')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{222}')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"fe\"}')") + + # test invalidate json key, key must can be printed assic char + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"tag1\":[1,true]}')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"tag1\":{}}')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"。loc\":\"fff\"}')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"\t\":\"fff\"}')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"试试\":\"fff\"}')") + + #test length limit + char1= ''.join(['abcd']*64) + char3= ''.join(['abcd']*1022) + print(len(char3)) # 4088 + tdSql.error("CREATE TABLE if not exists jsons1_15 using jsons1 tags('{\"%s1\":5}')" % char1) # len(key)=257 + tdSql.execute("CREATE TABLE if not exists jsons1_15 using jsons1 tags('{\"%s\":5}')" % char1) # len(key)=256 + tdSql.error("CREATE TABLE if not exists jsons1_16 using jsons1 tags('{\"TS\":\"%s\"}')" % char3) # len(object)=4097 + tdSql.execute("CREATE TABLE if not exists jsons1_16 using jsons1 tags('{\"T\":\"%s\"}')" % char3) # len(object)=4096 + tdSql.execute("drop table if exists jsons1_15") + tdSql.execute("drop table if exists jsons1_16") + + print("============== STEP 2 ===== alter table json tag") + tdSql.error("ALTER STABLE jsons1 add tag tag2 nchar(20)") + tdSql.error("ALTER STABLE jsons1 drop tag jtag") + tdSql.error("ALTER TABLE jsons1 MODIFY TAG jtag nchar(128)") + + tdSql.execute("ALTER TABLE jsons1_1 SET TAG jtag='{\"tag1\":\"femail\",\"tag2\":35,\"tag3\":true}'") + tdSql.query("select jtag from jsons1_1") + tdSql.checkData(0, 0, '{"tag1":"femail","tag2":35,"tag3":true}') + tdSql.execute("ALTER TABLE jsons1 CHANGE TAG jtag jtag_new") + tdSql.execute("ALTER TABLE jsons1 CHANGE TAG jtag_new jtag") + + print("============== STEP 3 ===== query table") + # test error syntax + tdSql.error("select * from jsons1 where jtag->tag1='beijing'") + tdSql.error("select * from jsons1 where jtag->'location'") + tdSql.error("select * from jsons1 where jtag->''") + tdSql.error("select * from jsons1 where jtag->''=9") + tdSql.error("select -> from jsons1") + tdSql.error("select * from jsons1 where contains") + tdSql.error("select * from jsons1 where jtag->") + tdSql.error("select jtag->location from jsons1") + tdSql.error("select jtag contains location from jsons1") + tdSql.error("select * from jsons1 where jtag contains location") + tdSql.error("select * from jsons1 where jtag contains''") + tdSql.error("select * from jsons1 where jtag contains 'location'='beijing'") + + # test function error + tdSql.error("select avg(jtag->'tag1') from jsons1") + tdSql.error("select avg(jtag) from jsons1") + tdSql.error("select min(jtag->'tag1') from jsons1") + tdSql.error("select min(jtag) from jsons1") + tdSql.error("select ceil(jtag->'tag1') from jsons1") + tdSql.error("select ceil(jtag) from jsons1") + + # test select normal column + tdSql.query("select dataint from jsons1") + tdSql.checkRows(9) + tdSql.checkData(1, 0, 1) + + # test select json tag + tdSql.query("select * from jsons1") + tdSql.checkRows(9) + tdSql.query("select jtag from jsons1") + tdSql.checkRows(13) + tdSql.query("select jtag from jsons1 where jtag is null") + tdSql.checkRows(5) + tdSql.query("select jtag from jsons1 where jtag is not null") + tdSql.checkRows(8) + + # test jtag is NULL + tdSql.query("select jtag from jsons1_9") + tdSql.checkData(0, 0, None) + + # test select json tag->'key', value is string + tdSql.query("select jtag->'tag1' from jsons1_1") + tdSql.checkData(0, 0, '"femail"') + tdSql.query("select jtag->'tag2' from jsons1_6") + tdSql.checkData(0, 0, '""') + # test select json tag->'key', value is int + tdSql.query("select jtag->'tag2' from jsons1_1") + tdSql.checkData(0, 0, 35) + # test select json tag->'key', value is bool + tdSql.query("select jtag->'tag3' from jsons1_1") + tdSql.checkData(0, 0, "true") + # test select json tag->'key', value is null + tdSql.query("select jtag->'tag1' from jsons1_4") + tdSql.checkData(0, 0, "null") + # test select json tag->'key', value is double + tdSql.query("select jtag->'tag1' from jsons1_5") + tdSql.checkData(0, 0, "1.232000000") + # test select json tag->'key', key is not exist + tdSql.query("select jtag->'tag10' from jsons1_4") + tdSql.checkData(0, 0, None) + + tdSql.query("select jtag->'tag1' from jsons1") + tdSql.checkRows(13) + # test header name + res = tdSql.getColNameList("select jtag->'tag1' from jsons1") + cname_list = [] + cname_list.append("jtag->'tag1'") + tdSql.checkColNameList(res, cname_list) + + + + # test where with json tag + tdSql.error("select * from jsons1_1 where jtag is not null") + tdSql.error("select * from jsons1 where jtag='{\"tag1\":11,\"tag2\":\"\"}'") + tdSql.error("select * from jsons1 where jtag->'tag1'={}") + + # where json value is string + tdSql.query("select * from jsons1 where jtag->'tag2'='beijing'") + tdSql.checkRows(2) + tdSql.query("select dataint,tbname,jtag->'tag1',jtag from jsons1 where jtag->'tag2'='beijing'") + tdSql.checkData(0, 0, 2) + tdSql.checkData(0, 1, 'jsons1_2') + tdSql.checkData(0, 2, 5) + tdSql.checkData(0, 3, '{"tag1":5,"tag2":"beijing"}') + tdSql.checkData(1, 0, 3) + tdSql.checkData(1, 1, 'jsons1_3') + tdSql.checkData(1, 2, 'false') + tdSql.query("select * from jsons1 where jtag->'tag1'='beijing'") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag1'='收到货'") + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag->'tag2'>'beijing'") + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag->'tag2'>='beijing'") + tdSql.checkRows(3) + tdSql.query("select * from jsons1 where jtag->'tag2'<'beijing'") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where jtag->'tag2'<='beijing'") + tdSql.checkRows(4) + tdSql.query("select * from jsons1 where jtag->'tag2'!='beijing'") + tdSql.checkRows(3) + tdSql.query("select * from jsons1 where jtag->'tag2'=''") + tdSql.checkRows(2) + + # where json value is int + tdSql.query("select * from jsons1 where jtag->'tag1'=5") + tdSql.checkRows(1) + tdSql.checkData(0, 1, 2) + tdSql.query("select * from jsons1 where jtag->'tag1'=10") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag1'<54") + tdSql.checkRows(3) + tdSql.query("select * from jsons1 where jtag->'tag1'<=11") + tdSql.checkRows(3) + tdSql.query("select * from jsons1 where jtag->'tag1'>4") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where jtag->'tag1'>=5") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where jtag->'tag1'!=5") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where jtag->'tag1'!=55") + tdSql.checkRows(3) + + # where json value is double + tdSql.query("select * from jsons1 where jtag->'tag1'=1.232") + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag->'tag1'<1.232") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag1'<=1.232") + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag->'tag1'>1.23") + tdSql.checkRows(3) + tdSql.query("select * from jsons1 where jtag->'tag1'>=1.232") + tdSql.checkRows(3) + tdSql.query("select * from jsons1 where jtag->'tag1'!=1.232") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where jtag->'tag1'!=3.232") + tdSql.checkRows(3) + tdSql.error("select * from jsons1 where jtag->'tag1'/0=3") + tdSql.error("select * from jsons1 where jtag->'tag1'/5=1") + + # where json value is bool + tdSql.query("select * from jsons1 where jtag->'tag1'=true") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag1'=false") + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag->'tag1'!=false") + tdSql.checkRows(0) + tdSql.error("select * from jsons1 where jtag->'tag1'>false") + + # where json value is null + tdSql.query("select * from jsons1 where jtag->'tag1'=null") # only json suport =null. This synatx will change later. + tdSql.checkRows(1) + + # where json is null + tdSql.query("select * from jsons1 where jtag is null") + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag is not null") + tdSql.checkRows(8) + + # where json key is null + tdSql.query("select * from jsons1 where jtag->'tag_no_exist'=3") + tdSql.checkRows(0) + + # where json value is not exist + tdSql.query("select * from jsons1 where jtag->'tag1' is null") + tdSql.checkData(0, 0, 'jsons1_9') + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag->'tag4' is null") + tdSql.checkRows(9) + tdSql.query("select * from jsons1 where jtag->'tag3' is not null") + tdSql.checkRows(4) + + # test contains + tdSql.query("select * from jsons1 where jtag contains 'tag1'") + tdSql.checkRows(8) + tdSql.query("select * from jsons1 where jtag contains 'tag3'") + tdSql.checkRows(4) + tdSql.query("select * from jsons1 where jtag contains 'tag_no_exist'") + tdSql.checkRows(0) + + # test json tag in where condition with and/or + tdSql.query("select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='beijing'") + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag->'tag1'=false or jtag->'tag2'='beijing'") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='shanghai'") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='shanghai'") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag1'=13 or jtag->'tag2'>35") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag1'=13 or jtag->'tag2'>35") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag1' is not null and jtag contains 'tag3'") + tdSql.checkRows(4) + tdSql.query("select * from jsons1 where jtag->'tag1'='femail' and jtag contains 'tag3'") + tdSql.checkRows(2) + + + # test with between and + tdSql.query("select * from jsons1 where jtag->'tag1' between 1 and 30") + tdSql.checkRows(3) + tdSql.query("select * from jsons1 where jtag->'tag1' between 'femail' and 'beijing'") + tdSql.checkRows(2) + + # test with tbname/normal column + tdSql.query("select * from jsons1 where tbname = 'jsons1_1'") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3'") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3' and dataint=3") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where tbname = 'jsons1_1' and jtag contains 'tag3' and dataint=23") + tdSql.checkRows(1) + + + # test where condition like + tdSql.query("select *,tbname from jsons1 where jtag->'tag2' like 'bei%'") + tdSql.checkRows(2) + tdSql.query("select *,tbname from jsons1 where jtag->'tag1' like 'fe%' and jtag->'tag2' is not null") + tdSql.checkRows(2) + + # test where condition in no support in + tdSql.error("select * from jsons1 where jtag->'tag1' in ('beijing')") + + # test where condition match/nmath + tdSql.query("select * from jsons1 where jtag->'tag1' match 'ma'") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where jtag->'tag1' match 'ma$'") + tdSql.checkRows(0) + tdSql.query("select * from jsons1 where jtag->'tag2' match 'jing$'") + tdSql.checkRows(2) + tdSql.query("select * from jsons1 where jtag->'tag1' match '收到'") + tdSql.checkRows(1) + tdSql.query("select * from jsons1 where jtag->'tag1' nmatch 'ma'") + tdSql.checkRows(1) + + # test distinct + tdSql.execute("insert into jsons1_14 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '你就会', 'dws')") + tdSql.query("select distinct jtag->'tag1' from jsons1") + tdSql.checkRows(8) + tdSql.query("select distinct jtag from jsons1") + tdSql.checkRows(9) + + #test dumplicate key with normal colomn + tdSql.execute("INSERT INTO jsons1_15 using jsons1 tags('{\"tbname\":\"tt\",\"databool\":true,\"datastr\":\"是是是\"}') values(1591060828000, 4, false, 'jjsf', \"你就会\")") + tdSql.query("select *,tbname,jtag from jsons1 where jtag->'datastr' match '是' and datastr match 'js'") + tdSql.checkRows(1) + tdSql.query("select tbname,jtag->'tbname' from jsons1 where jtag->'tbname'='tt' and tbname='jsons1_14'") + tdSql.checkRows(0) + + # test join + tdSql.execute("create table if not exists jsons2(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)") + tdSql.execute("insert into jsons2_1 using jsons2 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 2, false, 'json2', '你是2')") + tdSql.execute("insert into jsons2_2 using jsons2 tags('{\"tag1\":5,\"tag2\":null}') values (1591060628000, 2, true, 'json2', 'sss')") + + tdSql.execute("create table if not exists jsons3(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)") + tdSql.execute("insert into jsons3_1 using jsons3 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 3, false, 'json3', '你是3')") + tdSql.execute("insert into jsons3_2 using jsons3 tags('{\"tag1\":5,\"tag2\":\"beijing\"}') values (1591060638000, 2, true, 'json3', 'sss')") + tdSql.query("select 'sss',33,a.jtag->'tag3' from jsons2 a,jsons3 b where a.ts=b.ts and a.jtag->'tag1'=b.jtag->'tag1'") + tdSql.checkData(0, 0, "sss") + tdSql.checkData(0, 2, "true") + + res = tdSql.getColNameList("select 'sss',33,a.jtag->'tag3' from jsons2 a,jsons3 b where a.ts=b.ts and a.jtag->'tag1'=b.jtag->'tag1'") + cname_list = [] + cname_list.append("sss") + cname_list.append("33") + cname_list.append("a.jtag->'tag3'") + tdSql.checkColNameList(res, cname_list) + + # test group by & order by json tag + tdSql.error("select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag2'") + tdSql.error("select count(*) from jsons1 group by jtag->'tag1' order by jtag") + tdSql.query("select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag1' desc") + tdSql.checkRows(8) + tdSql.checkData(0, 0, 2) + tdSql.checkData(0, 1, '"femail"') + tdSql.checkData(2, 0, 1) + tdSql.checkData(2, 1, 11) + tdSql.checkData(5, 0, 1) + tdSql.checkData(5, 1, "false") + tdSql.checkData(6, 0, 1) + tdSql.checkData(6, 1, "null") + tdSql.checkData(7, 0, 2) + tdSql.checkData(7, 1, None) + + tdSql.query("select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag1' asc") + tdSql.checkRows(8) + tdSql.checkData(0, 0, 2) + tdSql.checkData(0, 1, None) + tdSql.checkData(2, 0, 1) + tdSql.checkData(2, 1, "false") + tdSql.checkData(5, 0, 1) + tdSql.checkData(5, 1, 11) + tdSql.checkData(7, 0, 2) + tdSql.checkData(7, 1, '"femail"') + + # test stddev with group by json tag + tdSql.query("select stddev(dataint) from jsons1 group by jtag->'tag1'") + tdSql.checkData(0, 0, 10) + tdSql.checkData(0, 1, None) + tdSql.checkData(1, 0, 0) + tdSql.checkData(1, 1, "null") + tdSql.checkData(7, 0, 11) + tdSql.checkData(7, 1, '"femail"') + + res = tdSql.getColNameList("select stddev(dataint) from jsons1 group by jsons1.jtag->'tag1'") + cname_list = [] + cname_list.append("stddev(dataint)") + cname_list.append("jsons1.jtag->'tag1'") + tdSql.checkColNameList(res, cname_list) + + # test top/bottom with group by json tag + tdSql.query("select top(dataint,100) from jsons1 group by jtag->'tag1'") + tdSql.checkRows(11) + tdSql.checkData(0, 1, 4) + tdSql.checkData(1, 1, 24) + tdSql.checkData(1, 2, None) + tdSql.checkData(10, 1, 1) + tdSql.checkData(10, 2, '"femail"') + + # test having + tdSql.query("select stddev(dataint) from jsons1 group by jtag->'tag1' having stddev(dataint) > 0") + tdSql.checkRows(2) + + # subquery with json tag + tdSql.query("select * from (select jtag, dataint from jsons1)") + tdSql.checkRows(11) + tdSql.checkData(1, 1, 1) + tdSql.checkData(2, 0, '{"tag1":5,"tag2":"beijing"}') + + tdSql.query("select jtag->'tag1' from (select jtag->'tag1', dataint from jsons1)") + tdSql.checkRows(11) + tdSql.checkData(0, 0, '"femail"') + tdSql.checkData(2, 0, 5) + + res = tdSql.getColNameList("select jtag->'tag1' from (select jtag->'tag1', dataint from jsons1)") + cname_list = [] + cname_list.append("jtag->'tag1'") + tdSql.checkColNameList(res, cname_list) + + tdSql.query("select ts,tbname,jtag->'tag1' from (select jtag->'tag1',tbname,ts from jsons1 order by ts)") + tdSql.checkRows(11) + tdSql.checkData(1, 1, "jsons1_1") + tdSql.checkData(1, 2, '"femail"') + + # union all + tdSql.error("select jtag->'tag1' from jsons1 union all select jtag->'tag2' from jsons2") + tdSql.error("select jtag->'tag1' from jsons1_1 union all select jtag->'tag2' from jsons2_1") + + tdSql.query("select jtag->'tag1' from jsons1_1 union all select jtag->'tag1' from jsons2_1") + tdSql.checkRows(2) + tdSql.query("select dataint,jtag->'tag1',tbname from jsons1 union all select dataint,jtag->'tag1',tbname from jsons2") + tdSql.checkRows(13) + tdSql.query("select dataint,jtag,tbname from jsons1 union all select dataint,jtag,tbname from jsons2") + tdSql.checkRows(13) + + #show create table + tdSql.query("show create table jsons1") + tdSql.checkData(0, 1, 'create table `jsons1` (`ts` TIMESTAMP,`dataint` INT,`databool` BOOL,`datastr` NCHAR(50),`datastrbin` BINARY(150)) TAGS (`jtag` JSON)') + + #test aggregate function:count/avg/twa/irate/sum/stddev/leastsquares + tdSql.query("select count(*) from jsons1 where jtag is not null") + tdSql.checkData(0, 0, 10) + tdSql.query("select avg(dataint) from jsons1 where jtag is not null") + tdSql.checkData(0, 0, 5.3) + tdSql.error("select twa(dataint) from jsons1 where jtag is not null") + tdSql.error("select irate(dataint) from jsons1 where jtag is not null") + tdSql.query("select sum(dataint) from jsons1 where jtag->'tag1' is not null") + tdSql.checkData(0, 0, 49) + tdSql.query("select stddev(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkData(0, 0, 4.496912521) + tdSql.error("SELECT LEASTSQUARES(dataint, 1, 1) from jsons1 where jtag is not null") + + #test selection function:min/max/first/last/top/bottom/percentile/apercentile/last_row/interp + tdSql.query("select min(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkData(0, 0, 1) + tdSql.query("select max(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkData(0, 0, 11) + tdSql.query("select first(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkData(0, 0, 2) + tdSql.query("select last(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkData(0, 0, 11) + tdSql.query("select top(dataint,100) from jsons1 where jtag->'tag1'>1") + tdSql.checkRows(3) + tdSql.query("select bottom(dataint,100) from jsons1 where jtag->'tag1'>1") + tdSql.checkRows(3) + tdSql.error("select percentile(dataint,20) from jsons1 where jtag->'tag1'>1") + tdSql.query("select apercentile(dataint, 50) from jsons1 where jtag->'tag1'>1") + tdSql.checkData(0, 0, 1.5) + tdSql.query("select last_row(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkData(0, 0, 11) + tdSql.error("select interp(dataint) from jsons1 where ts = '2020-06-02 09:17:08.000' and jtag->'tag1'>1") + + #test calculation function:diff/derivative/spread/ceil/floor/round/ + tdSql.error("select diff(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.error("select derivative(dataint, 10m, 0) from jsons1 where jtag->'tag1'>1") + tdSql.query("select spread(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkData(0, 0, 10) + tdSql.query("select ceil(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkRows(3) + tdSql.query("select floor(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkRows(3) + tdSql.query("select round(dataint) from jsons1 where jtag->'tag1'>1") + tdSql.checkRows(3) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) + diff --git a/tests/develop-test/fulltest.sh b/tests/develop-test/fulltest.sh index e71a25659b1e5a2eed92e615f63eb18ace64de92..5c3b225f3fa1e24a098bcfafb19981c58115c337 100755 --- a/tests/develop-test/fulltest.sh +++ b/tests/develop-test/fulltest.sh @@ -1 +1,2 @@ -python3 test.py -f 1-insert/0-sql/basic.py \ No newline at end of file +python3 test.py -f 0-management/3-tag/json_tag.py +python3 test.py -f 1-insert/0-sql/basic.py diff --git a/tests/pytest/functions/function_derivative.py b/tests/pytest/functions/function_derivative.py index 3b79726ed80c206338392cecb8f3d2adf4588e2a..a2a458ea290b13ed462d8dcd47a8af16e3af0f82 100644 --- a/tests/pytest/functions/function_derivative.py +++ b/tests/pytest/functions/function_derivative.py @@ -29,7 +29,6 @@ class TDTestCase: def insertAndCheckData(self): types = ["tinyint", "tinyint unsigned", "smallint", "smallint unsigned", "int", "int unsigned", "bigint", "bigint unsigned", "float", "double", "bool", "binary(20)", "nchar(20)"] - for type in types: print("============== create table using %s type ================" % type) tdSql.execute("drop table if exists stb") diff --git a/tests/pytest/stable/json_tag.rawsql b/tests/pytest/stable/json_tag.rawsql new file mode 100644 index 0000000000000000000000000000000000000000..222a3b784fa1a81d10e2197e2224ec5f9d209b94 --- /dev/null +++ b/tests/pytest/stable/json_tag.rawsql @@ -0,0 +1,163 @@ +create database db_json_tag_test; +drop table if exists db_json_tag_test.jsons1; +drop table if exists db_json_tag_test.jsons2; +drop table if exists db_json_tag_test.jsons3; +drop table if exists db_json_tag_test.jsons1_1; +drop table if exists db_json_tag_test.jsons1_2; +drop table if exists db_json_tag_test.jsons1_3; +drop table if exists db_json_tag_test.jsons1_4; +drop table if exists db_json_tag_test.jsons1_5; +drop table if exists db_json_tag_test.jsons1_6; +drop table if exists db_json_tag_test.jsons1_7; +drop table if exists db_json_tag_test.jsons1_8; +drop table if exists db_json_tag_test.jsons1_9; +drop table if exists db_json_tag_test.jsons1_10; +drop table if exists db_json_tag_test.jsons1_11; +drop table if exists db_json_tag_test.jsons1_12; +drop table if exists db_json_tag_test.jsons1_13; +drop table if exists db_json_tag_test.jsons1_20; +drop table if exists db_json_tag_test.jsons1_21; +drop table if exists db_json_tag_test.jsons1_22; +create table if not exists db_json_tag_test.jsons1(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50)) tags(jtag json); +CREATE TABLE if not exists db_json_tag_test.jsons1_1 using db_json_tag_test.jsons1 tags('{"loc":"fff","id":5}'); +insert into db_json_tag_test.jsons1_2 using db_json_tag_test.jsons1 tags('{"num":5,"location":"beijing"}') values (now, 2, true, 'json2'); +insert into db_json_tag_test.jsons1_1 values(now, 1, false, 'json1'); +insert into db_json_tag_test.jsons1_3 using db_json_tag_test.jsons1 tags('{"num":34,"location":"beijing","level":"l1"}') values (now, 3, false 'json3'); +insert into db_json_tag_test.jsons1_4 using db_json_tag_test.jsons1 tags('{"class":55,"location":"shanghai","name":"name4"}') values (now, 4, true, 'json4'); + +ALTER TABLE db_json_tag_test.jsons1_1 SET TAG jtag='{"sex":"femail","age":35, "isKey":true}'; +select jtag from db_json_tag_test.jsons1_1; + +select * from db_json_tag_test.jsons1; + +select jtag->'location' from db_json_tag_test.jsons1_2; + +select jtag->'location' from db_json_tag_test.jsons1; + +select jtag from db_json_tag_test.jsons1_1; + +# test json string value +select * from db_json_tag_test.jsons1 where jtag->'location'='beijing'; + +select * from db_json_tag_test.jsons1 where jtag->'location'!='beijing'; + +select jtag->'num' from db_json_tag_test.jsons1 where jtag->'level'='l1'; + +select *,tbname from db_json_tag_test.jsons1 where jtag->'class'>5 and jtag->'class'<9; tdSql.checkRows(0) + +select *,tbname from db_json_tag_test.jsons1 where jtag->'class'>5 and jtag->'class'<92; + +select * from db_json_tag_test.jsons1 where jtag?'sex' or jtag?'num'; + +select * from db_json_tag_test.jsons1 where jtag?'sex' or jtag?'numww'; + +select * from db_json_tag_test.jsons1 where jtag?'sex' and jtag?'num'; + +select jtag->'sex' from db_json_tag_test.jsons1 where jtag?'sex' or jtag?'num'; + +select *,tbname from db_json_tag_test.jsons1 where jtag->'location'='beijing'; + +select *,tbname from db_json_tag_test.jsons1 where jtag->'num'=5 or jtag?'sex'; + +select * from db_json_tag_test.jsons1 where tbname = 'jsons1_1'; + +select * from db_json_tag_test.jsons1 where tbname = 'jsons1_1' or jtag?'num'; + +select * from db_json_tag_test.jsons1 where tbname = 'jsons1_1' and jtag?'num'; + +select * from db_json_tag_test.jsons1 where tbname = 'jsons1_1' or jtag->'num'=5; + +select *,tbname from db_json_tag_test.jsons1 where jtag->'location' like 'bei%'; + +select *,tbname from db_json_tag_test.jsons1 where jtag->'location' like 'bei%' and jtag->'location'='beijin'; + +select *,tbname from db_json_tag_test.jsons1 where jtag->'location' like 'bei%' or jtag->'location'='beijin'; + +select *,tbname from db_json_tag_test.jsons1 where jtag->'location' like 'bei%' and jtag->'num'=34; + +select *,tbname from db_json_tag_test.jsons1 where (jtag->'location' like 'bei%' or jtag->'num'=34) and jtag->'class'=55; + +select * from db_json_tag_test.jsons1 where jtag->'location' in ('beijing'); + +select * from db_json_tag_test.jsons1 where jtag->'num' in (5,34); + +select * from db_json_tag_test.jsons1 where jtag->'location' in ('shanghai') and jtag->'class'=55; + +select * from db_json_tag_test.jsons1 where jtag->'location' match 'jin$'; + +select * from db_json_tag_test.jsons1 where jtag->'location' match 'jin'; + +select * from db_json_tag_test.jsons1 where datastr match 'json' and jtag->'location' match 'jin'; + +CREATE TABLE if not exists db_json_tag_test.jsons1_5 using db_json_tag_test.jsons1 tags('\t'); +CREATE TABLE if not exists db_json_tag_test.jsons1_6 using db_json_tag_test.jsons1 tags(''); + +select jtag from db_json_tag_test.jsons1_6; + +CREATE TABLE if not exists db_json_tag_test.jsons1_7 using db_json_tag_test.jsons1 tags('{}'); +select jtag from db_json_tag_test.jsons1_7; + +CREATE TABLE if not exists db_json_tag_test.jsons1_8 using db_json_tag_test.jsons1 tags('null'); +select jtag from db_json_tag_test.jsons1_8; + +CREATE TABLE if not exists db_json_tag_test.jsons1_9 using db_json_tag_test.jsons1 tags('{"":4, "time":null}'); +select jtag from db_json_tag_test.jsons1_9; + +CREATE TABLE if not exists db_json_tag_test.jsons1_10 using db_json_tag_test.jsons1 tags('{"k1":"","k1":"v1","k2":true,"k3":false,"k4":55}'); +select jtag from db_json_tag_test.jsons1_10; + +select jtag->'k2' from db_json_tag_test.jsons1_10; + +select jtag from db_json_tag_test.jsons1 where jtag->'k1'=''; + +select jtag from db_json_tag_test.jsons1 where jtag->'k2'=true; + +select jtag from db_json_tag_test.jsons1 where jtag is null; + +select jtag from db_json_tag_test.jsons1 where jtag is not null; + +select * from db_json_tag_test.jsons1 where jtag->'location' is not null; + +select tbname,jtag from db_json_tag_test.jsons1 where jtag->'location' is null; + +select * from db_json_tag_test.jsons1 where jtag->'num' is not null; + +select * from db_json_tag_test.jsons1 where jtag->'location'='null'; + +select distinct jtag from db_json_tag_test.jsons1; + +select distinct jtag->'location' from db_json_tag_test.jsons1; + +CREATE TABLE if not exists db_json_tag_test.jsons1_11 using db_json_tag_test.jsons1 tags('{"k1":"中国","k5":"是是是"}'); + +select tbname,jtag from db_json_tag_test.jsons1 where jtag->'k1' match '中'; + +select tbname,jtag from db_json_tag_test.jsons1 where jtag->'k1'='中国'; + +INSERT INTO db_json_tag_test.jsons1_12 using db_json_tag_test.jsons1 tags('{"tbname":"tt","databool":true,"dataStr":"是是是"}') values(now, 4, false, "你就会;; + +select *,tbname,jtag from db_json_tag_test.jsons1 where jtag->'dataStr' match '是'; + +select tbname,jtag->'tbname' from db_json_tag_test.jsons1 where jtag->'tbname'='tt'; + +select *,tbname,jtag from db_json_tag_test.jsons1 where dataBool=true; + +CREATE TABLE if not exists db_json_tag_test.jsons1_13 using db_json_tag_test.jsons1 tags('{"1loc":"fff",";id":5}'); + +create table if not exists db_json_tag_test.jsons2(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50)) tags(jtag json); +create table if not exists db_json_tag_test.jsons3(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50)) tags(jtag json); +CREATE TABLE if not exists db_json_tag_test.jsons2_1 using db_json_tag_test.jsons2 tags('{"loc":"fff","id":5}'); +insert into db_json_tag_test.jsons3_1 using db_json_tag_test.jsons3 tags('{"loc":"fff","num":5,"location":"beijing"}') values ('2020-04-18 15:00:00.000', 2, true, 'json2'); +insert into db_json_tag_test.jsons2_1 values('2020-04-18 15:00:00.000', 1, false, 'json1'); +select 'sss',33,a.jtag->'loc' from db_json_tag_test.jsons2 a,db_json_tag_test.jsons3 b where a.ts=b.ts and a.jtag->'loc'=b.jtag->'loc'; + +select avg(dataint),count(*) from db_json_tag_test.jsons1 group by jtag->'location' order by jtag->'location' desc; +INSERT INTO db_json_tag_test.jsons1_20 using db_json_tag_test.jsons1 tags('{"tagint":1}') values(now, 1, false, "你就会;; +INSERT INTO db_json_tag_test.jsons1_21 using db_json_tag_test.jsons1 tags('{"tagint":11}') values(now, 11, false, "你就会;; +INSERT INTO db_json_tag_test.jsons1_22 using db_json_tag_test.jsons1 tags('{"tagint":2}') values(now, 2, false, "你就会;; +select avg(dataint),count(*) from db_json_tag_test.jsons1 group by jtag->'tagint' order by jtag->'tagint' desc; +select avg(dataint),count(*) from db_json_tag_test.jsons1 group by jtag->'tagint' order by jtag->'tagint'; +insert into db_json_tag_test.jsons1_9 values('2020-04-17 15:20:00.000', 5, false, 'json19'); +select * from db_json_tag_test.jsons1; +select * from db_json_tag_test.jsons1 where jtag->'time' is null; +select * from db_json_tag_test.jsons1 where jtag->'time'=null; \ No newline at end of file diff --git a/tests/pytest/stable/json_tag2.rawsql b/tests/pytest/stable/json_tag2.rawsql new file mode 100644 index 0000000000000000000000000000000000000000..6b1420b60d66930d53f3cf2c1fca1724820ab1fe --- /dev/null +++ b/tests/pytest/stable/json_tag2.rawsql @@ -0,0 +1,137 @@ +drop database db; +create database db; +use db; +create table if not exists jsons1(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json) +insert into jsons1_1 using jsons1 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 1, false, 'json1', '你是') (1591060608000, 23, true, '等等', 'json') +insert into jsons1_2 using jsons1 tags('{\"tag1\":5,\"tag2\":\"beijing\"}') values (1591060628000, 2, true, 'json2', 'sss') +insert into jsons1_3 using jsons1 tags('{\"tag1\":false,\"tag2\":\"beijing\"}') values (1591060668000, 3, false, 'json3', 'efwe') +insert into jsons1_4 using jsons1 tags('{\"tag1\":null,\"tag2\":\"shanghai\",\"tag3\":\"hello\"}') values (1591060728000, 4, true, 'json4', '323sd') +insert into jsons1_5 using jsons1 tags('{\"tag1\":1.232, \"tag2\":null}') values(1591060928000, 1, false, '你就会', 'ewe') +insert into jsons1_6 using jsons1 tags('{\"tag1\":11,\"tag2\":\"\",\"tag2\":null}') values(1591061628000, 11, false, '你就会','') +insert into jsons1_7 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '你就会', 'dws') + +CREATE TABLE if not exists jsons1_8 using jsons1 tags('{\"tag1\":null, \"tag1\":true, \"tag1\":45, \"1tag$\":2, \" \":90}') + +insert into jsons1_9 using jsons1 tags('\t') values (1591062328000, 24, NULL, '你就会', '2sdw') +CREATE TABLE if not exists jsons1_10 using jsons1 tags('') +CREATE TABLE if not exists jsons1_11 using jsons1 tags(' ') +CREATE TABLE if not exists jsons1_12 using jsons1 tags('{}') +CREATE TABLE if not exists jsons1_13 using jsons1 tags('null') + +ALTER TABLE jsons1_1 SET TAG jtag='{\"tag1\":\"femail\",\"tag2\":35,\"tag3\":true}' + + +select dataint from jsons1 + +select * from jsons1 +select jtag from jsons1 +select jtag from jsons1 where jtag is null +select jtag from jsons1 where jtag is not null +select jtag from jsons1_8 +select jtag from jsons1_1 +select jtag from jsons1_9 +select jtag->'tag1' from jsons1_1 +select jtag->'tag2' from jsons1_6 +select jtag->'tag2' from jsons1_1 +select jtag->'tag3' from jsons1_1 +select jtag->'tag1' from jsons1_4 +select jtag->'tag1' from jsons1_5 +select jtag->'tag10' from jsons1_4 + +#select jtag->'tag1' from jsons1 +#select * from jsons1 where jtag->'tag2'='beijing' +#select dataint,tbname,jtag->'tag1',jtag from jsons1 where jtag->'tag2'='beijing' +select * from jsons1 where jtag->'tag1'='beijing' +select * from jsons1 where jtag->'tag1'='收到货' +select * from jsons1 where jtag->'tag2'>'beijing' +select * from jsons1 where jtag->'tag2'>='beijing' +select * from jsons1 where jtag->'tag2'<'beijing' +select * from jsons1 where jtag->'tag2'<='beijing' +select * from jsons1 where jtag->'tag2'!='beijing' +select * from jsons1 where jtag->'tag2'='' + +select * from jsons1 where jtag->'tag1'=5 +select * from jsons1 where jtag->'tag1'=10 +select * from jsons1 where jtag->'tag1'<54 +select * from jsons1 where jtag->'tag1'<=11 +select * from jsons1 where jtag->'tag1'>4 +select * from jsons1 where jtag->'tag1'>=5 +select * from jsons1 where jtag->'tag1'!=5 +select * from jsons1 where jtag->'tag1'!=55 + +select * from jsons1 where jtag->'tag1'=1.232 +select * from jsons1 where jtag->'tag1'<1.232 +select * from jsons1 where jtag->'tag1'<=1.232 +select * from jsons1 where jtag->'tag1'>1.23 +select * from jsons1 where jtag->'tag1'>=1.232 +select * from jsons1 where jtag->'tag1'!=1.232 +select * from jsons1 where jtag->'tag1'!=3.232 + +select * from jsons1 where jtag->'tag1'=true +select * from jsons1 where jtag->'tag1'=false +select * from jsons1 where jtag->'tag1'!=false +select * from jsons1 where jtag->'tag1'=null +select * from jsons1 where jtag is null +select * from jsons1 where jtag is not null + +select * from jsons1 where jtag->'tag_no_exist'=3 +select * from jsons1 where jtag->'tag1' is null +select * from jsons1 where jtag->'tag4' is null +select * from jsons1 where jtag->'tag3' is not null + +select * from jsons1 where jtag conatins 'tag1' +select * from jsons1 where jtag conatins 'tag3' +select * from jsons1 where jtag conatins 'tag_no_exist' + +select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='beijing' +select * from jsons1 where jtag->'tag1'=false or jtag->'tag2'='beijing' +select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='shanghai' +select * from jsons1 where jtag->'tag1'=false and jtag->'tag2'='shanghai' +select * from jsons1 where jtag->'tag1'=13 or jtag->'tag2'>35 +select * from jsons1 where jtag->'tag1'=13 or jtag->'tag2'>35 +select * from jsons1 where jtag->'tag1' is not null and jtag conatins 'tag3' +select * from jsons1 where jtag->'tag1'='femail' and jtag conatins 'tag3' +select * from jsons1 where tbname = 'jsons1_1' +select * from jsons1 where tbname = 'jsons1_1' and jtag conatins 'tag3' +select * from jsons1 where tbname = 'jsons1_1' and jtag conatins 'tag3' and dataint=3 +select * from jsons1 where tbname = 'jsons1_1' and jtag conatins 'tag3' and dataint=23 + +select *,tbname from jsons1 where jtag->'tag2' like 'bei%' +select *,tbname from jsons1 where jtag->'tag1' like 'fe%' and jtag->'tag2' is not null + +select * from jsons1 where jtag->'tag1' match 'ma' +select * from jsons1 where jtag->'tag1' match 'ma$' +select * from jsons1 where jtag->'tag2' match 'jing$' +select * from jsons1 where jtag->'tag1' match '收到' + +insert into jsons1_14 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '你就会', 'dws') +select distinct jtag->'tag1' from jsons1 +select distinct jtag from jsons1 + +INSERT INTO jsons1_15 using jsons1 tags('{\"tbname\":\"tt\",\"databool\":true,\"datastr\":\"是是是\"}') values(1591060828000, 4, false, 'jjsf', \"你就会\") +select *,tbname,jtag from jsons1 where jtag->'datastr' match '是' and datastr match 'js' +select tbname,jtag->'tbname' from jsons1 where jtag->'tbname'='tt' and tbname='jsons1_14' + +create table if not exists jsons2(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json) +insert into jsons2_1 using jsons2 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 2, false, 'json2', '你是2') +insert into jsons2_2 using jsons2 tags('{\"tag1\":5,\"tag2\":null}') values (1591060628000, 2, true, 'json2', 'sss') + +create table if not exists jsons3(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json) +insert into jsons3_1 using jsons3 tags('{\"tag1\":\"fff\",\"tag2\":5, \"tag3\":true}') values(1591060618000, 3, false, 'json3', '你是3') +insert into jsons3_2 using jsons3 tags('{\"tag1\":5,\"tag2\":\"beijing\"}') values (1591060638000, 2, true, 'json3', 'sss') +select 'sss',33,a.jtag->'tag3' from jsons2 a,jsons3 b where a.ts=b.ts and a.jtag->'tag1'=b.jtag->'tag1' + + +select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag1' desc + +select count(*) from jsons1 group by jtag->'tag1' order by jtag->'tag1' asc + +select stddev(dataint) from jsons1 group by jtag->'tag1' + +select top(dataint,100) from jsons1 group by jtag->'tag1' + +select * from (select jtag, dataint from jsons1) + +select jtag->'tag1' from (select jtag->'tag1', dataint from jsons1) + +select ts,tbname,jtag->'tag1' from (select jtag->'tag1',tbname,ts from jsons1 order by ts) diff --git a/tests/pytest/tag_lite/json_tag_extra.py b/tests/pytest/tag_lite/json_tag_extra.py index 40ee69d46b770a33a8255783f675d5071513bc28..3e0853d78bbab03344157604b83d1f28399cab75 100644 --- a/tests/pytest/tag_lite/json_tag_extra.py +++ b/tests/pytest/tag_lite/json_tag_extra.py @@ -27,19 +27,17 @@ class TDTestCase: def run(self): tdSql.prepare() - + tdSql.execute("drop database if exists db_json;") print("==============step1 tag format =======") - tdLog.info("create database two stables and ") - tdSql.execute("create database db_json_tag_test") - tdSql.execute("use db_json_tag_test") + tdLog.info("create database ") + tdSql.execute("create database db_json") + tdSql.execute("use db_json") # test tag format tdSql.execute("create table if not exists jsons1(ts timestamp, dataInt int, dataStr nchar(50)) tags(jtag json(128))") tdSql.error("create table if not exists jsons1(ts timestamp, dataInt int, dataStr nchar(50)) tags(jtag json(64),jtag1 json(100))") tdSql.error("create table if not exists jsons1(ts timestamp, dataInt int, dataStr nchar(50)) tags(jtag json(64),dataBool bool)") tdSql.execute("CREATE TABLE if not exists jsons1_1 using jsons1 tags('{\"loc\":\"fff\",\"id\":5}')") - tdSql.execute("use db_json_tag_test") - # two stables: jsons1 jsons2 ,test tag's value and key tdSql.execute("insert into jsons1_1(ts,dataInt) using jsons1 tags('{\"loc+\":\"fff\",\"id\":5}') values (now,12)") @@ -89,7 +87,7 @@ class TDTestCase: tdSql.checkData(0, 0, None) tdSql.execute("CREATE TABLE if not exists jsons2_6 using jsons2 tags('{\"nv\":null,\"tea\":true,\"\":false,\"\":123,\"tea\":false}')") tdSql.query("select jtag2 from jsons2_6") - tdSql.checkData(0, 0, "{\"tea\":true}") + tdSql.checkData(0, 0, "{\"nv\":null,\"tea\":true}") tdSql.error("CREATE TABLE if not exists jsons2_7 using jsons2 tags('{\"nv\":null,\"tea\":123,\"\":false,\"\":123,\"tea\":false}')") tdSql.execute("CREATE TABLE if not exists jsons2_7 using jsons2 tags('{\"test7\":\"\"}')") tdSql.query("select jtag2 from jsons2_7") @@ -100,8 +98,8 @@ class TDTestCase: tdSql.error("ALTER STABLE jsons2 add tag jtag3 nchar(20)") tdSql.error("ALTER STABLE jsons2 drop tag jtag2") tdSql.execute("ALTER STABLE jsons2 change tag jtag2 jtag3") - tdSql.query("select jtag3 from jsons2_6") - tdSql.checkData(0, 0, "{\"tea\":true}") + tdSql.query("select jtag3->'tea' from jsons2_6") + tdSql.checkData(0, 0, "true") tdSql.error("ALTER TABLE jsons2_6 SET TAG jtag3='{\"tea-=[].;!@#$%^&*()/\":}'") tdSql.execute("ALTER TABLE jsons2_6 SET TAG jtag3='{\"tea-=[].;!@#$%^&*()/\":false}'") tdSql.query("select jtag3 from jsons2_6") @@ -132,7 +130,7 @@ class TDTestCase: tdSql.checkRows(3) tdSql.query("select jtag->'location' from jsons1_2") - tdSql.checkData(0, 0, "beijing") + tdSql.checkData(0, 0, "\"beijing\"") tdSql.query("select jtag->'num' from jsons1 where jtag->'level'='l1'") @@ -151,7 +149,6 @@ class TDTestCase: tdSql.checkRows(0) tdSql.query("select jtag->'sex' from jsons1 where jtag?'sex' or jtag?'num'") - tdSql.checkData(0, 0, "femail") tdSql.checkRows(3) tdSql.query("select *,tbname from jsons1 where jtag->'location'='beijing'") @@ -233,7 +230,7 @@ class TDTestCase: tdSql.execute("CREATE TABLE if not exists jsons1_9 using jsons1 tags('{\"\":4, \"time\":null}')") tdSql.query("select jtag from jsons1_9") - tdSql.checkData(0, 0, None) + tdSql.checkData(0, 0, "{\"time\":null}") tdSql.execute("CREATE TABLE if not exists jsons1_10 using jsons1 tags('{\"k1\":\"\",\"k1\":\"v1\",\"k2\":true,\"k3\":false,\"k4\":55}')") tdSql.query("select jtag from jsons1_10") @@ -249,10 +246,10 @@ class TDTestCase: tdSql.checkRows(1) tdSql.query("select jtag from jsons1 where jtag is null") - tdSql.checkRows(5) + tdSql.checkRows(4) tdSql.query("select jtag from jsons1 where jtag is not null") - tdSql.checkRows(5) + tdSql.checkRows(6) tdSql.query("select * from jsons1 where jtag->'location' is not null") tdSql.checkRows(3) @@ -270,7 +267,7 @@ class TDTestCase: # test distinct tdSql.query("select distinct jtag from jsons1") - tdSql.checkRows(6) + tdSql.checkRows(7) tdSql.query("select distinct jtag->'location' from jsons1") tdSql.checkRows(2) @@ -293,18 +290,28 @@ class TDTestCase: tdSql.query("select tbname,jtag->'tbname' from jsons1 where jtag->'tbname'='tt'") tdSql.checkRows(1) - # tdSql.query("select * from jsons1 where jtag->'num' is not null or jtag?'class' and jtag?'databool'") - # tdSql.checkRows(0) + # test filter : and /or / in/ like + tdSql.query("select * from jsons1 where jtag->'num' is not null or jtag?'class' and jtag?'databool'") + tdSql.checkRows(2) - # tdSql.query("select * from jsons1 where jtag->'num' is not null or jtag?'class' and jtag?'databool' and jtag->'k1' match '中' or jtag->'location' in ('beijing') and jtag->'location' like 'bei%'") + tdSql.query("select * from jsons1 where jtag->'num' is not null and jtag?'class' or jtag?'databool'") + tdSql.checkRows(1) + tdSql.checkData(0, 1, 4) + + tdSql.query("select * from jsons1 where jtag->'num' is not null or jtag?'class' and jtag?'databool' and jtag->'k1' match '中' or jtag->'location' in ('beijing') and jtag->'location' like 'bei%'") + tdSql.checkRows(3) - # tdSql.query("select * from jsons1 where datastr like '你就会' and ( jtag->'num' is not null or jtag?'class' and jtag?'databool' )") + tdSql.query("select * from jsons1 where datastr like '你就会' and ( jtag->'num' is not null or jtag?'tbname' and jtag?'databool' )") + tdSql.checkRows(1) + tdSql.checkData(0, 1, 4) + + tdSql.error("select * from jsons1 where datastr like '你就会' and jtag->'num' is not null or jtag?'class' and jtag?'databool'") tdSql.error("select * from jsons1 where datastr like '你就会' or jtag->'num' is not null or jtag?'class' and jtag?'databool' and jtag->'k1' match '中' or jtag->'location' in ('beijing') and jtag->'location' like 'bei%' ") - # tdSql.query("select * from jsons1 where datastr like '你就会' and (jtag->'num' is not null or jtag?'class' and jtag?'databool' and jtag->'k1' match '中' or jtag->'location' in ('beijing') and jtag->'location' like 'bei%' )") - # tdSql.checkRows(0) + tdSql.query("select * from jsons1 where datastr like '你就会' and (jtag->'num' is not null or jtag?'class' and jtag?'databool' and jtag->'k1' match '中' or jtag->'location' in ('beijing') and jtag->'location' like 'bei%' )") + tdSql.checkRows(0) tdSql.error("select *,tbname,jtag from jsons1 where dataBool=true") @@ -315,14 +322,14 @@ class TDTestCase: tdSql.error("CREATE TABLE if not exists jsons1_13 using jsons1 tags('{\"试试\":\"fff\",\";id\":5}')") tdSql.error("insert into jsons1_13 using jsons1 tags(3)") - # test query normal column + # test query normal column,tag and tbname tdSql.execute("create stable if not exists jsons3(ts timestamp, dataInt3 int(100), dataBool3 bool, dataStr3 nchar(50)) tags(jtag3 json)") tdSql.execute("create table jsons3_2 using jsons3 tags('{\"t\":true,\"t123\":123,\"\":\"true\"}')") - tdSql.execute("create table jsons3_3 using jsons3 tags('{\"t\":true,\"t123\":456,\"k1\":true}')") + tdSql.execute("create table jsons3_3 using jsons3 tags('{\"t\":true,\"t123\":456,\"k1\":true,\"str1\":\"111\"}')") tdSql.execute("insert into jsons3_3 values(now, 4, true, 'test')") - tdSql.execute("insert into jsons3_4 using jsons3 tags('{\"t\":true,\"t123\":789,\"k1\":false,\"s\":null}') values(now, 5, true, 'test')") + tdSql.execute("insert into jsons3_4 using jsons3 tags('{\"t\":true,\"t123\":789,\"k1\":false,\"s\":null,\"str1\":\"112\"}') values(now, 5, true, 'test')") tdSql.query("select * from jsons3 where jtag3->'k1'=true") tdSql.checkRows(1) tdSql.error("select jtag3->k1 from jsons3 ") @@ -332,26 +339,177 @@ class TDTestCase: tdSql.error("select jtag3?'k1'=true from jsons3;") tdSql.error("select jtag3->'k1'=true from jsons3;") tdSql.error("insert into jsons3_5 using jsons3 tags('{\"t\":true,\"t123\":789,\"k1\":1,\"s\":null}') values(now, 5, true, 'test')") - tdSql.execute("insert into jsons3_5 using jsons3 tags('{\"t\":true,\"t123\":012,\"k1\":null,\"s\":null}') values(now, 5, true, 'test')") + tdSql.execute("insert into jsons3_5 using jsons3 tags('{\"t\":true,\"t123\":012,\"k2\":null,\"s\":null}') values(now, 5, true, 'test')") tdSql.execute("insert into jsons3_6 using jsons3 tags('{\"t\":true,\"t123\":789,\"k1\":false,\"s\":null}') values(now, 5, true, 'test')") - # tdSql.execute("select distinct jtag3 from jsons3 where jtag3->'t123'=12 or jtag3?'k1'") - # tdSql.checkRows(3) + tdSql.query("select jtag3 from jsons3 where jtag3->'t123'=12 or jtag3?'k1'") + tdSql.checkRows(4) + tdSql.query("select distinct jtag3 from jsons3 where jtag3->'t123'=12 or jtag3?'k1'") + tdSql.checkRows(4) tdSql.execute("INSERT INTO jsons1_14 using jsons1 tags('{\"tbname\":\"tt\",\"location\":\"tianjing\",\"dataStr\":\"是是是\"}') values(now,5, \"你就会\")") - # tdSql.execute("select ts,dataint3,jtag->tbname from jsons1 where dataint>=1 and jtag->'location' in ('tianjing','123') and jtag?'tbname'") - # tdSql.checkRows(1) - # tdSql.checkData(0, 2, 'tt') - - # query normal column and tag column + tdSql.query("select ts,jtag->'tbname',tbname from jsons1 where dataint>=1 and jtag->'location' in ('tianjing','123') and jtag?'tbname'") + tdSql.checkRows(1) + tdSql.checkData(0, 1, '\"tt\"') + + tdSql.query("select ts,jtag->'tbname',tbname from jsons1 where dataint between 1 and 5 and jtag->'location' in ('tianjing','123')") + tdSql.checkRows(1) + tdSql.checkData(0, 2, 'jsons1_14') + + tdSql.query("select ts,jtag3->'tbname', jtag3->'str1',tbname from jsons3 where jtag3->'t123' between 456 and 789 and jtag3->'str1' like '11%' ") + tdSql.checkRows(2) + for i in range(1): + if tdSql.queryResult[i][1] == 'jsons3_3': + tdSql.checkData(i, 2, 111) + tdSql.query("select jtag3->'',dataint3 from jsons3") tdSql.checkRows(4) + for i in range(4): + if tdSql.queryResult[i][1] == 4: + tdSql.checkData(i, 0, None) + tdSql.query("select tbname,dataint3,jtag3->'k1' from jsons3;") + tdSql.checkRows(4) + for i in range(3): + if tdSql.queryResult[i][1] == 4: + tdSql.checkData(i, 2, 'true') + + # Select_exprs is SQL function -Aggregation function , tests includes group by and order by + + tdSql.query("select avg(dataInt),count(dataint),sum(dataint) from jsons1 group by jtag->'location' order by jtag->'location';") + tdSql.checkData(2, 3, '\"tianjing\"') + tdSql.checkRows(3) + for i in range(2): + if tdSql.queryResult[i][3] == '\"beijing\"': + tdSql.checkData(i, 0, 1) + tdSql.checkData(i, 1, 3) + # tdSql.query("select avg(dataInt) as 123 ,count(dataint),sum(dataint) from jsons1 group by jtag->'location' order by 123") + # tdSql.query("select avg(dataInt) as avgdata ,count(dataint),sum(dataint) from jsons1 group by jtag->'location' order by avgdata ;") + tdSql.query("select avg(dataInt),count(dataint),sum(dataint) from jsons1 group by jtag->'location' order by ts;") + tdSql.checkRows(3) + #tdSql.query("select avg(dataInt),count(dataint),sum(dataint) from jsons1 group by jtag->'age' order by tbname;") + #tdSql.checkRows(2) + tdSql.error("select avg(dataInt) from jsons1 group by jtag->'location' order by dataInt;") + tdSql.error("select avg(dataInt),tbname from jsons1 group by jtag->'location' order by tbname;") + tdSql.execute("CREATE TABLE if not exists jsons1_15 using jsons1 tags('{\"tbname\":\"tt\",\"location\":\"beijing\"}')") + tdSql.execute("insert into jsons1_15 values(now+1s, 2, 'json1')") + tdSql.error("select twa(dataint) from jsons1 group by jtag->'location' order by jtag->'location';") + tdSql.error("select irate(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + # tdSql.query(" select stddev(dataint) from jsons1 group by jtag->'location';") + # tdSql.checkRows(2) + tdSql.query(" select stddev(dataint) from jsons1 where jtag->'location'='beijing';") + tdSql.checkRows(1) + tdSql.error(" select LEASTSQUARES(dataint,1,2) from jsons1_1 where jtag->'location' ='beijing' ;") - # query child table + # Select_exprs is SQL function -Selection function + + tdSql.query(" select min(dataint),jtag from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 1) + tdSql.query(" select max(dataint),jtag from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 12) + tdSql.query(" select first(*) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query(" select last(*) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.error(" select last(*),jtag from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.query(" select last_row(*) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query(" select apercentile(dataint,0) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query(" select apercentile(dataint,50) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query(" select apercentile(dataint,90) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query(" select apercentile(dataint,100) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query(" select apercentile(dataint,0,'t-digest') from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query(" select apercentile(dataint,50,'t-digest') from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query(" select apercentile(dataint,100,'t-digest') from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkRows(1) + tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location';") + #tdSql.query("select tbname,top(dataint,1) from jsons1 group by jtag->'location' order by tbname asc;") + #tdSql.query("select tbname,top(dataint,1) from jsons1 group by jtag->'location' order by tbname desc") + tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location' order by jtag->'location' asc;") + tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location' order by jtag->'location' desc;") + tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location' order by ts desc;") + tdSql.query("select top(dataint,1) from jsons1 group by jtag->'location' order by ts asc;") + + # tdSql.query("select top(dataint,100) from jsons1 group by jtag->'location';") + # tdSql.query("select bottom(dataint,1) from jsons1 group by jtag->'location';") + # tdSql.query("select bottom(dataint,100) from jsons1 group by jtag->'location';") + + tdSql.execute("create table if not exists jsons_interp(ts timestamp, dataInt int, dataBool bool, datafloat float, datadouble double,dataStr nchar(50)) tags(jtag json)") + tdSql.execute("insert into jsons_interp_1 using jsons_interp tags('{\"nv\":null,\"tea\":true,\"\":false,\"rate\":456,\"tea\":false}') values ('2021-07-25 02:19:54.119',2,'true',0.9,0.1,'123')") + tdSql.execute("insert into jsons_interp_1 values ('2021-07-25 02:19:54.219',3,'true',-4.8,-5.5,'123') ") + tdSql.execute("insert into jsons_interp_2 using jsons_interp tags('{\"nv\":null,\"tea\":true,\"level\":\"123456\",\"rate\":123,\"tea\":false}') values ('2021-07-25 02:19:54.319',4,'true',0.9,0.1,'123')") + tdSql.execute("insert into jsons_interp_2 values ('2021-07-25 02:19:54.419',5,'true',-5.1,1.3,'123') ") + #tdSql.query(" select interp(dataint) from jsons_interp where jtag->'rate' in (123,456) and ts >= '2021-07-25 02:19:53.19' and ts<= '2021-07-25 02:19:54.519' every(100a) ;") + #tdSql.query(" select interp(dataint) from jsons_interp where jtag->'rate'=123 and ts >= '2021-07-25 02:19:53.19' and ts<= '2021-07-25 02:19:54.519' every(100a) ;") + #tdSql.query(" select interp(dataint) from jsons_interp where ts >= '2021-07-25 02:19:53.19' and ts<= '2021-07-25 02:19:54.519' every(100a) ;") + + + # tdSql.checkData(0,0,1) + # tdSql.checkRows(1) + + # Select_exprs is SQL function -Calculation function + + tdSql.error(" select diff(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.error(" select Derivative(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.query(" select SPREAD(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.checkData(0, 0, 11) + tdSql.query(" select ceil(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.query(" select floor(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + tdSql.query(" select round(dataint) from jsons1 where jtag->'location' in ('beijing','tianjing') or jtag?'num' or jtag->'age'=35 ;") + #need insert new data --data type is double or float and tests ceil floor round . + tdSql.execute("create table if not exists jsons7(ts timestamp, dataInt int, dataBool bool, datafloat float, datadouble double,dataStr nchar(50)) tags(jtag json)") + tdSql.execute("insert into jsons7_1 using jsons7 tags('{\"nv\":null,\"tea\":true,\"\":false,\" \":123,\"tea\":false}') values (now,2,'true',0.9,0.1,'123')") + tdSql.query("select * from jsons7 where jtag->'tea'=0 ;") + tdSql.checkRows(0) + tdSql.query("select * from jsons7 where jtag->'tea'=3;") + # tdSql.checkRows(0) + tdSql.execute("insert into jsons7_1 values (now+1s,3,'true',-4.8,-5.5,'123') ") + tdSql.execute("insert into jsons7_1 values (now+2s,4,'true',1.9998,2.00001,'123') ") + tdSql.execute("insert into jsons7_2 using jsons7 tags('{\"nv\":null,\"tea\":true,\"\":false,\"tag\":123,\"tea\":false}') values (now,5,'true',4.01,2.2,'123') ") + tdSql.execute("insert into jsons7_2 (ts,datadouble) values (now+3s,-0.9) ") + tdSql.execute("insert into jsons7_2 (ts,datadouble) values (now+4s,-2.9) ") + tdSql.execute("insert into jsons7_2 (ts,datafloat) values (now+1s,-0.9) ") + tdSql.execute("insert into jsons7_2 (ts,datafloat) values (now+2s,-1.9) ") + # tdSql.execute("CREATE TABLE if not exists jsons7_3 using jsons7 tags('{\"nv\":null,\"tea\":true,\"\":false,\"tag\":4569\"tea\":false}') ") + tdSql.query("select ts,ceil(dataint),ceil(datafloat),ceil(datadouble) from jsons7 where jtag?'tea';") + tdSql.query("select ceil(dataint),ceil(datafloat),ceil(datadouble) from jsons7 where jtag?'tea';") + tdSql.query("select ts,floor(dataint),floor(datafloat),floor(datadouble) from jsons7 where jtag?'tea';") + tdSql.query("select floor(dataint),floor(datafloat),floor(datadouble) from jsons7 where jtag?'tea';") + tdSql.query("select ts,round(dataint),round(datafloat),round(datadouble) from jsons7 where jtag?'tea';") + tdSql.query("select round(dataint),round(datafloat),round(datadouble) from jsons7 where jtag?'tea';") - tdSql.error("select * from jsons3_2 where jtag3->'k1'=true;") + + # test join + tdSql.execute("create table if not exists jsons6(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50)) tags(jtag json)") + tdSql.execute("create table if not exists jsons5(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50)) tags(jtag json)") + tdSql.execute("CREATE TABLE if not exists jsons6_1 using jsons6 tags('{\"loc\":\"fff\",\"id\":6,\"user\":\"ffc\"}')") + tdSql.execute("CREATE TABLE if not exists jsons6_2 using jsons6 tags('{\"loc\":\"ffc\",\"id\":5}')") + tdSql.execute("insert into jsons6_1 values ('2020-04-18 15:00:00.000', 1, false, 'json1')") + tdSql.execute("insert into jsons6_2 values ('2020-04-18 15:00:01.000', 2, false, 'json1')") + tdSql.execute("insert into jsons5_1 using jsons5 tags('{\"loc\":\"fff\",\"num\":5,\"location\":\"beijing\"}') values ('2020-04-18 15:00:00.000', 2, true, 'json2')") + tdSql.execute("insert into jsons5_2 using jsons5 tags('{\"loc\":\"fff\",\"id\":5,\"location\":\"beijing\"}') values ('2020-04-18 15:00:01.000', 2, true, 'json2')") + + tdSql.error("select 'sss',33,a.jtag->'loc' from jsons6 a,jsons5 b where a.ts=b.ts and a.jtag->'loc'=b.jtag->'loc'") + tdSql.error("select 'sss',33,a.jtag->'loc' from jsons6 a,jsons5 b where a.ts=b.ts and a.jtag->'user'=b.jtag->'loc';") + tdSql.query("select 'sss',33,a.jtag->'loc' from jsons6 a,jsons5 b where a.ts=b.ts and a.jtag->'id'=b.jtag->'id'") + tdSql.checkData(0, 0, "sss") + tdSql.checkData(0, 2, "\"ffc\"") + + #nested query + tdSql.query("select jtag->'tag' from (select tbname,jtag,ts,ceil(dataint) as cdata,ceil(datafloat) ,ceil(datadouble) from jsons7 where jtag?'tea') where cdata=3 ") + # tdSql.query("select * from (select tbname,jtag,ts,ceil(dataint) as cdata,ceil(datafloat) ,ceil(datadouble) from jsons7 where jtag?'tea') where cdata=3 ") + # tdSql.query("select jtag from (select tbname,jtag,ts,ceil(dataint) as cdata,ceil(datafloat) ,ceil(datadouble) from jsons7 where jtag?'tea') where jtag->'tag'=123 ") + # query child table + # tdSql.error("select * from jsons3_2 where jtag3->'k1'=true;") # tdSql.checkData(0, 0, None) # tdSql.checkRows(3) @@ -362,7 +520,7 @@ class TDTestCase: # tdSql.execute("drop stable jsons1") # tdSql.execute("drop stable jsons3") # tdSql.execute("drop stable jsons2") - # tdSql.execute("drop database db_json_tag_test") + # tdSql.execute("drop database db_json") diff --git a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json index c9c4ae2c1b650da99853d6c82106b3f6ee80d0c0..d6e3afdea31955992cc0c9cc8842bc6ae7c6e3f6 100755 --- a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json +++ b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json @@ -15,7 +15,7 @@ "max_sql_len": 102400000, "databases": [{ "dbinfo": { - "name": "json", + "name": "json_test", "drop": "yes", "replica": 1, "days": 10, diff --git a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py index ce3f6ca4c2be3210cc84e8b3f13683b0dd268fa4..56b51f5498aed0a540a86bf03625266ad3599b58 100755 --- a/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py +++ b/tests/pytest/tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.py @@ -105,7 +105,7 @@ class TDTestCase: # insert: create one or mutiple tables per sql and insert multiple rows per sql # test case for https://jira.taosdata.com:18080/browse/TD-5213 os.system("%staosBenchmark -f tools/taosdemoAllTest/TD-5213/insertSigcolumnsNum4096.json -y " % binPath) - tdSql.execute("use json") + tdSql.execute("use json_test") tdSql.query("select count (tbname) from stb_old") tdSql.checkData(0, 0, 1) diff --git a/tests/pytest/util/dnodes.py b/tests/pytest/util/dnodes.py index 55c964c2557eff3204cf31bfb63cd5e3f3dd5501..254d5f166b408e4abe488bf41b33143a7b702b26 100644 --- a/tests/pytest/util/dnodes.py +++ b/tests/pytest/util/dnodes.py @@ -44,6 +44,7 @@ class TDSimClient: "jnidebugFlag": "135", "qdebugFlag": "135", "telemetryReporting": "0", + "enableCoreFile": "1", } def getLogDir(self): @@ -151,7 +152,8 @@ class TDDnode: "udebugFlag":"135", "jnidebugFlag":"135", "qdebugFlag":"135", - "maxSQLLength":"1048576" + "maxSQLLength":"1048576", + "enableCoreFile": "1", } def init(self, path): diff --git a/tests/script/api/stmt.c b/tests/script/api/stmt.c index f4fb9233a83f930a808eadf2135003d0e644c597..085263e06638417dd8035a7108f8b105bc521bfa 100644 --- a/tests/script/api/stmt.c +++ b/tests/script/api/stmt.c @@ -173,6 +173,44 @@ void taos_stmt_set_tbname_tags_test() { printf("finish taos_stmt_set_tbname_tags test\n"); } +void taos_stmt_set_tbname_tags_json_test() { + printf("start taos_stmt_set_tbname_tags_json_test test\n"); + TAOS_STMT *stmt = NULL; + char * name = calloc(1, 20); + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND)); + // ASM ERROR + assert(taos_stmt_set_tbname_tags(stmt, name, tags) != 0); + void *taos = taos_connect("127.0.0.1", "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("Cannot connect to tdengine server\n"); + exit(EXIT_FAILURE); + } + execute_simple_sql(taos, "drop database if exists stmt_test_json"); + execute_simple_sql(taos, "create database stmt_test_json"); + execute_simple_sql(taos, "use stmt_test_json"); + execute_simple_sql(taos, "create stable super(ts timestamp, c1 int) tags (jtag json)"); + stmt = taos_stmt_init(taos); + assert(stmt != NULL); + char *stmt_sql = calloc(1, 1000); + sprintf(stmt_sql, "insert into ? using super tags (?) values (?,?)"); + assert(taos_stmt_prepare(stmt, stmt_sql, 0) == 0); + assert(taos_stmt_set_tbname_tags(stmt, name, tags) != 0); + sprintf(name, "tb"); + assert(taos_stmt_set_tbname_tags(stmt, name, tags) != 0); + tags->buffer_type = TSDB_DATA_TYPE_JSON; + tags->buffer = "{\\\"key1\\\":\\\"value1\\\",\\\"key2\\\":null,\\\"key3\\\":3,\\\"key4\\\":3.2}"; + tags->buffer_length = strlen(tags->buffer); + tags->length = &tags->buffer_length; + tags->is_null = NULL; + assert(taos_stmt_set_tbname_tags(stmt, name, tags) == 0); + free(stmt_sql); + free(name); + free(tags); + assert(taos_stmt_affected_rows(stmt) == 0); + taos_stmt_close(stmt); + printf("finish taos_stmt_set_tbname_tags_json_test test\n"); +} + void taos_stmt_set_sub_tbname_test() { printf("start taos_stmt_set_sub_tbname test\n"); TAOS_STMT *stmt = NULL; @@ -492,6 +530,76 @@ void taos_stmt_use_result_query(void *taos, char *col, int type) { free(stmt_sql); } +void taos_stmt_use_result_query_json(void *taos, char *col, int type) { + TAOS_STMT *stmt = taos_stmt_init(taos); + assert(stmt != NULL); + char *stmt_sql = calloc(1, 1024); + sprintf(stmt_sql, "select * from stmt_test_json.super where jtag->? = ?"); + printf("stmt_sql: %s\n", stmt_sql); + assert(taos_stmt_prepare(stmt, stmt_sql, 0) == 0); + + + struct { + int64_t long_value; + double double_value; + char nchar_value[32]; + } v = {0}; + v.long_value = 4; + v.double_value = 3.3; + strcpy(v.nchar_value, "一二三四五六七八"); + + TAOS_BIND params[2] = {0}; + +// char jsonTag[32] = "jtag"; +// params[0].buffer_type = TSDB_DATA_TYPE_NCHAR; +// params[0].buffer_length = strlen(jsonTag); +// params[0].buffer = &jsonTag; +// params[0].length = ¶ms[0].buffer_length; +// params[0].is_null = NULL; + + params[0].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[0].buffer_length = strlen(col); + params[0].buffer = col; + params[0].length = ¶ms[0].buffer_length; + params[0].is_null = NULL; + + switch (type) { + case TSDB_DATA_TYPE_BIGINT: + params[1].buffer_type = type; + params[1].buffer_length = sizeof(v.long_value); + params[1].buffer = &v.long_value; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + break; + case TSDB_DATA_TYPE_NCHAR: + params[1].buffer_type = type; + params[1].buffer_length = strlen(v.nchar_value); + params[1].buffer = &v.nchar_value; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + break; + case TSDB_DATA_TYPE_DOUBLE: + params[1].buffer_type = type; + params[1].buffer_length = sizeof(v.double_value); + params[1].buffer = &v.double_value; + params[1].length = ¶ms[1].buffer_length; + params[1].is_null = NULL; + break; + default: + printf("Cannnot find type: %d\n", type); + break; + } + + assert(taos_stmt_bind_param(stmt, params) == 0); + assert(taos_stmt_execute(stmt) == 0); + TAOS_RES *result = taos_stmt_use_result(stmt); + assert(result != NULL); + print_result(result); + taos_free_result(result); + assert(taos_stmt_close(stmt) == 0); + free(stmt_sql); +} + void taos_stmt_use_result_test() { printf("start taos_stmt_use_result test\n"); void *taos = taos_connect("127.0.0.1", "root", "taosdata", NULL, 0); @@ -534,6 +642,47 @@ void taos_stmt_use_result_test() { printf("finish taos_stmt_use_result test\n"); } +void taos_stmt_use_result_json_test() { + printf("start taos_stmt_use_result_json_test test\n"); + void *taos = taos_connect("127.0.0.1", "root", "taosdata", NULL, 0); + if (taos == NULL) { + printf("Cannot connect to tdengine server\n"); + exit(EXIT_FAILURE); + } + execute_simple_sql(taos, "drop database if exists stmt_test_json"); + execute_simple_sql(taos, "create database stmt_test_json"); + execute_simple_sql(taos, "use stmt_test_json"); + execute_simple_sql( + taos, + "create table super(ts timestamp, c1 int) tags (jtag json)"); + execute_simple_sql(taos, + "create table t1 using super tags ('{\\\"key1\\\":\\\"一二三四五六七八\\\",\\\"key2\\\":null,\\\"key3\\\":3,\\\"key4\\\":3.1}')"); + execute_simple_sql( + taos, "insert into t1 values (1591060628000, 1)"); + execute_simple_sql( + taos, "insert into t1 values (1591060628001, 2)"); + + execute_simple_sql(taos, + "create table t2 using super tags ('{\\\"key1\\\":5,\\\"key2\\\":null,\\\"key3\\\":4,\\\"key4\\\":3.2}')"); + execute_simple_sql( + taos, "insert into t2 values (1591060628003, 21)"); + execute_simple_sql( + taos, "insert into t2 values (1591060628004, 22)"); + + execute_simple_sql(taos, + "create table t3 using super tags ('{\\\"key1\\\":\\\"一二\\\",\\\"key2\\\":null,\\\"key3\\\":null,\\\"key4\\\":3.3}')"); + execute_simple_sql( + taos, "insert into t3 values (1591060628005, 31)"); + execute_simple_sql( + taos, "insert into t3 values (1591060628006, 32)"); + + taos_stmt_use_result_query_json(taos, "key1", TSDB_DATA_TYPE_NCHAR); + taos_stmt_use_result_query_json(taos, "key3", TSDB_DATA_TYPE_BIGINT); + taos_stmt_use_result_query_json(taos, "key4", TSDB_DATA_TYPE_DOUBLE); + + printf("finish taos_stmt_use_result_json_test test\n"); +} + void taos_stmt_close_test() { printf("start taos_stmt_close test\n"); // ASM ERROR @@ -548,6 +697,7 @@ void test_api_reliability() { taos_stmt_preprare_test(); taos_stmt_set_tbname_test(); taos_stmt_set_tbname_tags_test(); + taos_stmt_set_tbname_tags_json_test(); taos_stmt_set_sub_tbname_test(); taos_stmt_bind_param_test(); taos_stmt_bind_single_param_batch_test(); @@ -557,7 +707,7 @@ void test_api_reliability() { taos_stmt_close_test(); } -void test_query() { taos_stmt_use_result_test(); } +void test_query() { taos_stmt_use_result_test(); taos_stmt_use_result_json_test(); } int main(int argc, char *argv[]) { test_api_reliability();