diff --git a/include/util/taoserror.h b/include/util/taoserror.h index cda08a96a90e9274ef4ec1da8fb270af85ec5a0d..e318978339316de794cb8d455f7e1f68a82800a1 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -639,6 +639,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x264F) #define TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY TAOS_DEF_ERROR_CODE(0, 0x2650) #define TSDB_CODE_PAR_INVALID_DROP_COL TAOS_DEF_ERROR_CODE(0, 0x2651) +#define TSDB_CODE_PAR_INVALID_COL_JSON TAOS_DEF_ERROR_CODE(0, 0x2652) //planner #define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700) diff --git a/include/util/tdef.h b/include/util/tdef.h index a7ddb0e0bcf4405cc3c474f283255cd317b08e2e..808fcf01526f003bae9878a997cb338438528121 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -234,6 +234,7 @@ typedef enum ELogicConditionType { #define TSDB_MAX_TAG_CONDITIONS 1024 #define TSDB_MAX_JSON_TAG_LEN 16384 +#define TSDB_MAX_JSON_KEY_LEN 256 #define TSDB_AUTH_LEN 16 #define TSDB_PASSWORD_LEN 32 diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index b1428858418a499a0260376eb4b1b6af60c06ea7..daa5887127ae5df63fe600b59b9ef5c8da7a592a 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -866,8 +866,7 @@ static char* parseTagDatatoJson(void* p) { if (j == 0) { if (*val == TSDB_DATA_TYPE_NULL) { string = taosMemoryCalloc(1, 8); - sprintf(varDataVal(string), "%s", TSDB_DATA_NULL_STR_L); - varDataSetLen(string, strlen(varDataVal(string))); + sprintf(string, "%s", TSDB_DATA_NULL_STR_L); goto end; } continue; @@ -1003,7 +1002,7 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int length = 0; } varDataSetLen(dst, length + CHAR_BYTES * 2); - *(char*)(varDataVal(dst), length + CHAR_BYTES) = '\"'; + *(char*)POINTER_SHIFT(varDataVal(dst), length + CHAR_BYTES) = '\"'; } else if (jsonInnerType == TSDB_DATA_TYPE_DOUBLE) { double jsonVd = *(double*)(jsonInnerData); sprintf(varDataVal(dst), "%.9lf", jsonVd); diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index 8afd20e0bcbad8a6dcc259e53aa1a387bffbbf73..a792343380aa5799d0ae303eb5b37ace65419f04 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -607,31 +607,39 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA if (iCol == 0) { // TODO : need to update tag index } - ctbEntry.version = version; - SKVRowBuilder kvrb = {0}; - const SKVRow pOldTag = (const SKVRow)ctbEntry.ctbEntry.pTags; - SKVRow pNewTag = NULL; - - tdInitKVRowBuilder(&kvrb); - for (int32_t i = 0; i < pTagSchema->nCols; i++) { - SSchema *pCol = &pTagSchema->pSchema[i]; - if (iCol == i) { - tdAddColToKVRow(&kvrb, pCol->colId, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal); - } else { - void *p = tdGetKVRowValOfCol(pOldTag, pCol->colId); - if (p) { - if (IS_VAR_DATA_TYPE(pCol->type)) { - tdAddColToKVRow(&kvrb, pCol->colId, p, varDataTLen(p)); - } else { - tdAddColToKVRow(&kvrb, pCol->colId, p, pCol->bytes); + if(pTagSchema->nCols == 1 && pTagSchema->pSchema[0].type == TSDB_DATA_TYPE_JSON){ + ctbEntry.ctbEntry.pTags = taosMemoryMalloc(pAlterTbReq->nTagVal); + if(ctbEntry.ctbEntry.pTags == NULL){ + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + memcpy((void*)ctbEntry.ctbEntry.pTags, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal); + }else{ + SKVRowBuilder kvrb = {0}; + const SKVRow pOldTag = (const SKVRow)ctbEntry.ctbEntry.pTags; + SKVRow pNewTag = NULL; + + tdInitKVRowBuilder(&kvrb); + for (int32_t i = 0; i < pTagSchema->nCols; i++) { + SSchema *pCol = &pTagSchema->pSchema[i]; + if (iCol == i) { + tdAddColToKVRow(&kvrb, pCol->colId, pAlterTbReq->pTagVal, pAlterTbReq->nTagVal); + } else { + void *p = tdGetKVRowValOfCol(pOldTag, pCol->colId); + if (p) { + if (IS_VAR_DATA_TYPE(pCol->type)) { + tdAddColToKVRow(&kvrb, pCol->colId, p, varDataTLen(p)); + } else { + tdAddColToKVRow(&kvrb, pCol->colId, p, pCol->bytes); + } } } } - } - ctbEntry.ctbEntry.pTags = tdGetKVRowFromBuilder(&kvrb); - tdDestroyKVRowBuilder(&kvrb); + ctbEntry.ctbEntry.pTags = tdGetKVRowFromBuilder(&kvrb); + tdDestroyKVRowBuilder(&kvrb); + } // save to table.db metaSaveToTbDb(pMeta, &ctbEntry); @@ -641,6 +649,7 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA tDecoderClear(&dc1); tDecoderClear(&dc2); + if (ctbEntry.ctbEntry.pTags) taosMemoryFree((void*)ctbEntry.ctbEntry.pTags); if (ctbEntry.pBuf) taosMemoryFree(ctbEntry.pBuf); if (stbEntry.pBuf) tdbFree(stbEntry.pBuf); tdbTbcClose(pTbDbc); diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index 621ea7b7fc7483dd6b073cf6301bf373e154e634..3034b4b02a293dd4cce91814bde367682db6ac8d 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -21,6 +21,7 @@ static int32_t getSchemaBytes(const SSchema* pSchema) { case TSDB_DATA_TYPE_BINARY: return (pSchema->bytes - VARSTR_HEADER_SIZE); case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_JSON: return (pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE; default: return pSchema->bytes; diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index c1aaec1681cbcbf8fbe47756cb514e429fb0815b..3f7003dfa3b5a911e35c8823d1d883d9cca5bea7 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -1119,6 +1119,7 @@ bool nodesIsComparisonOp(const SOperatorNode* pOp) { bool nodesIsJsonOp(const SOperatorNode* pOp) { switch (pOp->opType) { case OP_TYPE_JSON_GET_VALUE: + case OP_TYPE_JSON_CONTAINS: return true; default: break; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index b6b119074857c0a5d3683256bae2d62fd40cd52a..e57fc3556455d731dc937e4dcdb9cdabe12c350b 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -677,7 +677,6 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD varDataSetLen(pVal->datum.p, len); break; } - case TSDB_DATA_TYPE_JSON: case TSDB_DATA_TYPE_DECIMAL: case TSDB_DATA_TYPE_BLOB: return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); @@ -738,8 +737,7 @@ static EDealRes translateUnaryOperator(STranslateContext* pCxt, SOperatorNode* p static EDealRes translateArithmeticOperator(STranslateContext* pCxt, SOperatorNode* pOp) { SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType; SDataType rdt = ((SExprNode*)(pOp->pRight))->resType; - if (TSDB_DATA_TYPE_JSON == ldt.type || TSDB_DATA_TYPE_BLOB == ldt.type || TSDB_DATA_TYPE_JSON == rdt.type || - TSDB_DATA_TYPE_BLOB == rdt.type) { + if (TSDB_DATA_TYPE_BLOB == ldt.type || TSDB_DATA_TYPE_BLOB == rdt.type) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName); } if ((TSDB_DATA_TYPE_TIMESTAMP == ldt.type && TSDB_DATA_TYPE_TIMESTAMP == rdt.type) || @@ -764,14 +762,14 @@ static EDealRes translateArithmeticOperator(STranslateContext* pCxt, SOperatorNo static EDealRes translateComparisonOperator(STranslateContext* pCxt, SOperatorNode* pOp) { SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType; SDataType rdt = ((SExprNode*)(pOp->pRight))->resType; - if (TSDB_DATA_TYPE_BLOB == ldt.type || TSDB_DATA_TYPE_JSON == rdt.type || TSDB_DATA_TYPE_BLOB == rdt.type) { + if (TSDB_DATA_TYPE_BLOB == ldt.type || TSDB_DATA_TYPE_BLOB == rdt.type) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName); } if (OP_TYPE_IN == pOp->opType || OP_TYPE_NOT_IN == pOp->opType) { ((SExprNode*)pOp->pRight)->resType = ((SExprNode*)pOp->pLeft)->resType; } if (nodesIsRegularOp(pOp)) { - if (!IS_STR_DATA_TYPE(((SExprNode*)(pOp->pLeft))->resType.type)) { + if (!IS_VAR_DATA_TYPE(((SExprNode*)(pOp->pLeft))->resType.type)) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pLeft))->aliasName); } if (QUERY_NODE_VALUE != nodeType(pOp->pRight) || !IS_STR_DATA_TYPE(((SExprNode*)(pOp->pRight))->resType.type)) { @@ -2485,6 +2483,9 @@ static int32_t checkTableColsSchema(STranslateContext* pCxt, SHashObj* pHash, SN code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FIRST_COLUMN); } } + if (TSDB_CODE_SUCCESS == code && pCol->dataType.type == TSDB_DATA_TYPE_JSON) { + code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON); + } int32_t len = strlen(pCol->colName); if (TSDB_CODE_SUCCESS == code && NULL != taosHashGet(pHash, pCol->colName, len)) { code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN); @@ -2492,7 +2493,7 @@ static int32_t checkTableColsSchema(STranslateContext* pCxt, SHashObj* pHash, SN if (TSDB_CODE_SUCCESS == code) { if ((TSDB_DATA_TYPE_VARCHAR == pCol->dataType.type && calcTypeBytes(pCol->dataType) > TSDB_MAX_BINARY_LEN) || (TSDB_DATA_TYPE_NCHAR == pCol->dataType.type && calcTypeBytes(pCol->dataType) > TSDB_MAX_NCHAR_LEN)) { - code = code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN); + code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN); } } if (TSDB_CODE_SUCCESS == code) { @@ -4451,11 +4452,38 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS } pReq->isNull = (TSDB_DATA_TYPE_NULL == pStmt->pVal->node.resType.type); - pReq->nTagVal = pStmt->pVal->node.resType.bytes; - if (TSDB_DATA_TYPE_NCHAR == pStmt->pVal->node.resType.type) { - pReq->nTagVal = pReq->nTagVal * TSDB_NCHAR_SIZE; + if(pStmt->pVal->node.resType.type == TSDB_DATA_TYPE_JSON){ + SKVRowBuilder kvRowBuilder = {0}; + int32_t code = tdInitKVRowBuilder(&kvRowBuilder); + + if (TSDB_CODE_SUCCESS != code) { + return TSDB_CODE_OUT_OF_MEMORY; + } + if (pStmt->pVal->literal && strlen(pStmt->pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) { + return buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pStmt->pVal->literal); + } + + code = parseJsontoTagData(pStmt->pVal->literal, &kvRowBuilder, &pCxt->msgBuf, pSchema->colId); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + + SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder); + if (NULL == row) { + tdDestroyKVRowBuilder(&kvRowBuilder); + return TSDB_CODE_OUT_OF_MEMORY; + } + pReq->nTagVal = kvRowLen(row); + pReq->pTagVal = row; + pStmt->pVal->datum.p = row; // for free + tdDestroyKVRowBuilder(&kvRowBuilder); + }else{ + pReq->nTagVal = pStmt->pVal->node.resType.bytes; + if (TSDB_DATA_TYPE_NCHAR == pStmt->pVal->node.resType.type) { + pReq->nTagVal = pReq->nTagVal * TSDB_NCHAR_SIZE; + } + pReq->pTagVal = nodesGetValueFromNode(pStmt->pVal); } - pReq->pTagVal = nodesGetValueFromNode(pStmt->pVal); return TSDB_CODE_SUCCESS; } @@ -4652,7 +4680,26 @@ static int32_t rewriteAlterTable(STranslateContext* pCxt, SQuery* pQuery) { return code; } + if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG); + } + + if (pStmt->dataType.type == TSDB_DATA_TYPE_JSON && pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COL_JSON); + } + + if (getNumOfTags(pTableMeta) == 1 && pStmt->alterType == TSDB_ALTER_TABLE_DROP_TAG) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE, "can not drop tag if there is only one tag"); + } + if (TSDB_SUPER_TABLE == pTableMeta->tableType) { + SSchema* pTagsSchema = getTableTagSchema(pTableMeta); + if (getNumOfTags(pTableMeta) == 1 && pTagsSchema->type == TSDB_DATA_TYPE_JSON && + (pStmt->alterType == TSDB_ALTER_TABLE_ADD_TAG || + pStmt->alterType == TSDB_ALTER_TABLE_DROP_TAG || + pStmt->alterType == TSDB_ALTER_TABLE_UPDATE_TAG_BYTES)) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG); + } return TSDB_CODE_SUCCESS; } else if (TSDB_CHILD_TABLE != pTableMeta->tableType && TSDB_NORMAL_TABLE != pTableMeta->tableType) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE); diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 3df9c8abf7f36d5f04b9ce79070c71dd63a712ff..652ed10ce8b71c71c8eaa640dde145499fe69098 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -171,6 +171,8 @@ static char* getSyntaxErrFormat(int32_t errCode) { return "Window query not supported, since the result of subquery not include valid timestamp column"; case TSDB_CODE_PAR_INVALID_DROP_COL: return "No columns can be dropped"; + case TSDB_CODE_PAR_INVALID_COL_JSON: + return "Only tag can be json type"; case TSDB_CODE_OUT_OF_MEMORY: return "Out of memory"; default: @@ -328,7 +330,7 @@ int parseJsontoTagData(const char* json, SKVRowBuilder* kvRowBuilder, SMsgBuf* p // set json NULL data uint8_t jsonNULL = TSDB_DATA_TYPE_NULL; int jsonIndex = startColId + 1; - if (!json || strcasecmp(json, TSDB_DATA_NULL_STR_L) == 0) { + if (!json || strtrim((char*)json) == 0 ||strcasecmp(json, TSDB_DATA_NULL_STR_L) == 0) { tdAddColToKVRow(kvRowBuilder, jsonIndex, &jsonNULL, CHAR_BYTES); return TSDB_CODE_SUCCESS; } @@ -360,12 +362,12 @@ int parseJsontoTagData(const char* json, SKVRowBuilder* kvRowBuilder, SMsgBuf* p retCode = buildSyntaxErrMsg(pMsgBuf, "json key not validate", jsonKey); 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; - // } size_t keyLen = strlen(jsonKey); + if(keyLen > TSDB_MAX_JSON_KEY_LEN){ + qError("json key too long error"); + retCode = buildSyntaxErrMsg(pMsgBuf, "json key too long, more than 256", jsonKey); + goto end; + } if (keyLen == 0 || taosHashGet(keyHash, jsonKey, keyLen) != NULL) { continue; } diff --git a/source/libs/scalar/test/scalar/scalarTests.cpp b/source/libs/scalar/test/scalar/scalarTests.cpp index fb67695e8983f32973fdbe1dafa675082df5c81f..3fafc83b18365d490003a792748606c8d4fce804 100644 --- a/source/libs/scalar/test/scalar/scalarTests.cpp +++ b/source/libs/scalar/test/scalar/scalarTests.cpp @@ -1089,7 +1089,7 @@ void makeCalculate(void *json, void *key, int32_t rightType, void *rightData, do }else if(opType == OP_TYPE_ADD || opType == OP_TYPE_SUB || opType == OP_TYPE_MULTI || opType == OP_TYPE_DIV || opType == OP_TYPE_MOD || opType == OP_TYPE_MINUS){ printf("1result:%f,except:%f\n", *((double *)colDataGetData(column, 0)), exceptValue); - ASSERT_TRUE(abs(*((double *)colDataGetData(column, 0)) - exceptValue) < 1e-15); + ASSERT_TRUE(fabs(*((double *)colDataGetData(column, 0)) - exceptValue) < 0.0001); }else if(opType == OP_TYPE_BIT_AND || opType == OP_TYPE_BIT_OR){ printf("2result:%ld,except:%f\n", *((int64_t *)colDataGetData(column, 0)), exceptValue); ASSERT_EQ(*((int64_t *)colDataGetData(column, 0)), exceptValue); @@ -1107,8 +1107,10 @@ void makeCalculate(void *json, void *key, int32_t rightType, void *rightData, do TEST(columnTest, json_column_arith_op) { scltInitLogFile(); - char *rightv= "{\"k1\":4,\"k2\":\"hello\",\"k3\":null,\"k4\":true,\"k5\":5.44}"; + char *rightvTmp= "{\"k1\":4,\"k2\":\"hello\",\"k3\":null,\"k4\":true,\"k5\":5.44}"; + char rightv[256] = {0}; + memcpy(rightv, rightvTmp, strlen(rightvTmp)); SKVRowBuilder kvRowBuilder; tdInitKVRowBuilder(&kvRowBuilder); parseJsontoTagData(rightv, &kvRowBuilder, NULL, 0); @@ -1189,8 +1191,10 @@ void *prepareNchar(char* rightData){ TEST(columnTest, json_column_logic_op) { scltInitLogFile(); - char *rightv= "{\"k1\":4,\"k2\":\"hello\",\"k3\":null,\"k4\":true,\"k5\":5.44,\"k6\":\"6.6hello\"}"; + char *rightvTmp= "{\"k1\":4,\"k2\":\"hello\",\"k3\":null,\"k4\":true,\"k5\":5.44,\"k6\":\"6.6hello\"}"; + char rightv[256] = {0}; + memcpy(rightv, rightvTmp, strlen(rightvTmp)); SKVRowBuilder kvRowBuilder; tdInitKVRowBuilder(&kvRowBuilder); parseJsontoTagData(rightv, &kvRowBuilder, NULL, 0); diff --git a/source/util/src/tutil.c b/source/util/src/tutil.c index adb6a37ba737fbf1ccafe35231853f8a2fc4cfc8..0534eb3462f92a6ae4252efed389b0d309412c01 100644 --- a/source/util/src/tutil.c +++ b/source/util/src/tutil.c @@ -52,7 +52,7 @@ size_t strtrim(char *z) { int32_t j = 0; int32_t delta = 0; - while (z[j] == ' ') { + while (isspace(z[j])) { ++j; } @@ -65,9 +65,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; } diff --git a/tests/system-test/2-query/json_tag.py b/tests/system-test/2-query/json_tag.py new file mode 100644 index 0000000000000000000000000000000000000000..d8ef8fa363fe1f2911f4ea3fde9d43a82f7a8a88 --- /dev/null +++ b/tests/system-test/2-query/json_tag.py @@ -0,0 +1,565 @@ +################################################################### +# 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 +import json + + +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. + case1: [TD-12452] fix error if json tag is NULL + case2: [TD-12389] describe child table, tag length error if the tag is json tag + ''' + 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 invalidate json value, value number can not be inf,nan TD-12166 + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"k\":1.8e308}')") + tdSql.error("CREATE TABLE if not exists jsons1_14 using jsons1 tags('{\"k\":-1.8e308}')") + # + #test length limit + char1= ''.join(['abcd']*64) + char3= ''.join(['abcd']*1021) + print(len(char3)) # 4084 + 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('{\"TSSSS\":\"%s\"}')" % char3) # len(object)=4096 + #tdSql.execute("CREATE TABLE if not exists jsons1_16 using jsons1 tags('{\"TSSS\":\"%s\"}')" % char3) # len(object)=4095 + 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 rename TAG jtag jtag_new") + tdSql.execute("ALTER TABLE jsons1 rename TAG jtag_new jtag") + + tdSql.execute("create table st(ts timestamp, i int) tags(t int)") + tdSql.error("ALTER STABLE st add tag jtag json") + tdSql.error("ALTER STABLE st add column jtag json") + # + # 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(8) + # tdSql.query("select jtag from jsons1") + # tdSql.checkRows(7) + # 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(1, 0, 2) + # tdSql.checkData(1, 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(6, 0, 2) + # tdSql.checkData(6, 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(6, 0, 11) + # tdSql.checkData(6, 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(8, 1, 1) + # tdSql.checkData(8, 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(1, 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) + # + # #test TD-12077 + # tdSql.execute("insert into jsons1_16 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":-2.111}') values(1591062628000, 2, NULL, '你就会', 'dws')") + # tdSql.query("select jtag->'tag3' from jsons1_16") + # tdSql.checkData(0, 0, '-2.111000000') + # + # # test TD-12452 + # tdSql.execute("ALTER TABLE jsons1_1 SET TAG jtag=NULL") + # tdSql.query("select jtag from jsons1_1") + # tdSql.checkData(0, 0, None) + # tdSql.execute("CREATE TABLE if not exists jsons1_20 using jsons1 tags(NULL)") + # tdSql.query("select jtag from jsons1_20") + # tdSql.checkData(0, 0, None) + # tdSql.execute("insert into jsons1_21 using jsons1 tags(NULL) values(1591061628000, 11, false, '你就会','')") + # tdSql.query("select jtag from jsons1_21") + # tdSql.checkData(0, 0, None) + # + # #test TD-12389 + tdSql.query("describe jsons1") + tdSql.checkData(5, 2, 4095) + tdSql.query("describe jsons1_1") + tdSql.checkData(5, 2, 4095) + # + # #test TD-13918 + # tdSql.execute("drop table if exists jsons_13918_1") + # tdSql.execute("drop table if exists jsons_13918_2") + # tdSql.execute("drop table if exists jsons_13918_3") + # tdSql.execute("drop table if exists jsons_13918_4") + # tdSql.execute("drop table if exists jsons_stb") + # tdSql.execute("create table jsons_stb (ts timestamp, dataInt int) tags (jtag json)") + # tdSql.error("create table jsons_13918_1 using jsons_stb tags ('nullx')") + # tdSql.error("create table jsons_13918_2 using jsons_stb tags (nullx)") + # tdSql.error("insert into jsons_13918_3 using jsons_stb tags('NULLx') values(1591061628001, 11)") + # tdSql.error("insert into jsons_13918_4 using jsons_stb tags(NULLx) values(1591061628002, 11)") + # tdSql.execute("create table jsons_13918_1 using jsons_stb tags ('null')") + # tdSql.execute("create table jsons_13918_2 using jsons_stb tags (null)") + # tdSql.execute("insert into jsons_13918_1 values(1591061628003, 11)") + # tdSql.execute("insert into jsons_13918_2 values(1591061628004, 11)") + # tdSql.execute("insert into jsons_13918_3 using jsons_stb tags('NULL') values(1591061628005, 11)") + # tdSql.execute("insert into jsons_13918_4 using jsons_stb tags(\"NULL\") values(1591061628006, 11)") + # tdSql.query("select * from jsons_stb") + # tdSql.checkRows(4) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) +