diff --git a/Jenkinsfile b/Jenkinsfile index d606479006c50afc976361208175762899c87e5e..491e70742825fb9d655ca76321085a133c4aea63 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -456,23 +456,42 @@ pipeline { nohup taosd >/dev/null & sleep 10 ''' + sh ''' - cd ${WKC}/tests/examples/nodejs - npm install td2.0-connector > /dev/null 2>&1 - node nodejsChecker.js host=localhost - node test1970.js - cd ${WKC}/tests/connectorTest/nodejsTest/nanosupport - npm install td2.0-connector > /dev/null 2>&1 - node nanosecondTest.js + cd ${WKC}/src/connector/python + export PYTHONPATH=$PWD/ + export LD_LIBRARY_PATH=${WKC}/debug/build/lib + pip3 install pytest + pytest tests/ + python3 examples/bind-multi.py + python3 examples/bind-row.py + python3 examples/demo.py + python3 examples/insert-lines.py + python3 examples/pep-249.py + python3 examples/query-async.py + python3 examples/query-objectively.py + python3 examples/subscribe-sync.py + python3 examples/subscribe-async.py + ''' + + sh ''' + cd ${WKC}/tests/examples/nodejs + npm install td2.0-connector > /dev/null 2>&1 + node nodejsChecker.js host=localhost + node test1970.js + cd ${WKC}/tests/connectorTest/nodejsTest/nanosupport + npm install td2.0-connector > /dev/null 2>&1 + node nanosecondTest.js ''' catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { sh ''' cd ${WKC}/tests/examples/C#/taosdemo - mcs -out:taosdemo *.cs > /dev/null 2>&1 - echo '' |./taosdemo -c /etc/taos + dotnet build -c Release + tree | true + ./bin/Release/net5.0/taosdemo -c /etc/taos -y ''' - } + } sh ''' cd ${WKC}/tests/gotest bash batchtest.sh diff --git a/packaging/cfg/taosd.service b/packaging/cfg/taosd.service index fff4b74e62a6da8f2bda9a6306a79132d7585e42..452488b4e951e36c043c823e17cca5ab7dbfd21b 100644 --- a/packaging/cfg/taosd.service +++ b/packaging/cfg/taosd.service @@ -1,7 +1,7 @@ [Unit] Description=TDengine server service -After=network-online.target -Wants=network-online.target +After=network-online.target taosadapter.service +Wants=network-online.target taosadapter.service [Service] Type=simple diff --git a/packaging/release.sh b/packaging/release.sh index 8eaf18774232e10c0435d1bf9e78ed42e16bdac6..ca8715f68430fc08b86f008936ddfc9409ae58a8 100755 --- a/packaging/release.sh +++ b/packaging/release.sh @@ -3,7 +3,7 @@ # Generate the deb package for ubuntu, or rpm package for centos, or tar.gz package for other linux os set -e -#set -x +set -x # release.sh -v [cluster | edge] # -c [aarch32 | aarch64 | x64 | x86 | mips64 ...] @@ -414,10 +414,14 @@ fi if [[ "$httpdBuild" == "true" ]]; then BUILD_HTTP=true - BUILD_TOOLS=false else BUILD_HTTP=false +fi + +if [[ "$pagMode" == "full" ]]; then BUILD_TOOLS=true +else + BUILD_TOOLS=false fi # check support cpu type @@ -514,15 +518,17 @@ if [ "$osType" != "Darwin" ]; then cd ${script_dir}/deb ${csudo} ./makedeb.sh ${compile_dir} ${output_dir} ${verNumber} ${cpuType} ${osType} ${verMode} ${verType} - if [ -d ${top_dir}/src/kit/taos-tools/packaging/deb ]; then - cd ${top_dir}/src/kit/taos-tools/packaging/deb - [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" + if [[ "$pagMode" == "full" ]]; then + if [ -d ${top_dir}/src/kit/taos-tools/packaging/deb ]; then + cd ${top_dir}/src/kit/taos-tools/packaging/deb + [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" - taos_tools_ver=$(git describe --tags|sed -e 's/ver-//g'|awk -F '-' '{print $1}') - ${csudo} ./make-taos-tools-deb.sh ${top_dir} \ - ${compile_dir} ${output_dir} ${taos_tools_ver} ${cpuType} ${osType} ${verMode} ${verType} + taos_tools_ver=$(git describe --tags|sed -e 's/ver-//g'|awk -F '-' '{print $1}') + ${csudo} ./make-taos-tools-deb.sh ${top_dir} \ + ${compile_dir} ${output_dir} ${taos_tools_ver} ${cpuType} ${osType} ${verMode} ${verType} + fi fi - else + else echo "==========dpkg command not exist, so not release deb package!!!" fi ret='0' @@ -537,15 +543,17 @@ if [ "$osType" != "Darwin" ]; then cd ${script_dir}/rpm ${csudo} ./makerpm.sh ${compile_dir} ${output_dir} ${verNumber} ${cpuType} ${osType} ${verMode} ${verType} - if [ -d ${top_dir}/src/kit/taos-tools/packaging/rpm ]; then - cd ${top_dir}/src/kit/taos-tools/packaging/rpm - [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" + if [[ "$pagMode" == "full" ]]; then + if [ -d ${top_dir}/src/kit/taos-tools/packaging/rpm ]; then + cd ${top_dir}/src/kit/taos-tools/packaging/rpm + [ -z "$taos_tools_ver" ] && taos_tools_ver="0.1.0" - taos_tools_ver=$(git describe --tags|sed -e 's/ver-//g'|awk -F '-' '{print $1}'|sed -e 's/-/_/g') - ${csudo} ./make-taos-tools-rpm.sh ${top_dir} \ - ${compile_dir} ${output_dir} ${taos_tools_ver} ${cpuType} ${osType} ${verMode} ${verType} + taos_tools_ver=$(git describe --tags|sed -e 's/ver-//g'|awk -F '-' '{print $1}'|sed -e 's/-/_/g') + ${csudo} ./make-taos-tools-rpm.sh ${top_dir} \ + ${compile_dir} ${output_dir} ${taos_tools_ver} ${cpuType} ${osType} ${verMode} ${verType} + fi fi - else + else echo "==========rpmbuild command not exist, so not release rpm package!!!" fi fi diff --git a/packaging/tools/install_client_jh.sh b/packaging/tools/install_client_jh.sh index cccf0a97be053796099d5b5f4a2c3db018c24955..a8599812feaea06120aa3391771e7c94523a53c2 100755 --- a/packaging/tools/install_client_jh.sh +++ b/packaging/tools/install_client_jh.sh @@ -188,9 +188,6 @@ function update() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config @@ -215,9 +212,6 @@ function install() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config diff --git a/packaging/tools/install_client_kh.sh b/packaging/tools/install_client_kh.sh index 210fd27fb6978527d76f0c915d0293370b93cf3e..3e7df18486a20b9ea75dba3d2644d46bee6b423b 100755 --- a/packaging/tools/install_client_kh.sh +++ b/packaging/tools/install_client_kh.sh @@ -189,9 +189,6 @@ function update() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config @@ -216,9 +213,6 @@ function install() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config diff --git a/packaging/tools/install_client_power.sh b/packaging/tools/install_client_power.sh index f96b0134dc34f61425410360d0b0f935da7b39e5..3c9abddb09646ea54f44e28664afea49822055f6 100755 --- a/packaging/tools/install_client_power.sh +++ b/packaging/tools/install_client_power.sh @@ -247,9 +247,6 @@ function update_PowerDB() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config @@ -275,9 +272,6 @@ function install_PowerDB() { install_header install_lib install_jemalloc - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config diff --git a/packaging/tools/install_client_pro.sh b/packaging/tools/install_client_pro.sh index c21f9d2e6aa685096eb55dcc03924bf453906b8f..e34dc6d4ac1d1ef1715ff903b38b1a8735001985 100755 --- a/packaging/tools/install_client_pro.sh +++ b/packaging/tools/install_client_pro.sh @@ -189,9 +189,6 @@ function update_prodb() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config @@ -216,9 +213,6 @@ function install_prodb() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config diff --git a/packaging/tools/install_client_tq.sh b/packaging/tools/install_client_tq.sh index 31a75f4fe74fbb4c68942f226602fa2117e1a01c..b7f10324dcd1c62fee20fe11399fbb61d8a38577 100755 --- a/packaging/tools/install_client_tq.sh +++ b/packaging/tools/install_client_tq.sh @@ -193,9 +193,6 @@ function update_tq() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config @@ -220,9 +217,6 @@ function install_tq() { install_log install_header install_lib - if [ "$pagMode" != "lite" ]; then - install_connector - fi install_examples install_bin install_config diff --git a/packaging/tools/makeclient_jh.sh b/packaging/tools/makeclient_jh.sh index 267d78b953be33c567f8175a369b13f326ee3f5a..ed61cffaf793ede0f774fa1ba2c81d7645f714dc 100755 --- a/packaging/tools/makeclient_jh.sh +++ b/packaging/tools/makeclient_jh.sh @@ -69,10 +69,10 @@ if [ "$osType" != "Darwin" ]; then if [ "$pagMode" == "lite" ]; then strip ${build_dir}/bin/taos cp ${build_dir}/bin/taos ${install_dir}/bin/jh_taos - cp ${script_dir}/remove_jh.sh ${install_dir}/bin + cp ${script_dir}/remove_client_jh.sh ${install_dir}/bin else cp ${build_dir}/bin/taos ${install_dir}/bin/jh_taos - cp ${script_dir}/remove_jh.sh ${install_dir}/bin + cp ${script_dir}/remove_client_jh.sh ${install_dir}/bin cp ${build_dir}/bin/taosdemo ${install_dir}/bin/jhdemo cp ${build_dir}/bin/taosdump ${install_dir}/bin/jh_taosdump cp ${script_dir}/set_core.sh ${install_dir}/bin diff --git a/packaging/tools/makeclient_kh.sh b/packaging/tools/makeclient_kh.sh index b991e2a6fae69a72d678cf5ff8751429a9f88fc6..86d37105a4acd3fcefbfa8d230804d7d2f820fb5 100755 --- a/packaging/tools/makeclient_kh.sh +++ b/packaging/tools/makeclient_kh.sh @@ -69,10 +69,10 @@ if [ "$osType" != "Darwin" ]; then if [ "$pagMode" == "lite" ]; then strip ${build_dir}/bin/taos cp ${build_dir}/bin/taos ${install_dir}/bin/khclient - cp ${script_dir}/remove_kh.sh ${install_dir}/bin + cp ${script_dir}/remove_client_kh.sh ${install_dir}/bin else cp ${build_dir}/bin/taos ${install_dir}/bin/khclient - cp ${script_dir}/remove_kh.sh ${install_dir}/bin + cp ${script_dir}/remove_client_kh.sh ${install_dir}/bin cp ${build_dir}/bin/taosdemo ${install_dir}/bin/khdemo cp ${build_dir}/bin/taosdump ${install_dir}/bin/khdump cp ${script_dir}/set_core.sh ${install_dir}/bin diff --git a/packaging/tools/makeclient_power.sh b/packaging/tools/makeclient_power.sh index 07dc9d30d21e130aff15f1c84a3db7e209867f88..2f01748f5e40925b905a715b3c308692d46e71b0 100755 --- a/packaging/tools/makeclient_power.sh +++ b/packaging/tools/makeclient_power.sh @@ -109,10 +109,10 @@ if [ "$osType" != "Darwin" ]; then if [ "$pagMode" == "lite" ]; then strip ${build_dir}/bin/taos cp ${build_dir}/bin/taos ${install_dir}/bin/power - cp ${script_dir}/remove_power.sh ${install_dir}/bin + cp ${script_dir}/remove_client_power.sh ${install_dir}/bin else cp ${build_dir}/bin/taos ${install_dir}/bin/power - cp ${script_dir}/remove_power.sh ${install_dir}/bin + cp ${script_dir}/remove_client_power.sh ${install_dir}/bin cp ${build_dir}/bin/taosdemo ${install_dir}/bin/powerdemo cp ${build_dir}/bin/taosdump ${install_dir}/bin/powerdump cp ${script_dir}/set_core.sh ${install_dir}/bin diff --git a/packaging/tools/makeclient_pro.sh b/packaging/tools/makeclient_pro.sh index 0c5033d87dd5815e9e3ec309e6b1bb9abe98ca42..769d0274e5eb5198fedb6c6c3a7f1590fd2ff44a 100755 --- a/packaging/tools/makeclient_pro.sh +++ b/packaging/tools/makeclient_pro.sh @@ -69,10 +69,10 @@ if [ "$osType" != "Darwin" ]; then if [ "$pagMode" == "lite" ]; then strip ${build_dir}/bin/taos cp ${build_dir}/bin/taos ${install_dir}/bin/prodbc - cp ${script_dir}/remove_pro.sh ${install_dir}/bin + cp ${script_dir}/remove_client_pro.sh ${install_dir}/bin else cp ${build_dir}/bin/taos ${install_dir}/bin/prodbc - cp ${script_dir}/remove_pro.sh ${install_dir}/bin + cp ${script_dir}/remove_client_pro.sh ${install_dir}/bin cp ${build_dir}/bin/taosdemo ${install_dir}/bin/prodemo cp ${build_dir}/bin/taosdump ${install_dir}/bin/prodump cp ${script_dir}/set_core.sh ${install_dir}/bin diff --git a/packaging/tools/makeclient_tq.sh b/packaging/tools/makeclient_tq.sh index 3ed97520939be51f2f634f8955f16ecf9a46821b..f8d87ba76a9ab32ea729d4999a05712976a32634 100755 --- a/packaging/tools/makeclient_tq.sh +++ b/packaging/tools/makeclient_tq.sh @@ -69,10 +69,10 @@ if [ "$osType" != "Darwin" ]; then if [ "$pagMode" == "lite" ]; then strip ${build_dir}/bin/taos cp ${build_dir}/bin/taos ${install_dir}/bin/tq - cp ${script_dir}/remove_tq.sh ${install_dir}/bin + cp ${script_dir}/remove_client_tq.sh ${install_dir}/bin else cp ${build_dir}/bin/taos ${install_dir}/bin/tq - cp ${script_dir}/remove_tq.sh ${install_dir}/bin + cp ${script_dir}/remove_client_tq.sh ${install_dir}/bin cp ${build_dir}/bin/taosdemo ${install_dir}/bin/tqdemo cp ${build_dir}/bin/taosdump ${install_dir}/bin/tqdump cp ${script_dir}/set_core.sh ${install_dir}/bin diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 249d0bc4c73a610b2915c5fd81f6787875d44b5c..dd9db517956e9e72ebef040c6b765c8a315a95ad 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 97cc3383c9b5609a2a7064ae247d074b15374751..b1130e1b86eb1ed24b11f3aa3ca1c38f4d5fdf12 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/tscParseLineProtocol.c b/src/client/src/tscParseLineProtocol.c index 1a9c90bf4d9f13c2b2c04fa9825c1b3a5c8b76e5..085b949cc102e3752abd41caacdf07985351e1db 100644 --- a/src/client/src/tscParseLineProtocol.c +++ b/src/client/src/tscParseLineProtocol.c @@ -887,7 +887,7 @@ static int32_t applyChildTableDataPointsWithInsertSQL(TAOS* taos, char* cTableNa TAOS_RES* res = taos_query(taos, sql); free(sql); code = taos_errno(res); - info->affectedRows = taos_affected_rows(res); + info->affectedRows += taos_affected_rows(res); taos_free_result(res); return code; } @@ -1303,14 +1303,6 @@ clean_up: return code; } -int tsc_sml_insert(TAOS* taos, TAOS_SML_DATA_POINT* points, int numPoint) { - SSmlLinesInfo* info = calloc(1, sizeof(SSmlLinesInfo)); - info->id = genLinesSmlId(); - int code = tscSmlInsert(taos, points, numPoint, info); - free(info); - return code; -} - //========================================================================= /* Field Escape charaters diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index 215861295fa0ff94352956fa3fd740ace9e90766..8d1a79e734cabf6694daf30d8887265488bcf630 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -1533,6 +1533,41 @@ int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAO return TSDB_CODE_SUCCESS; } +int32_t stmtValidateValuesFields(SSqlCmd *pCmd, char * sql) { + int32_t loopCont = 1, index0 = 0, values = 0; + SStrToken sToken; + + while (loopCont) { + sToken = tStrGetToken(sql, &index0, false); + if (sToken.n <= 0) { + return TSDB_CODE_SUCCESS; + } + + switch (sToken.type) { + case TK_RP: + if (values) { + return TSDB_CODE_SUCCESS; + } + break; + case TK_VALUES: + values = 1; + break; + case TK_QUESTION: + case TK_LP: + break; + default: + if (values) { + tscError("only ? allowed in values"); + return tscInvalidOperationMsg(pCmd->payload, "only ? allowed in values", NULL); + } + break; + } + } + + return TSDB_CODE_SUCCESS; +} + + //////////////////////////////////////////////////////////////////////////////// // interface functions @@ -1637,6 +1672,11 @@ int taos_stmt_prepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { STMT_RET(ret); } + ret = stmtValidateValuesFields(&pSql->cmd, pSql->sqlstr); + if (ret != TSDB_CODE_SUCCESS) { + STMT_RET(ret); + } + if (pStmt->multiTbInsert) { STMT_RET(TSDB_CODE_SUCCESS); } diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index f229b06a878c197a75ce7563234cbbf4923f5f6e..bbe148a3ed74546fecec364ac105e65825039d9c 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" @@ -164,6 +165,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); @@ -285,6 +287,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: @@ -1521,7 +1527,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; } @@ -1560,7 +1566,6 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) { return true; } - static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd) { assert(pTagsList != NULL); @@ -1571,6 +1576,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); @@ -1586,6 +1592,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); @@ -1604,18 +1615,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; } @@ -1642,6 +1656,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; @@ -1667,6 +1682,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); @@ -1675,6 +1693,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; } @@ -1975,20 +1997,34 @@ static int32_t handleSQLExprItem(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t 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; } @@ -2155,6 +2191,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_EXPR) { int32_t code = handleSQLExprItem(pCmd, pQueryInfo, i, pItem); @@ -2346,6 +2386,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; @@ -2385,13 +2428,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); } @@ -2438,6 +2497,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; } @@ -3531,7 +3598,9 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { return TSDB_CODE_TSC_INVALID_OPERATION; } - strncpy(pCmd->payload, idStr->z, idStr->n); + SKillQueryMsg* msg = (SKillQueryMsg*)pCmd->payload; + + strncpy(msg->queryId, idStr->z, idStr->n); const char delim = ':'; char* connIdStr = strtok(idStr->z, &delim); @@ -3539,7 +3608,7 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { int32_t connId = (int32_t)strtol(connIdStr, NULL, 10); if (connId <= 0) { - memset(pCmd->payload, 0, strlen(pCmd->payload)); + memset(msg, 0, sizeof(*msg)); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -3549,7 +3618,7 @@ int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killType) { int32_t queryId = (int32_t)strtol(queryIdStr, NULL, 10); if (queryId <= 0) { - memset(pCmd->payload, 0, strlen(pCmd->payload)); + memset(msg, 0, sizeof(*msg)); if (killType == TSDB_SQL_KILL_QUERY) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } else { @@ -3845,6 +3914,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; @@ -3880,13 +3952,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; @@ -3909,6 +3986,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); @@ -3923,9 +4007,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 { @@ -3935,7 +4027,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)); @@ -3954,7 +4046,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); } } @@ -4281,8 +4373,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); } @@ -4298,6 +4399,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; @@ -4316,7 +4420,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); } @@ -4332,6 +4436,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; @@ -4563,6 +4670,11 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr, } } else if (pExpr->type == SQL_NODE_TABLE_COLUMN) { SColumnIndex index = COLUMN_INDEX_INITIALIZER; + + if (pExpr->tokenId == TK_ARROW) { + pExpr = pExpr->pLeft; + } + if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -4628,7 +4740,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 @@ -4665,8 +4777,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; @@ -4743,13 +4875,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; } @@ -4787,7 +4919,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); } } @@ -4795,6 +4927,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"; @@ -4863,10 +5048,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); } @@ -4975,7 +5174,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; } @@ -4991,7 +5198,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; } @@ -5142,6 +5352,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; } @@ -5466,7 +5679,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); @@ -5653,7 +5866,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; } @@ -6060,7 +6274,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"; @@ -6070,6 +6284,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); @@ -6106,14 +6322,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; @@ -6147,7 +6373,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 @@ -6182,10 +6422,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; @@ -6206,12 +6446,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); @@ -6237,7 +6477,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; @@ -6255,9 +6495,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); } @@ -6265,8 +6514,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; } } @@ -6296,7 +6544,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; } @@ -6322,7 +6570,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; @@ -6333,7 +6581,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 { @@ -6370,7 +6618,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; } @@ -6407,6 +6655,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; @@ -6566,22 +6816,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; @@ -6617,15 +6877,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 @@ -7415,12 +7692,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; + } } } @@ -7456,7 +7739,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; } @@ -7640,16 +7923,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)) { @@ -8168,6 +8458,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; @@ -8292,7 +8583,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. @@ -8309,7 +8599,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; @@ -8331,7 +8621,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); @@ -8347,8 +8637,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. @@ -8365,7 +8653,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; } } @@ -9709,6 +10021,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS if (pSqlExpr->type != SQL_NODE_EXPR && pSqlExpr->type != SQL_NODE_SQLFUNCTION) { assert(pSqlExpr->pLeft == NULL && 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; @@ -9863,7 +10178,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 9947faf0524c6c3af090f78fb1d3c284cb61e754..35582973c2af7b214d3054807d31a897c7256191 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -506,7 +506,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { } } - if (pRes->code == TSDB_CODE_SUCCESS && tscProcessMsgRsp[pCmd->command]) { + if (pRes->code == TSDB_CODE_SUCCESS && pCmd->command < TSDB_SQL_MAX && tscProcessMsgRsp[pCmd->command]) { rpcMsg->code = (*tscProcessMsgRsp[pCmd->command])(pSql); } @@ -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; } @@ -906,6 +906,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SArray* queryOperator = createExecOperatorPlan(&query); SQueryTableMsg *pQueryMsg = (SQueryTableMsg *)pCmd->payload; + tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version)); int32_t numOfTags = query.numOfTags; @@ -1146,6 +1147,23 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { memcpy(pMsg, pSql->sqlstr, sqlLen); pMsg += sqlLen; + +/* + //MSG EXTEND DEMO + pQueryMsg->extend = 1; + + STLV *tlv = (STLV *)pMsg; + tlv->type = htons(TLV_TYPE_DUMMY); + tlv->len = htonl(sizeof(int16_t)); + *(int16_t *)tlv->value = htons(12345); + pMsg += sizeof(*tlv) + ntohl(tlv->len); + + tlv = (STLV *)pMsg; + tlv->len = 0; + pMsg += sizeof(*tlv); + +*/ + int32_t msgLen = (int32_t)(pMsg - pCmd->payload); tscDebug("0x%"PRIx64" msg built success, len:%d bytes", pSql->self, msgLen); @@ -1492,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); } @@ -1614,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); @@ -1645,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; @@ -1854,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) { @@ -2813,7 +2824,11 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn tscAddQueryInfo(&pNew->cmd); SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd); - if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen)) { + int payLoadLen = TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen; + if (autocreate && pSql->cmd.insertParam.tagData.dataLen != 0) { + payLoadLen += pSql->cmd.insertParam.tagData.dataLen; + } + if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, payLoadLen)) { tscError("0x%"PRIx64" malloc failed for payload to get table meta", pSql->self); tscFreeSqlObj(pNew); 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 cf6bb4640758e0d7f4fe6e5d83e76073faeacc60..5f8964bb34b5939ab768877cb8ae701e20443f75 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 c4d98d0bdc29c8cedb64dcc43c57943771340f0e..527185468f4032e50475f7f040642a33c5037ac6 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; @@ -734,34 +736,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); @@ -785,8 +786,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) { @@ -794,6 +850,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) { @@ -807,11 +867,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) { @@ -822,7 +882,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)) { @@ -878,17 +938,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; @@ -1278,14 +1327,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); @@ -1319,8 +1368,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); @@ -1435,7 +1482,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 @@ -1444,7 +1490,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) { @@ -3095,12 +3141,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; } @@ -5396,3 +5442,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 94e56940c4a9e911e9a2e15b9c0da00686f53705..63a19c5c1b74028b8536982b0b2445c06de121b4 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -247,6 +247,7 @@ 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); } else if (pNode->nodeType == TSQL_NODE_FUNC) { @@ -255,7 +256,7 @@ void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) { tfree(pNode->pType); } - free(pNode); + tfree(pNode); } static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { @@ -272,7 +273,7 @@ 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); } else if ((*pExpr)->nodeType == TSQL_NODE_FUNC) { @@ -284,7 +285,7 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { tfree((*pExpr)->pType); } - free(*pExpr); + tfree(*pExpr); *pExpr = NULL; } @@ -502,7 +503,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 { @@ -571,7 +572,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/main/java/com/taosdata/jdbc/AbstractResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java index e17548055c792e900a1e2fb5b510de8bf65de7a7..07553d7ef4e1ea0745d25523d0fd1612086c3826 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java @@ -11,6 +11,11 @@ import java.util.Map; public abstract class AbstractResultSet extends WrapperImpl implements ResultSet { private int fetchSize; protected boolean wasNull; + protected int timestampPrecision; + + public void setTimestampPrecision(int timestampPrecision) { + this.timestampPrecision = timestampPrecision; + } protected void checkAvailability(int columnIndex, int bounds) throws SQLException { if (isClosed()) diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java index 3814186f779203741001943efe47b85c0be83acb..003324d27a57c3557f0bb3205fcee208aa776ed5 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java @@ -74,9 +74,8 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { public boolean next() throws SQLException { if (this.getBatchFetch()) { - if (this.blockData.forward()) { + if (this.blockData.forward()) return true; - } int code = this.jniConnector.fetchBlock(this.resultSetPointer, this.blockData); this.blockData.reset(); @@ -214,7 +213,18 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (!lastWasNull) { Object value = this.rowData.getObject(columnIndex); if (value instanceof Timestamp) { - res = ((Timestamp) value).getTime(); + Timestamp ts = (Timestamp) value; + long epochSec = ts.getTime() / 1000; + long nanoAdjustment = ts.getNanos(); + switch (this.timestampPrecision) { + case 0: + default: // ms + return ts.getTime(); + case 1: // us + return epochSec * 1000_000L + nanoAdjustment / 1000L; + case 2: // ns + return epochSec * 1000_000_000L + nanoAdjustment; + } } else { int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); res = this.rowData.getLong(columnIndex, nativeType); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java index 2c77df2981e18931d6cb56cca84bb2115716b349..ce877987e6e9073defbff62e283910ee34366c4d 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java @@ -47,6 +47,8 @@ public class TSDBStatement extends AbstractStatement { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); } TSDBResultSet res = new TSDBResultSet(this, this.connection.getConnector(), pSql); + int timestampPrecision = this.connection.getConnector().getResultTimePrecision(pSql); + res.setTimestampPrecision(timestampPrecision); res.setBatchFetch(this.connection.getBatchFetch()); return res; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java index 79350076c7f4b31743ab9fb61226e506186f0f17..4558dfa84bfccacf9f0d4fa2d7991c8bd0546b30 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java @@ -1,8 +1,7 @@ package com.taosdata.jdbc.enums; -public enum TimestampPrecision { - MS, - US, - NS, - UNKNOWN +public class TimestampPrecision { + public static final int MS = 0; + public static final int US = 1; + public static final int NS = 2; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java index f3e3f138df8fc854817c0adf57c5f5453f52bf05..d4c30115f851aa0f8b6f80994bbece609649428d 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java @@ -168,11 +168,22 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { case TIMESTAMP: { Long value = row.getLong(colIndex); //TODO: this implementation has bug if the timestamp bigger than 9999_9999_9999_9 - if (value < 1_0000_0000_0000_0L) + if (value < 1_0000_0000_0000_0L) { + this.timestampPrecision = TimestampPrecision.MS; return new Timestamp(value); - long epochSec = value / 1000_000L; - long nanoAdjustment = value % 1000_000L * 1000L; - return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); + } + if (value >= 1_0000_0000_0000_0L && value < 1_000_000_000_000_000_0l) { + this.timestampPrecision = TimestampPrecision.US; + long epochSec = value / 1000_000L; + long nanoAdjustment = value % 1000_000L * 1000L; + return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); + } + if (value >= 1_000_000_000_000_000_0l) { + this.timestampPrecision = TimestampPrecision.NS; + long epochSec = value / 1000_000_000L; + long nanoAdjustment = value % 1000_000_000L; + return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); + } } case UTC: { String value = row.getString(colIndex); @@ -182,12 +193,15 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { if (value.length() > 31) { // ns timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSSSSS+0x00 nanoAdjustment = fractionalSec; + this.timestampPrecision = TimestampPrecision.NS; } else if (value.length() > 28) { // ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00 nanoAdjustment = fractionalSec * 1000L; + this.timestampPrecision = TimestampPrecision.US; } else { // ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00 nanoAdjustment = fractionalSec * 1000_000L; + this.timestampPrecision = TimestampPrecision.MS; } ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5)); Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant(); @@ -196,7 +210,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { case STRING: default: { String value = row.getString(colIndex); - TimestampPrecision precision = Utils.guessTimestampPrecision(value); + int precision = Utils.guessTimestampPrecision(value); + this.timestampPrecision = precision; + if (precision == TimestampPrecision.MS) { // ms timestamp: yyyy-MM-dd HH:mm:ss.SSS return row.getTimestamp(colIndex); @@ -338,8 +354,18 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { wasNull = value == null; if (value == null) return 0; - if (value instanceof Timestamp) - return ((Timestamp) value).getTime(); + if (value instanceof Timestamp) { + Timestamp ts = (Timestamp) value; + switch (this.timestampPrecision) { + case TimestampPrecision.MS: + default: + return ts.getTime(); + case TimestampPrecision.US: + return ts.getTime() * 1000 + ts.getNanos() / 1000 % 1000; + case TimestampPrecision.NS: + return ts.getTime() * 1000_000 + ts.getNanos() % 1000_000; + } + } long valueAsLong = 0; try { valueAsLong = Long.parseLong(value.toString()); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java index 6cd1ff7200962b7347969e0b8b10443083505912..6ec76fffd93751b0cb57e116085de9da550f214e 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java @@ -194,14 +194,14 @@ public class Utils { return timestamp.toLocalDateTime().format(milliSecFormatter); } - public static TimestampPrecision guessTimestampPrecision(String value) { + public static int guessTimestampPrecision(String value) { if (isMilliSecFormat(value)) return TimestampPrecision.MS; if (isMicroSecFormat(value)) return TimestampPrecision.US; if (isNanoSecFormat(value)) return TimestampPrecision.NS; - return TimestampPrecision.UNKNOWN; + return TimestampPrecision.MS; } private static boolean isMilliSecFormat(String timestampStr) { 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/jdbc/src/test/java/com/taosdata/jdbc/cases/GetLongWithDifferentTimestampPrecision.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/GetLongWithDifferentTimestampPrecision.java new file mode 100644 index 0000000000000000000000000000000000000000..1ba7bdc4057e5c9e2977d3723fe329e761e7258c --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/GetLongWithDifferentTimestampPrecision.java @@ -0,0 +1,59 @@ +package com.taosdata.jdbc.cases; + +import org.junit.Assert; +import org.junit.Test; + +import java.sql.*; +import java.text.SimpleDateFormat; + +public class GetLongWithDifferentTimestampPrecision { + + private final String host = "127.0.0.1"; + + @Test + public void testRestful() throws SQLException { + // given + String url = "jdbc:TAOS-RS://" + host + ":6041/"; + Connection conn = DriverManager.getConnection(url, "root", "taosdata"); + long ts = System.currentTimeMillis(); + + // when and then + assertResultSet(conn, "ms", ts, ts); + assertResultSet(conn, "us", ts, ts * 1000); + assertResultSet(conn, "ns", ts, ts * 1000_000); + } + + @Test + public void testJni() throws SQLException { + // given + String url = "jdbc:TAOS://" + host + ":6030/"; + Connection conn = DriverManager.getConnection(url, "root", "taosdata"); + long ts = System.currentTimeMillis(); + + // when and then + assertResultSet(conn, "ms", ts, ts); + assertResultSet(conn, "us", ts, ts * 1000); + assertResultSet(conn, "ns", ts, ts * 1000_000); + } + + private void assertResultSet(Connection conn, String precision, long timestamp, long expect) throws SQLException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + try (Statement stmt = conn.createStatement()) { + stmt.execute("drop database if exists test"); + stmt.execute("create database if not exists test precision '" + precision + "'"); + stmt.execute("create table test.weather(ts timestamp, f1 int)"); + + String dateTimeStr = sdf.format(new Date(timestamp)); + stmt.execute("insert into test.weather values('" + dateTimeStr + "', 1)"); + + ResultSet rs = stmt.executeQuery("select * from test.weather"); + rs.next(); + long actual = rs.getLong("ts"); + Assert.assertEquals(expect, actual); + stmt.execute("drop database if exists test"); + } + } + + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java index 5de1655ee48776b6798619814fe2729625282764..da30bbd568c7043af493baeecc118f256ad73b10 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java @@ -9,29 +9,29 @@ import java.util.Random; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class RestfulJDBCTest { - // private static final String host = "127.0.0.1"; - private static final String host = "master"; + private static final String host = "127.0.0.1"; private static final Random random = new Random(System.currentTimeMillis()); private static Connection connection; + private static final String dbname = "restful_test"; @Test public void testCase001() throws SQLException { // given - String sql = "drop database if exists restful_test"; + String sql = "drop database if exists " + dbname; // when boolean execute = execute(connection, sql); // then Assert.assertFalse(execute); // given - sql = "create database if not exists restful_test"; + sql = "create database if not exists " + dbname; // when execute = execute(connection, sql); // then Assert.assertFalse(execute); // given - sql = "use restful_test"; + sql = "use " + dbname; // when execute = execute(connection, sql); // then @@ -41,7 +41,7 @@ public class RestfulJDBCTest { @Test public void testCase002() throws SQLException { // given - String sql = "create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)"; + String sql = "create table " + dbname + ".weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)"; // when boolean execute = execute(connection, sql); // then @@ -52,7 +52,7 @@ public class RestfulJDBCTest { public void testCase004() throws SQLException { for (int i = 1; i <= 100; i++) { // given - String sql = "create table t" + i + " using weather tags('beijing', '" + i + "')"; + String sql = "create table " + dbname + ".t" + i + " using " + dbname + ".weather tags('beijing', '" + i + "')"; // when boolean execute = execute(connection, sql); // then @@ -68,7 +68,7 @@ public class RestfulJDBCTest { // given long currentTimeMillis = System.currentTimeMillis(); - String sql = "insert into t" + j + " values(" + currentTimeMillis + "," + (random.nextFloat() * 50) + "," + random.nextInt(100) + ")"; + String sql = "insert into " + dbname + ".t" + j + " values(" + currentTimeMillis + "," + (random.nextFloat() * 50) + "," + random.nextInt(100) + ")"; // when int affectRows = executeUpdate(connection, sql); // then @@ -83,7 +83,7 @@ public class RestfulJDBCTest { @Test public void testCase006() throws SQLException { // given - String sql = "select * from weather"; + String sql = "select * from " + dbname + ".weather"; // when ResultSet rs = executeQuery(connection, sql); ResultSetMetaData meta = rs.getMetaData(); @@ -102,7 +102,7 @@ public class RestfulJDBCTest { @Test public void testCase007() throws SQLException { // given - String sql = "drop database restful_test"; + String sql = "drop database " + dbname; // when boolean execute = execute(connection, sql); @@ -143,7 +143,7 @@ public class RestfulJDBCTest { public static void afterClass() throws SQLException { if (connection != null) { Statement stmt = connection.createStatement(); - stmt.execute("drop database if exists restful_test"); + stmt.execute("drop database if exists " + dbname); stmt.close(); connection.close(); } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java index 4058dd8b550b6e9ac5553144de92d908d804dce1..c1ca31ae388f577a33cc6f3a6bc943ce52112507 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java @@ -17,12 +17,25 @@ import java.text.SimpleDateFormat; public class RestfulResultSetTest { - // private static final String host = "127.0.0.1"; - private static final String host = "master"; + private static final String host = "127.0.0.1"; private static Connection conn; private static Statement stmt; private static ResultSet rs; + @BeforeClass + public static void beforeClass() throws SQLException { + conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"); + stmt = conn.createStatement(); + stmt.execute("drop database if exists restful_test"); + stmt.execute("create database if not exists restful_test"); + stmt.execute("use restful_test"); + stmt.execute("drop table if exists weather"); + stmt.execute("create table if not exists weather(f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 binary(64), f7 smallint, f8 tinyint, f9 bool, f10 nchar(64))"); + stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')"); + rs = stmt.executeQuery("select * from restful_test.weather"); + rs.next(); + } + @Test public void wasNull() throws SQLException { Assert.assertFalse(rs.wasNull()); @@ -658,20 +671,6 @@ public class RestfulResultSetTest { Assert.assertTrue(rs.isWrapperFor(RestfulResultSet.class)); } - @BeforeClass - public static void beforeClass() throws SQLException { - conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"); - stmt = conn.createStatement(); - stmt.execute("drop database if exists restful_test"); - stmt.execute("create database if not exists restful_test"); - stmt.execute("use restful_test"); - stmt.execute("drop table if exists weather"); - stmt.execute("create table if not exists weather(f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 binary(64), f7 smallint, f8 tinyint, f9 bool, f10 nchar(64))"); - stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')"); - rs = stmt.executeQuery("select * from restful_test.weather"); - rs.next(); - } - @AfterClass public static void afterClass() throws SQLException { if (rs != null) diff --git a/src/connector/python/examples/subscribe-async.py b/src/connector/python/examples/subscribe-async.py index 3782ce5505152e78838406e313094eb911bea4a2..49156de7edfb4322d7888727c28b76868cf6a16a 100644 --- a/src/connector/python/examples/subscribe-async.py +++ b/src/connector/python/examples/subscribe-async.py @@ -7,7 +7,7 @@ import time def subscribe_callback(p_sub, p_result, p_param, errno): # type: (c_void_p, c_void_p, c_void_p, c_int) -> None print("# fetch in callback") - result = TaosResult(p_result) + result = TaosResult(c_void_p(p_result)) result.check_error(errno) for row in result.rows_iter(): ts, n = row() @@ -18,18 +18,21 @@ def test_subscribe_callback(conn): # type: (TaosConnection) -> None dbname = "pytest_taos_subscribe_callback" try: + print("drop if exists") conn.execute("drop database if exists %s" % dbname) + print("create database") conn.execute("create database if not exists %s" % dbname) - conn.select_db(dbname) - conn.execute("create table if not exists log(ts timestamp, n int)") + print("create table") + # conn.execute("use %s" % dbname) + conn.execute("create table if not exists %s.log(ts timestamp, n int)" % dbname) print("# subscribe with callback") - sub = conn.subscribe(False, "test", "select * from log", 1000, subscribe_callback) + sub = conn.subscribe(False, "test", "select * from %s.log" % dbname, 1000, subscribe_callback) for i in range(10): - conn.execute("insert into log values(now, %d)" % i) + conn.execute("insert into %s.log values(now, %d)" % (dbname, i)) time.sleep(0.7) - # sub.close() + sub.close() conn.execute("drop database if exists %s" % dbname) # conn.close() 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/cinterface.py b/src/connector/python/taos/cinterface.py index 37bc90d4c63fe3f75b12d46bb1bf535441869938..740af5838235a6abc41ae27e7c6a462c30977616 100644 --- a/src/connector/python/taos/cinterface.py +++ b/src/connector/python/taos/cinterface.py @@ -110,7 +110,7 @@ _libtaos.taos_get_client_info.restype = c_char_p def taos_get_client_info(): # type: () -> str """Get client version info.""" - return _libtaos.taos_get_client_info().decode() + return _libtaos.taos_get_client_info().decode("utf-8") _libtaos.taos_get_server_info.restype = c_char_p @@ -120,7 +120,7 @@ _libtaos.taos_get_server_info.argtypes = (c_void_p,) def taos_get_server_info(connection): # type: (c_void_p) -> str """Get server version as string.""" - return _libtaos.taos_get_server_info(connection).decode() + return _libtaos.taos_get_server_info(connection).decode("utf-8") _libtaos.taos_close.restype = None @@ -308,16 +308,14 @@ def taos_subscribe(connection, restart, topic, sql, interval, callback=None, par """ if callback != None: callback = subscribe_callback_type(callback) - if param != None: - param = c_void_p(param) return c_void_p( _libtaos.taos_subscribe( connection, 1 if restart else 0, c_char_p(topic.encode("utf-8")), c_char_p(sql.encode("utf-8")), - callback or None, - param, + callback, + c_void_p(param), interval, ) ) 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 b0bec58b932f2136b868739bb28fca04de759e3f..a6d64422e238b46b096a5ae62c42566666f226ad 100644 --- a/src/connector/python/taos/field.py +++ b/src/connector/python/taos/field.py @@ -144,7 +144,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_ try: if num_of_rows >= 0: tmpstr = ctypes.c_char_p(data) - res.append(tmpstr.value.decode()) + res.append(tmpstr.value.decode("utf-8")) else: res.append( ( @@ -172,7 +172,7 @@ def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, precision=Field if rbyte == 1 and buffer[0] == b'\xff': res.append(None) else: - res.append(cast(buffer, c_char_p).value.decode()) + res.append(cast(buffer, c_char_p).value.decode("utf-8")) return res @@ -188,7 +188,7 @@ def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, precision=FieldT if rbyte == 4 and buffer[:4] == b'\xff'*4: res.append(None) else: - res.append(cast(buffer, c_char_p).value.decode()) + res.append(cast(buffer, c_char_p).value.decode("utf-8")) return res @@ -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/connector/python/taos/result.py b/src/connector/python/taos/result.py index c9feb4d6502515cc6e3e2d4be688f2e7fcd895b2..8b8a0cf108cf7c941d0a6476d8a9c1e2c5a41b84 100644 --- a/src/connector/python/taos/result.py +++ b/src/connector/python/taos/result.py @@ -3,6 +3,8 @@ from .cinterface import * # from .connection import TaosConnection from .error import * +from ctypes import c_void_p + class TaosResult(object): """TDengine result interface""" @@ -12,7 +14,11 @@ class TaosResult(object): # to make the __del__ order right self._conn = conn self._close_after = close_after - self._result = result + if isinstance(result, c_void_p): + self._result = result + else: + self._result = c_void_p(result) + self._fields = None self._field_count = None self._precision = None diff --git a/src/connector/python/tests/test_stream.py b/src/connector/python/tests/test_stream.py index de6e20928b176e51bc6d350fb01268459f4e7f95..32ec4c5999c975be907cf69a42a04b5f4dd5d54c 100644 --- a/src/connector/python/tests/test_stream.py +++ b/src/connector/python/tests/test_stream.py @@ -20,7 +20,8 @@ def stream_callback(p_param, p_result, p_row): result = TaosResult(p_result) row = TaosRow(result, p_row) try: - ts, count = row() + ts, count = row.as_tuple() + print(ts, count) p = cast(p_param, POINTER(Counter)) p.contents.count += count print("[%s] inserted %d in 5s, total count: %d" % (ts.strftime("%Y-%m-%d %H:%M:%S"), count, p.contents.count)) diff --git a/src/connector/python/tests/test_subscribe.py b/src/connector/python/tests/test_subscribe.py index 99fe5b263625c63200f416ec98fcb561773becd8..d8acd60e4f3b32bb87a9663b3f7dc43a73f2877b 100644 --- a/src/connector/python/tests/test_subscribe.py +++ b/src/connector/python/tests/test_subscribe.py @@ -63,7 +63,7 @@ def test_subscribe(conn): def subscribe_callback(p_sub, p_result, p_param, errno): # type: (c_void_p, c_void_p, c_void_p, c_int) -> None print("callback") - result = TaosResult(p_result) + result = TaosResult(c_void_p(p_result)) result.check_error(errno) for row in result.rows_iter(): ts, n = row() @@ -76,7 +76,7 @@ def test_subscribe_callback(conn): try: conn.execute("drop database if exists %s" % dbname) conn.execute("create database if not exists %s" % dbname) - conn.select_db(dbname) + conn.execute("use %s" % dbname) conn.execute("create table if not exists log(ts timestamp, n int)") print("# subscribe with callback") 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/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c index f62e0c0df41f2fe399d0f4c1c8e661fcd0ef91b9..7676343b37d242c1d174a31959ea4be25a9d5af2 100644 --- a/src/dnode/src/dnodeShell.c +++ b/src/dnode/src/dnodeShell.c @@ -120,6 +120,14 @@ static void dnodeProcessMsgFromShell(SRpcMsg *pMsg, SRpcEpSet *pEpSet) { if (pMsg->pCont == NULL) return; + if (pMsg->msgType >= TSDB_MSG_TYPE_MAX) { + dError("RPC %p, shell msg type:%d is not processed", pMsg->handle, pMsg->msgType); + rpcMsg.code = TSDB_CODE_DND_MSG_NOT_PROCESSED; + rpcSendResponse(&rpcMsg); + rpcFreeCont(pMsg->pCont); + return; + } + SRunStatus dnodeStatus = dnodeGetRunStatus(); if (dnodeStatus == TSDB_RUN_STATUS_STOPPED) { dError("RPC %p, shell msg:%s is ignored since dnode exiting", pMsg->handle, taosMsg[pMsg->msgType]); 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 84491e0a438fdb3b5dd2905acffaf32c76b23c9b..9dc76466aadbe9781dbdd727a524a32f8103650f 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -230,6 +230,7 @@ typedef struct SSubmitBlk { // Submit message for this TSDB typedef struct SSubmitMsg { SMsgHead header; + int8_t extend; int32_t length; int32_t numOfBlocks; char blocks[]; @@ -243,6 +244,7 @@ typedef struct { } SShellSubmitRspBlock; typedef struct { + int8_t extend; int32_t code; // 0-success, > 0 error code int32_t numOfRows; // number of records the client is trying to write int32_t affectedRows; // number of records actually written @@ -278,6 +280,7 @@ typedef struct { } SMDCreateTableMsg; typedef struct { + int8_t extend; int32_t len; // one create table message char tableName[TSDB_TABLE_FNAME_LEN]; int8_t igExists; @@ -290,11 +293,13 @@ typedef struct { } SCreateTableMsg; typedef struct { + int8_t extend; int32_t numOfTables; int32_t contLen; } SCMCreateTableMsg; typedef struct { + int8_t extend; char name[TSDB_TABLE_FNAME_LEN]; // if user specify DROP STABLE, this flag will be set. And an error will be returned if it is not a super table int8_t supertable; @@ -302,6 +307,7 @@ typedef struct { } SCMDropTableMsg; typedef struct { + int8_t extend; char tableFname[TSDB_TABLE_FNAME_LEN]; char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int16_t type; /* operation type */ @@ -314,6 +320,7 @@ typedef struct { typedef struct { SMsgHead head; + int8_t extend; int64_t uid; int32_t tid; int16_t tversion; @@ -327,6 +334,7 @@ typedef struct { } SUpdateTableTagValMsg; typedef struct { + int8_t extend; char clientVersion[TSDB_VERSION_LEN]; char msgVersion[TSDB_VERSION_LEN]; char db[TSDB_TABLE_FNAME_LEN]; @@ -335,6 +343,7 @@ typedef struct { } SConnectMsg; typedef struct { + int8_t extend; char acctId[TSDB_ACCT_ID_LEN]; char serverVersion[TSDB_VERSION_LEN]; char clusterId[TSDB_CLUSTER_ID_LEN]; @@ -361,16 +370,19 @@ typedef struct { } SAcctCfg; typedef struct { + int8_t extend; char user[TSDB_USER_LEN]; char pass[TSDB_KEY_LEN]; SAcctCfg cfg; } SCreateAcctMsg, SAlterAcctMsg; typedef struct { - char user[TSDB_USER_LEN]; + int8_t extend; + char user[TSDB_USER_LEN]; } SDropUserMsg, SDropAcctMsg; typedef struct { + int8_t extend; char user[TSDB_USER_LEN]; char pass[TSDB_KEY_LEN]; int8_t privilege; @@ -400,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 { @@ -462,6 +474,7 @@ typedef struct { typedef struct { SMsgHead head; + int8_t extend; char version[TSDB_VERSION_LEN]; bool stableQuery; // super table query or not @@ -514,6 +527,7 @@ typedef struct { } SQueryTableMsg; typedef struct { + int8_t extend; int32_t code; union{uint64_t qhandle; uint64_t qId;}; // query handle } SQueryTableRsp; @@ -521,11 +535,13 @@ typedef struct { // todo: the show handle should be replaced with id typedef struct { SMsgHead header; + int8_t extend; union{uint64_t qhandle; uint64_t qId;}; // query handle uint16_t free; } SRetrieveTableMsg; typedef struct SRetrieveTableRsp { + int8_t extend; int32_t numOfRows; int8_t completed; // all results are returned to client int16_t precision; @@ -551,6 +567,7 @@ typedef struct { } SVnodeLoad; typedef struct { + int8_t extend; char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int32_t cacheBlockSize; //MB int32_t totalBlocks; @@ -577,6 +594,7 @@ typedef struct { } SCreateDbMsg, SAlterDbMsg; typedef struct { + int8_t extend; char name[TSDB_FUNC_NAME_LEN]; char path[PATH_MAX]; int32_t funcType; @@ -588,11 +606,13 @@ typedef struct { } SCreateFuncMsg; typedef struct { + int8_t extend; int32_t num; char name[]; } SRetrieveFuncMsg; typedef struct { + int8_t extend; char name[TSDB_FUNC_NAME_LEN]; int32_t funcType; int8_t resType; @@ -603,15 +623,18 @@ typedef struct { } SFunctionInfoMsg; typedef struct { + int8_t extend; int32_t num; char content[]; } SUdfFuncMsg; typedef struct { + int8_t extend; char name[TSDB_FUNC_NAME_LEN]; } SDropFuncMsg; typedef struct { + int8_t extend; char db[TSDB_TABLE_FNAME_LEN]; uint8_t ignoreNotExists; } SDropDbMsg, SUseDbMsg, SSyncDbMsg; @@ -744,12 +767,14 @@ typedef struct { } SCreateVnodeMsg, SAlterVnodeMsg; typedef struct { + int8_t extend; char tableFname[TSDB_TABLE_FNAME_LEN]; int16_t createFlag; char tags[]; } STableInfoMsg; typedef struct { + int8_t extend; uint8_t metaClone; // create local clone of the cached table meta int32_t numOfVgroups; int32_t numOfTables; @@ -758,21 +783,25 @@ typedef struct { } SMultiTableInfoMsg; typedef struct SSTableVgroupMsg { + int8_t extend; int32_t numOfTables; } SSTableVgroupMsg, SSTableVgroupRspMsg; typedef struct { + int8_t extend; int32_t vgId; int8_t numOfEps; SEpAddrMsg epAddr[TSDB_MAX_REPLICA]; } SVgroupMsg, SVgroupInfo; typedef struct { + int8_t extend; int32_t numOfVgroups; SVgroupMsg vgroups[]; } SVgroupsMsg, SVgroupsInfo; typedef struct STableMetaMsg { + int8_t extend; int32_t contLen; char tableFname[TSDB_TABLE_FNAME_LEN]; // table id uint8_t numOfTags; @@ -792,6 +821,7 @@ typedef struct STableMetaMsg { } STableMetaMsg; typedef struct SMultiTableMeta { + int8_t extend; int32_t numOfTables; int32_t numOfVgroup; int32_t numOfUdf; @@ -814,6 +844,7 @@ typedef struct { * payloadLen is the length of payload */ typedef struct { + int8_t extend; int8_t type; char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; uint16_t payloadLen; @@ -821,17 +852,20 @@ typedef struct { } SShowMsg; typedef struct { + int8_t extend; char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int32_t numOfVgroup; int32_t vgid[]; } SCompactMsg; typedef struct SShowRsp { + int8_t extend; uint64_t qhandle; STableMetaMsg tableMeta; } SShowRsp; typedef struct { + int8_t extend; char ep[TSDB_EP_LEN]; // end point, hostname:port } SCreateDnodeMsg, SDropDnodeMsg; @@ -853,6 +887,7 @@ typedef struct { } SConfigVnodeMsg; typedef struct { + int8_t extend; char ep[TSDB_EP_LEN]; // end point, hostname:port char config[64]; } SCfgDnodeMsg; @@ -884,6 +919,7 @@ typedef struct { } SStreamDesc; typedef struct { + int8_t extend; char clientVer[TSDB_VERSION_LEN]; uint32_t connId; int32_t pid; @@ -894,6 +930,7 @@ typedef struct { } SHeartBeatMsg; typedef struct { + int8_t extend; uint32_t queryId; uint32_t streamId; uint32_t totalDnodes; @@ -904,10 +941,12 @@ typedef struct { } SHeartBeatRsp; typedef struct { + int8_t extend; char queryId[TSDB_KILL_MSG_LEN + 1]; } SKillQueryMsg, SKillStreamMsg, SKillConnMsg; typedef struct { + int8_t extend; int32_t vnode; int32_t sid; uint64_t uid; @@ -932,6 +971,16 @@ typedef struct { char reserved2[64]; } SStartupStep; +typedef struct { + int16_t type; + int32_t len; + char value[]; +} STLV; + +enum { + TLV_TYPE_DUMMY = 1, +}; + #pragma pack(pop) #ifdef __cplusplus 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 d97bc943a9ade49f629dfce8e0b71860ab5905a6..5d73f48eb6378573bbecc8261790a18a147f2133 100644 --- a/src/inc/ttokendef.h +++ b/src/inc/ttokendef.h @@ -29,196 +29,194 @@ #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_UMINUS 42 -#define TK_UPLUS 43 -#define TK_BITNOT 44 -#define TK_SHOW 45 -#define TK_DATABASES 46 -#define TK_TOPICS 47 -#define TK_FUNCTIONS 48 -#define TK_MNODES 49 -#define TK_DNODES 50 -#define TK_ACCOUNTS 51 -#define TK_USERS 52 -#define TK_MODULES 53 -#define TK_QUERIES 54 -#define TK_CONNECTIONS 55 -#define TK_STREAMS 56 -#define TK_VARIABLES 57 -#define TK_SCORES 58 -#define TK_GRANTS 59 -#define TK_VNODES 60 -#define TK_DOT 61 -#define TK_CREATE 62 -#define TK_TABLE 63 -#define TK_STABLE 64 -#define TK_DATABASE 65 -#define TK_TABLES 66 -#define TK_STABLES 67 -#define TK_VGROUPS 68 -#define TK_DROP 69 -#define TK_TOPIC 70 -#define TK_FUNCTION 71 -#define TK_DNODE 72 -#define TK_USER 73 -#define TK_ACCOUNT 74 -#define TK_USE 75 -#define TK_DESCRIBE 76 -#define TK_DESC 77 -#define TK_ALTER 78 -#define TK_PASS 79 -#define TK_PRIVILEGE 80 -#define TK_LOCAL 81 -#define TK_COMPACT 82 -#define TK_LP 83 -#define TK_RP 84 -#define TK_IF 85 -#define TK_EXISTS 86 -#define TK_AS 87 -#define TK_OUTPUTTYPE 88 -#define TK_AGGREGATE 89 -#define TK_BUFSIZE 90 -#define TK_PPS 91 -#define TK_TSERIES 92 -#define TK_DBS 93 -#define TK_STORAGE 94 -#define TK_QTIME 95 -#define TK_CONNS 96 -#define TK_STATE 97 -#define TK_COMMA 98 -#define TK_KEEP 99 -#define TK_CACHE 100 -#define TK_REPLICA 101 -#define TK_QUORUM 102 -#define TK_DAYS 103 -#define TK_MINROWS 104 -#define TK_MAXROWS 105 -#define TK_BLOCKS 106 -#define TK_CTIME 107 -#define TK_WAL 108 -#define TK_FSYNC 109 -#define TK_COMP 110 -#define TK_PRECISION 111 -#define TK_UPDATE 112 -#define TK_CACHELAST 113 -#define TK_PARTITIONS 114 -#define TK_UNSIGNED 115 -#define TK_TAGS 116 -#define TK_USING 117 -#define TK_NULL 118 -#define TK_NOW 119 -#define TK_SELECT 120 -#define TK_UNION 121 -#define TK_ALL 122 -#define TK_DISTINCT 123 -#define TK_FROM 124 -#define TK_VARIABLE 125 -#define TK_RANGE 126 -#define TK_INTERVAL 127 -#define TK_EVERY 128 -#define TK_SESSION 129 -#define TK_STATE_WINDOW 130 -#define TK_FILL 131 -#define TK_SLIDING 132 -#define TK_ORDER 133 -#define TK_BY 134 -#define TK_ASC 135 -#define TK_GROUP 136 -#define TK_HAVING 137 -#define TK_LIMIT 138 -#define TK_OFFSET 139 -#define TK_SLIMIT 140 -#define TK_SOFFSET 141 -#define TK_WHERE 142 -#define TK_RESET 143 -#define TK_QUERY 144 -#define TK_SYNCDB 145 -#define TK_ADD 146 -#define TK_COLUMN 147 -#define TK_MODIFY 148 -#define TK_TAG 149 -#define TK_CHANGE 150 -#define TK_SET 151 -#define TK_KILL 152 -#define TK_CONNECTION 153 -#define TK_STREAM 154 -#define TK_COLON 155 -#define TK_ABORT 156 -#define TK_AFTER 157 -#define TK_ATTACH 158 -#define TK_BEFORE 159 -#define TK_BEGIN 160 -#define TK_CASCADE 161 -#define TK_CLUSTER 162 -#define TK_CONFLICT 163 -#define TK_COPY 164 -#define TK_DEFERRED 165 -#define TK_DELIMITERS 166 -#define TK_DETACH 167 -#define TK_EACH 168 -#define TK_END 169 -#define TK_EXPLAIN 170 -#define TK_FAIL 171 -#define TK_FOR 172 -#define TK_IGNORE 173 -#define TK_IMMEDIATE 174 -#define TK_INITIALLY 175 -#define TK_INSTEAD 176 -#define TK_KEY 177 -#define TK_OF 178 -#define TK_RAISE 179 -#define TK_REPLACE 180 -#define TK_RESTRICT 181 -#define TK_ROW 182 -#define TK_STATEMENT 183 -#define TK_TRIGGER 184 -#define TK_VIEW 185 -#define TK_IPTOKEN 186 -#define TK_SEMI 187 -#define TK_NONE 188 -#define TK_PREV 189 -#define TK_LINEAR 190 -#define TK_IMPORT 191 -#define TK_TBNAME 192 -#define TK_JOIN 193 -#define TK_INSERT 194 -#define TK_INTO 195 -#define TK_VALUES 196 -#define TK_FILE 197 - - - - - +#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_UMINUS 44 +#define TK_UPLUS 45 +#define TK_BITNOT 46 +#define TK_ARROW 47 +#define TK_SHOW 48 +#define TK_DATABASES 49 +#define TK_TOPICS 50 +#define TK_FUNCTIONS 51 +#define TK_MNODES 52 +#define TK_DNODES 53 +#define TK_ACCOUNTS 54 +#define TK_USERS 55 +#define TK_MODULES 56 +#define TK_QUERIES 57 +#define TK_CONNECTIONS 58 +#define TK_STREAMS 59 +#define TK_VARIABLES 60 +#define TK_SCORES 61 +#define TK_GRANTS 62 +#define TK_VNODES 63 +#define TK_DOT 64 +#define TK_CREATE 65 +#define TK_TABLE 66 +#define TK_STABLE 67 +#define TK_DATABASE 68 +#define TK_TABLES 69 +#define TK_STABLES 70 +#define TK_VGROUPS 71 +#define TK_DROP 72 +#define TK_TOPIC 73 +#define TK_FUNCTION 74 +#define TK_DNODE 75 +#define TK_USER 76 +#define TK_ACCOUNT 77 +#define TK_USE 78 +#define TK_DESCRIBE 79 +#define TK_DESC 80 +#define TK_ALTER 81 +#define TK_PASS 82 +#define TK_PRIVILEGE 83 +#define TK_LOCAL 84 +#define TK_COMPACT 85 +#define TK_LP 86 +#define TK_RP 87 +#define TK_IF 88 +#define TK_EXISTS 89 +#define TK_AS 90 +#define TK_OUTPUTTYPE 91 +#define TK_AGGREGATE 92 +#define TK_BUFSIZE 93 +#define TK_PPS 94 +#define TK_TSERIES 95 +#define TK_DBS 96 +#define TK_STORAGE 97 +#define TK_QTIME 98 +#define TK_CONNS 99 +#define TK_STATE 100 +#define TK_COMMA 101 +#define TK_KEEP 102 +#define TK_CACHE 103 +#define TK_REPLICA 104 +#define TK_QUORUM 105 +#define TK_DAYS 106 +#define TK_MINROWS 107 +#define TK_MAXROWS 108 +#define TK_BLOCKS 109 +#define TK_CTIME 110 +#define TK_WAL 111 +#define TK_FSYNC 112 +#define TK_COMP 113 +#define TK_PRECISION 114 +#define TK_UPDATE 115 +#define TK_CACHELAST 116 +#define TK_PARTITIONS 117 +#define TK_UNSIGNED 118 +#define TK_TAGS 119 +#define TK_USING 120 +#define TK_NULL 121 +#define TK_NOW 122 +#define TK_SELECT 123 +#define TK_UNION 124 +#define TK_ALL 125 +#define TK_DISTINCT 126 +#define TK_FROM 127 +#define TK_VARIABLE 128 +#define TK_RANGE 129 +#define TK_INTERVAL 130 +#define TK_EVERY 131 +#define TK_SESSION 132 +#define TK_STATE_WINDOW 133 +#define TK_FILL 134 +#define TK_SLIDING 135 +#define TK_ORDER 136 +#define TK_BY 137 +#define TK_ASC 138 +#define TK_GROUP 139 +#define TK_HAVING 140 +#define TK_LIMIT 141 +#define TK_OFFSET 142 +#define TK_SLIMIT 143 +#define TK_SOFFSET 144 +#define TK_WHERE 145 +#define TK_RESET 146 +#define TK_QUERY 147 +#define TK_SYNCDB 148 +#define TK_ADD 149 +#define TK_COLUMN 150 +#define TK_MODIFY 151 +#define TK_TAG 152 +#define TK_CHANGE 153 +#define TK_SET 154 +#define TK_KILL 155 +#define TK_CONNECTION 156 +#define TK_STREAM 157 +#define TK_COLON 158 +#define TK_ABORT 159 +#define TK_AFTER 160 +#define TK_ATTACH 161 +#define TK_BEFORE 162 +#define TK_BEGIN 163 +#define TK_CASCADE 164 +#define TK_CLUSTER 165 +#define TK_CONFLICT 166 +#define TK_COPY 167 +#define TK_DEFERRED 168 +#define TK_DELIMITERS 169 +#define TK_DETACH 170 +#define TK_EACH 171 +#define TK_END 172 +#define TK_EXPLAIN 173 +#define TK_FAIL 174 +#define TK_FOR 175 +#define TK_IGNORE 176 +#define TK_IMMEDIATE 177 +#define TK_INITIALLY 178 +#define TK_INSTEAD 179 +#define TK_KEY 180 +#define TK_OF 181 +#define TK_RAISE 182 +#define TK_REPLACE 183 +#define TK_RESTRICT 184 +#define TK_ROW 185 +#define TK_STATEMENT 186 +#define TK_TRIGGER 187 +#define TK_VIEW 188 +#define TK_IPTOKEN 189 +#define TK_SEMI 190 +#define TK_NONE 191 +#define TK_PREV 192 +#define TK_LINEAR 193 +#define TK_IMPORT 194 +#define TK_TBNAME 195 +#define TK_JOIN 196 +#define TK_INSERT 197 +#define TK_INTO 198 +#define TK_VALUES 199 +#define TK_FILE 200 diff --git a/src/inc/ttype.h b/src/inc/ttype.h index 0ac382ca603263a7ae20e2029d3b9543126ccbdb..1b7d07262e50da893e1bc3009df94b49ee306637 100644 --- a/src/inc/ttype.h +++ b/src/inc/ttype.h @@ -236,6 +236,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: @@ -266,10 +268,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 2f054cb913fd947af38c21476768c147681a22ab..3f672c4531921642bcf1a20888b482c98968f9c7 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 24356ee095d0a7dd12a650a450a975005ac3a54e..b1b82ae762d8c832ae47df515127525b7a1ae6cc 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -200,7 +200,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 142ebe31ad994ae8021f66dcd701658bc55a2e65..f3253c0d8396582454f9d4ef39e09f6ade181d5f 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -81,6 +81,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; @@ -163,7 +172,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; @@ -281,6 +289,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 6aa5ad7b9a48f638d8a3854bcb007c823bf7bd8a..b435722d2093ce6434fe38f1af2f743885b46249 100644 --- a/src/query/inc/sql.y +++ b/src/query/inc/sql.y @@ -6,18 +6,19 @@ %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. %left DIVIDE TIMES. %left STAR SLASH REM. %right UMINUS UPLUS BITNOT. +%right ARROW. %include { #include @@ -629,25 +630,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); } @@ -666,11 +675,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 @@ -767,6 +784,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 593284ddf02bbcd03f031c809c10603071e9f8f9..e033650b74fe503c73f75b95acdc0e466a241e9a 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -2935,8 +2935,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; } @@ -2970,6 +2969,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 d438115ad6b3fa42a683fcd4bb09318ba5187bb9..1249f6db3082b411b6d47ecc56501cdbc90b9bed 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,10 +137,18 @@ 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() { - return tsShellActivityTimer * 2; + return tsShellActivityTimer * 10; } int64_t genQueryId(void) { int64_t uid = 0; @@ -1211,7 +1222,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); } } } @@ -1455,33 +1466,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); } @@ -1497,7 +1509,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; } @@ -1519,8 +1532,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); } @@ -1539,8 +1552,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); } @@ -1550,20 +1563,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; @@ -1915,6 +1926,7 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr pCtx->ptsOutputBuf = NULL; + pCtx->colId = pIndex->colId; pCtx->outputBytes = pSqlExpr->resBytes; pCtx->outputType = pSqlExpr->resType; @@ -2171,7 +2183,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; } @@ -2950,7 +2962,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; @@ -3027,19 +3039,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); } } @@ -3227,7 +3242,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; @@ -3235,7 +3250,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)) { @@ -3243,11 +3258,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); } @@ -3273,12 +3296,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. @@ -3294,7 +3317,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) @@ -3922,20 +3946,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); } } } @@ -3953,7 +3978,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); @@ -3964,7 +3989,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); @@ -3972,7 +3997,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); @@ -5368,7 +5393,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); @@ -7463,7 +7488,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); @@ -7499,13 +7533,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); } @@ -8181,6 +8222,32 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { goto _cleanup; } + + +/* + //MSG EXTEND DEMO + if (pQueryMsg->extend) { + pMsg += pQueryMsg->sqlstrLen; + + STLV *tlv = NULL; + while (1) { + tlv = (STLV *)pMsg; + tlv->type = ntohs(tlv->type); + tlv->len = ntohl(tlv->len); + if (tlv->len > 0) { + *(int16_t *)tlv->value = ntohs(*(int16_t *)tlv->value); + qDebug("Got TLV,type:%d,len:%d,value:%d", tlv->type, tlv->len, *(int16_t*)tlv->value); + pMsg += sizeof(*tlv) + tlv->len; + continue; + } + + break; + } + } + +*/ + + qDebug("qmsg:%p query %d tables, type:%d, qrange:%" PRId64 "-%" PRId64 ", numOfGroupbyTagCols:%d, order:%d, " "outputCols:%d, numOfCols:%d, interval:%" PRId64 ", fillType:%d, comptsLen:%d, compNumOfBlocks:%d, limit:%" PRId64 ", offset:%" PRId64, pQueryMsg, pQueryMsg->numOfTables, pQueryMsg->queryType, pQueryMsg->window.skey, pQueryMsg->window.ekey, pQueryMsg->numOfGroupCols, @@ -8462,8 +8529,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 d388fc43e5b098e4dfd06b5a1e39877bbd6c6e87..1cbec22c01c378765580c2379f64f477498a739c 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); @@ -414,6 +414,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; @@ -549,12 +554,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) { @@ -602,6 +608,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)); @@ -909,6 +933,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); @@ -928,10 +961,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); @@ -1046,7 +1079,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/queryMain.c b/src/query/src/queryMain.c index fce7f649892f87d075c8dd64e4d1160e5d05bf77..2a2ccf9cae0f9e2aab60bddca7c27a8ceb719239 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -279,6 +279,7 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { if (isQueryKilled(pQInfo)) { qDebug("QInfo:0x%"PRIx64" it is already killed, abort", pQInfo->qId); + pQInfo->runtimeEnv.outputBuf = NULL; return doBuildResCheck(pQInfo); } diff --git a/src/query/src/sql.c b/src/query/src/sql.c index 7be015626df1d448dc3645dbeebb2b4d280e041f..0b8e9542742b9ab8b04d265c7cd6da0e482b7c92 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,211 @@ #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_UMINUS 44 +#define TK_UPLUS 45 +#define TK_BITNOT 46 +#define TK_ARROW 47 +#define TK_SHOW 48 +#define TK_DATABASES 49 +#define TK_TOPICS 50 +#define TK_FUNCTIONS 51 +#define TK_MNODES 52 +#define TK_DNODES 53 +#define TK_ACCOUNTS 54 +#define TK_USERS 55 +#define TK_MODULES 56 +#define TK_QUERIES 57 +#define TK_CONNECTIONS 58 +#define TK_STREAMS 59 +#define TK_VARIABLES 60 +#define TK_SCORES 61 +#define TK_GRANTS 62 +#define TK_VNODES 63 +#define TK_DOT 64 +#define TK_CREATE 65 +#define TK_TABLE 66 +#define TK_STABLE 67 +#define TK_DATABASE 68 +#define TK_TABLES 69 +#define TK_STABLES 70 +#define TK_VGROUPS 71 +#define TK_DROP 72 +#define TK_TOPIC 73 +#define TK_FUNCTION 74 +#define TK_DNODE 75 +#define TK_USER 76 +#define TK_ACCOUNT 77 +#define TK_USE 78 +#define TK_DESCRIBE 79 +#define TK_DESC 80 +#define TK_ALTER 81 +#define TK_PASS 82 +#define TK_PRIVILEGE 83 +#define TK_LOCAL 84 +#define TK_COMPACT 85 +#define TK_LP 86 +#define TK_RP 87 +#define TK_IF 88 +#define TK_EXISTS 89 +#define TK_AS 90 +#define TK_OUTPUTTYPE 91 +#define TK_AGGREGATE 92 +#define TK_BUFSIZE 93 +#define TK_PPS 94 +#define TK_TSERIES 95 +#define TK_DBS 96 +#define TK_STORAGE 97 +#define TK_QTIME 98 +#define TK_CONNS 99 +#define TK_STATE 100 +#define TK_COMMA 101 +#define TK_KEEP 102 +#define TK_CACHE 103 +#define TK_REPLICA 104 +#define TK_QUORUM 105 +#define TK_DAYS 106 +#define TK_MINROWS 107 +#define TK_MAXROWS 108 +#define TK_BLOCKS 109 +#define TK_CTIME 110 +#define TK_WAL 111 +#define TK_FSYNC 112 +#define TK_COMP 113 +#define TK_PRECISION 114 +#define TK_UPDATE 115 +#define TK_CACHELAST 116 +#define TK_PARTITIONS 117 +#define TK_UNSIGNED 118 +#define TK_TAGS 119 +#define TK_USING 120 +#define TK_NULL 121 +#define TK_NOW 122 +#define TK_SELECT 123 +#define TK_UNION 124 +#define TK_ALL 125 +#define TK_DISTINCT 126 +#define TK_FROM 127 +#define TK_VARIABLE 128 +#define TK_RANGE 129 +#define TK_INTERVAL 130 +#define TK_EVERY 131 +#define TK_SESSION 132 +#define TK_STATE_WINDOW 133 +#define TK_FILL 134 +#define TK_SLIDING 135 +#define TK_ORDER 136 +#define TK_BY 137 +#define TK_ASC 138 +#define TK_GROUP 139 +#define TK_HAVING 140 +#define TK_LIMIT 141 +#define TK_OFFSET 142 +#define TK_SLIMIT 143 +#define TK_SOFFSET 144 +#define TK_WHERE 145 +#define TK_RESET 146 +#define TK_QUERY 147 +#define TK_SYNCDB 148 +#define TK_ADD 149 +#define TK_COLUMN 150 +#define TK_MODIFY 151 +#define TK_TAG 152 +#define TK_CHANGE 153 +#define TK_SET 154 +#define TK_KILL 155 +#define TK_CONNECTION 156 +#define TK_STREAM 157 +#define TK_COLON 158 +#define TK_ABORT 159 +#define TK_AFTER 160 +#define TK_ATTACH 161 +#define TK_BEFORE 162 +#define TK_BEGIN 163 +#define TK_CASCADE 164 +#define TK_CLUSTER 165 +#define TK_CONFLICT 166 +#define TK_COPY 167 +#define TK_DEFERRED 168 +#define TK_DELIMITERS 169 +#define TK_DETACH 170 +#define TK_EACH 171 +#define TK_END 172 +#define TK_EXPLAIN 173 +#define TK_FAIL 174 +#define TK_FOR 175 +#define TK_IGNORE 176 +#define TK_IMMEDIATE 177 +#define TK_INITIALLY 178 +#define TK_INSTEAD 179 +#define TK_KEY 180 +#define TK_OF 181 +#define TK_RAISE 182 +#define TK_REPLACE 183 +#define TK_RESTRICT 184 +#define TK_ROW 185 +#define TK_STATEMENT 186 +#define TK_TRIGGER 187 +#define TK_VIEW 188 +#define TK_IPTOKEN 189 +#define TK_SEMI 190 +#define TK_NONE 191 +#define TK_PREV 192 +#define TK_LINEAR 193 +#define TK_IMPORT 194 +#define TK_TBNAME 195 +#define TK_JOIN 196 +#define TK_INSERT 197 +#define TK_INTO 198 +#define TK_VALUES 199 +#define TK_FILE 200 +#endif +/**************** End token definitions ***************************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. @@ -100,30 +299,30 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 281 +#define YYNOCODE 284 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SStrToken typedef union { int yyinit; ParseTOKENTYPE yy0; - int32_t yy2; - SCreatedTableInfo yy42; - tSqlExpr* yy44; - SRelationInfo* yy46; - SCreateAcctInfo yy47; - TAOS_FIELD yy179; - SLimitVal yy204; - int yy222; - SSqlNode* yy246; - SArray* yy247; - SCreateDbInfo yy262; - SCreateTableSql* yy336; - tVariant yy378; - SRangeVal yy379; - int64_t yy403; - SIntervalVal yy430; - SWindowStateVal yy492; - SSessionWindowVal yy507; + SCreateTableSql* yy6; + SSqlNode* yy16; + tSqlExpr* yy18; + SIntervalVal yy32; + SRelationInfo* yy36; + SLimitVal yy38; + SCreateAcctInfo yy51; + int64_t yy69; + SRangeVal yy124; + SSessionWindowVal yy155; + tVariant yy162; + SArray* yy189; + SCreatedTableInfo yy208; + TAOS_FIELD yy279; + SWindowStateVal yy336; + int yy420; + SCreateDbInfo yy470; + int32_t yy516; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -139,18 +338,18 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 381 -#define YYNRULE 303 -#define YYNRULE_WITH_ACTION 303 -#define YYNTOKEN 198 -#define YY_MAX_SHIFT 380 -#define YY_MIN_SHIFTREDUCE 597 -#define YY_MAX_SHIFTREDUCE 899 -#define YY_ERROR_ACTION 900 -#define YY_ACCEPT_ACTION 901 -#define YY_NO_ACTION 902 -#define YY_MIN_REDUCE 903 -#define YY_MAX_REDUCE 1205 +#define YYNSTATE 390 +#define YYNRULE 313 +#define YYNRULE_WITH_ACTION 313 +#define YYNTOKEN 201 +#define YY_MAX_SHIFT 389 +#define YY_MIN_SHIFTREDUCE 613 +#define YY_MAX_SHIFTREDUCE 925 +#define YY_ERROR_ACTION 926 +#define YY_ACCEPT_ACTION 927 +#define YY_NO_ACTION 928 +#define YY_MIN_REDUCE 929 +#define YY_MAX_REDUCE 1241 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -217,305 +416,314 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (813) +#define YY_ACTTAB_COUNT (854) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 166, 648, 23, 1080, 379, 239, 214, 732, 1044, 649, - /* 10 */ 684, 901, 380, 60, 61, 246, 64, 65, 1181, 1058, - /* 20 */ 260, 54, 53, 52, 648, 63, 336, 68, 66, 69, - /* 30 */ 67, 159, 649, 375, 989, 59, 58, 357, 356, 57, - /* 40 */ 56, 55, 60, 61, 252, 64, 65, 175, 1058, 260, - /* 50 */ 54, 53, 52, 166, 63, 336, 68, 66, 69, 67, - /* 60 */ 1028, 1071, 1026, 1027, 59, 58, 298, 1029, 57, 56, - /* 70 */ 55, 1030, 1077, 1031, 1032, 59, 58, 1127, 282, 57, - /* 80 */ 56, 55, 60, 61, 254, 64, 65, 85, 1058, 260, - /* 90 */ 54, 53, 52, 334, 63, 336, 68, 66, 69, 67, - /* 100 */ 951, 289, 288, 166, 59, 58, 257, 195, 57, 56, - /* 110 */ 55, 60, 61, 14, 64, 65, 38, 99, 260, 54, - /* 120 */ 53, 52, 769, 63, 336, 68, 66, 69, 67, 128, - /* 130 */ 1128, 788, 308, 59, 58, 791, 648, 57, 56, 55, - /* 140 */ 100, 367, 60, 62, 649, 64, 65, 102, 9, 260, - /* 150 */ 54, 53, 52, 835, 63, 336, 68, 66, 69, 67, - /* 160 */ 1071, 294, 295, 91, 59, 58, 256, 210, 57, 56, - /* 170 */ 55, 39, 334, 1041, 1042, 35, 1045, 242, 310, 1182, - /* 180 */ 96, 598, 599, 600, 601, 602, 603, 604, 605, 606, - /* 190 */ 607, 608, 609, 610, 611, 157, 61, 240, 64, 65, - /* 200 */ 46, 367, 260, 54, 53, 52, 648, 63, 336, 68, - /* 210 */ 66, 69, 67, 263, 649, 269, 241, 59, 58, 166, - /* 220 */ 1055, 57, 56, 55, 64, 65, 181, 214, 260, 54, - /* 230 */ 53, 52, 274, 63, 336, 68, 66, 69, 67, 1182, - /* 240 */ 817, 278, 277, 59, 58, 244, 1052, 57, 56, 55, - /* 250 */ 45, 332, 374, 373, 331, 330, 329, 372, 328, 327, - /* 260 */ 326, 371, 325, 370, 369, 1020, 1008, 1009, 1010, 1011, - /* 270 */ 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1021, 1022, - /* 280 */ 24, 259, 850, 39, 261, 839, 212, 842, 29, 845, - /* 290 */ 264, 1071, 262, 253, 345, 344, 97, 218, 816, 259, - /* 300 */ 850, 800, 801, 839, 226, 842, 34, 845, 243, 1057, - /* 310 */ 142, 141, 140, 225, 1201, 237, 238, 342, 91, 338, - /* 320 */ 5, 42, 185, 103, 57, 56, 55, 184, 109, 114, - /* 330 */ 105, 113, 1054, 237, 238, 68, 66, 69, 67, 316, - /* 340 */ 841, 39, 844, 59, 58, 214, 321, 57, 56, 55, - /* 350 */ 268, 756, 1, 183, 753, 46, 754, 1182, 755, 1046, - /* 360 */ 840, 269, 843, 70, 126, 120, 131, 156, 154, 153, - /* 370 */ 39, 130, 182, 136, 139, 129, 3, 196, 281, 339, - /* 380 */ 83, 70, 133, 1193, 265, 266, 250, 233, 39, 39, - /* 390 */ 1055, 39, 84, 205, 203, 201, 39, 39, 851, 846, - /* 400 */ 200, 146, 145, 144, 143, 847, 39, 39, 772, 39, - /* 410 */ 269, 45, 79, 374, 373, 251, 851, 846, 372, 1055, - /* 420 */ 98, 337, 371, 847, 370, 369, 1043, 270, 269, 267, - /* 430 */ 283, 352, 351, 346, 347, 86, 348, 1055, 1055, 1056, - /* 440 */ 1055, 349, 353, 961, 40, 1055, 1055, 378, 377, 625, - /* 450 */ 195, 354, 355, 80, 359, 1055, 1055, 952, 1055, 88, - /* 460 */ 848, 89, 293, 292, 195, 76, 837, 757, 758, 797, - /* 470 */ 807, 808, 742, 313, 744, 315, 743, 874, 258, 852, - /* 480 */ 849, 647, 855, 161, 71, 26, 40, 40, 71, 101, - /* 490 */ 71, 25, 776, 25, 82, 25, 285, 16, 285, 15, - /* 500 */ 6, 119, 213, 118, 838, 18, 219, 17, 77, 761, - /* 510 */ 759, 762, 760, 20, 220, 19, 221, 125, 22, 124, - /* 520 */ 21, 138, 137, 1176, 1175, 290, 731, 1174, 235, 236, - /* 530 */ 216, 217, 222, 215, 223, 224, 228, 229, 230, 227, - /* 540 */ 211, 279, 1138, 1137, 158, 248, 291, 1134, 1079, 1133, - /* 550 */ 249, 358, 1090, 49, 1072, 1120, 1087, 1088, 155, 1092, - /* 560 */ 160, 286, 165, 304, 1053, 1119, 297, 177, 178, 245, - /* 570 */ 322, 299, 1051, 179, 180, 787, 966, 172, 318, 319, - /* 580 */ 320, 167, 323, 324, 47, 1069, 168, 311, 169, 301, - /* 590 */ 307, 81, 170, 51, 208, 78, 43, 309, 335, 960, - /* 600 */ 343, 1200, 116, 1199, 1196, 186, 350, 1192, 122, 1191, - /* 610 */ 1188, 305, 187, 986, 44, 41, 48, 303, 209, 948, - /* 620 */ 132, 946, 134, 135, 944, 943, 271, 300, 198, 199, - /* 630 */ 940, 939, 938, 937, 936, 935, 934, 202, 204, 930, - /* 640 */ 928, 926, 296, 206, 923, 207, 919, 368, 50, 284, - /* 650 */ 87, 92, 127, 302, 1121, 360, 361, 362, 363, 364, - /* 660 */ 365, 366, 376, 899, 273, 234, 272, 898, 255, 317, - /* 670 */ 276, 897, 275, 880, 231, 232, 879, 285, 280, 110, - /* 680 */ 965, 964, 111, 312, 10, 287, 764, 90, 942, 941, - /* 690 */ 30, 93, 933, 190, 147, 189, 987, 188, 932, 192, - /* 700 */ 191, 193, 988, 194, 148, 149, 150, 2, 796, 1024, - /* 710 */ 925, 924, 74, 794, 33, 173, 171, 176, 174, 4, - /* 720 */ 793, 790, 789, 75, 1034, 798, 162, 164, 809, 163, - /* 730 */ 247, 803, 94, 31, 805, 95, 306, 32, 13, 11, - /* 740 */ 12, 314, 104, 27, 28, 102, 107, 662, 697, 695, - /* 750 */ 694, 693, 36, 691, 106, 690, 37, 108, 689, 686, - /* 760 */ 652, 112, 333, 7, 340, 854, 856, 853, 8, 341, - /* 770 */ 115, 72, 117, 73, 40, 121, 123, 734, 733, 730, - /* 780 */ 678, 676, 668, 674, 670, 672, 666, 664, 700, 699, - /* 790 */ 698, 696, 692, 688, 687, 197, 650, 615, 903, 902, - /* 800 */ 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, - /* 810 */ 902, 151, 152, + /* 0 */ 102, 664, 664, 1158, 161, 1159, 311, 804, 260, 665, + /* 10 */ 665, 807, 388, 241, 37, 38, 24, 41, 42, 1078, + /* 20 */ 1070, 263, 31, 30, 29, 1083, 1215, 40, 343, 45, + /* 30 */ 43, 46, 44, 1067, 1068, 55, 1071, 36, 35, 297, + /* 40 */ 298, 34, 33, 32, 37, 38, 213, 41, 42, 250, + /* 50 */ 84, 263, 31, 30, 29, 214, 1215, 40, 343, 45, + /* 60 */ 43, 46, 44, 927, 389, 1215, 256, 36, 35, 211, + /* 70 */ 215, 34, 33, 32, 292, 291, 128, 122, 133, 1215, + /* 80 */ 1215, 1218, 1217, 132, 1069, 138, 141, 131, 37, 38, + /* 90 */ 85, 41, 42, 977, 135, 263, 31, 30, 29, 664, + /* 100 */ 196, 40, 343, 45, 43, 46, 44, 665, 339, 286, + /* 110 */ 13, 36, 35, 1097, 101, 34, 33, 32, 37, 38, + /* 120 */ 58, 41, 42, 60, 246, 263, 31, 30, 29, 220, + /* 130 */ 285, 40, 343, 45, 43, 46, 44, 315, 97, 1215, + /* 140 */ 96, 36, 35, 664, 104, 34, 33, 32, 339, 37, + /* 150 */ 39, 665, 41, 42, 1097, 176, 263, 31, 30, 29, + /* 160 */ 1106, 856, 40, 343, 45, 43, 46, 44, 34, 33, + /* 170 */ 32, 244, 36, 35, 301, 221, 34, 33, 32, 206, + /* 180 */ 204, 202, 376, 59, 51, 1215, 201, 148, 147, 146, + /* 190 */ 145, 614, 615, 616, 617, 618, 619, 620, 621, 622, + /* 200 */ 623, 624, 625, 626, 627, 159, 987, 242, 38, 277, + /* 210 */ 41, 42, 59, 196, 263, 31, 30, 29, 281, 280, + /* 220 */ 40, 343, 45, 43, 46, 44, 978, 222, 243, 1103, + /* 230 */ 36, 35, 1081, 196, 34, 33, 32, 1215, 41, 42, + /* 240 */ 384, 1015, 263, 31, 30, 29, 1, 184, 40, 343, + /* 250 */ 45, 43, 46, 44, 387, 386, 641, 253, 36, 35, + /* 260 */ 700, 1081, 34, 33, 32, 67, 337, 383, 382, 336, + /* 270 */ 335, 334, 381, 333, 332, 331, 380, 330, 379, 378, + /* 280 */ 1046, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, + /* 290 */ 1043, 1044, 1045, 1047, 1048, 234, 871, 25, 862, 860, + /* 300 */ 865, 863, 1237, 866, 772, 59, 59, 769, 1207, 770, + /* 310 */ 861, 771, 864, 1206, 219, 1205, 234, 871, 1215, 59, + /* 320 */ 860, 227, 863, 1215, 866, 1215, 59, 144, 143, 142, + /* 330 */ 226, 239, 240, 788, 351, 91, 5, 62, 186, 268, + /* 340 */ 269, 3, 197, 185, 111, 116, 107, 115, 266, 91, + /* 350 */ 254, 355, 239, 240, 1081, 1081, 345, 45, 43, 46, + /* 360 */ 44, 59, 326, 271, 356, 36, 35, 785, 1081, 34, + /* 370 */ 33, 32, 68, 1229, 67, 1080, 383, 382, 36, 35, + /* 380 */ 47, 381, 34, 33, 32, 380, 68, 379, 378, 1054, + /* 390 */ 259, 1052, 1053, 10, 293, 284, 1055, 83, 264, 1169, + /* 400 */ 1056, 47, 1057, 1058, 235, 59, 357, 59, 59, 342, + /* 410 */ 1081, 158, 156, 155, 748, 872, 867, 1097, 792, 59, + /* 420 */ 130, 869, 868, 773, 774, 267, 100, 265, 59, 354, + /* 430 */ 353, 341, 376, 870, 245, 294, 872, 867, 88, 237, + /* 440 */ 273, 86, 270, 868, 361, 360, 366, 365, 262, 1215, + /* 450 */ 358, 215, 362, 363, 1081, 238, 1081, 1081, 1156, 215, + /* 460 */ 1157, 1215, 217, 1218, 364, 1215, 218, 105, 1081, 1215, + /* 470 */ 6, 1218, 1215, 368, 223, 288, 1215, 1081, 836, 216, + /* 480 */ 224, 225, 229, 230, 1215, 99, 231, 98, 228, 1215, + /* 490 */ 1215, 1215, 1215, 1215, 212, 248, 1215, 89, 1215, 1084, + /* 500 */ 272, 255, 257, 1072, 1215, 1084, 1084, 816, 817, 272, + /* 510 */ 272, 182, 272, 296, 295, 813, 823, 824, 341, 76, + /* 520 */ 183, 344, 79, 1082, 758, 318, 760, 320, 759, 163, + /* 530 */ 71, 48, 54, 347, 288, 314, 835, 900, 60, 60, + /* 540 */ 71, 103, 71, 873, 261, 348, 663, 15, 82, 14, + /* 550 */ 282, 9, 121, 1168, 120, 346, 17, 9, 16, 251, + /* 560 */ 9, 1165, 77, 80, 777, 321, 778, 19, 775, 18, + /* 570 */ 776, 160, 127, 21, 126, 20, 140, 139, 1164, 252, + /* 580 */ 747, 1105, 367, 26, 859, 1116, 1113, 178, 1114, 1118, + /* 590 */ 162, 1098, 167, 289, 307, 1079, 179, 1148, 1077, 1147, + /* 600 */ 1146, 1145, 180, 181, 992, 157, 323, 324, 325, 300, + /* 610 */ 328, 329, 803, 169, 69, 209, 65, 340, 986, 352, + /* 620 */ 1095, 247, 1236, 118, 302, 304, 81, 1235, 1232, 187, + /* 630 */ 359, 78, 168, 316, 1228, 124, 1227, 1224, 188, 1012, + /* 640 */ 28, 312, 172, 170, 171, 66, 61, 70, 210, 310, + /* 650 */ 876, 974, 134, 308, 972, 136, 137, 970, 969, 306, + /* 660 */ 274, 199, 299, 200, 966, 303, 965, 964, 963, 962, + /* 670 */ 961, 960, 203, 205, 327, 956, 954, 952, 207, 27, + /* 680 */ 949, 208, 945, 377, 129, 287, 87, 92, 305, 369, + /* 690 */ 370, 371, 372, 373, 374, 236, 375, 258, 322, 385, + /* 700 */ 925, 276, 924, 275, 232, 278, 279, 923, 173, 233, + /* 710 */ 991, 990, 112, 906, 113, 905, 283, 288, 317, 11, + /* 720 */ 290, 90, 968, 967, 780, 149, 959, 191, 190, 1013, + /* 730 */ 189, 192, 193, 195, 194, 2, 52, 150, 1014, 4, + /* 740 */ 1050, 151, 958, 951, 53, 152, 174, 177, 175, 950, + /* 750 */ 93, 812, 74, 1060, 810, 809, 806, 805, 75, 166, + /* 760 */ 814, 164, 249, 825, 165, 22, 819, 94, 63, 821, + /* 770 */ 95, 309, 346, 313, 12, 64, 23, 49, 319, 50, + /* 780 */ 104, 106, 109, 56, 108, 678, 713, 711, 710, 57, + /* 790 */ 110, 709, 707, 706, 705, 702, 668, 338, 114, 7, + /* 800 */ 897, 895, 875, 898, 874, 896, 8, 877, 350, 117, + /* 810 */ 72, 60, 349, 119, 73, 123, 750, 125, 749, 746, + /* 820 */ 694, 692, 684, 690, 686, 688, 682, 680, 716, 715, + /* 830 */ 714, 712, 708, 704, 703, 198, 666, 631, 929, 928, + /* 840 */ 928, 928, 928, 928, 928, 928, 928, 928, 928, 928, + /* 850 */ 928, 928, 153, 154, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 200, 1, 268, 200, 200, 201, 268, 5, 0, 9, - /* 10 */ 5, 198, 199, 13, 14, 246, 16, 17, 280, 250, - /* 20 */ 20, 21, 22, 23, 1, 25, 26, 27, 28, 29, - /* 30 */ 30, 200, 9, 222, 223, 35, 36, 35, 36, 39, - /* 40 */ 40, 41, 13, 14, 246, 16, 17, 255, 250, 20, - /* 50 */ 21, 22, 23, 200, 25, 26, 27, 28, 29, 30, - /* 60 */ 224, 248, 226, 227, 35, 36, 274, 231, 39, 40, - /* 70 */ 41, 235, 269, 237, 238, 35, 36, 277, 265, 39, - /* 80 */ 40, 41, 13, 14, 246, 16, 17, 87, 250, 20, - /* 90 */ 21, 22, 23, 85, 25, 26, 27, 28, 29, 30, - /* 100 */ 206, 270, 271, 200, 35, 36, 207, 213, 39, 40, - /* 110 */ 41, 13, 14, 83, 16, 17, 87, 87, 20, 21, - /* 120 */ 22, 23, 98, 25, 26, 27, 28, 29, 30, 79, - /* 130 */ 277, 5, 279, 35, 36, 9, 1, 39, 40, 41, - /* 140 */ 208, 91, 13, 14, 9, 16, 17, 117, 124, 20, - /* 150 */ 21, 22, 23, 84, 25, 26, 27, 28, 29, 30, - /* 160 */ 248, 35, 36, 83, 35, 36, 207, 268, 39, 40, - /* 170 */ 41, 200, 85, 241, 242, 243, 244, 265, 275, 280, - /* 180 */ 277, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 190 */ 55, 56, 57, 58, 59, 60, 14, 62, 16, 17, - /* 200 */ 120, 91, 20, 21, 22, 23, 1, 25, 26, 27, - /* 210 */ 28, 29, 30, 69, 9, 200, 245, 35, 36, 200, - /* 220 */ 249, 39, 40, 41, 16, 17, 211, 268, 20, 21, - /* 230 */ 22, 23, 144, 25, 26, 27, 28, 29, 30, 280, - /* 240 */ 77, 153, 154, 35, 36, 119, 200, 39, 40, 41, - /* 250 */ 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - /* 260 */ 109, 110, 111, 112, 113, 224, 225, 226, 227, 228, - /* 270 */ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - /* 280 */ 45, 1, 2, 200, 207, 5, 268, 7, 83, 9, - /* 290 */ 146, 248, 148, 247, 150, 151, 277, 62, 135, 1, - /* 300 */ 2, 127, 128, 5, 69, 7, 83, 9, 265, 250, - /* 310 */ 75, 76, 77, 78, 250, 35, 36, 82, 83, 39, - /* 320 */ 63, 64, 65, 208, 39, 40, 41, 70, 71, 72, - /* 330 */ 73, 74, 249, 35, 36, 27, 28, 29, 30, 116, - /* 340 */ 5, 200, 7, 35, 36, 268, 89, 39, 40, 41, - /* 350 */ 69, 2, 209, 210, 5, 120, 7, 280, 9, 244, - /* 360 */ 5, 200, 7, 83, 63, 64, 65, 63, 64, 65, - /* 370 */ 200, 70, 211, 72, 73, 74, 204, 205, 143, 15, - /* 380 */ 145, 83, 81, 250, 35, 36, 245, 152, 200, 200, - /* 390 */ 249, 200, 208, 63, 64, 65, 200, 200, 118, 119, - /* 400 */ 70, 71, 72, 73, 74, 125, 200, 200, 39, 200, - /* 410 */ 200, 99, 98, 101, 102, 245, 118, 119, 106, 249, - /* 420 */ 251, 211, 110, 125, 112, 113, 242, 146, 200, 148, - /* 430 */ 84, 150, 151, 245, 245, 266, 245, 249, 249, 211, - /* 440 */ 249, 245, 245, 206, 98, 249, 249, 66, 67, 68, - /* 450 */ 213, 245, 245, 139, 245, 249, 249, 206, 249, 84, - /* 460 */ 125, 84, 35, 36, 213, 98, 1, 118, 119, 84, - /* 470 */ 84, 84, 84, 84, 84, 84, 84, 84, 61, 84, - /* 480 */ 125, 84, 118, 98, 98, 98, 98, 98, 98, 98, - /* 490 */ 98, 98, 123, 98, 83, 98, 121, 147, 121, 149, - /* 500 */ 83, 147, 268, 149, 39, 147, 268, 149, 141, 5, - /* 510 */ 5, 7, 7, 147, 268, 149, 268, 147, 147, 149, - /* 520 */ 149, 79, 80, 268, 268, 273, 115, 268, 268, 268, - /* 530 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 540 */ 268, 200, 240, 240, 200, 240, 273, 240, 200, 240, - /* 550 */ 240, 240, 200, 267, 248, 278, 200, 200, 61, 200, - /* 560 */ 200, 248, 200, 200, 248, 278, 272, 252, 200, 272, - /* 570 */ 90, 272, 200, 200, 200, 125, 200, 258, 200, 200, - /* 580 */ 200, 263, 200, 200, 200, 264, 262, 133, 261, 272, - /* 590 */ 131, 138, 260, 137, 200, 140, 200, 136, 200, 200, - /* 600 */ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, - /* 610 */ 200, 130, 200, 200, 200, 200, 200, 129, 200, 200, - /* 620 */ 200, 200, 200, 200, 200, 200, 200, 132, 200, 200, - /* 630 */ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, - /* 640 */ 200, 200, 126, 200, 200, 200, 200, 114, 142, 202, - /* 650 */ 202, 202, 97, 202, 202, 96, 52, 93, 95, 56, - /* 660 */ 94, 92, 85, 5, 5, 202, 155, 5, 202, 202, - /* 670 */ 5, 5, 155, 101, 202, 202, 100, 121, 144, 208, - /* 680 */ 212, 212, 208, 116, 83, 98, 84, 122, 202, 202, - /* 690 */ 83, 98, 202, 215, 203, 219, 221, 220, 202, 216, - /* 700 */ 218, 217, 223, 214, 203, 203, 203, 209, 84, 239, - /* 710 */ 202, 202, 98, 125, 254, 257, 259, 253, 256, 204, - /* 720 */ 125, 5, 5, 83, 239, 84, 83, 98, 84, 83, - /* 730 */ 1, 84, 83, 98, 84, 83, 83, 98, 83, 134, - /* 740 */ 134, 116, 79, 83, 83, 117, 71, 5, 9, 5, - /* 750 */ 5, 5, 88, 5, 87, 5, 88, 87, 5, 5, - /* 760 */ 86, 79, 15, 83, 26, 84, 118, 84, 83, 60, - /* 770 */ 149, 16, 149, 16, 98, 149, 149, 5, 5, 84, - /* 780 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - /* 790 */ 5, 5, 5, 5, 5, 98, 86, 61, 0, 281, - /* 800 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 810 */ 281, 21, 21, 281, 281, 281, 281, 281, 281, 281, - /* 820 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 830 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 840 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 850 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 860 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 870 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 880 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 890 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 900 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 910 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 920 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 930 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 940 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 950 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 960 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 970 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 980 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 990 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1000 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1010 */ 281, + /* 0 */ 211, 1, 1, 279, 203, 281, 282, 5, 210, 9, + /* 10 */ 9, 9, 203, 204, 14, 15, 271, 17, 18, 203, + /* 20 */ 0, 21, 22, 23, 24, 253, 281, 27, 28, 29, + /* 30 */ 30, 31, 32, 244, 245, 246, 247, 37, 38, 37, + /* 40 */ 38, 41, 42, 43, 14, 15, 271, 17, 18, 1, + /* 50 */ 211, 21, 22, 23, 24, 271, 281, 27, 28, 29, + /* 60 */ 30, 31, 32, 201, 202, 281, 250, 37, 38, 271, + /* 70 */ 271, 41, 42, 43, 273, 274, 66, 67, 68, 281, + /* 80 */ 281, 283, 283, 73, 245, 75, 76, 77, 14, 15, + /* 90 */ 90, 17, 18, 209, 84, 21, 22, 23, 24, 1, + /* 100 */ 216, 27, 28, 29, 30, 31, 32, 9, 88, 87, + /* 110 */ 86, 37, 38, 251, 90, 41, 42, 43, 14, 15, + /* 120 */ 90, 17, 18, 101, 122, 21, 22, 23, 24, 271, + /* 130 */ 268, 27, 28, 29, 30, 31, 32, 278, 279, 281, + /* 140 */ 281, 37, 38, 1, 120, 41, 42, 43, 88, 14, + /* 150 */ 15, 9, 17, 18, 251, 258, 21, 22, 23, 24, + /* 160 */ 203, 87, 27, 28, 29, 30, 31, 32, 41, 42, + /* 170 */ 43, 268, 37, 38, 277, 271, 41, 42, 43, 66, + /* 180 */ 67, 68, 94, 203, 86, 281, 73, 74, 75, 76, + /* 190 */ 77, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 200 */ 58, 59, 60, 61, 62, 63, 209, 65, 15, 147, + /* 210 */ 17, 18, 203, 216, 21, 22, 23, 24, 156, 157, + /* 220 */ 27, 28, 29, 30, 31, 32, 209, 271, 248, 272, + /* 230 */ 37, 38, 252, 216, 41, 42, 43, 281, 17, 18, + /* 240 */ 225, 226, 21, 22, 23, 24, 212, 213, 27, 28, + /* 250 */ 29, 30, 31, 32, 69, 70, 71, 248, 37, 38, + /* 260 */ 5, 252, 41, 42, 43, 102, 103, 104, 105, 106, + /* 270 */ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + /* 280 */ 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + /* 290 */ 237, 238, 239, 240, 241, 1, 2, 48, 5, 5, + /* 300 */ 7, 7, 253, 9, 2, 203, 203, 5, 271, 7, + /* 310 */ 5, 9, 7, 271, 65, 271, 1, 2, 281, 203, + /* 320 */ 5, 72, 7, 281, 9, 281, 203, 78, 79, 80, + /* 330 */ 81, 37, 38, 41, 85, 86, 66, 67, 68, 37, + /* 340 */ 38, 207, 208, 73, 74, 75, 76, 77, 72, 86, + /* 350 */ 248, 248, 37, 38, 252, 252, 41, 29, 30, 31, + /* 360 */ 32, 203, 92, 72, 248, 37, 38, 101, 252, 41, + /* 370 */ 42, 43, 123, 253, 102, 252, 104, 105, 37, 38, + /* 380 */ 86, 109, 41, 42, 43, 113, 123, 115, 116, 227, + /* 390 */ 210, 229, 230, 127, 276, 146, 234, 148, 210, 243, + /* 400 */ 238, 86, 240, 241, 155, 203, 248, 203, 203, 25, + /* 410 */ 252, 66, 67, 68, 5, 121, 122, 251, 126, 203, + /* 420 */ 82, 128, 128, 121, 122, 149, 254, 151, 203, 153, + /* 430 */ 154, 47, 94, 128, 268, 276, 121, 122, 87, 271, + /* 440 */ 149, 269, 151, 128, 153, 154, 37, 38, 64, 281, + /* 450 */ 248, 271, 248, 248, 252, 271, 252, 252, 279, 271, + /* 460 */ 281, 281, 271, 283, 248, 281, 271, 211, 252, 281, + /* 470 */ 86, 283, 281, 248, 271, 124, 281, 252, 80, 271, + /* 480 */ 271, 271, 271, 271, 281, 279, 271, 281, 271, 281, + /* 490 */ 281, 281, 281, 281, 271, 249, 281, 87, 281, 253, + /* 500 */ 203, 249, 249, 247, 281, 253, 253, 130, 131, 203, + /* 510 */ 203, 214, 203, 37, 38, 87, 87, 87, 47, 101, + /* 520 */ 214, 214, 101, 214, 87, 87, 87, 87, 87, 101, + /* 530 */ 101, 101, 86, 25, 124, 64, 138, 87, 101, 101, + /* 540 */ 101, 101, 101, 87, 1, 16, 87, 150, 86, 152, + /* 550 */ 203, 101, 150, 243, 152, 47, 150, 101, 152, 243, + /* 560 */ 101, 243, 144, 142, 5, 119, 7, 150, 5, 152, + /* 570 */ 7, 203, 150, 150, 152, 152, 82, 83, 243, 243, + /* 580 */ 118, 203, 243, 270, 41, 203, 203, 255, 203, 203, + /* 590 */ 203, 251, 203, 251, 203, 251, 203, 280, 203, 280, + /* 600 */ 280, 280, 203, 203, 203, 64, 203, 203, 203, 275, + /* 610 */ 203, 203, 128, 265, 203, 203, 203, 203, 203, 203, + /* 620 */ 267, 275, 203, 203, 275, 275, 141, 203, 203, 203, + /* 630 */ 203, 143, 266, 136, 203, 203, 203, 203, 203, 203, + /* 640 */ 140, 139, 262, 264, 263, 203, 203, 203, 203, 134, + /* 650 */ 121, 203, 203, 133, 203, 203, 203, 203, 203, 132, + /* 660 */ 203, 203, 129, 203, 203, 135, 203, 203, 203, 203, + /* 670 */ 203, 203, 203, 203, 93, 203, 203, 203, 203, 145, + /* 680 */ 203, 203, 203, 117, 100, 205, 205, 205, 205, 99, + /* 690 */ 55, 96, 98, 59, 97, 205, 95, 205, 205, 88, + /* 700 */ 5, 5, 5, 158, 205, 158, 5, 5, 261, 205, + /* 710 */ 215, 215, 211, 104, 211, 103, 147, 124, 119, 86, + /* 720 */ 101, 125, 205, 205, 87, 206, 205, 218, 222, 224, + /* 730 */ 223, 221, 219, 217, 220, 212, 86, 206, 226, 207, + /* 740 */ 242, 206, 205, 205, 257, 206, 260, 256, 259, 205, + /* 750 */ 101, 87, 101, 242, 128, 128, 5, 5, 86, 101, + /* 760 */ 87, 86, 1, 87, 86, 137, 87, 86, 101, 87, + /* 770 */ 86, 86, 47, 1, 86, 101, 137, 86, 119, 86, + /* 780 */ 120, 82, 74, 91, 90, 5, 9, 5, 5, 91, + /* 790 */ 90, 5, 5, 5, 5, 5, 89, 16, 82, 86, + /* 800 */ 9, 9, 87, 9, 87, 9, 86, 121, 63, 152, + /* 810 */ 17, 101, 28, 152, 17, 152, 5, 152, 5, 87, + /* 820 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + /* 830 */ 5, 5, 5, 5, 5, 101, 89, 64, 0, 284, + /* 840 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 850 */ 284, 284, 22, 22, 284, 284, 284, 284, 284, 284, + /* 860 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 870 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 880 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 890 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 900 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 910 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 920 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 930 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 940 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 950 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 960 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 970 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 980 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 990 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 1000 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 1010 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 1020 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 1030 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 1040 */ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + /* 1050 */ 284, 284, 284, 284, 284, }; -#define YY_SHIFT_COUNT (380) +#define YY_SHIFT_COUNT (389) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (798) +#define YY_SHIFT_MAX (838) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 235, 151, 151, 312, 312, 87, 280, 298, 298, 205, - /* 10 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - /* 20 */ 23, 23, 23, 0, 135, 298, 349, 349, 349, 80, - /* 30 */ 80, 23, 23, 174, 23, 8, 23, 23, 23, 23, - /* 40 */ 23, 50, 87, 110, 110, 5, 813, 813, 813, 298, - /* 50 */ 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, - /* 60 */ 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, - /* 70 */ 298, 349, 349, 349, 126, 126, 2, 2, 2, 2, - /* 80 */ 2, 2, 2, 23, 23, 23, 369, 23, 23, 23, - /* 90 */ 80, 80, 23, 23, 23, 23, 163, 163, 24, 80, - /* 100 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - /* 110 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - /* 120 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - /* 130 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - /* 140 */ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - /* 150 */ 23, 23, 23, 23, 23, 23, 23, 23, 497, 497, - /* 160 */ 497, 450, 450, 450, 450, 497, 497, 453, 455, 454, - /* 170 */ 456, 461, 459, 481, 488, 495, 516, 506, 497, 497, - /* 180 */ 497, 480, 480, 533, 87, 87, 497, 497, 555, 559, - /* 190 */ 604, 564, 563, 603, 566, 569, 533, 5, 497, 497, - /* 200 */ 577, 577, 497, 577, 497, 577, 497, 497, 813, 813, - /* 210 */ 29, 69, 98, 98, 98, 129, 182, 208, 257, 308, - /* 220 */ 308, 308, 308, 308, 308, 301, 330, 40, 40, 40, - /* 230 */ 40, 144, 281, 88, 30, 285, 285, 335, 355, 381, - /* 240 */ 304, 346, 375, 377, 427, 385, 386, 387, 367, 314, - /* 250 */ 388, 389, 390, 391, 392, 223, 393, 395, 465, 417, - /* 260 */ 364, 397, 350, 354, 358, 504, 505, 366, 370, 411, - /* 270 */ 371, 442, 658, 511, 659, 662, 517, 665, 666, 572, - /* 280 */ 576, 534, 556, 567, 601, 565, 602, 607, 587, 593, - /* 290 */ 624, 614, 588, 595, 716, 717, 640, 641, 643, 644, - /* 300 */ 646, 647, 629, 649, 650, 652, 729, 653, 635, 605, - /* 310 */ 639, 606, 655, 567, 660, 625, 661, 628, 663, 664, - /* 320 */ 667, 675, 742, 668, 670, 739, 744, 745, 746, 748, - /* 330 */ 750, 753, 754, 674, 747, 682, 680, 681, 683, 648, - /* 340 */ 685, 738, 709, 755, 621, 623, 676, 676, 676, 676, - /* 350 */ 757, 626, 627, 676, 676, 676, 772, 773, 695, 676, - /* 360 */ 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, - /* 370 */ 785, 786, 787, 788, 789, 697, 710, 790, 791, 736, - /* 380 */ 798, + /* 0 */ 249, 163, 163, 272, 272, 60, 315, 294, 294, 294, + /* 10 */ 98, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 20 */ 1, 1, 48, 48, 0, 142, 294, 294, 294, 294, + /* 30 */ 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, + /* 40 */ 294, 294, 294, 294, 294, 294, 294, 294, 302, 302, + /* 50 */ 302, 263, 263, 377, 1, 20, 1, 1, 1, 1, + /* 60 */ 1, 338, 60, 48, 48, 88, 88, 255, 854, 854, + /* 70 */ 854, 302, 302, 302, 2, 2, 409, 409, 409, 409, + /* 80 */ 409, 409, 409, 1, 1, 1, 292, 1, 1, 1, + /* 90 */ 263, 263, 1, 1, 1, 1, 398, 398, 398, 398, + /* 100 */ 266, 263, 1, 1, 1, 1, 1, 1, 1, 1, + /* 110 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 120 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 130 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 140 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 150 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /* 160 */ 541, 541, 541, 484, 484, 484, 484, 541, 485, 488, + /* 170 */ 497, 500, 502, 515, 520, 527, 530, 533, 534, 541, + /* 180 */ 541, 541, 581, 581, 566, 60, 60, 541, 541, 584, + /* 190 */ 590, 635, 595, 594, 634, 597, 601, 566, 255, 541, + /* 200 */ 541, 611, 611, 541, 611, 541, 611, 541, 541, 854, + /* 210 */ 854, 30, 74, 104, 104, 104, 135, 193, 221, 270, + /* 220 */ 328, 328, 328, 328, 328, 328, 10, 113, 341, 341, + /* 230 */ 341, 341, 276, 291, 384, 62, 24, 127, 127, 293, + /* 240 */ 305, 185, 345, 22, 351, 410, 476, 428, 429, 430, + /* 250 */ 471, 418, 421, 437, 438, 439, 440, 441, 446, 450, + /* 260 */ 456, 508, 543, 529, 459, 397, 402, 406, 559, 563, + /* 270 */ 417, 422, 462, 423, 494, 695, 545, 696, 697, 547, + /* 280 */ 701, 702, 609, 612, 569, 593, 599, 633, 596, 637, + /* 290 */ 650, 619, 649, 664, 651, 626, 627, 751, 752, 672, + /* 300 */ 673, 675, 676, 678, 679, 658, 681, 682, 684, 761, + /* 310 */ 685, 667, 628, 725, 772, 674, 639, 688, 599, 691, + /* 320 */ 659, 693, 660, 699, 692, 694, 708, 780, 698, 700, + /* 330 */ 777, 782, 783, 786, 787, 788, 789, 790, 707, 781, + /* 340 */ 716, 791, 792, 713, 715, 717, 794, 796, 686, 720, + /* 350 */ 784, 745, 793, 657, 661, 710, 710, 710, 710, 797, + /* 360 */ 663, 665, 710, 710, 710, 811, 813, 732, 710, 815, + /* 370 */ 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, + /* 380 */ 826, 827, 828, 829, 734, 747, 830, 831, 773, 838, }; -#define YY_REDUCE_COUNT (209) -#define YY_REDUCE_MIN (-266) -#define YY_REDUCE_MAX (515) +#define YY_REDUCE_COUNT (210) +#define YY_REDUCE_MIN (-276) +#define YY_REDUCE_MAX (544) static const short yy_reduce_ofst[] = { - /* 0 */ -187, 41, 41, -164, -164, -68, -101, -41, 77, -169, - /* 10 */ -29, -147, -97, 141, 170, 188, 189, 191, 196, 197, - /* 20 */ 206, 207, 209, -197, -196, -262, -231, -202, -162, -88, - /* 30 */ 43, -200, 19, -208, 46, 115, 15, 161, 210, 228, - /* 40 */ 83, -106, 184, 237, 251, -189, 169, 143, 172, -266, - /* 50 */ 18, 234, 238, 246, 248, 255, 256, 259, 260, 261, - /* 60 */ 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - /* 70 */ 272, 59, 64, 133, 252, 273, 302, 303, 305, 307, - /* 80 */ 309, 310, 311, 341, 344, 348, 286, 352, 356, 357, - /* 90 */ 306, 313, 359, 360, 362, 363, 277, 287, 315, 316, - /* 100 */ 368, 372, 373, 374, 376, 378, 379, 380, 382, 383, - /* 110 */ 384, 394, 396, 398, 399, 400, 401, 402, 403, 404, - /* 120 */ 405, 406, 407, 408, 409, 410, 412, 413, 414, 415, - /* 130 */ 416, 418, 419, 420, 421, 422, 423, 424, 425, 426, - /* 140 */ 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, - /* 150 */ 438, 439, 440, 441, 443, 444, 445, 446, 447, 448, - /* 160 */ 449, 294, 297, 299, 317, 451, 452, 321, 318, 324, - /* 170 */ 327, 332, 457, 319, 458, 462, 460, 464, 463, 466, - /* 180 */ 467, 468, 469, 470, 471, 474, 472, 473, 475, 477, - /* 190 */ 476, 478, 482, 483, 484, 489, 485, 479, 486, 487, - /* 200 */ 491, 501, 490, 502, 496, 503, 508, 509, 498, 515, + /* 0 */ -138, 53, 53, 162, 162, -211, -202, 180, 188, -201, + /* 10 */ -199, -20, 9, 102, 103, 116, 158, 202, 204, 205, + /* 20 */ 216, 225, -276, -141, -43, -191, -255, -225, -216, -142, + /* 30 */ -96, -44, 37, 42, 44, 168, 184, 191, 195, 203, + /* 40 */ 208, 209, 210, 211, 212, 215, 217, 223, 246, 252, + /* 50 */ 253, -97, 166, -103, -184, 256, 297, 306, 307, 309, + /* 60 */ 123, -116, -161, 179, 206, -3, 17, 15, 172, 34, + /* 70 */ 134, -228, 49, 120, 118, 159, 156, 310, 316, 318, + /* 80 */ 335, 336, 339, 347, 368, 378, 313, 382, 383, 385, + /* 90 */ 340, 342, 386, 387, 389, 391, 317, 319, 320, 321, + /* 100 */ 332, 344, 393, 395, 399, 400, 401, 403, 404, 405, + /* 110 */ 407, 408, 411, 412, 413, 414, 415, 416, 419, 420, + /* 120 */ 424, 425, 426, 427, 431, 432, 433, 434, 435, 436, + /* 130 */ 442, 443, 444, 445, 448, 449, 451, 452, 453, 454, + /* 140 */ 455, 457, 458, 460, 461, 463, 464, 465, 466, 467, + /* 150 */ 468, 469, 470, 472, 473, 474, 475, 477, 478, 479, + /* 160 */ 480, 481, 482, 334, 346, 349, 350, 483, 353, 366, + /* 170 */ 348, 379, 381, 380, 447, 486, 489, 487, 491, 490, + /* 180 */ 492, 493, 495, 496, 498, 501, 503, 499, 504, 505, + /* 190 */ 507, 506, 509, 510, 513, 514, 516, 511, 512, 517, + /* 200 */ 518, 519, 531, 521, 535, 537, 539, 538, 544, 523, + /* 210 */ 532, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 900, 1023, 962, 1033, 949, 959, 1184, 1184, 1184, 900, - /* 10 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 20 */ 900, 900, 900, 1081, 920, 1184, 900, 900, 900, 900, - /* 30 */ 900, 900, 900, 1105, 900, 959, 900, 900, 900, 900, - /* 40 */ 900, 969, 959, 969, 969, 900, 1076, 1007, 1025, 900, - /* 50 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 60 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 70 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 80 */ 900, 900, 900, 900, 900, 900, 1083, 1089, 1086, 900, - /* 90 */ 900, 900, 1091, 900, 900, 900, 1124, 1124, 1074, 900, - /* 100 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 110 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 120 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 130 */ 900, 900, 947, 900, 945, 900, 900, 900, 900, 900, - /* 140 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 150 */ 900, 900, 900, 900, 900, 900, 900, 918, 922, 922, - /* 160 */ 922, 900, 900, 900, 900, 922, 922, 1131, 1135, 1117, - /* 170 */ 1129, 1125, 1112, 1110, 1108, 1116, 1101, 1139, 922, 922, - /* 180 */ 922, 967, 967, 963, 959, 959, 922, 922, 985, 983, - /* 190 */ 981, 973, 979, 975, 977, 971, 950, 900, 922, 922, - /* 200 */ 957, 957, 922, 957, 922, 957, 922, 922, 1007, 1025, - /* 210 */ 1183, 900, 1140, 1130, 1183, 900, 1171, 1170, 900, 1179, - /* 220 */ 1178, 1177, 1169, 1168, 1167, 900, 900, 1163, 1166, 1165, - /* 230 */ 1164, 900, 900, 900, 900, 1173, 1172, 900, 900, 900, - /* 240 */ 900, 900, 900, 900, 1098, 900, 900, 900, 1136, 1132, - /* 250 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 1142, - /* 260 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 1035, - /* 270 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 280 */ 900, 900, 1073, 900, 900, 900, 900, 900, 1085, 1084, - /* 290 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 300 */ 900, 900, 900, 900, 900, 900, 900, 900, 1126, 900, - /* 310 */ 1118, 900, 900, 1047, 900, 900, 900, 900, 900, 900, - /* 320 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 330 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 340 */ 900, 900, 900, 900, 900, 900, 1202, 1197, 1198, 1195, - /* 350 */ 900, 900, 900, 1194, 1189, 1190, 900, 900, 900, 1187, - /* 360 */ 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, - /* 370 */ 900, 900, 900, 900, 900, 991, 900, 929, 927, 900, - /* 380 */ 900, + /* 0 */ 926, 1049, 988, 1059, 975, 985, 1220, 1220, 1220, 1220, + /* 10 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 20 */ 926, 926, 926, 926, 1107, 946, 926, 926, 926, 926, + /* 30 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 40 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 50 */ 926, 926, 926, 1131, 926, 985, 926, 926, 926, 926, + /* 60 */ 926, 995, 985, 926, 926, 995, 995, 926, 1102, 1033, + /* 70 */ 1051, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 80 */ 926, 926, 926, 926, 926, 926, 1109, 1115, 1112, 926, + /* 90 */ 926, 926, 1117, 926, 926, 926, 1153, 1153, 1153, 1153, + /* 100 */ 1100, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 110 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 120 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 130 */ 926, 926, 926, 926, 973, 926, 971, 926, 926, 926, + /* 140 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 150 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 944, + /* 160 */ 948, 948, 948, 926, 926, 926, 926, 948, 1162, 1166, + /* 170 */ 1143, 1160, 1154, 1138, 1136, 1134, 1142, 1127, 1170, 948, + /* 180 */ 948, 948, 993, 993, 989, 985, 985, 948, 948, 1011, + /* 190 */ 1009, 1007, 999, 1005, 1001, 1003, 997, 976, 926, 948, + /* 200 */ 948, 983, 983, 948, 983, 948, 983, 948, 948, 1033, + /* 210 */ 1051, 1219, 926, 1171, 1161, 1219, 926, 1202, 1201, 926, + /* 220 */ 1210, 1209, 1208, 1200, 1199, 1198, 926, 926, 1194, 1197, + /* 230 */ 1196, 1195, 926, 926, 1173, 926, 926, 1204, 1203, 926, + /* 240 */ 926, 926, 926, 926, 926, 926, 1124, 926, 926, 926, + /* 250 */ 1149, 1167, 1163, 926, 926, 926, 926, 926, 926, 926, + /* 260 */ 926, 1174, 926, 926, 926, 926, 926, 926, 926, 926, + /* 270 */ 926, 926, 1061, 926, 926, 926, 926, 926, 926, 926, + /* 280 */ 926, 926, 926, 926, 926, 1099, 926, 926, 926, 926, + /* 290 */ 926, 1111, 1110, 926, 926, 926, 926, 926, 926, 926, + /* 300 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 310 */ 926, 1155, 926, 1150, 926, 1144, 926, 926, 1073, 926, + /* 320 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 330 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 340 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 350 */ 926, 926, 926, 926, 926, 1238, 1233, 1234, 1231, 926, + /* 360 */ 926, 926, 1230, 1225, 1226, 926, 926, 926, 1223, 926, + /* 370 */ 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, + /* 380 */ 926, 926, 926, 926, 1017, 926, 955, 953, 926, 926, }; /********** End of lemon-generated parsing tables *****************************/ @@ -548,6 +756,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 */ @@ -559,6 +768,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 */ @@ -580,6 +790,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 */ @@ -786,6 +997,7 @@ typedef struct yyParser yyParser; #ifndef NDEBUG #include +#include static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ @@ -833,274 +1045,277 @@ 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 */ "UMINUS", - /* 43 */ "UPLUS", - /* 44 */ "BITNOT", - /* 45 */ "SHOW", - /* 46 */ "DATABASES", - /* 47 */ "TOPICS", - /* 48 */ "FUNCTIONS", - /* 49 */ "MNODES", - /* 50 */ "DNODES", - /* 51 */ "ACCOUNTS", - /* 52 */ "USERS", - /* 53 */ "MODULES", - /* 54 */ "QUERIES", - /* 55 */ "CONNECTIONS", - /* 56 */ "STREAMS", - /* 57 */ "VARIABLES", - /* 58 */ "SCORES", - /* 59 */ "GRANTS", - /* 60 */ "VNODES", - /* 61 */ "DOT", - /* 62 */ "CREATE", - /* 63 */ "TABLE", - /* 64 */ "STABLE", - /* 65 */ "DATABASE", - /* 66 */ "TABLES", - /* 67 */ "STABLES", - /* 68 */ "VGROUPS", - /* 69 */ "DROP", - /* 70 */ "TOPIC", - /* 71 */ "FUNCTION", - /* 72 */ "DNODE", - /* 73 */ "USER", - /* 74 */ "ACCOUNT", - /* 75 */ "USE", - /* 76 */ "DESCRIBE", - /* 77 */ "DESC", - /* 78 */ "ALTER", - /* 79 */ "PASS", - /* 80 */ "PRIVILEGE", - /* 81 */ "LOCAL", - /* 82 */ "COMPACT", - /* 83 */ "LP", - /* 84 */ "RP", - /* 85 */ "IF", - /* 86 */ "EXISTS", - /* 87 */ "AS", - /* 88 */ "OUTPUTTYPE", - /* 89 */ "AGGREGATE", - /* 90 */ "BUFSIZE", - /* 91 */ "PPS", - /* 92 */ "TSERIES", - /* 93 */ "DBS", - /* 94 */ "STORAGE", - /* 95 */ "QTIME", - /* 96 */ "CONNS", - /* 97 */ "STATE", - /* 98 */ "COMMA", - /* 99 */ "KEEP", - /* 100 */ "CACHE", - /* 101 */ "REPLICA", - /* 102 */ "QUORUM", - /* 103 */ "DAYS", - /* 104 */ "MINROWS", - /* 105 */ "MAXROWS", - /* 106 */ "BLOCKS", - /* 107 */ "CTIME", - /* 108 */ "WAL", - /* 109 */ "FSYNC", - /* 110 */ "COMP", - /* 111 */ "PRECISION", - /* 112 */ "UPDATE", - /* 113 */ "CACHELAST", - /* 114 */ "PARTITIONS", - /* 115 */ "UNSIGNED", - /* 116 */ "TAGS", - /* 117 */ "USING", - /* 118 */ "NULL", - /* 119 */ "NOW", - /* 120 */ "SELECT", - /* 121 */ "UNION", - /* 122 */ "ALL", - /* 123 */ "DISTINCT", - /* 124 */ "FROM", - /* 125 */ "VARIABLE", - /* 126 */ "RANGE", - /* 127 */ "INTERVAL", - /* 128 */ "EVERY", - /* 129 */ "SESSION", - /* 130 */ "STATE_WINDOW", - /* 131 */ "FILL", - /* 132 */ "SLIDING", - /* 133 */ "ORDER", - /* 134 */ "BY", - /* 135 */ "ASC", - /* 136 */ "GROUP", - /* 137 */ "HAVING", - /* 138 */ "LIMIT", - /* 139 */ "OFFSET", - /* 140 */ "SLIMIT", - /* 141 */ "SOFFSET", - /* 142 */ "WHERE", - /* 143 */ "RESET", - /* 144 */ "QUERY", - /* 145 */ "SYNCDB", - /* 146 */ "ADD", - /* 147 */ "COLUMN", - /* 148 */ "MODIFY", - /* 149 */ "TAG", - /* 150 */ "CHANGE", - /* 151 */ "SET", - /* 152 */ "KILL", - /* 153 */ "CONNECTION", - /* 154 */ "STREAM", - /* 155 */ "COLON", - /* 156 */ "ABORT", - /* 157 */ "AFTER", - /* 158 */ "ATTACH", - /* 159 */ "BEFORE", - /* 160 */ "BEGIN", - /* 161 */ "CASCADE", - /* 162 */ "CLUSTER", - /* 163 */ "CONFLICT", - /* 164 */ "COPY", - /* 165 */ "DEFERRED", - /* 166 */ "DELIMITERS", - /* 167 */ "DETACH", - /* 168 */ "EACH", - /* 169 */ "END", - /* 170 */ "EXPLAIN", - /* 171 */ "FAIL", - /* 172 */ "FOR", - /* 173 */ "IGNORE", - /* 174 */ "IMMEDIATE", - /* 175 */ "INITIALLY", - /* 176 */ "INSTEAD", - /* 177 */ "KEY", - /* 178 */ "OF", - /* 179 */ "RAISE", - /* 180 */ "REPLACE", - /* 181 */ "RESTRICT", - /* 182 */ "ROW", - /* 183 */ "STATEMENT", - /* 184 */ "TRIGGER", - /* 185 */ "VIEW", - /* 186 */ "IPTOKEN", - /* 187 */ "SEMI", - /* 188 */ "NONE", - /* 189 */ "PREV", - /* 190 */ "LINEAR", - /* 191 */ "IMPORT", - /* 192 */ "TBNAME", - /* 193 */ "JOIN", - /* 194 */ "INSERT", - /* 195 */ "INTO", - /* 196 */ "VALUES", - /* 197 */ "FILE", - /* 198 */ "program", - /* 199 */ "cmd", - /* 200 */ "ids", - /* 201 */ "dbPrefix", - /* 202 */ "cpxName", - /* 203 */ "ifexists", - /* 204 */ "alter_db_optr", - /* 205 */ "alter_topic_optr", - /* 206 */ "acct_optr", - /* 207 */ "exprlist", - /* 208 */ "ifnotexists", - /* 209 */ "db_optr", - /* 210 */ "topic_optr", - /* 211 */ "typename", - /* 212 */ "bufsize", - /* 213 */ "pps", - /* 214 */ "tseries", - /* 215 */ "dbs", - /* 216 */ "streams", - /* 217 */ "storage", - /* 218 */ "qtime", - /* 219 */ "users", - /* 220 */ "conns", - /* 221 */ "state", - /* 222 */ "intitemlist", - /* 223 */ "intitem", - /* 224 */ "keep", - /* 225 */ "cache", - /* 226 */ "replica", - /* 227 */ "quorum", - /* 228 */ "days", - /* 229 */ "minrows", - /* 230 */ "maxrows", - /* 231 */ "blocks", - /* 232 */ "ctime", - /* 233 */ "wal", - /* 234 */ "fsync", - /* 235 */ "comp", - /* 236 */ "prec", - /* 237 */ "update", - /* 238 */ "cachelast", - /* 239 */ "partitions", - /* 240 */ "signed", - /* 241 */ "create_table_args", - /* 242 */ "create_stable_args", - /* 243 */ "create_table_list", - /* 244 */ "create_from_stable", - /* 245 */ "columnlist", - /* 246 */ "tagitemlist", - /* 247 */ "tagNamelist", - /* 248 */ "select", - /* 249 */ "column", - /* 250 */ "tagitem", - /* 251 */ "selcollist", - /* 252 */ "from", - /* 253 */ "where_opt", - /* 254 */ "range_option", - /* 255 */ "interval_option", - /* 256 */ "sliding_opt", - /* 257 */ "session_option", - /* 258 */ "windowstate_option", - /* 259 */ "fill_opt", - /* 260 */ "groupby_opt", - /* 261 */ "having_opt", - /* 262 */ "orderby_opt", - /* 263 */ "slimit_opt", - /* 264 */ "limit_opt", - /* 265 */ "union", - /* 266 */ "sclp", - /* 267 */ "distinct", - /* 268 */ "expr", - /* 269 */ "as", - /* 270 */ "tablelist", - /* 271 */ "sub", - /* 272 */ "tmvar", - /* 273 */ "timestamp", - /* 274 */ "intervalKey", - /* 275 */ "sortlist", - /* 276 */ "sortitem", - /* 277 */ "item", - /* 278 */ "sortorder", - /* 279 */ "grouplist", - /* 280 */ "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 */ "UMINUS", + /* 45 */ "UPLUS", + /* 46 */ "BITNOT", + /* 47 */ "ARROW", + /* 48 */ "SHOW", + /* 49 */ "DATABASES", + /* 50 */ "TOPICS", + /* 51 */ "FUNCTIONS", + /* 52 */ "MNODES", + /* 53 */ "DNODES", + /* 54 */ "ACCOUNTS", + /* 55 */ "USERS", + /* 56 */ "MODULES", + /* 57 */ "QUERIES", + /* 58 */ "CONNECTIONS", + /* 59 */ "STREAMS", + /* 60 */ "VARIABLES", + /* 61 */ "SCORES", + /* 62 */ "GRANTS", + /* 63 */ "VNODES", + /* 64 */ "DOT", + /* 65 */ "CREATE", + /* 66 */ "TABLE", + /* 67 */ "STABLE", + /* 68 */ "DATABASE", + /* 69 */ "TABLES", + /* 70 */ "STABLES", + /* 71 */ "VGROUPS", + /* 72 */ "DROP", + /* 73 */ "TOPIC", + /* 74 */ "FUNCTION", + /* 75 */ "DNODE", + /* 76 */ "USER", + /* 77 */ "ACCOUNT", + /* 78 */ "USE", + /* 79 */ "DESCRIBE", + /* 80 */ "DESC", + /* 81 */ "ALTER", + /* 82 */ "PASS", + /* 83 */ "PRIVILEGE", + /* 84 */ "LOCAL", + /* 85 */ "COMPACT", + /* 86 */ "LP", + /* 87 */ "RP", + /* 88 */ "IF", + /* 89 */ "EXISTS", + /* 90 */ "AS", + /* 91 */ "OUTPUTTYPE", + /* 92 */ "AGGREGATE", + /* 93 */ "BUFSIZE", + /* 94 */ "PPS", + /* 95 */ "TSERIES", + /* 96 */ "DBS", + /* 97 */ "STORAGE", + /* 98 */ "QTIME", + /* 99 */ "CONNS", + /* 100 */ "STATE", + /* 101 */ "COMMA", + /* 102 */ "KEEP", + /* 103 */ "CACHE", + /* 104 */ "REPLICA", + /* 105 */ "QUORUM", + /* 106 */ "DAYS", + /* 107 */ "MINROWS", + /* 108 */ "MAXROWS", + /* 109 */ "BLOCKS", + /* 110 */ "CTIME", + /* 111 */ "WAL", + /* 112 */ "FSYNC", + /* 113 */ "COMP", + /* 114 */ "PRECISION", + /* 115 */ "UPDATE", + /* 116 */ "CACHELAST", + /* 117 */ "PARTITIONS", + /* 118 */ "UNSIGNED", + /* 119 */ "TAGS", + /* 120 */ "USING", + /* 121 */ "NULL", + /* 122 */ "NOW", + /* 123 */ "SELECT", + /* 124 */ "UNION", + /* 125 */ "ALL", + /* 126 */ "DISTINCT", + /* 127 */ "FROM", + /* 128 */ "VARIABLE", + /* 129 */ "RANGE", + /* 130 */ "INTERVAL", + /* 131 */ "EVERY", + /* 132 */ "SESSION", + /* 133 */ "STATE_WINDOW", + /* 134 */ "FILL", + /* 135 */ "SLIDING", + /* 136 */ "ORDER", + /* 137 */ "BY", + /* 138 */ "ASC", + /* 139 */ "GROUP", + /* 140 */ "HAVING", + /* 141 */ "LIMIT", + /* 142 */ "OFFSET", + /* 143 */ "SLIMIT", + /* 144 */ "SOFFSET", + /* 145 */ "WHERE", + /* 146 */ "RESET", + /* 147 */ "QUERY", + /* 148 */ "SYNCDB", + /* 149 */ "ADD", + /* 150 */ "COLUMN", + /* 151 */ "MODIFY", + /* 152 */ "TAG", + /* 153 */ "CHANGE", + /* 154 */ "SET", + /* 155 */ "KILL", + /* 156 */ "CONNECTION", + /* 157 */ "STREAM", + /* 158 */ "COLON", + /* 159 */ "ABORT", + /* 160 */ "AFTER", + /* 161 */ "ATTACH", + /* 162 */ "BEFORE", + /* 163 */ "BEGIN", + /* 164 */ "CASCADE", + /* 165 */ "CLUSTER", + /* 166 */ "CONFLICT", + /* 167 */ "COPY", + /* 168 */ "DEFERRED", + /* 169 */ "DELIMITERS", + /* 170 */ "DETACH", + /* 171 */ "EACH", + /* 172 */ "END", + /* 173 */ "EXPLAIN", + /* 174 */ "FAIL", + /* 175 */ "FOR", + /* 176 */ "IGNORE", + /* 177 */ "IMMEDIATE", + /* 178 */ "INITIALLY", + /* 179 */ "INSTEAD", + /* 180 */ "KEY", + /* 181 */ "OF", + /* 182 */ "RAISE", + /* 183 */ "REPLACE", + /* 184 */ "RESTRICT", + /* 185 */ "ROW", + /* 186 */ "STATEMENT", + /* 187 */ "TRIGGER", + /* 188 */ "VIEW", + /* 189 */ "IPTOKEN", + /* 190 */ "SEMI", + /* 191 */ "NONE", + /* 192 */ "PREV", + /* 193 */ "LINEAR", + /* 194 */ "IMPORT", + /* 195 */ "TBNAME", + /* 196 */ "JOIN", + /* 197 */ "INSERT", + /* 198 */ "INTO", + /* 199 */ "VALUES", + /* 200 */ "FILE", + /* 201 */ "program", + /* 202 */ "cmd", + /* 203 */ "ids", + /* 204 */ "dbPrefix", + /* 205 */ "cpxName", + /* 206 */ "ifexists", + /* 207 */ "alter_db_optr", + /* 208 */ "alter_topic_optr", + /* 209 */ "acct_optr", + /* 210 */ "exprlist", + /* 211 */ "ifnotexists", + /* 212 */ "db_optr", + /* 213 */ "topic_optr", + /* 214 */ "typename", + /* 215 */ "bufsize", + /* 216 */ "pps", + /* 217 */ "tseries", + /* 218 */ "dbs", + /* 219 */ "streams", + /* 220 */ "storage", + /* 221 */ "qtime", + /* 222 */ "users", + /* 223 */ "conns", + /* 224 */ "state", + /* 225 */ "intitemlist", + /* 226 */ "intitem", + /* 227 */ "keep", + /* 228 */ "cache", + /* 229 */ "replica", + /* 230 */ "quorum", + /* 231 */ "days", + /* 232 */ "minrows", + /* 233 */ "maxrows", + /* 234 */ "blocks", + /* 235 */ "ctime", + /* 236 */ "wal", + /* 237 */ "fsync", + /* 238 */ "comp", + /* 239 */ "prec", + /* 240 */ "update", + /* 241 */ "cachelast", + /* 242 */ "partitions", + /* 243 */ "signed", + /* 244 */ "create_table_args", + /* 245 */ "create_stable_args", + /* 246 */ "create_table_list", + /* 247 */ "create_from_stable", + /* 248 */ "columnlist", + /* 249 */ "tagitemlist", + /* 250 */ "tagNamelist", + /* 251 */ "select", + /* 252 */ "column", + /* 253 */ "tagitem", + /* 254 */ "selcollist", + /* 255 */ "from", + /* 256 */ "where_opt", + /* 257 */ "range_option", + /* 258 */ "interval_option", + /* 259 */ "sliding_opt", + /* 260 */ "session_option", + /* 261 */ "windowstate_option", + /* 262 */ "fill_opt", + /* 263 */ "groupby_opt", + /* 264 */ "having_opt", + /* 265 */ "orderby_opt", + /* 266 */ "slimit_opt", + /* 267 */ "limit_opt", + /* 268 */ "union", + /* 269 */ "sclp", + /* 270 */ "distinct", + /* 271 */ "expr", + /* 272 */ "as", + /* 273 */ "tablelist", + /* 274 */ "sub", + /* 275 */ "tmvar", + /* 276 */ "timestamp", + /* 277 */ "intervalKey", + /* 278 */ "sortlist", + /* 279 */ "item", + /* 280 */ "sortorder", + /* 281 */ "arrow", + /* 282 */ "grouplist", + /* 283 */ "expritem", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -1325,92 +1540,102 @@ 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 ::= ID LP expr AS typename RP", - /* 258 */ "expr ::= expr IS NULL", - /* 259 */ "expr ::= expr IS NOT NULL", - /* 260 */ "expr ::= expr LT expr", - /* 261 */ "expr ::= expr GT expr", - /* 262 */ "expr ::= expr LE expr", - /* 263 */ "expr ::= expr GE expr", - /* 264 */ "expr ::= expr NE expr", - /* 265 */ "expr ::= expr EQ expr", - /* 266 */ "expr ::= expr BETWEEN expr AND expr", - /* 267 */ "expr ::= expr AND expr", - /* 268 */ "expr ::= expr OR expr", - /* 269 */ "expr ::= expr PLUS expr", - /* 270 */ "expr ::= expr MINUS expr", - /* 271 */ "expr ::= expr STAR expr", - /* 272 */ "expr ::= expr SLASH expr", - /* 273 */ "expr ::= expr REM expr", - /* 274 */ "expr ::= expr LIKE expr", - /* 275 */ "expr ::= expr MATCH expr", - /* 276 */ "expr ::= expr NMATCH expr", - /* 277 */ "expr ::= expr IN LP exprlist RP", - /* 278 */ "exprlist ::= exprlist COMMA expritem", - /* 279 */ "exprlist ::= expritem", - /* 280 */ "expritem ::= expr", - /* 281 */ "expritem ::=", - /* 282 */ "cmd ::= RESET QUERY CACHE", - /* 283 */ "cmd ::= SYNCDB ids REPLICA", - /* 284 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", - /* 285 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", - /* 286 */ "cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist", - /* 287 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", - /* 288 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", - /* 289 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", - /* 290 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", - /* 291 */ "cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist", - /* 292 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", - /* 293 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", - /* 294 */ "cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist", - /* 295 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", - /* 296 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", - /* 297 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", - /* 298 */ "cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem", - /* 299 */ "cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist", - /* 300 */ "cmd ::= KILL CONNECTION INTEGER", - /* 301 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", - /* 302 */ "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 ::= ID LP expr AS typename RP", + /* 263 */ "expr ::= expr IS NULL", + /* 264 */ "expr ::= expr IS NOT NULL", + /* 265 */ "expr ::= expr LT expr", + /* 266 */ "expr ::= expr GT expr", + /* 267 */ "expr ::= expr LE expr", + /* 268 */ "expr ::= expr GE expr", + /* 269 */ "expr ::= expr NE expr", + /* 270 */ "expr ::= expr EQ expr", + /* 271 */ "expr ::= expr BETWEEN expr AND expr", + /* 272 */ "expr ::= expr AND expr", + /* 273 */ "expr ::= expr OR expr", + /* 274 */ "expr ::= expr PLUS expr", + /* 275 */ "expr ::= expr MINUS expr", + /* 276 */ "expr ::= expr STAR expr", + /* 277 */ "expr ::= expr SLASH expr", + /* 278 */ "expr ::= expr REM expr", + /* 279 */ "expr ::= expr LIKE expr", + /* 280 */ "expr ::= expr MATCH expr", + /* 281 */ "expr ::= expr NMATCH expr", + /* 282 */ "expr ::= ID CONTAINS STRING", + /* 283 */ "expr ::= ID DOT ID CONTAINS STRING", + /* 284 */ "arrow ::= ID ARROW STRING", + /* 285 */ "arrow ::= ID DOT ID ARROW STRING", + /* 286 */ "expr ::= arrow", + /* 287 */ "expr ::= expr IN LP exprlist RP", + /* 288 */ "exprlist ::= exprlist COMMA expritem", + /* 289 */ "exprlist ::= expritem", + /* 290 */ "expritem ::= expr", + /* 291 */ "expritem ::=", + /* 292 */ "cmd ::= RESET QUERY CACHE", + /* 293 */ "cmd ::= SYNCDB ids REPLICA", + /* 294 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", + /* 295 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", + /* 296 */ "cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist", + /* 297 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", + /* 298 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", + /* 299 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", + /* 300 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", + /* 301 */ "cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist", + /* 302 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", + /* 303 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", + /* 304 */ "cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist", + /* 305 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", + /* 306 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", + /* 307 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", + /* 308 */ "cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem", + /* 309 */ "cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist", + /* 310 */ "cmd ::= KILL CONNECTION INTEGER", + /* 311 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", + /* 312 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", }; #endif /* NDEBUG */ @@ -1536,61 +1761,57 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 207: /* exprlist */ - case 251: /* selcollist */ - case 266: /* sclp */ + case 210: /* exprlist */ + case 254: /* selcollist */ + case 269: /* sclp */ { -tSqlExprListDestroy((yypminor->yy247)); -} - break; - case 222: /* intitemlist */ - case 224: /* keep */ - case 245: /* columnlist */ - case 246: /* tagitemlist */ - case 247: /* tagNamelist */ - case 259: /* fill_opt */ - case 260: /* groupby_opt */ - case 262: /* orderby_opt */ - case 275: /* sortlist */ - case 279: /* grouplist */ -{ -taosArrayDestroy((yypminor->yy247)); +tSqlExprListDestroy((yypminor->yy189)); } break; - case 243: /* create_table_list */ + case 225: /* intitemlist */ + case 227: /* keep */ + case 248: /* columnlist */ + case 249: /* tagitemlist */ + case 250: /* tagNamelist */ + case 262: /* fill_opt */ + case 263: /* groupby_opt */ + case 265: /* orderby_opt */ + case 278: /* sortlist */ + case 282: /* grouplist */ { -destroyCreateTableSql((yypminor->yy336)); +taosArrayDestroy((yypminor->yy189)); } break; - case 248: /* select */ + case 246: /* create_table_list */ { -destroySqlNode((yypminor->yy246)); +destroyCreateTableSql((yypminor->yy6)); } break; - case 252: /* from */ - case 270: /* tablelist */ - case 271: /* sub */ + case 251: /* select */ { -destroyRelationInfo((yypminor->yy46)); +destroySqlNode((yypminor->yy16)); } break; - case 253: /* where_opt */ - case 261: /* having_opt */ - case 268: /* expr */ - case 273: /* timestamp */ - case 280: /* expritem */ + case 255: /* from */ + case 273: /* tablelist */ + case 274: /* sub */ { -tSqlExprDestroy((yypminor->yy44)); +destroyRelationInfo((yypminor->yy36)); } break; - case 265: /* union */ + case 256: /* where_opt */ + case 264: /* having_opt */ + case 271: /* expr */ + case 276: /* timestamp */ + case 281: /* arrow */ + case 283: /* expritem */ { -destroyAllSqlNode((yypminor->yy247)); +tSqlExprDestroy((yypminor->yy18)); } break; - case 276: /* sortitem */ + case 268: /* union */ { -tVariantDestroy(&(yypminor->yy378)); +destroyAllSqlNode((yypminor->yy189)); } break; /********* End destructor definitions *****************************************/ @@ -1757,7 +1978,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); @@ -1879,309 +2100,319 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 198, /* (0) program ::= cmd */ - 199, /* (1) cmd ::= SHOW DATABASES */ - 199, /* (2) cmd ::= SHOW TOPICS */ - 199, /* (3) cmd ::= SHOW FUNCTIONS */ - 199, /* (4) cmd ::= SHOW MNODES */ - 199, /* (5) cmd ::= SHOW DNODES */ - 199, /* (6) cmd ::= SHOW ACCOUNTS */ - 199, /* (7) cmd ::= SHOW USERS */ - 199, /* (8) cmd ::= SHOW MODULES */ - 199, /* (9) cmd ::= SHOW QUERIES */ - 199, /* (10) cmd ::= SHOW CONNECTIONS */ - 199, /* (11) cmd ::= SHOW STREAMS */ - 199, /* (12) cmd ::= SHOW VARIABLES */ - 199, /* (13) cmd ::= SHOW SCORES */ - 199, /* (14) cmd ::= SHOW GRANTS */ - 199, /* (15) cmd ::= SHOW VNODES */ - 199, /* (16) cmd ::= SHOW VNODES ids */ - 201, /* (17) dbPrefix ::= */ - 201, /* (18) dbPrefix ::= ids DOT */ - 202, /* (19) cpxName ::= */ - 202, /* (20) cpxName ::= DOT ids */ - 199, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ - 199, /* (22) cmd ::= SHOW CREATE STABLE ids cpxName */ - 199, /* (23) cmd ::= SHOW CREATE DATABASE ids */ - 199, /* (24) cmd ::= SHOW dbPrefix TABLES */ - 199, /* (25) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - 199, /* (26) cmd ::= SHOW dbPrefix STABLES */ - 199, /* (27) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - 199, /* (28) cmd ::= SHOW dbPrefix VGROUPS */ - 199, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ - 199, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ - 199, /* (31) cmd ::= DROP DATABASE ifexists ids */ - 199, /* (32) cmd ::= DROP TOPIC ifexists ids */ - 199, /* (33) cmd ::= DROP FUNCTION ids */ - 199, /* (34) cmd ::= DROP DNODE ids */ - 199, /* (35) cmd ::= DROP USER ids */ - 199, /* (36) cmd ::= DROP ACCOUNT ids */ - 199, /* (37) cmd ::= USE ids */ - 199, /* (38) cmd ::= DESCRIBE ids cpxName */ - 199, /* (39) cmd ::= DESC ids cpxName */ - 199, /* (40) cmd ::= ALTER USER ids PASS ids */ - 199, /* (41) cmd ::= ALTER USER ids PRIVILEGE ids */ - 199, /* (42) cmd ::= ALTER DNODE ids ids */ - 199, /* (43) cmd ::= ALTER DNODE ids ids ids */ - 199, /* (44) cmd ::= ALTER LOCAL ids */ - 199, /* (45) cmd ::= ALTER LOCAL ids ids */ - 199, /* (46) cmd ::= ALTER DATABASE ids alter_db_optr */ - 199, /* (47) cmd ::= ALTER TOPIC ids alter_topic_optr */ - 199, /* (48) cmd ::= ALTER ACCOUNT ids acct_optr */ - 199, /* (49) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - 199, /* (50) cmd ::= COMPACT VNODES IN LP exprlist RP */ - 200, /* (51) ids ::= ID */ - 200, /* (52) ids ::= STRING */ - 203, /* (53) ifexists ::= IF EXISTS */ - 203, /* (54) ifexists ::= */ - 208, /* (55) ifnotexists ::= IF NOT EXISTS */ - 208, /* (56) ifnotexists ::= */ - 199, /* (57) cmd ::= CREATE DNODE ids */ - 199, /* (58) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - 199, /* (59) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - 199, /* (60) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - 199, /* (61) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - 199, /* (62) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - 199, /* (63) cmd ::= CREATE USER ids PASS ids */ - 212, /* (64) bufsize ::= */ - 212, /* (65) bufsize ::= BUFSIZE INTEGER */ - 213, /* (66) pps ::= */ - 213, /* (67) pps ::= PPS INTEGER */ - 214, /* (68) tseries ::= */ - 214, /* (69) tseries ::= TSERIES INTEGER */ - 215, /* (70) dbs ::= */ - 215, /* (71) dbs ::= DBS INTEGER */ - 216, /* (72) streams ::= */ - 216, /* (73) streams ::= STREAMS INTEGER */ - 217, /* (74) storage ::= */ - 217, /* (75) storage ::= STORAGE INTEGER */ - 218, /* (76) qtime ::= */ - 218, /* (77) qtime ::= QTIME INTEGER */ - 219, /* (78) users ::= */ - 219, /* (79) users ::= USERS INTEGER */ - 220, /* (80) conns ::= */ - 220, /* (81) conns ::= CONNS INTEGER */ - 221, /* (82) state ::= */ - 221, /* (83) state ::= STATE ids */ - 206, /* (84) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - 222, /* (85) intitemlist ::= intitemlist COMMA intitem */ - 222, /* (86) intitemlist ::= intitem */ - 223, /* (87) intitem ::= INTEGER */ - 224, /* (88) keep ::= KEEP intitemlist */ - 225, /* (89) cache ::= CACHE INTEGER */ - 226, /* (90) replica ::= REPLICA INTEGER */ - 227, /* (91) quorum ::= QUORUM INTEGER */ - 228, /* (92) days ::= DAYS INTEGER */ - 229, /* (93) minrows ::= MINROWS INTEGER */ - 230, /* (94) maxrows ::= MAXROWS INTEGER */ - 231, /* (95) blocks ::= BLOCKS INTEGER */ - 232, /* (96) ctime ::= CTIME INTEGER */ - 233, /* (97) wal ::= WAL INTEGER */ - 234, /* (98) fsync ::= FSYNC INTEGER */ - 235, /* (99) comp ::= COMP INTEGER */ - 236, /* (100) prec ::= PRECISION STRING */ - 237, /* (101) update ::= UPDATE INTEGER */ - 238, /* (102) cachelast ::= CACHELAST INTEGER */ - 239, /* (103) partitions ::= PARTITIONS INTEGER */ - 209, /* (104) db_optr ::= */ - 209, /* (105) db_optr ::= db_optr cache */ - 209, /* (106) db_optr ::= db_optr replica */ - 209, /* (107) db_optr ::= db_optr quorum */ - 209, /* (108) db_optr ::= db_optr days */ - 209, /* (109) db_optr ::= db_optr minrows */ - 209, /* (110) db_optr ::= db_optr maxrows */ - 209, /* (111) db_optr ::= db_optr blocks */ - 209, /* (112) db_optr ::= db_optr ctime */ - 209, /* (113) db_optr ::= db_optr wal */ - 209, /* (114) db_optr ::= db_optr fsync */ - 209, /* (115) db_optr ::= db_optr comp */ - 209, /* (116) db_optr ::= db_optr prec */ - 209, /* (117) db_optr ::= db_optr keep */ - 209, /* (118) db_optr ::= db_optr update */ - 209, /* (119) db_optr ::= db_optr cachelast */ - 210, /* (120) topic_optr ::= db_optr */ - 210, /* (121) topic_optr ::= topic_optr partitions */ - 204, /* (122) alter_db_optr ::= */ - 204, /* (123) alter_db_optr ::= alter_db_optr replica */ - 204, /* (124) alter_db_optr ::= alter_db_optr quorum */ - 204, /* (125) alter_db_optr ::= alter_db_optr keep */ - 204, /* (126) alter_db_optr ::= alter_db_optr blocks */ - 204, /* (127) alter_db_optr ::= alter_db_optr comp */ - 204, /* (128) alter_db_optr ::= alter_db_optr update */ - 204, /* (129) alter_db_optr ::= alter_db_optr cachelast */ - 205, /* (130) alter_topic_optr ::= alter_db_optr */ - 205, /* (131) alter_topic_optr ::= alter_topic_optr partitions */ - 211, /* (132) typename ::= ids */ - 211, /* (133) typename ::= ids LP signed RP */ - 211, /* (134) typename ::= ids UNSIGNED */ - 240, /* (135) signed ::= INTEGER */ - 240, /* (136) signed ::= PLUS INTEGER */ - 240, /* (137) signed ::= MINUS INTEGER */ - 199, /* (138) cmd ::= CREATE TABLE create_table_args */ - 199, /* (139) cmd ::= CREATE TABLE create_stable_args */ - 199, /* (140) cmd ::= CREATE STABLE create_stable_args */ - 199, /* (141) cmd ::= CREATE TABLE create_table_list */ - 243, /* (142) create_table_list ::= create_from_stable */ - 243, /* (143) create_table_list ::= create_table_list create_from_stable */ - 241, /* (144) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - 242, /* (145) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - 244, /* (146) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - 244, /* (147) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - 247, /* (148) tagNamelist ::= tagNamelist COMMA ids */ - 247, /* (149) tagNamelist ::= ids */ - 241, /* (150) create_table_args ::= ifnotexists ids cpxName AS select */ - 245, /* (151) columnlist ::= columnlist COMMA column */ - 245, /* (152) columnlist ::= column */ - 249, /* (153) column ::= ids typename */ - 246, /* (154) tagitemlist ::= tagitemlist COMMA tagitem */ - 246, /* (155) tagitemlist ::= tagitem */ - 250, /* (156) tagitem ::= INTEGER */ - 250, /* (157) tagitem ::= FLOAT */ - 250, /* (158) tagitem ::= STRING */ - 250, /* (159) tagitem ::= BOOL */ - 250, /* (160) tagitem ::= NULL */ - 250, /* (161) tagitem ::= NOW */ - 250, /* (162) tagitem ::= MINUS INTEGER */ - 250, /* (163) tagitem ::= MINUS FLOAT */ - 250, /* (164) tagitem ::= PLUS INTEGER */ - 250, /* (165) tagitem ::= PLUS FLOAT */ - 248, /* (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 */ - 248, /* (167) select ::= LP select RP */ - 265, /* (168) union ::= select */ - 265, /* (169) union ::= union UNION ALL select */ - 199, /* (170) cmd ::= union */ - 248, /* (171) select ::= SELECT selcollist */ - 266, /* (172) sclp ::= selcollist COMMA */ - 266, /* (173) sclp ::= */ - 251, /* (174) selcollist ::= sclp distinct expr as */ - 251, /* (175) selcollist ::= sclp STAR */ - 269, /* (176) as ::= AS ids */ - 269, /* (177) as ::= ids */ - 269, /* (178) as ::= */ - 267, /* (179) distinct ::= DISTINCT */ - 267, /* (180) distinct ::= */ - 252, /* (181) from ::= FROM tablelist */ - 252, /* (182) from ::= FROM sub */ - 271, /* (183) sub ::= LP union RP */ - 271, /* (184) sub ::= LP union RP ids */ - 271, /* (185) sub ::= sub COMMA LP union RP ids */ - 270, /* (186) tablelist ::= ids cpxName */ - 270, /* (187) tablelist ::= ids cpxName ids */ - 270, /* (188) tablelist ::= tablelist COMMA ids cpxName */ - 270, /* (189) tablelist ::= tablelist COMMA ids cpxName ids */ - 272, /* (190) tmvar ::= VARIABLE */ - 273, /* (191) timestamp ::= INTEGER */ - 273, /* (192) timestamp ::= MINUS INTEGER */ - 273, /* (193) timestamp ::= PLUS INTEGER */ - 273, /* (194) timestamp ::= STRING */ - 273, /* (195) timestamp ::= NOW */ - 273, /* (196) timestamp ::= NOW PLUS VARIABLE */ - 273, /* (197) timestamp ::= NOW MINUS VARIABLE */ - 254, /* (198) range_option ::= */ - 254, /* (199) range_option ::= RANGE LP timestamp COMMA timestamp RP */ - 255, /* (200) interval_option ::= intervalKey LP tmvar RP */ - 255, /* (201) interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ - 255, /* (202) interval_option ::= */ - 274, /* (203) intervalKey ::= INTERVAL */ - 274, /* (204) intervalKey ::= EVERY */ - 257, /* (205) session_option ::= */ - 257, /* (206) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - 258, /* (207) windowstate_option ::= */ - 258, /* (208) windowstate_option ::= STATE_WINDOW LP ids RP */ - 259, /* (209) fill_opt ::= */ - 259, /* (210) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - 259, /* (211) fill_opt ::= FILL LP ID RP */ - 256, /* (212) sliding_opt ::= SLIDING LP tmvar RP */ - 256, /* (213) sliding_opt ::= */ - 262, /* (214) orderby_opt ::= */ - 262, /* (215) orderby_opt ::= ORDER BY sortlist */ - 275, /* (216) sortlist ::= sortlist COMMA item sortorder */ - 275, /* (217) sortlist ::= item sortorder */ - 277, /* (218) item ::= ids cpxName */ - 278, /* (219) sortorder ::= ASC */ - 278, /* (220) sortorder ::= DESC */ - 278, /* (221) sortorder ::= */ - 260, /* (222) groupby_opt ::= */ - 260, /* (223) groupby_opt ::= GROUP BY grouplist */ - 279, /* (224) grouplist ::= grouplist COMMA item */ - 279, /* (225) grouplist ::= item */ - 261, /* (226) having_opt ::= */ - 261, /* (227) having_opt ::= HAVING expr */ - 264, /* (228) limit_opt ::= */ - 264, /* (229) limit_opt ::= LIMIT signed */ - 264, /* (230) limit_opt ::= LIMIT signed OFFSET signed */ - 264, /* (231) limit_opt ::= LIMIT signed COMMA signed */ - 263, /* (232) slimit_opt ::= */ - 263, /* (233) slimit_opt ::= SLIMIT signed */ - 263, /* (234) slimit_opt ::= SLIMIT signed SOFFSET signed */ - 263, /* (235) slimit_opt ::= SLIMIT signed COMMA signed */ - 253, /* (236) where_opt ::= */ - 253, /* (237) where_opt ::= WHERE expr */ - 268, /* (238) expr ::= LP expr RP */ - 268, /* (239) expr ::= ID */ - 268, /* (240) expr ::= ID DOT ID */ - 268, /* (241) expr ::= ID DOT STAR */ - 268, /* (242) expr ::= INTEGER */ - 268, /* (243) expr ::= MINUS INTEGER */ - 268, /* (244) expr ::= PLUS INTEGER */ - 268, /* (245) expr ::= FLOAT */ - 268, /* (246) expr ::= MINUS FLOAT */ - 268, /* (247) expr ::= PLUS FLOAT */ - 268, /* (248) expr ::= STRING */ - 268, /* (249) expr ::= NOW */ - 268, /* (250) expr ::= VARIABLE */ - 268, /* (251) expr ::= PLUS VARIABLE */ - 268, /* (252) expr ::= MINUS VARIABLE */ - 268, /* (253) expr ::= BOOL */ - 268, /* (254) expr ::= NULL */ - 268, /* (255) expr ::= ID LP exprlist RP */ - 268, /* (256) expr ::= ID LP STAR RP */ - 268, /* (257) expr ::= ID LP expr AS typename RP */ - 268, /* (258) expr ::= expr IS NULL */ - 268, /* (259) expr ::= expr IS NOT NULL */ - 268, /* (260) expr ::= expr LT expr */ - 268, /* (261) expr ::= expr GT expr */ - 268, /* (262) expr ::= expr LE expr */ - 268, /* (263) expr ::= expr GE expr */ - 268, /* (264) expr ::= expr NE expr */ - 268, /* (265) expr ::= expr EQ expr */ - 268, /* (266) expr ::= expr BETWEEN expr AND expr */ - 268, /* (267) expr ::= expr AND expr */ - 268, /* (268) expr ::= expr OR expr */ - 268, /* (269) expr ::= expr PLUS expr */ - 268, /* (270) expr ::= expr MINUS expr */ - 268, /* (271) expr ::= expr STAR expr */ - 268, /* (272) expr ::= expr SLASH expr */ - 268, /* (273) expr ::= expr REM expr */ - 268, /* (274) expr ::= expr LIKE expr */ - 268, /* (275) expr ::= expr MATCH expr */ - 268, /* (276) expr ::= expr NMATCH expr */ - 268, /* (277) expr ::= expr IN LP exprlist RP */ - 207, /* (278) exprlist ::= exprlist COMMA expritem */ - 207, /* (279) exprlist ::= expritem */ - 280, /* (280) expritem ::= expr */ - 280, /* (281) expritem ::= */ - 199, /* (282) cmd ::= RESET QUERY CACHE */ - 199, /* (283) cmd ::= SYNCDB ids REPLICA */ - 199, /* (284) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - 199, /* (285) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - 199, /* (286) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ - 199, /* (287) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - 199, /* (288) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - 199, /* (289) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - 199, /* (290) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - 199, /* (291) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ - 199, /* (292) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - 199, /* (293) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - 199, /* (294) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ - 199, /* (295) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - 199, /* (296) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - 199, /* (297) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - 199, /* (298) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ - 199, /* (299) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ - 199, /* (300) cmd ::= KILL CONNECTION INTEGER */ - 199, /* (301) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - 199, /* (302) cmd ::= KILL QUERY INTEGER COLON INTEGER */ + 201, /* (0) program ::= cmd */ + 202, /* (1) cmd ::= SHOW DATABASES */ + 202, /* (2) cmd ::= SHOW TOPICS */ + 202, /* (3) cmd ::= SHOW FUNCTIONS */ + 202, /* (4) cmd ::= SHOW MNODES */ + 202, /* (5) cmd ::= SHOW DNODES */ + 202, /* (6) cmd ::= SHOW ACCOUNTS */ + 202, /* (7) cmd ::= SHOW USERS */ + 202, /* (8) cmd ::= SHOW MODULES */ + 202, /* (9) cmd ::= SHOW QUERIES */ + 202, /* (10) cmd ::= SHOW CONNECTIONS */ + 202, /* (11) cmd ::= SHOW STREAMS */ + 202, /* (12) cmd ::= SHOW VARIABLES */ + 202, /* (13) cmd ::= SHOW SCORES */ + 202, /* (14) cmd ::= SHOW GRANTS */ + 202, /* (15) cmd ::= SHOW VNODES */ + 202, /* (16) cmd ::= SHOW VNODES ids */ + 204, /* (17) dbPrefix ::= */ + 204, /* (18) dbPrefix ::= ids DOT */ + 205, /* (19) cpxName ::= */ + 205, /* (20) cpxName ::= DOT ids */ + 202, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ + 202, /* (22) cmd ::= SHOW CREATE STABLE ids cpxName */ + 202, /* (23) cmd ::= SHOW CREATE DATABASE ids */ + 202, /* (24) cmd ::= SHOW dbPrefix TABLES */ + 202, /* (25) cmd ::= SHOW dbPrefix TABLES LIKE ids */ + 202, /* (26) cmd ::= SHOW dbPrefix STABLES */ + 202, /* (27) cmd ::= SHOW dbPrefix STABLES LIKE ids */ + 202, /* (28) cmd ::= SHOW dbPrefix VGROUPS */ + 202, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ + 202, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ + 202, /* (31) cmd ::= DROP DATABASE ifexists ids */ + 202, /* (32) cmd ::= DROP TOPIC ifexists ids */ + 202, /* (33) cmd ::= DROP FUNCTION ids */ + 202, /* (34) cmd ::= DROP DNODE ids */ + 202, /* (35) cmd ::= DROP USER ids */ + 202, /* (36) cmd ::= DROP ACCOUNT ids */ + 202, /* (37) cmd ::= USE ids */ + 202, /* (38) cmd ::= DESCRIBE ids cpxName */ + 202, /* (39) cmd ::= DESC ids cpxName */ + 202, /* (40) cmd ::= ALTER USER ids PASS ids */ + 202, /* (41) cmd ::= ALTER USER ids PRIVILEGE ids */ + 202, /* (42) cmd ::= ALTER DNODE ids ids */ + 202, /* (43) cmd ::= ALTER DNODE ids ids ids */ + 202, /* (44) cmd ::= ALTER LOCAL ids */ + 202, /* (45) cmd ::= ALTER LOCAL ids ids */ + 202, /* (46) cmd ::= ALTER DATABASE ids alter_db_optr */ + 202, /* (47) cmd ::= ALTER TOPIC ids alter_topic_optr */ + 202, /* (48) cmd ::= ALTER ACCOUNT ids acct_optr */ + 202, /* (49) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ + 202, /* (50) cmd ::= COMPACT VNODES IN LP exprlist RP */ + 203, /* (51) ids ::= ID */ + 203, /* (52) ids ::= STRING */ + 206, /* (53) ifexists ::= IF EXISTS */ + 206, /* (54) ifexists ::= */ + 211, /* (55) ifnotexists ::= IF NOT EXISTS */ + 211, /* (56) ifnotexists ::= */ + 202, /* (57) cmd ::= CREATE DNODE ids */ + 202, /* (58) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ + 202, /* (59) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ + 202, /* (60) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ + 202, /* (61) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ + 202, /* (62) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ + 202, /* (63) cmd ::= CREATE USER ids PASS ids */ + 215, /* (64) bufsize ::= */ + 215, /* (65) bufsize ::= BUFSIZE INTEGER */ + 216, /* (66) pps ::= */ + 216, /* (67) pps ::= PPS INTEGER */ + 217, /* (68) tseries ::= */ + 217, /* (69) tseries ::= TSERIES INTEGER */ + 218, /* (70) dbs ::= */ + 218, /* (71) dbs ::= DBS INTEGER */ + 219, /* (72) streams ::= */ + 219, /* (73) streams ::= STREAMS INTEGER */ + 220, /* (74) storage ::= */ + 220, /* (75) storage ::= STORAGE INTEGER */ + 221, /* (76) qtime ::= */ + 221, /* (77) qtime ::= QTIME INTEGER */ + 222, /* (78) users ::= */ + 222, /* (79) users ::= USERS INTEGER */ + 223, /* (80) conns ::= */ + 223, /* (81) conns ::= CONNS INTEGER */ + 224, /* (82) state ::= */ + 224, /* (83) state ::= STATE ids */ + 209, /* (84) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ + 225, /* (85) intitemlist ::= intitemlist COMMA intitem */ + 225, /* (86) intitemlist ::= intitem */ + 226, /* (87) intitem ::= INTEGER */ + 227, /* (88) keep ::= KEEP intitemlist */ + 228, /* (89) cache ::= CACHE INTEGER */ + 229, /* (90) replica ::= REPLICA INTEGER */ + 230, /* (91) quorum ::= QUORUM INTEGER */ + 231, /* (92) days ::= DAYS INTEGER */ + 232, /* (93) minrows ::= MINROWS INTEGER */ + 233, /* (94) maxrows ::= MAXROWS INTEGER */ + 234, /* (95) blocks ::= BLOCKS INTEGER */ + 235, /* (96) ctime ::= CTIME INTEGER */ + 236, /* (97) wal ::= WAL INTEGER */ + 237, /* (98) fsync ::= FSYNC INTEGER */ + 238, /* (99) comp ::= COMP INTEGER */ + 239, /* (100) prec ::= PRECISION STRING */ + 240, /* (101) update ::= UPDATE INTEGER */ + 241, /* (102) cachelast ::= CACHELAST INTEGER */ + 242, /* (103) partitions ::= PARTITIONS INTEGER */ + 212, /* (104) db_optr ::= */ + 212, /* (105) db_optr ::= db_optr cache */ + 212, /* (106) db_optr ::= db_optr replica */ + 212, /* (107) db_optr ::= db_optr quorum */ + 212, /* (108) db_optr ::= db_optr days */ + 212, /* (109) db_optr ::= db_optr minrows */ + 212, /* (110) db_optr ::= db_optr maxrows */ + 212, /* (111) db_optr ::= db_optr blocks */ + 212, /* (112) db_optr ::= db_optr ctime */ + 212, /* (113) db_optr ::= db_optr wal */ + 212, /* (114) db_optr ::= db_optr fsync */ + 212, /* (115) db_optr ::= db_optr comp */ + 212, /* (116) db_optr ::= db_optr prec */ + 212, /* (117) db_optr ::= db_optr keep */ + 212, /* (118) db_optr ::= db_optr update */ + 212, /* (119) db_optr ::= db_optr cachelast */ + 213, /* (120) topic_optr ::= db_optr */ + 213, /* (121) topic_optr ::= topic_optr partitions */ + 207, /* (122) alter_db_optr ::= */ + 207, /* (123) alter_db_optr ::= alter_db_optr replica */ + 207, /* (124) alter_db_optr ::= alter_db_optr quorum */ + 207, /* (125) alter_db_optr ::= alter_db_optr keep */ + 207, /* (126) alter_db_optr ::= alter_db_optr blocks */ + 207, /* (127) alter_db_optr ::= alter_db_optr comp */ + 207, /* (128) alter_db_optr ::= alter_db_optr update */ + 207, /* (129) alter_db_optr ::= alter_db_optr cachelast */ + 208, /* (130) alter_topic_optr ::= alter_db_optr */ + 208, /* (131) alter_topic_optr ::= alter_topic_optr partitions */ + 214, /* (132) typename ::= ids */ + 214, /* (133) typename ::= ids LP signed RP */ + 214, /* (134) typename ::= ids UNSIGNED */ + 243, /* (135) signed ::= INTEGER */ + 243, /* (136) signed ::= PLUS INTEGER */ + 243, /* (137) signed ::= MINUS INTEGER */ + 202, /* (138) cmd ::= CREATE TABLE create_table_args */ + 202, /* (139) cmd ::= CREATE TABLE create_stable_args */ + 202, /* (140) cmd ::= CREATE STABLE create_stable_args */ + 202, /* (141) cmd ::= CREATE TABLE create_table_list */ + 246, /* (142) create_table_list ::= create_from_stable */ + 246, /* (143) create_table_list ::= create_table_list create_from_stable */ + 244, /* (144) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ + 245, /* (145) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ + 247, /* (146) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ + 247, /* (147) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ + 250, /* (148) tagNamelist ::= tagNamelist COMMA ids */ + 250, /* (149) tagNamelist ::= ids */ + 244, /* (150) create_table_args ::= ifnotexists ids cpxName AS select */ + 248, /* (151) columnlist ::= columnlist COMMA column */ + 248, /* (152) columnlist ::= column */ + 252, /* (153) column ::= ids typename */ + 249, /* (154) tagitemlist ::= tagitemlist COMMA tagitem */ + 249, /* (155) tagitemlist ::= tagitem */ + 253, /* (156) tagitem ::= INTEGER */ + 253, /* (157) tagitem ::= FLOAT */ + 253, /* (158) tagitem ::= STRING */ + 253, /* (159) tagitem ::= BOOL */ + 253, /* (160) tagitem ::= NULL */ + 253, /* (161) tagitem ::= NOW */ + 253, /* (162) tagitem ::= MINUS INTEGER */ + 253, /* (163) tagitem ::= MINUS FLOAT */ + 253, /* (164) tagitem ::= PLUS INTEGER */ + 253, /* (165) tagitem ::= PLUS FLOAT */ + 251, /* (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 */ + 251, /* (167) select ::= LP select RP */ + 268, /* (168) union ::= select */ + 268, /* (169) union ::= union UNION ALL select */ + 202, /* (170) cmd ::= union */ + 251, /* (171) select ::= SELECT selcollist */ + 269, /* (172) sclp ::= selcollist COMMA */ + 269, /* (173) sclp ::= */ + 254, /* (174) selcollist ::= sclp distinct expr as */ + 254, /* (175) selcollist ::= sclp STAR */ + 272, /* (176) as ::= AS ids */ + 272, /* (177) as ::= ids */ + 272, /* (178) as ::= */ + 270, /* (179) distinct ::= DISTINCT */ + 270, /* (180) distinct ::= */ + 255, /* (181) from ::= FROM tablelist */ + 255, /* (182) from ::= FROM sub */ + 274, /* (183) sub ::= LP union RP */ + 274, /* (184) sub ::= LP union RP ids */ + 274, /* (185) sub ::= sub COMMA LP union RP ids */ + 273, /* (186) tablelist ::= ids cpxName */ + 273, /* (187) tablelist ::= ids cpxName ids */ + 273, /* (188) tablelist ::= tablelist COMMA ids cpxName */ + 273, /* (189) tablelist ::= tablelist COMMA ids cpxName ids */ + 275, /* (190) tmvar ::= VARIABLE */ + 276, /* (191) timestamp ::= INTEGER */ + 276, /* (192) timestamp ::= MINUS INTEGER */ + 276, /* (193) timestamp ::= PLUS INTEGER */ + 276, /* (194) timestamp ::= STRING */ + 276, /* (195) timestamp ::= NOW */ + 276, /* (196) timestamp ::= NOW PLUS VARIABLE */ + 276, /* (197) timestamp ::= NOW MINUS VARIABLE */ + 257, /* (198) range_option ::= */ + 257, /* (199) range_option ::= RANGE LP timestamp COMMA timestamp RP */ + 258, /* (200) interval_option ::= intervalKey LP tmvar RP */ + 258, /* (201) interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ + 258, /* (202) interval_option ::= */ + 277, /* (203) intervalKey ::= INTERVAL */ + 277, /* (204) intervalKey ::= EVERY */ + 260, /* (205) session_option ::= */ + 260, /* (206) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + 261, /* (207) windowstate_option ::= */ + 261, /* (208) windowstate_option ::= STATE_WINDOW LP ids RP */ + 262, /* (209) fill_opt ::= */ + 262, /* (210) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + 262, /* (211) fill_opt ::= FILL LP ID RP */ + 259, /* (212) sliding_opt ::= SLIDING LP tmvar RP */ + 259, /* (213) sliding_opt ::= */ + 265, /* (214) orderby_opt ::= */ + 265, /* (215) orderby_opt ::= ORDER BY sortlist */ + 278, /* (216) sortlist ::= sortlist COMMA item sortorder */ + 278, /* (217) sortlist ::= sortlist COMMA arrow sortorder */ + 278, /* (218) sortlist ::= item sortorder */ + 278, /* (219) sortlist ::= arrow sortorder */ + 279, /* (220) item ::= ID */ + 279, /* (221) item ::= ID DOT ID */ + 280, /* (222) sortorder ::= ASC */ + 280, /* (223) sortorder ::= DESC */ + 280, /* (224) sortorder ::= */ + 263, /* (225) groupby_opt ::= */ + 263, /* (226) groupby_opt ::= GROUP BY grouplist */ + 282, /* (227) grouplist ::= grouplist COMMA item */ + 282, /* (228) grouplist ::= grouplist COMMA arrow */ + 282, /* (229) grouplist ::= item */ + 282, /* (230) grouplist ::= arrow */ + 264, /* (231) having_opt ::= */ + 264, /* (232) having_opt ::= HAVING expr */ + 267, /* (233) limit_opt ::= */ + 267, /* (234) limit_opt ::= LIMIT signed */ + 267, /* (235) limit_opt ::= LIMIT signed OFFSET signed */ + 267, /* (236) limit_opt ::= LIMIT signed COMMA signed */ + 266, /* (237) slimit_opt ::= */ + 266, /* (238) slimit_opt ::= SLIMIT signed */ + 266, /* (239) slimit_opt ::= SLIMIT signed SOFFSET signed */ + 266, /* (240) slimit_opt ::= SLIMIT signed COMMA signed */ + 256, /* (241) where_opt ::= */ + 256, /* (242) where_opt ::= WHERE expr */ + 271, /* (243) expr ::= LP expr RP */ + 271, /* (244) expr ::= ID */ + 271, /* (245) expr ::= ID DOT ID */ + 271, /* (246) expr ::= ID DOT STAR */ + 271, /* (247) expr ::= INTEGER */ + 271, /* (248) expr ::= MINUS INTEGER */ + 271, /* (249) expr ::= PLUS INTEGER */ + 271, /* (250) expr ::= FLOAT */ + 271, /* (251) expr ::= MINUS FLOAT */ + 271, /* (252) expr ::= PLUS FLOAT */ + 271, /* (253) expr ::= STRING */ + 271, /* (254) expr ::= NOW */ + 271, /* (255) expr ::= VARIABLE */ + 271, /* (256) expr ::= PLUS VARIABLE */ + 271, /* (257) expr ::= MINUS VARIABLE */ + 271, /* (258) expr ::= BOOL */ + 271, /* (259) expr ::= NULL */ + 271, /* (260) expr ::= ID LP exprlist RP */ + 271, /* (261) expr ::= ID LP STAR RP */ + 271, /* (262) expr ::= ID LP expr AS typename RP */ + 271, /* (263) expr ::= expr IS NULL */ + 271, /* (264) expr ::= expr IS NOT NULL */ + 271, /* (265) expr ::= expr LT expr */ + 271, /* (266) expr ::= expr GT expr */ + 271, /* (267) expr ::= expr LE expr */ + 271, /* (268) expr ::= expr GE expr */ + 271, /* (269) expr ::= expr NE expr */ + 271, /* (270) expr ::= expr EQ expr */ + 271, /* (271) expr ::= expr BETWEEN expr AND expr */ + 271, /* (272) expr ::= expr AND expr */ + 271, /* (273) expr ::= expr OR expr */ + 271, /* (274) expr ::= expr PLUS expr */ + 271, /* (275) expr ::= expr MINUS expr */ + 271, /* (276) expr ::= expr STAR expr */ + 271, /* (277) expr ::= expr SLASH expr */ + 271, /* (278) expr ::= expr REM expr */ + 271, /* (279) expr ::= expr LIKE expr */ + 271, /* (280) expr ::= expr MATCH expr */ + 271, /* (281) expr ::= expr NMATCH expr */ + 271, /* (282) expr ::= ID CONTAINS STRING */ + 271, /* (283) expr ::= ID DOT ID CONTAINS STRING */ + 281, /* (284) arrow ::= ID ARROW STRING */ + 281, /* (285) arrow ::= ID DOT ID ARROW STRING */ + 271, /* (286) expr ::= arrow */ + 271, /* (287) expr ::= expr IN LP exprlist RP */ + 210, /* (288) exprlist ::= exprlist COMMA expritem */ + 210, /* (289) exprlist ::= expritem */ + 283, /* (290) expritem ::= expr */ + 283, /* (291) expritem ::= */ + 202, /* (292) cmd ::= RESET QUERY CACHE */ + 202, /* (293) cmd ::= SYNCDB ids REPLICA */ + 202, /* (294) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + 202, /* (295) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + 202, /* (296) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ + 202, /* (297) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + 202, /* (298) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + 202, /* (299) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + 202, /* (300) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + 202, /* (301) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ + 202, /* (302) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + 202, /* (303) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + 202, /* (304) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ + 202, /* (305) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + 202, /* (306) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + 202, /* (307) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + 202, /* (308) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ + 202, /* (309) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ + 202, /* (310) cmd ::= KILL CONNECTION INTEGER */ + 202, /* (311) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + 202, /* (312) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -2404,92 +2635,102 @@ 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 */ - -6, /* (257) expr ::= ID LP expr AS typename RP */ - -3, /* (258) expr ::= expr IS NULL */ - -4, /* (259) expr ::= expr IS NOT NULL */ - -3, /* (260) expr ::= expr LT expr */ - -3, /* (261) expr ::= expr GT expr */ - -3, /* (262) expr ::= expr LE expr */ - -3, /* (263) expr ::= expr GE expr */ - -3, /* (264) expr ::= expr NE expr */ - -3, /* (265) expr ::= expr EQ expr */ - -5, /* (266) expr ::= expr BETWEEN expr AND expr */ - -3, /* (267) expr ::= expr AND expr */ - -3, /* (268) expr ::= expr OR expr */ - -3, /* (269) expr ::= expr PLUS expr */ - -3, /* (270) expr ::= expr MINUS expr */ - -3, /* (271) expr ::= expr STAR expr */ - -3, /* (272) expr ::= expr SLASH expr */ - -3, /* (273) expr ::= expr REM expr */ - -3, /* (274) expr ::= expr LIKE expr */ - -3, /* (275) expr ::= expr MATCH expr */ - -3, /* (276) expr ::= expr NMATCH expr */ - -5, /* (277) expr ::= expr IN LP exprlist RP */ - -3, /* (278) exprlist ::= exprlist COMMA expritem */ - -1, /* (279) exprlist ::= expritem */ - -1, /* (280) expritem ::= expr */ - 0, /* (281) expritem ::= */ - -3, /* (282) cmd ::= RESET QUERY CACHE */ - -3, /* (283) cmd ::= SYNCDB ids REPLICA */ - -7, /* (284) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (285) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - -7, /* (286) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ - -7, /* (287) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - -7, /* (288) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - -8, /* (289) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - -9, /* (290) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - -7, /* (291) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ - -7, /* (292) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (293) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - -7, /* (294) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ - -7, /* (295) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - -7, /* (296) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - -8, /* (297) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - -9, /* (298) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ - -7, /* (299) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ - -3, /* (300) cmd ::= KILL CONNECTION INTEGER */ - -5, /* (301) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - -5, /* (302) 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 */ + -6, /* (262) expr ::= ID LP expr AS typename RP */ + -3, /* (263) expr ::= expr IS NULL */ + -4, /* (264) expr ::= expr IS NOT NULL */ + -3, /* (265) expr ::= expr LT expr */ + -3, /* (266) expr ::= expr GT expr */ + -3, /* (267) expr ::= expr LE expr */ + -3, /* (268) expr ::= expr GE expr */ + -3, /* (269) expr ::= expr NE expr */ + -3, /* (270) expr ::= expr EQ expr */ + -5, /* (271) expr ::= expr BETWEEN expr AND expr */ + -3, /* (272) expr ::= expr AND expr */ + -3, /* (273) expr ::= expr OR expr */ + -3, /* (274) expr ::= expr PLUS expr */ + -3, /* (275) expr ::= expr MINUS expr */ + -3, /* (276) expr ::= expr STAR expr */ + -3, /* (277) expr ::= expr SLASH expr */ + -3, /* (278) expr ::= expr REM expr */ + -3, /* (279) expr ::= expr LIKE expr */ + -3, /* (280) expr ::= expr MATCH expr */ + -3, /* (281) expr ::= expr NMATCH expr */ + -3, /* (282) expr ::= ID CONTAINS STRING */ + -5, /* (283) expr ::= ID DOT ID CONTAINS STRING */ + -3, /* (284) arrow ::= ID ARROW STRING */ + -5, /* (285) arrow ::= ID DOT ID ARROW STRING */ + -1, /* (286) expr ::= arrow */ + -5, /* (287) expr ::= expr IN LP exprlist RP */ + -3, /* (288) exprlist ::= exprlist COMMA expritem */ + -1, /* (289) exprlist ::= expritem */ + -1, /* (290) expritem ::= expr */ + 0, /* (291) expritem ::= */ + -3, /* (292) cmd ::= RESET QUERY CACHE */ + -3, /* (293) cmd ::= SYNCDB ids REPLICA */ + -7, /* (294) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + -7, /* (295) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + -7, /* (296) cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ + -7, /* (297) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + -7, /* (298) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + -8, /* (299) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + -9, /* (300) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + -7, /* (301) cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ + -7, /* (302) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + -7, /* (303) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + -7, /* (304) cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ + -7, /* (305) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + -7, /* (306) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + -8, /* (307) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + -9, /* (308) cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ + -7, /* (309) cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ + -3, /* (310) cmd ::= KILL CONNECTION INTEGER */ + -5, /* (311) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + -5, /* (312) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -2519,54 +2760,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 @@ -2752,16 +2945,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.yy262, &t);} +{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy470, &t);} break; case 48: /* cmd ::= ALTER ACCOUNT ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy47);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy51);} 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.yy47);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy51);} break; case 50: /* cmd ::= COMPACT VNODES IN LP exprlist RP */ -{ setCompactVnodeSql(pInfo, TSDB_SQL_COMPACT_VNODE, yymsp[-1].minor.yy247);} +{ setCompactVnodeSql(pInfo, TSDB_SQL_COMPACT_VNODE, yymsp[-1].minor.yy189);} break; case 51: /* ids ::= ID */ case 52: /* ids ::= STRING */ yytestcase(yyruleno==52); @@ -2783,17 +2976,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.yy47);} +{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy51);} 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.yy262, &yymsp[-2].minor.yy0);} +{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy470, &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.yy179, &yymsp[0].minor.yy0, 1);} +{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy279, &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.yy179, &yymsp[0].minor.yy0, 2);} +{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy279, &yymsp[0].minor.yy0, 2);} break; case 63: /* cmd ::= CREATE USER ids PASS ids */ { setCreateUserSql(pInfo, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);} @@ -2824,38 +3017,38 @@ static YYACTIONTYPE yy_reduce( break; case 84: /* acct_optr ::= pps tseries storage streams qtime dbs users conns state */ { - yylhsminor.yy47.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; - yylhsminor.yy47.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; - yylhsminor.yy47.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; - yylhsminor.yy47.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; - yylhsminor.yy47.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; - yylhsminor.yy47.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy47.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy47.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; - yylhsminor.yy47.stat = yymsp[0].minor.yy0; + yylhsminor.yy51.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; + yylhsminor.yy51.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; + yylhsminor.yy51.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; + yylhsminor.yy51.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; + yylhsminor.yy51.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; + yylhsminor.yy51.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy51.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy51.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; + yylhsminor.yy51.stat = yymsp[0].minor.yy0; } - yymsp[-8].minor.yy47 = yylhsminor.yy47; + yymsp[-8].minor.yy51 = yylhsminor.yy51; break; case 85: /* intitemlist ::= intitemlist COMMA intitem */ case 154: /* tagitemlist ::= tagitemlist COMMA tagitem */ yytestcase(yyruleno==154); -{ yylhsminor.yy247 = tVariantListAppend(yymsp[-2].minor.yy247, &yymsp[0].minor.yy378, -1); } - yymsp[-2].minor.yy247 = yylhsminor.yy247; +{ yylhsminor.yy189 = tVariantListAppend(yymsp[-2].minor.yy189, &yymsp[0].minor.yy162, -1); } + yymsp[-2].minor.yy189 = yylhsminor.yy189; break; case 86: /* intitemlist ::= intitem */ case 155: /* tagitemlist ::= tagitem */ yytestcase(yyruleno==155); -{ yylhsminor.yy247 = tVariantListAppend(NULL, &yymsp[0].minor.yy378, -1); } - yymsp[0].minor.yy247 = yylhsminor.yy247; +{ yylhsminor.yy189 = tVariantListAppend(NULL, &yymsp[0].minor.yy162, -1); } + yymsp[0].minor.yy189 = yylhsminor.yy189; 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.yy378, &yymsp[0].minor.yy0, true); } - yymsp[0].minor.yy378 = yylhsminor.yy378; +{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy162, &yymsp[0].minor.yy0, true); } + yymsp[0].minor.yy162 = yylhsminor.yy162; break; case 88: /* keep ::= KEEP intitemlist */ -{ yymsp[-1].minor.yy247 = yymsp[0].minor.yy247; } +{ yymsp[-1].minor.yy189 = yymsp[0].minor.yy189; } break; case 89: /* cache ::= CACHE INTEGER */ case 90: /* replica ::= REPLICA INTEGER */ yytestcase(yyruleno==90); @@ -2875,221 +3068,221 @@ static YYACTIONTYPE yy_reduce( { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } break; case 104: /* db_optr ::= */ -{setDefaultCreateDbOption(&yymsp[1].minor.yy262); yymsp[1].minor.yy262.dbType = TSDB_DB_TYPE_DEFAULT;} +{setDefaultCreateDbOption(&yymsp[1].minor.yy470); yymsp[1].minor.yy470.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 105: /* db_optr ::= db_optr cache */ -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 106: /* db_optr ::= db_optr replica */ case 123: /* alter_db_optr ::= alter_db_optr replica */ yytestcase(yyruleno==123); -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 107: /* db_optr ::= db_optr quorum */ case 124: /* alter_db_optr ::= alter_db_optr quorum */ yytestcase(yyruleno==124); -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 108: /* db_optr ::= db_optr days */ -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 109: /* db_optr ::= db_optr minrows */ -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 110: /* db_optr ::= db_optr maxrows */ -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 111: /* db_optr ::= db_optr blocks */ case 126: /* alter_db_optr ::= alter_db_optr blocks */ yytestcase(yyruleno==126); -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 112: /* db_optr ::= db_optr ctime */ -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 113: /* db_optr ::= db_optr wal */ -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 114: /* db_optr ::= db_optr fsync */ -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 115: /* db_optr ::= db_optr comp */ case 127: /* alter_db_optr ::= alter_db_optr comp */ yytestcase(yyruleno==127); -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 116: /* db_optr ::= db_optr prec */ -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.precision = yymsp[0].minor.yy0; } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.precision = yymsp[0].minor.yy0; } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 117: /* db_optr ::= db_optr keep */ case 125: /* alter_db_optr ::= alter_db_optr keep */ yytestcase(yyruleno==125); -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.keep = yymsp[0].minor.yy247; } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.keep = yymsp[0].minor.yy189; } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 118: /* db_optr ::= db_optr update */ case 128: /* alter_db_optr ::= alter_db_optr update */ yytestcase(yyruleno==128); -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 119: /* db_optr ::= db_optr cachelast */ case 129: /* alter_db_optr ::= alter_db_optr cachelast */ yytestcase(yyruleno==129); -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 120: /* topic_optr ::= db_optr */ case 130: /* alter_topic_optr ::= alter_db_optr */ yytestcase(yyruleno==130); -{ yylhsminor.yy262 = yymsp[0].minor.yy262; yylhsminor.yy262.dbType = TSDB_DB_TYPE_TOPIC; } - yymsp[0].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[0].minor.yy470; yylhsminor.yy470.dbType = TSDB_DB_TYPE_TOPIC; } + yymsp[0].minor.yy470 = yylhsminor.yy470; break; case 121: /* topic_optr ::= topic_optr partitions */ case 131: /* alter_topic_optr ::= alter_topic_optr partitions */ yytestcase(yyruleno==131); -{ yylhsminor.yy262 = yymsp[-1].minor.yy262; yylhsminor.yy262.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy262 = yylhsminor.yy262; +{ yylhsminor.yy470 = yymsp[-1].minor.yy470; yylhsminor.yy470.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy470 = yylhsminor.yy470; break; case 122: /* alter_db_optr ::= */ -{ setDefaultCreateDbOption(&yymsp[1].minor.yy262); yymsp[1].minor.yy262.dbType = TSDB_DB_TYPE_DEFAULT;} +{ setDefaultCreateDbOption(&yymsp[1].minor.yy470); yymsp[1].minor.yy470.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 132: /* typename ::= ids */ { yymsp[0].minor.yy0.type = 0; - tSetColumnType (&yylhsminor.yy179, &yymsp[0].minor.yy0); + tSetColumnType (&yylhsminor.yy279, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy179 = yylhsminor.yy179; + yymsp[0].minor.yy279 = yylhsminor.yy279; break; case 133: /* typename ::= ids LP signed RP */ { - if (yymsp[-1].minor.yy403 <= 0) { + if (yymsp[-1].minor.yy69 <= 0) { yymsp[-3].minor.yy0.type = 0; - tSetColumnType(&yylhsminor.yy179, &yymsp[-3].minor.yy0); + tSetColumnType(&yylhsminor.yy279, &yymsp[-3].minor.yy0); } else { - yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy403; // negative value of name length - tSetColumnType(&yylhsminor.yy179, &yymsp[-3].minor.yy0); + yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy69; // negative value of name length + tSetColumnType(&yylhsminor.yy279, &yymsp[-3].minor.yy0); } } - yymsp[-3].minor.yy179 = yylhsminor.yy179; + yymsp[-3].minor.yy279 = yylhsminor.yy279; 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.yy179, &yymsp[-1].minor.yy0); + tSetColumnType (&yylhsminor.yy279, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy179 = yylhsminor.yy179; + yymsp[-1].minor.yy279 = yylhsminor.yy279; break; case 135: /* signed ::= INTEGER */ -{ yylhsminor.yy403 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[0].minor.yy403 = yylhsminor.yy403; +{ yylhsminor.yy69 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[0].minor.yy69 = yylhsminor.yy69; break; case 136: /* signed ::= PLUS INTEGER */ -{ yymsp[-1].minor.yy403 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy69 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 137: /* signed ::= MINUS INTEGER */ -{ yymsp[-1].minor.yy403 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} +{ yymsp[-1].minor.yy69 = -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.yy336;} +{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy6;} 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.yy42); + taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy208); pCreateTable->type = TSQL_CREATE_TABLE_FROM_STABLE; - yylhsminor.yy336 = pCreateTable; + yylhsminor.yy6 = pCreateTable; } - yymsp[0].minor.yy336 = yylhsminor.yy336; + yymsp[0].minor.yy6 = yylhsminor.yy6; break; case 143: /* create_table_list ::= create_table_list create_from_stable */ { - taosArrayPush(yymsp[-1].minor.yy336->childTableInfo, &yymsp[0].minor.yy42); - yylhsminor.yy336 = yymsp[-1].minor.yy336; + taosArrayPush(yymsp[-1].minor.yy6->childTableInfo, &yymsp[0].minor.yy208); + yylhsminor.yy6 = yymsp[-1].minor.yy6; } - yymsp[-1].minor.yy336 = yylhsminor.yy336; + yymsp[-1].minor.yy6 = yylhsminor.yy6; break; case 144: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ { - yylhsminor.yy336 = tSetCreateTableInfo(yymsp[-1].minor.yy247, NULL, NULL, TSQL_CREATE_TABLE); - setSqlInfo(pInfo, yylhsminor.yy336, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy6 = tSetCreateTableInfo(yymsp[-1].minor.yy189, NULL, NULL, TSQL_CREATE_TABLE); + setSqlInfo(pInfo, yylhsminor.yy6, 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.yy336 = yylhsminor.yy336; + yymsp[-5].minor.yy6 = yylhsminor.yy6; break; case 145: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ { - yylhsminor.yy336 = tSetCreateTableInfo(yymsp[-5].minor.yy247, yymsp[-1].minor.yy247, NULL, TSQL_CREATE_STABLE); - setSqlInfo(pInfo, yylhsminor.yy336, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy6 = tSetCreateTableInfo(yymsp[-5].minor.yy189, yymsp[-1].minor.yy189, NULL, TSQL_CREATE_STABLE); + setSqlInfo(pInfo, yylhsminor.yy6, 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.yy336 = yylhsminor.yy336; + yymsp[-9].minor.yy6 = yylhsminor.yy6; 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.yy42 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy247, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); + yylhsminor.yy208 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy189, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy42 = yylhsminor.yy42; + yymsp[-9].minor.yy208 = yylhsminor.yy208; 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.yy42 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy247, yymsp[-1].minor.yy247, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); + yylhsminor.yy208 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy189, yymsp[-1].minor.yy189, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); } - yymsp[-12].minor.yy42 = yylhsminor.yy42; + yymsp[-12].minor.yy208 = yylhsminor.yy208; break; case 148: /* tagNamelist ::= tagNamelist COMMA ids */ -{taosArrayPush(yymsp[-2].minor.yy247, &yymsp[0].minor.yy0); yylhsminor.yy247 = yymsp[-2].minor.yy247; } - yymsp[-2].minor.yy247 = yylhsminor.yy247; +{taosArrayPush(yymsp[-2].minor.yy189, &yymsp[0].minor.yy0); yylhsminor.yy189 = yymsp[-2].minor.yy189; } + yymsp[-2].minor.yy189 = yylhsminor.yy189; break; case 149: /* tagNamelist ::= ids */ -{yylhsminor.yy247 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy247, &yymsp[0].minor.yy0);} - yymsp[0].minor.yy247 = yylhsminor.yy247; +{yylhsminor.yy189 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy189, &yymsp[0].minor.yy0);} + yymsp[0].minor.yy189 = yylhsminor.yy189; break; case 150: /* create_table_args ::= ifnotexists ids cpxName AS select */ { - yylhsminor.yy336 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy246, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy336, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy6 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy16, TSQL_CREATE_STREAM); + setSqlInfo(pInfo, yylhsminor.yy6, 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.yy336 = yylhsminor.yy336; + yymsp[-4].minor.yy6 = yylhsminor.yy6; break; case 151: /* columnlist ::= columnlist COMMA column */ -{taosArrayPush(yymsp[-2].minor.yy247, &yymsp[0].minor.yy179); yylhsminor.yy247 = yymsp[-2].minor.yy247; } - yymsp[-2].minor.yy247 = yylhsminor.yy247; +{taosArrayPush(yymsp[-2].minor.yy189, &yymsp[0].minor.yy279); yylhsminor.yy189 = yymsp[-2].minor.yy189; } + yymsp[-2].minor.yy189 = yylhsminor.yy189; break; case 152: /* columnlist ::= column */ -{yylhsminor.yy247 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy247, &yymsp[0].minor.yy179);} - yymsp[0].minor.yy247 = yylhsminor.yy247; +{yylhsminor.yy189 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy189, &yymsp[0].minor.yy279);} + yymsp[0].minor.yy189 = yylhsminor.yy189; break; case 153: /* column ::= ids typename */ { - tSetColumnInfo(&yylhsminor.yy179, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy179); + tSetColumnInfo(&yylhsminor.yy279, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy279); } - yymsp[-1].minor.yy179 = yylhsminor.yy179; + yymsp[-1].minor.yy279 = yylhsminor.yy279; break; case 160: /* tagitem ::= NULL */ -{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy378, &yymsp[0].minor.yy0, true); } - yymsp[0].minor.yy378 = yylhsminor.yy378; +{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy162, &yymsp[0].minor.yy0, true); } + yymsp[0].minor.yy162 = yylhsminor.yy162; break; case 161: /* tagitem ::= NOW */ -{ yymsp[0].minor.yy0.type = TSDB_DATA_TYPE_TIMESTAMP; tVariantCreate(&yylhsminor.yy378, &yymsp[0].minor.yy0, true);} - yymsp[0].minor.yy378 = yylhsminor.yy378; +{ yymsp[0].minor.yy0.type = TSDB_DATA_TYPE_TIMESTAMP; tVariantCreate(&yylhsminor.yy162, &yymsp[0].minor.yy0, true);} + yymsp[0].minor.yy162 = yylhsminor.yy162; break; case 162: /* tagitem ::= MINUS INTEGER */ case 163: /* tagitem ::= MINUS FLOAT */ yytestcase(yyruleno==163); @@ -3099,56 +3292,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.yy378, &yymsp[-1].minor.yy0, true); + tVariantCreate(&yylhsminor.yy162, &yymsp[-1].minor.yy0, true); } - yymsp[-1].minor.yy378 = yylhsminor.yy378; + yymsp[-1].minor.yy162 = yylhsminor.yy162; 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.yy246 = tSetQuerySqlNode(&yymsp[-14].minor.yy0, yymsp[-13].minor.yy247, yymsp[-12].minor.yy46, yymsp[-11].minor.yy44, yymsp[-4].minor.yy247, yymsp[-2].minor.yy247, &yymsp[-9].minor.yy430, &yymsp[-7].minor.yy507, &yymsp[-6].minor.yy492, &yymsp[-8].minor.yy0, yymsp[-5].minor.yy247, &yymsp[0].minor.yy204, &yymsp[-1].minor.yy204, yymsp[-3].minor.yy44, &yymsp[-10].minor.yy379); + yylhsminor.yy16 = tSetQuerySqlNode(&yymsp[-14].minor.yy0, yymsp[-13].minor.yy189, yymsp[-12].minor.yy36, yymsp[-11].minor.yy18, yymsp[-4].minor.yy189, yymsp[-2].minor.yy189, &yymsp[-9].minor.yy32, &yymsp[-7].minor.yy155, &yymsp[-6].minor.yy336, &yymsp[-8].minor.yy0, yymsp[-5].minor.yy189, &yymsp[0].minor.yy38, &yymsp[-1].minor.yy38, yymsp[-3].minor.yy18, &yymsp[-10].minor.yy124); } - yymsp[-14].minor.yy246 = yylhsminor.yy246; + yymsp[-14].minor.yy16 = yylhsminor.yy16; break; case 167: /* select ::= LP select RP */ -{yymsp[-2].minor.yy246 = yymsp[-1].minor.yy246;} +{yymsp[-2].minor.yy16 = yymsp[-1].minor.yy16;} break; case 168: /* union ::= select */ -{ yylhsminor.yy247 = setSubclause(NULL, yymsp[0].minor.yy246); } - yymsp[0].minor.yy247 = yylhsminor.yy247; +{ yylhsminor.yy189 = setSubclause(NULL, yymsp[0].minor.yy16); } + yymsp[0].minor.yy189 = yylhsminor.yy189; break; case 169: /* union ::= union UNION ALL select */ -{ yylhsminor.yy247 = appendSelectClause(yymsp[-3].minor.yy247, yymsp[0].minor.yy246); } - yymsp[-3].minor.yy247 = yylhsminor.yy247; +{ yylhsminor.yy189 = appendSelectClause(yymsp[-3].minor.yy189, yymsp[0].minor.yy16); } + yymsp[-3].minor.yy189 = yylhsminor.yy189; break; case 170: /* cmd ::= union */ -{ setSqlInfo(pInfo, yymsp[0].minor.yy247, NULL, TSDB_SQL_SELECT); } +{ setSqlInfo(pInfo, yymsp[0].minor.yy189, NULL, TSDB_SQL_SELECT); } break; case 171: /* select ::= SELECT selcollist */ { - yylhsminor.yy246 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy247, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + yylhsminor.yy16 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy189, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } - yymsp[-1].minor.yy246 = yylhsminor.yy246; + yymsp[-1].minor.yy16 = yylhsminor.yy16; break; case 172: /* sclp ::= selcollist COMMA */ -{yylhsminor.yy247 = yymsp[-1].minor.yy247;} - yymsp[-1].minor.yy247 = yylhsminor.yy247; +{yylhsminor.yy189 = yymsp[-1].minor.yy189;} + yymsp[-1].minor.yy189 = yylhsminor.yy189; break; case 173: /* sclp ::= */ case 214: /* orderby_opt ::= */ yytestcase(yyruleno==214); -{yymsp[1].minor.yy247 = 0;} +{yymsp[1].minor.yy189 = 0;} break; case 174: /* selcollist ::= sclp distinct expr as */ { - yylhsminor.yy247 = tSqlExprListAppend(yymsp[-3].minor.yy247, yymsp[-1].minor.yy44, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); + yylhsminor.yy189 = tSqlExprListAppend(yymsp[-3].minor.yy189, yymsp[-1].minor.yy18, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); } - yymsp[-3].minor.yy247 = yylhsminor.yy247; + yymsp[-3].minor.yy189 = yylhsminor.yy189; break; case 175: /* selcollist ::= sclp STAR */ { tSqlExpr *pNode = tSqlExprCreateIdValue(pInfo, NULL, TK_ALL); - yylhsminor.yy247 = tSqlExprListAppend(yymsp[-1].minor.yy247, pNode, 0, 0); + yylhsminor.yy189 = tSqlExprListAppend(yymsp[-1].minor.yy189, pNode, 0, 0); } - yymsp[-1].minor.yy247 = yylhsminor.yy247; + yymsp[-1].minor.yy189 = yylhsminor.yy189; break; case 176: /* as ::= AS ids */ { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } @@ -3166,114 +3359,114 @@ static YYACTIONTYPE yy_reduce( break; case 181: /* from ::= FROM tablelist */ case 182: /* from ::= FROM sub */ yytestcase(yyruleno==182); -{yymsp[-1].minor.yy46 = yymsp[0].minor.yy46;} +{yymsp[-1].minor.yy36 = yymsp[0].minor.yy36;} break; case 183: /* sub ::= LP union RP */ -{yymsp[-2].minor.yy46 = addSubqueryElem(NULL, yymsp[-1].minor.yy247, NULL);} +{yymsp[-2].minor.yy36 = addSubqueryElem(NULL, yymsp[-1].minor.yy189, NULL);} break; case 184: /* sub ::= LP union RP ids */ -{yymsp[-3].minor.yy46 = addSubqueryElem(NULL, yymsp[-2].minor.yy247, &yymsp[0].minor.yy0);} +{yymsp[-3].minor.yy36 = addSubqueryElem(NULL, yymsp[-2].minor.yy189, &yymsp[0].minor.yy0);} break; case 185: /* sub ::= sub COMMA LP union RP ids */ -{yylhsminor.yy46 = addSubqueryElem(yymsp[-5].minor.yy46, yymsp[-2].minor.yy247, &yymsp[0].minor.yy0);} - yymsp[-5].minor.yy46 = yylhsminor.yy46; +{yylhsminor.yy36 = addSubqueryElem(yymsp[-5].minor.yy36, yymsp[-2].minor.yy189, &yymsp[0].minor.yy0);} + yymsp[-5].minor.yy36 = yylhsminor.yy36; break; case 186: /* tablelist ::= ids cpxName */ { yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy46 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy36 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); } - yymsp[-1].minor.yy46 = yylhsminor.yy46; + yymsp[-1].minor.yy36 = yylhsminor.yy36; break; case 187: /* tablelist ::= ids cpxName ids */ { yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy46 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy36 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy46 = yylhsminor.yy46; + yymsp[-2].minor.yy36 = yylhsminor.yy36; break; case 188: /* tablelist ::= tablelist COMMA ids cpxName */ { yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy46 = setTableNameList(yymsp[-3].minor.yy46, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy36 = setTableNameList(yymsp[-3].minor.yy36, &yymsp[-1].minor.yy0, NULL); } - yymsp[-3].minor.yy46 = yylhsminor.yy46; + yymsp[-3].minor.yy36 = yylhsminor.yy36; break; case 189: /* tablelist ::= tablelist COMMA ids cpxName ids */ { yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n; - yylhsminor.yy46 = setTableNameList(yymsp[-4].minor.yy46, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy36 = setTableNameList(yymsp[-4].minor.yy36, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-4].minor.yy46 = yylhsminor.yy46; + yymsp[-4].minor.yy36 = yylhsminor.yy36; break; case 190: /* tmvar ::= VARIABLE */ {yylhsminor.yy0 = yymsp[0].minor.yy0;} yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 191: /* timestamp ::= INTEGER */ -{ yylhsminor.yy44 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy44 = yylhsminor.yy44; +{ yylhsminor.yy18 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_INTEGER);} + yymsp[0].minor.yy18 = yylhsminor.yy18; 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.yy44 = tSqlExprCreateTimestamp(&yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy44 = yylhsminor.yy44; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy18 = tSqlExprCreateTimestamp(&yymsp[-1].minor.yy0, TK_INTEGER);} + yymsp[-1].minor.yy18 = yylhsminor.yy18; break; case 194: /* timestamp ::= STRING */ -{ yylhsminor.yy44 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy44 = yylhsminor.yy44; +{ yylhsminor.yy18 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_STRING);} + yymsp[0].minor.yy18 = yylhsminor.yy18; break; case 195: /* timestamp ::= NOW */ -{ yylhsminor.yy44 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy44 = yylhsminor.yy44; +{ yylhsminor.yy18 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_NOW); } + yymsp[0].minor.yy18 = yylhsminor.yy18; break; case 196: /* timestamp ::= NOW PLUS VARIABLE */ -{yymsp[-2].minor.yy44 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_PLUS); } +{yymsp[-2].minor.yy18 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_PLUS); } break; case 197: /* timestamp ::= NOW MINUS VARIABLE */ -{yymsp[-2].minor.yy44 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_MINUS); } +{yymsp[-2].minor.yy18 = tSqlExprCreateTimestamp(&yymsp[0].minor.yy0, TK_MINUS); } break; case 198: /* range_option ::= */ -{yymsp[1].minor.yy379.start = 0; yymsp[1].minor.yy379.end = 0;} +{yymsp[1].minor.yy124.start = 0; yymsp[1].minor.yy124.end = 0;} break; case 199: /* range_option ::= RANGE LP timestamp COMMA timestamp RP */ -{yymsp[-5].minor.yy379.start = yymsp[-3].minor.yy44; yymsp[-5].minor.yy379.end = yymsp[-1].minor.yy44;} +{yymsp[-5].minor.yy124.start = yymsp[-3].minor.yy18; yymsp[-5].minor.yy124.end = yymsp[-1].minor.yy18;} break; case 200: /* interval_option ::= intervalKey LP tmvar RP */ -{yylhsminor.yy430.interval = yymsp[-1].minor.yy0; yylhsminor.yy430.offset.n = 0; yylhsminor.yy430.token = yymsp[-3].minor.yy2;} - yymsp[-3].minor.yy430 = yylhsminor.yy430; +{yylhsminor.yy32.interval = yymsp[-1].minor.yy0; yylhsminor.yy32.offset.n = 0; yylhsminor.yy32.token = yymsp[-3].minor.yy516;} + yymsp[-3].minor.yy32 = yylhsminor.yy32; break; case 201: /* interval_option ::= intervalKey LP tmvar COMMA tmvar RP */ -{yylhsminor.yy430.interval = yymsp[-3].minor.yy0; yylhsminor.yy430.offset = yymsp[-1].minor.yy0; yylhsminor.yy430.token = yymsp[-5].minor.yy2;} - yymsp[-5].minor.yy430 = yylhsminor.yy430; +{yylhsminor.yy32.interval = yymsp[-3].minor.yy0; yylhsminor.yy32.offset = yymsp[-1].minor.yy0; yylhsminor.yy32.token = yymsp[-5].minor.yy516;} + yymsp[-5].minor.yy32 = yylhsminor.yy32; break; case 202: /* interval_option ::= */ -{memset(&yymsp[1].minor.yy430, 0, sizeof(yymsp[1].minor.yy430));} +{memset(&yymsp[1].minor.yy32, 0, sizeof(yymsp[1].minor.yy32));} break; case 203: /* intervalKey ::= INTERVAL */ -{yymsp[0].minor.yy2 = TK_INTERVAL;} +{yymsp[0].minor.yy516 = TK_INTERVAL;} break; case 204: /* intervalKey ::= EVERY */ -{yymsp[0].minor.yy2 = TK_EVERY; } +{yymsp[0].minor.yy516 = TK_EVERY; } break; case 205: /* session_option ::= */ -{yymsp[1].minor.yy507.col.n = 0; yymsp[1].minor.yy507.gap.n = 0;} +{yymsp[1].minor.yy155.col.n = 0; yymsp[1].minor.yy155.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.yy507.col = yymsp[-4].minor.yy0; - yymsp[-6].minor.yy507.gap = yymsp[-1].minor.yy0; + yymsp[-6].minor.yy155.col = yymsp[-4].minor.yy0; + yymsp[-6].minor.yy155.gap = yymsp[-1].minor.yy0; } break; case 207: /* windowstate_option ::= */ -{ yymsp[1].minor.yy492.col.n = 0; yymsp[1].minor.yy492.col.z = NULL;} +{ yymsp[1].minor.yy336.col.n = 0; yymsp[1].minor.yy336.col.z = NULL;} break; case 208: /* windowstate_option ::= STATE_WINDOW LP ids RP */ -{ yymsp[-3].minor.yy492.col = yymsp[-1].minor.yy0; } +{ yymsp[-3].minor.yy336.col = yymsp[-1].minor.yy0; } break; case 209: /* fill_opt ::= */ -{ yymsp[1].minor.yy247 = 0; } +{ yymsp[1].minor.yy189 = 0; } break; case 210: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ { @@ -3281,14 +3474,14 @@ static YYACTIONTYPE yy_reduce( toTSDBType(yymsp[-3].minor.yy0.type); tVariantCreate(&A, &yymsp[-3].minor.yy0, true); - tVariantListInsert(yymsp[-1].minor.yy247, &A, -1, 0); - yymsp[-5].minor.yy247 = yymsp[-1].minor.yy247; + tVariantListInsert(yymsp[-1].minor.yy189, &A, -1, 0); + yymsp[-5].minor.yy189 = yymsp[-1].minor.yy189; } break; case 211: /* fill_opt ::= FILL LP ID RP */ { toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-3].minor.yy247 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1, true); + yymsp[-3].minor.yy189 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1, true); } break; case 212: /* sliding_opt ::= SLIDING LP tmvar RP */ @@ -3298,262 +3491,309 @@ 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.yy247 = yymsp[0].minor.yy247;} +{yymsp[-2].minor.yy189 = yymsp[0].minor.yy189;} break; case 216: /* sortlist ::= sortlist COMMA item sortorder */ { - yylhsminor.yy247 = tVariantListAppend(yymsp[-3].minor.yy247, &yymsp[-1].minor.yy378, yymsp[0].minor.yy222); + yylhsminor.yy189 = commonItemAppend(yymsp[-3].minor.yy189, &yymsp[-1].minor.yy162, NULL, false, yymsp[0].minor.yy420); } - yymsp[-3].minor.yy247 = yylhsminor.yy247; + yymsp[-3].minor.yy189 = yylhsminor.yy189; break; - case 217: /* sortlist ::= item sortorder */ + case 217: /* sortlist ::= sortlist COMMA arrow sortorder */ { - yylhsminor.yy247 = tVariantListAppend(NULL, &yymsp[-1].minor.yy378, yymsp[0].minor.yy222); + yylhsminor.yy189 = commonItemAppend(yymsp[-3].minor.yy189, NULL, yymsp[-1].minor.yy18, true, yymsp[0].minor.yy420); } - yymsp[-1].minor.yy247 = yylhsminor.yy247; + yymsp[-3].minor.yy189 = yylhsminor.yy189; 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.yy378, &yymsp[-1].minor.yy0, true); + yylhsminor.yy189 = commonItemAppend(NULL, &yymsp[-1].minor.yy162, NULL, false, yymsp[0].minor.yy420); } - yymsp[-1].minor.yy378 = yylhsminor.yy378; + yymsp[-1].minor.yy189 = yylhsminor.yy189; break; - case 219: /* sortorder ::= ASC */ -{ yymsp[0].minor.yy222 = TSDB_ORDER_ASC; } + case 219: /* sortlist ::= arrow sortorder */ +{ + yylhsminor.yy189 = commonItemAppend(NULL, NULL, yymsp[-1].minor.yy18, true, yymsp[0].minor.yy420); +} + yymsp[-1].minor.yy189 = yylhsminor.yy189; break; - case 220: /* sortorder ::= DESC */ -{ yymsp[0].minor.yy222 = TSDB_ORDER_DESC;} + case 220: /* item ::= ID */ +{ + toTSDBType(yymsp[0].minor.yy0.type); + tVariantCreate(&yylhsminor.yy162, &yymsp[0].minor.yy0, true); +} + yymsp[0].minor.yy162 = yylhsminor.yy162; break; - case 221: /* sortorder ::= */ -{ yymsp[1].minor.yy222 = 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.yy162, &yymsp[-2].minor.yy0, true); +} + yymsp[-2].minor.yy162 = yylhsminor.yy162; break; - case 222: /* groupby_opt ::= */ -{ yymsp[1].minor.yy247 = 0;} + case 222: /* sortorder ::= ASC */ +{ yymsp[0].minor.yy420 = TSDB_ORDER_ASC; } break; - case 223: /* groupby_opt ::= GROUP BY grouplist */ -{ yymsp[-2].minor.yy247 = yymsp[0].minor.yy247;} + case 223: /* sortorder ::= DESC */ +{ yymsp[0].minor.yy420 = TSDB_ORDER_DESC;} break; - case 224: /* grouplist ::= grouplist COMMA item */ + case 224: /* sortorder ::= */ +{ yymsp[1].minor.yy420 = TSDB_ORDER_ASC; } + break; + case 225: /* groupby_opt ::= */ +{ yymsp[1].minor.yy189 = 0;} + break; + case 226: /* groupby_opt ::= GROUP BY grouplist */ +{ yymsp[-2].minor.yy189 = yymsp[0].minor.yy189;} + break; + case 227: /* grouplist ::= grouplist COMMA item */ +{ + yylhsminor.yy189 = commonItemAppend(yymsp[-2].minor.yy189, &yymsp[0].minor.yy162, NULL, false, -1); +} + yymsp[-2].minor.yy189 = yylhsminor.yy189; + break; + case 228: /* grouplist ::= grouplist COMMA arrow */ +{ + yylhsminor.yy189 = commonItemAppend(yymsp[-2].minor.yy189, NULL, yymsp[0].minor.yy18, true, -1); +} + yymsp[-2].minor.yy189 = yylhsminor.yy189; + break; + case 229: /* grouplist ::= item */ { - yylhsminor.yy247 = tVariantListAppend(yymsp[-2].minor.yy247, &yymsp[0].minor.yy378, -1); + yylhsminor.yy189 = commonItemAppend(NULL, &yymsp[0].minor.yy162, NULL, false, -1); } - yymsp[-2].minor.yy247 = yylhsminor.yy247; + yymsp[0].minor.yy189 = yylhsminor.yy189; break; - case 225: /* grouplist ::= item */ + case 230: /* grouplist ::= arrow */ { - yylhsminor.yy247 = tVariantListAppend(NULL, &yymsp[0].minor.yy378, -1); + yylhsminor.yy189 = commonItemAppend(NULL, NULL, yymsp[0].minor.yy18, true, -1); } - yymsp[0].minor.yy247 = yylhsminor.yy247; + yymsp[0].minor.yy189 = yylhsminor.yy189; + break; + case 231: /* having_opt ::= */ + case 241: /* where_opt ::= */ yytestcase(yyruleno==241); + case 291: /* expritem ::= */ yytestcase(yyruleno==291); +{yymsp[1].minor.yy18 = 0;} + break; + case 232: /* having_opt ::= HAVING expr */ + case 242: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==242); +{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;} + break; + case 233: /* limit_opt ::= */ + case 237: /* slimit_opt ::= */ yytestcase(yyruleno==237); +{yymsp[1].minor.yy38.limit = -1; yymsp[1].minor.yy38.offset = 0;} break; - case 226: /* having_opt ::= */ - case 236: /* where_opt ::= */ yytestcase(yyruleno==236); - case 281: /* expritem ::= */ yytestcase(yyruleno==281); -{yymsp[1].minor.yy44 = 0;} + case 234: /* limit_opt ::= LIMIT signed */ + case 238: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==238); +{yymsp[-1].minor.yy38.limit = yymsp[0].minor.yy69; yymsp[-1].minor.yy38.offset = 0;} break; - case 227: /* having_opt ::= HAVING expr */ - case 237: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==237); -{yymsp[-1].minor.yy44 = yymsp[0].minor.yy44;} + case 235: /* limit_opt ::= LIMIT signed OFFSET signed */ +{ yymsp[-3].minor.yy38.limit = yymsp[-2].minor.yy69; yymsp[-3].minor.yy38.offset = yymsp[0].minor.yy69;} break; - case 228: /* limit_opt ::= */ - case 232: /* slimit_opt ::= */ yytestcase(yyruleno==232); -{yymsp[1].minor.yy204.limit = -1; yymsp[1].minor.yy204.offset = 0;} + case 236: /* limit_opt ::= LIMIT signed COMMA signed */ +{ yymsp[-3].minor.yy38.limit = yymsp[0].minor.yy69; yymsp[-3].minor.yy38.offset = yymsp[-2].minor.yy69;} break; - case 229: /* limit_opt ::= LIMIT signed */ - case 233: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==233); -{yymsp[-1].minor.yy204.limit = yymsp[0].minor.yy403; yymsp[-1].minor.yy204.offset = 0;} + case 239: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ +{yymsp[-3].minor.yy38.limit = yymsp[-2].minor.yy69; yymsp[-3].minor.yy38.offset = yymsp[0].minor.yy69;} break; - case 230: /* limit_opt ::= LIMIT signed OFFSET signed */ -{ yymsp[-3].minor.yy204.limit = yymsp[-2].minor.yy403; yymsp[-3].minor.yy204.offset = yymsp[0].minor.yy403;} + case 240: /* slimit_opt ::= SLIMIT signed COMMA signed */ +{yymsp[-3].minor.yy38.limit = yymsp[0].minor.yy69; yymsp[-3].minor.yy38.offset = yymsp[-2].minor.yy69;} break; - case 231: /* limit_opt ::= LIMIT signed COMMA signed */ -{ yymsp[-3].minor.yy204.limit = yymsp[0].minor.yy403; yymsp[-3].minor.yy204.offset = yymsp[-2].minor.yy403;} + case 243: /* expr ::= LP expr RP */ +{yylhsminor.yy18 = yymsp[-1].minor.yy18; yylhsminor.yy18->exprToken.z = yymsp[-2].minor.yy0.z; yylhsminor.yy18->exprToken.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 234: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ -{yymsp[-3].minor.yy204.limit = yymsp[-2].minor.yy403; yymsp[-3].minor.yy204.offset = yymsp[0].minor.yy403;} + case 244: /* expr ::= ID */ +{ yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_ID);} + yymsp[0].minor.yy18 = yylhsminor.yy18; break; - case 235: /* slimit_opt ::= SLIMIT signed COMMA signed */ -{yymsp[-3].minor.yy204.limit = yymsp[0].minor.yy403; yymsp[-3].minor.yy204.offset = yymsp[-2].minor.yy403;} + case 245: /* expr ::= ID DOT ID */ +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ID);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 238: /* expr ::= LP expr RP */ -{yylhsminor.yy44 = yymsp[-1].minor.yy44; yylhsminor.yy44->exprToken.z = yymsp[-2].minor.yy0.z; yylhsminor.yy44->exprToken.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 246: /* expr ::= ID DOT STAR */ +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ALL);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 239: /* expr ::= ID */ -{ yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_ID);} - yymsp[0].minor.yy44 = yylhsminor.yy44; + case 247: /* expr ::= INTEGER */ +{ yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_INTEGER);} + yymsp[0].minor.yy18 = yylhsminor.yy18; break; - case 240: /* expr ::= ID DOT ID */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ID);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + 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.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_INTEGER);} + yymsp[-1].minor.yy18 = yylhsminor.yy18; break; - case 241: /* expr ::= ID DOT STAR */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[-2].minor.yy0, TK_ALL);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 250: /* expr ::= FLOAT */ +{ yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_FLOAT);} + yymsp[0].minor.yy18 = yylhsminor.yy18; break; - case 242: /* expr ::= INTEGER */ -{ yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy44 = yylhsminor.yy44; + 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.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_FLOAT);} + yymsp[-1].minor.yy18 = yylhsminor.yy18; 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.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy44 = yylhsminor.yy44; + case 253: /* expr ::= STRING */ +{ yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_STRING);} + yymsp[0].minor.yy18 = yylhsminor.yy18; break; - case 245: /* expr ::= FLOAT */ -{ yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_FLOAT);} - yymsp[0].minor.yy44 = yylhsminor.yy44; + case 254: /* expr ::= NOW */ +{ yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_NOW); } + yymsp[0].minor.yy18 = yylhsminor.yy18; 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.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_FLOAT);} - yymsp[-1].minor.yy44 = yylhsminor.yy44; + case 255: /* expr ::= VARIABLE */ +{ yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_VARIABLE);} + yymsp[0].minor.yy18 = yylhsminor.yy18; break; - case 248: /* expr ::= STRING */ -{ yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy44 = yylhsminor.yy44; + 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.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_VARIABLE);} + yymsp[-1].minor.yy18 = yylhsminor.yy18; break; - case 249: /* expr ::= NOW */ -{ yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy44 = yylhsminor.yy44; + case 258: /* expr ::= BOOL */ +{ yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_BOOL);} + yymsp[0].minor.yy18 = yylhsminor.yy18; break; - case 250: /* expr ::= VARIABLE */ -{ yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_VARIABLE);} - yymsp[0].minor.yy44 = yylhsminor.yy44; + case 259: /* expr ::= NULL */ +{ yylhsminor.yy18 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_NULL);} + yymsp[0].minor.yy18 = yylhsminor.yy18; 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.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[-1].minor.yy0, TK_VARIABLE);} - yymsp[-1].minor.yy44 = yylhsminor.yy44; + case 260: /* expr ::= ID LP exprlist RP */ +{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy18 = tSqlExprCreateFunction(yymsp[-1].minor.yy189, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy18 = yylhsminor.yy18; break; - case 253: /* expr ::= BOOL */ -{ yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_BOOL);} - yymsp[0].minor.yy44 = yylhsminor.yy44; + case 261: /* expr ::= ID LP STAR RP */ +{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy18 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy18 = yylhsminor.yy18; break; - case 254: /* expr ::= NULL */ -{ yylhsminor.yy44 = tSqlExprCreateIdValue(pInfo, &yymsp[0].minor.yy0, TK_NULL);} - yymsp[0].minor.yy44 = yylhsminor.yy44; + case 262: /* expr ::= ID LP expr AS typename RP */ +{ tStrTokenAppend(pInfo->funcs, &yymsp[-5].minor.yy0); yylhsminor.yy18 = tSqlExprCreateFuncWithParams(pInfo, yymsp[-3].minor.yy18, &yymsp[-1].minor.yy279, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, yymsp[-5].minor.yy0.type); } + yymsp[-5].minor.yy18 = yylhsminor.yy18; break; - case 255: /* expr ::= ID LP exprlist RP */ -{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy44 = tSqlExprCreateFunction(yymsp[-1].minor.yy247, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy44 = yylhsminor.yy44; + case 263: /* expr ::= expr IS NULL */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, NULL, TK_ISNULL);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 256: /* expr ::= ID LP STAR RP */ -{ tStrTokenAppend(pInfo->funcs, &yymsp[-3].minor.yy0); yylhsminor.yy44 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy44 = yylhsminor.yy44; + case 264: /* expr ::= expr IS NOT NULL */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-3].minor.yy18, NULL, TK_NOTNULL);} + yymsp[-3].minor.yy18 = yylhsminor.yy18; break; - case 257: /* expr ::= ID LP expr AS typename RP */ -{ tStrTokenAppend(pInfo->funcs, &yymsp[-5].minor.yy0); yylhsminor.yy44 = tSqlExprCreateFuncWithParams(pInfo, yymsp[-3].minor.yy44, &yymsp[-1].minor.yy179, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, yymsp[-5].minor.yy0.type); } - yymsp[-5].minor.yy44 = yylhsminor.yy44; + case 265: /* expr ::= expr LT expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_LT);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 258: /* expr ::= expr IS NULL */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, NULL, TK_ISNULL);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 266: /* expr ::= expr GT expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_GT);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 259: /* expr ::= expr IS NOT NULL */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-3].minor.yy44, NULL, TK_NOTNULL);} - yymsp[-3].minor.yy44 = yylhsminor.yy44; + case 267: /* expr ::= expr LE expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_LE);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 260: /* expr ::= expr LT expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_LT);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 268: /* expr ::= expr GE expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_GE);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 261: /* expr ::= expr GT expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_GT);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 269: /* expr ::= expr NE expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_NE);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 262: /* expr ::= expr LE expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_LE);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 270: /* expr ::= expr EQ expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_EQ);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 263: /* expr ::= expr GE expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_GE);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 271: /* expr ::= expr BETWEEN expr AND expr */ +{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy18); yylhsminor.yy18 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy18, yymsp[-2].minor.yy18, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy18, TK_LE), TK_AND);} + yymsp[-4].minor.yy18 = yylhsminor.yy18; break; - case 264: /* expr ::= expr NE expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_NE);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 272: /* expr ::= expr AND expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_AND);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 265: /* expr ::= expr EQ expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_EQ);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 273: /* expr ::= expr OR expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_OR); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 266: /* expr ::= expr BETWEEN expr AND expr */ -{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy44); yylhsminor.yy44 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy44, yymsp[-2].minor.yy44, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy44, TK_LE), TK_AND);} - yymsp[-4].minor.yy44 = yylhsminor.yy44; + case 274: /* expr ::= expr PLUS expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_PLUS); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 267: /* expr ::= expr AND expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_AND);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 275: /* expr ::= expr MINUS expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_MINUS); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 268: /* expr ::= expr OR expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_OR); } - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 276: /* expr ::= expr STAR expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_STAR); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 269: /* expr ::= expr PLUS expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_PLUS); } - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 277: /* expr ::= expr SLASH expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_DIVIDE);} + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 270: /* expr ::= expr MINUS expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_MINUS); } - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 278: /* expr ::= expr REM expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_REM); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 271: /* expr ::= expr STAR expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_STAR); } - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 279: /* expr ::= expr LIKE expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_LIKE); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 272: /* expr ::= expr SLASH expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_DIVIDE);} - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 280: /* expr ::= expr MATCH expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_MATCH); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 273: /* expr ::= expr REM expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_REM); } - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 281: /* expr ::= expr NMATCH expr */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-2].minor.yy18, yymsp[0].minor.yy18, TK_NMATCH); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 274: /* expr ::= expr LIKE expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_LIKE); } - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 282: /* 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.yy18 = tSqlExprCreate(S, M, TK_CONTAINS); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 275: /* expr ::= expr MATCH expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_MATCH); } - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 283: /* 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.yy18 = tSqlExprCreate(S, M, TK_CONTAINS); } + yymsp[-4].minor.yy18 = yylhsminor.yy18; break; - case 276: /* expr ::= expr NMATCH expr */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-2].minor.yy44, yymsp[0].minor.yy44, TK_NMATCH); } - yymsp[-2].minor.yy44 = yylhsminor.yy44; + case 284: /* 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.yy18 = tSqlExprCreate(S, M, TK_ARROW); } + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 277: /* expr ::= expr IN LP exprlist RP */ -{yylhsminor.yy44 = tSqlExprCreate(yymsp[-4].minor.yy44, (tSqlExpr*)yymsp[-1].minor.yy247, TK_IN); } - yymsp[-4].minor.yy44 = yylhsminor.yy44; + case 285: /* 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.yy18 = tSqlExprCreate(S, M, TK_ARROW); } + yymsp[-4].minor.yy18 = yylhsminor.yy18; break; - case 278: /* exprlist ::= exprlist COMMA expritem */ -{yylhsminor.yy247 = tSqlExprListAppend(yymsp[-2].minor.yy247,yymsp[0].minor.yy44,0, 0);} - yymsp[-2].minor.yy247 = yylhsminor.yy247; + case 286: /* expr ::= arrow */ + case 290: /* expritem ::= expr */ yytestcase(yyruleno==290); +{yylhsminor.yy18 = yymsp[0].minor.yy18;} + yymsp[0].minor.yy18 = yylhsminor.yy18; break; - case 279: /* exprlist ::= expritem */ -{yylhsminor.yy247 = tSqlExprListAppend(0,yymsp[0].minor.yy44,0, 0);} - yymsp[0].minor.yy247 = yylhsminor.yy247; + case 287: /* expr ::= expr IN LP exprlist RP */ +{yylhsminor.yy18 = tSqlExprCreate(yymsp[-4].minor.yy18, (tSqlExpr*)yymsp[-1].minor.yy189, TK_IN); } + yymsp[-4].minor.yy18 = yylhsminor.yy18; break; - case 280: /* expritem ::= expr */ -{yylhsminor.yy44 = yymsp[0].minor.yy44;} - yymsp[0].minor.yy44 = yylhsminor.yy44; + case 288: /* exprlist ::= exprlist COMMA expritem */ +{yylhsminor.yy189 = tSqlExprListAppend(yymsp[-2].minor.yy189,yymsp[0].minor.yy18,0, 0);} + yymsp[-2].minor.yy189 = yylhsminor.yy189; break; - case 282: /* cmd ::= RESET QUERY CACHE */ + case 289: /* exprlist ::= expritem */ +{yylhsminor.yy189 = tSqlExprListAppend(0,yymsp[0].minor.yy18,0, 0);} + yymsp[0].minor.yy189 = yylhsminor.yy189; + break; + case 292: /* cmd ::= RESET QUERY CACHE */ { setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} break; - case 283: /* cmd ::= SYNCDB ids REPLICA */ + case 293: /* cmd ::= SYNCDB ids REPLICA */ { setDCLSqlElems(pInfo, TSDB_SQL_SYNC_DB_REPLICA, 1, &yymsp[-1].minor.yy0);} break; - case 284: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + case 294: /* 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.yy247, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy189, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 285: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + case 295: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3564,21 +3804,21 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 286: /* cmd ::= ALTER TABLE ids cpxName MODIFY COLUMN columnlist */ + case 296: /* 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.yy247, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy189, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 287: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + case 297: /* 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.yy247, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy189, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 288: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + case 298: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3589,7 +3829,7 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 289: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + case 299: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3603,33 +3843,33 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 290: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + case 300: /* 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.yy378, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy162, -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 291: /* cmd ::= ALTER TABLE ids cpxName MODIFY TAG columnlist */ + case 301: /* 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.yy247, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy189, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 292: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + case 302: /* 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.yy247, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy189, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 293: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + case 303: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3640,21 +3880,21 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 294: /* cmd ::= ALTER STABLE ids cpxName MODIFY COLUMN columnlist */ + case 304: /* 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.yy247, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy189, NULL, TSDB_ALTER_TABLE_CHANGE_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 295: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + case 305: /* 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.yy247, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy189, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 296: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + case 306: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3665,7 +3905,7 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 297: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + case 307: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3679,32 +3919,32 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 298: /* cmd ::= ALTER STABLE ids cpxName SET TAG ids EQ tagitem */ + case 308: /* 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.yy378, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy162, -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 299: /* cmd ::= ALTER STABLE ids cpxName MODIFY TAG columnlist */ + case 309: /* 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.yy247, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy189, NULL, TSDB_ALTER_TABLE_MODIFY_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 300: /* cmd ::= KILL CONNECTION INTEGER */ + case 310: /* cmd ::= KILL CONNECTION INTEGER */ {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &yymsp[0].minor.yy0);} break; - case 301: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ + case 311: /* 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 302: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ + case 312: /* 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: @@ -3875,12 +4115,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 @@ -3993,7 +4277,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 5eb6a2271a094b676a13d10e0cb271be672e070c..5876d82bea9f0373b5086b2ce285f7ad86002536 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}, @@ -229,7 +230,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[] = { @@ -311,6 +313,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/1-insert/0-sql/basic.py b/tests/develop-test/1-insert/0-sql/basic.py index 86872eeaa20ce6c8f473342da3da1f17f19bc8cc..273ff8ba488db609cfa4aa5978c689288d14750b 100644 --- a/tests/develop-test/1-insert/0-sql/basic.py +++ b/tests/develop-test/1-insert/0-sql/basic.py @@ -20,9 +20,9 @@ from util.sql import * class TDTestCase: def caseDescription(self): ''' - insert 倒序插入 - 语法解析错误同时meta请求也发出去了导致callback中处理逻辑失效 - insert语句在values之间加入多个逗号 + case1: insert 倒序插入 + case2: 语法解析错误同时meta请求也发出去了导致callback中处理逻辑失效 + case3: [TD-XXXX]insert语句在values之间加入多个逗号 ''' return 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/stream/stream2.py b/tests/pytest/stream/stream2.py index 9b4eb8725c96f95196f251c55b0b773cd68e9ed5..95f5d233855bbb743eaf0390d6c145258fd8f84d 100644 --- a/tests/pytest/stream/stream2.py +++ b/tests/pytest/stream/stream2.py @@ -153,10 +153,14 @@ class TDTestCase: tdSql.checkRows(2) tdSql.checkData(0, 2, 's1') tdSql.checkData(1, 2, 's0') + tdSql.execute('kill stream %s ;' % tdSql.queryResult[0][0]) + time.sleep(5) + tdSql.query("show streams") + tdSql.checkRows(1) def stop(self): - tdSql.close() + #tdSql.close() tdLog.success("%s successfully executed" % __file__) 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/batchprepare.c b/tests/script/api/batchprepare.c index 2cbee8eac91719a4cbff4d9c323f1f304e8e8684..8931f2021f16674140844a1d4bf76cb9d7168b45 100644 --- a/tests/script/api/batchprepare.c +++ b/tests/script/api/batchprepare.c @@ -2722,6 +2722,38 @@ int stmt_funcb_autoctb_e5(TAOS_STMT *stmt) { } +int stmt_funcb_autoctb_e6(TAOS_STMT *stmt) { + char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(now,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("case success:failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(stmt)); + } + + return 0; +} + + +int stmt_funcb_autoctb_e7(TAOS_STMT *stmt) { + char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,true,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("case success:failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(stmt)); + } + + return 0; +} + + +int stmt_funcb_autoctb_e8(TAOS_STMT *stmt) { + char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,1,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("case success:failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(stmt)); + } + + return 0; +} + //300 tables 60 records int stmt_funcb1(TAOS_STMT *stmt) { @@ -4857,6 +4889,44 @@ void* runcase(void *par) { #endif + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("e6 start\n"); + stmt_funcb_autoctb_e6(stmt); + printf("e6 end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("e7 start\n"); + stmt_funcb_autoctb_e7(stmt); + printf("e7 end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("e8 start\n"); + stmt_funcb_autoctb_e8(stmt); + printf("e8 end\n"); + taos_stmt_close(stmt); + +#endif + + #if 1 prepare(taos, 1, 0); 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(); diff --git a/tests/system-test/0-management/1-stable/create_col_tag.py b/tests/system-test/0-management/1-stable/create_col_tag.py new file mode 100644 index 0000000000000000000000000000000000000000..d195e73321ea24a8b9de1f2ca5f9c07f9182dd65 --- /dev/null +++ b/tests/system-test/0-management/1-stable/create_col_tag.py @@ -0,0 +1,853 @@ +################################################################### +# 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, 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 +import time +import os +from util.log import tdLog +from util.cases import tdCases +from util.sql import tdSql + + +class TDTestCase: + def caseDescription(self): + ''' + case1:The escape char "`" can be used for both tag name and column name + case2:create stable(column&tag); insert data; show stable; show create table; add stable(column&tag);change stable(tag);drop stable(column&tag);modify stable(column&tag)(binary和nchar);drop stable; + case3:create stable_child; insert data; show stable_child; show create stable_child; drop stable_child; + case4:create regular_table(column); insert data; show regular_table; show create regular_table; add regular_table(column);drop regular_table(column);modify regular_table(column)(binary和nchar);drop regular_table; + ''' + return + + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + now = time.time() + self.ts = int(round(now * 1000)) + + def table1_checkall(self,sql): + tdLog.info(sql) + tdSql.query(sql) + tdSql.checkData(0,1,1) + tdSql.checkData(0,2,2) + tdSql.checkData(0,3,3) + tdSql.checkData(0,4,4) + tdSql.checkData(0,5,'True') + tdSql.checkData(0,6,6) + tdSql.checkData(0,7,7) + tdSql.checkData(0,8,8) + tdSql.checkData(0,9,9) + tdSql.checkData(0,10,'1970-01-01 08:00:00.010') + + def table1_checkall_1(self,sql): + tdSql.query(sql) + tdSql.checkData(0,1,1) + + def table1_checkall_2(self,sql): + self.table1_checkall_1(sql) + tdSql.checkData(0,2,2) + + def table1_checkall_3(self,sql): + self.table1_checkall_2(sql) + tdSql.checkData(0,3,3) + + def table1_checkall_4(self,sql): + self.table1_checkall_3(sql) + tdSql.checkData(0,4,4) + + def table1_checkall_5(self,sql): + self.table1_checkall_4(sql) + tdSql.checkData(0,5,'True') + + def table1_checkall_6(self,sql): + self.table1_checkall_5(sql) + tdSql.checkData(0,6,6) + + def table1_checkall_7(self,sql): + self.table1_checkall_6(sql) + tdSql.checkData(0,7,7) + + def table1_checkall_8(self,sql): + self.table1_checkall_7(sql) + tdSql.checkData(0,8,8) + + def table1_checkall_9(self,sql): + self.table1_checkall_8(sql) + tdSql.checkData(0,9,9) + + def table1_checkall_10(self,sql): + self.table1_checkall_9(sql) + tdSql.checkData(0,10,'1970-01-01 08:00:00.010') + + def run(self): + + testcaseFilename = os.path.split(__file__)[-1] + os.system("rm -rf 0-management/1-stable/%s.sql" % testcaseFilename ) + tdSql.prepare() + + print("==============step1") + print("prepare data") + + # case for defect: https://jira.taosdata.com:18080/browse/TD-2693 + tdSql.execute("create database db2") + tdSql.execute("use db2") + + print("==============new version [escape character] for stable==============") + print("==============step1,#create db.stable,db.table; insert db.table; show db.table; select db.table; drop db.table;") + print("prepare data") + + self.stb1 = "stable_1~!@#$%^&*()-_+=[]{}':,<.>/?stST13579" + self.tb1 = "table_1~!@#$%^&*()-_+=[]{}':,<.>/?stST13579" + + self.col_base = "123~!@#$%^&*()-_+=[]{}':,<.>/?stST13579" + + self.col_int = "stable_col_int%s" %self.col_base + print(self.col_int) + self.col_bigint = "stable_col_bigint%s" %self.col_base + self.col_smallint = "stable_col_smallint%s" %self.col_base + self.col_tinyint = "stable_col_tinyint%s" %self.col_base + self.col_bool = "stable_col_bool%s" %self.col_base + self.col_binary = "stable_col_binary%s" %self.col_base + self.col_nchar = "stable_col_nchar%s" %self.col_base + self.col_float = "stable_col_float%s" %self.col_base + self.col_double = "stable_col_double%s" %self.col_base + self.col_ts = "stable_col_ts%s" %self.col_base + + self.tag_base = "abc~!@#$%^&*()-_+=[]{}':,<.>/?stST13579" + self.tag_int = "stable_tag_int%s" %self.tag_base + self.tag_bigint = "stable_tag_bigint%s" %self.tag_base + self.tag_smallint = "stable_tag_smallint%s" %self.tag_base + self.tag_tinyint = "stable_tag_tinyint%s" %self.tag_base + self.tag_bool = "stable_tag_bool%s" %self.tag_base + self.tag_binary = "stable_tag_binary%s" %self.tag_base + self.tag_nchar = "stable_tag_nchar%s" %self.tag_base + self.tag_float = "stable_tag_float%s" %self.tag_base + self.tag_double = "stable_tag_double%s" %self.tag_base + self.tag_ts = "stable_tag_ts%s" %self.tag_base + + tdSql.execute('''create stable db.`%s` (ts timestamp, `%s` int , `%s` bigint , `%s` smallint , `%s` tinyint, `%s` bool , + `%s` binary(20) , `%s` nchar(20) ,`%s` float , `%s` double , `%s` timestamp) + tags(loc nchar(20), `%s` int , `%s` bigint , `%s` smallint , `%s` tinyint, `%s` bool , + `%s` binary(20) , `%s` nchar(20) ,`%s` float , `%s` double , `%s` timestamp);''' + %(self.stb1, self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, + self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts, + self.tag_int, self.tag_bigint, self.tag_smallint, self.tag_tinyint, self.tag_bool, + self.tag_binary, self.tag_nchar, self.tag_float, self.tag_double, self.tag_ts)) + tdSql.query("describe db.`%s` ; " %self.stb1) + tdSql.checkRows(22) + + tdSql.query("select _block_dist() from db.`%s` ; " %self.stb1) + tdSql.checkRows(0) + + tdSql.query("show create stable db.`%s` ; " %self.stb1) + tdSql.checkData(0, 0, self.stb1) + tdSql.checkData(0, 1, "create table `%s` (`ts` TIMESTAMP,`%s` INT,`%s` BIGINT,`%s` SMALLINT,`%s` TINYINT,`%s` BOOL,`%s` BINARY(20),`%s` NCHAR(20),`%s` FLOAT,`%s` DOUBLE,`%s` TIMESTAMP)\ + TAGS (`loc` NCHAR(20),`%s` INT,`%s` BIGINT,`%s` SMALLINT,`%s` TINYINT,`%s` BOOL,`%s` BINARY(20),`%s` NCHAR(20),`%s` FLOAT,`%s` DOUBLE,`%s` TIMESTAMP)" + %(self.stb1, self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, + self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts, + self.tag_int, self.tag_bigint, self.tag_smallint, self.tag_tinyint, self.tag_bool, + self.tag_binary, self.tag_nchar, self.tag_float, self.tag_double, self.tag_ts)) + + tdSql.execute("create table db.`table!1` using db.`%s` tags('table_1' , '0' , '0' , '0' , '0' , 0 , '0' , '0' , '0' , '0' ,'0')" %self.stb1) + tdSql.query("describe db.`table!1` ; ") + tdSql.checkRows(22) + + time.sleep(10) + tdSql.query("show create table db.`table!1` ; ") + tdSql.checkData(0, 0, "table!1") + tdSql.checkData(0, 1, "CREATE TABLE `table!1` USING `%s` TAGS (\"table_1\",0,0,0,0,false,\"0\",\"0\",0.000000,0.000000,\"0\")" %self.stb1) + + tdSql.execute("insert into db.`table!1` values(now, 1 , 2, 3, 4, 5, 6 ,7 ,8 ,9 ,10)") + sql = " select * from db.`table!1`; " + datacheck = self.table1_checkall(sql) + tdSql.checkRows(1) + sql = '''select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from db.`table!1`; '''\ + %(self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(1) + + time.sleep(1) + tdSql.execute('''insert into db.`table!1`(ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`) values(now, 1 , 2, 3, 4, 5, 6 ,7 ,8 ,9 ,10)'''\ + %(self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts) ) + sql = " select * from db.`table!1`; " + datacheck = self.table1_checkall(sql) + tdSql.checkRows(2) + + tdSql.query("select count(*) from db.`table!1`; ") + tdSql.checkData(0, 0, 2) + tdSql.query("select _block_dist() from db.`%s` ; " %self.stb1) + tdSql.checkRows(1) + + tdSql.execute("create table db.`%s` using db.`%s` TAGS (\"table_2\",2,2,2,2,true,\"2\",\"2\",2.000000,2.000000,\"2\")" %(self.tb1,self.stb1)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.query("show create table db.`%s` ; " %self.tb1) + tdSql.checkData(0, 0, self.tb1) + tdSql.checkData(0, 1, "CREATE TABLE `%s` USING `%s` TAGS (\"table_2\",2,2,2,2,true,\"2\",\"2\",2.000000,2.000000,\"2\")" %(self.tb1,self.stb1)) + + tdSql.execute("insert into db.`%s` values(now, 1 , 2, 3, 4, 5, 6 ,7 ,8 ,9 ,10)" %self.tb1) + sql = "select * from db.`%s` ; " %self.tb1 + datacheck = self.table1_checkall(sql) + tdSql.checkRows(1) + sql = '''select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from db.`%s` ; '''\ + %(self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts,\ + self.tag_int, self.tag_bigint, self.tag_smallint, self.tag_tinyint, self.tag_bool, self.tag_binary, self.tag_nchar, self.tag_float, self.tag_double, self.tag_ts, self.tb1) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(1) + + time.sleep(1) + tdSql.execute('''insert into db.`%s`(ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`) values(now, 1 , 2, 3, 4, 5, 6 ,7 ,8 ,9 ,10)'''\ + %(self.tb1, self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts) ) + sql = " select * from db.`%s` ; " %self.tb1 + datacheck = self.table1_checkall(sql) + tdSql.checkRows(2) + + sql = " select * from db.`%s` where `%s`=1 and `%s`=2 and `%s`=3 and `%s`=4 and `%s`='True' and `%s`=6 and `%s`=7 and `%s`=8 and `%s`=9 and `%s`=10; " \ + %(self.tb1, self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(2) + + tdSql.query("select count(*) from db.`%s`; " %self.tb1) + tdSql.checkData(0, 0, 2) + sql = "select * from db.`%s` ; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.checkRows(4) + tdSql.query("select count(*) from db.`%s`; " %self.stb1) + tdSql.checkData(0, 0, 4) + + sql = "select * from (select * from db.`%s`) ; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.checkRows(4) + tdSql.query("select count(*) from (select * from db.`%s`) ; " %self.stb1) + tdSql.checkData(0, 0, 4) + + sql = "select * from (select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from db.`%s`) ; " \ + %(self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts, self.stb1) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(4) + + sql = "select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from (select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from db.`%s`) ; " \ + %(self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts,\ + self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts, self.stb1) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(4) + + sql = "select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from (select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from db.`%s`\ + where `%s`=1 and `%s`=2 and `%s`=3 and `%s`=4 and `%s`='True' and `%s`=6 and `%s`=7 and `%s`=8 and `%s`=9 and `%s`=10 ) ; " \ + %(self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts,\ + self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts, self.stb1, \ + self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(4) + + tdSql.query("show db.stables like 'stable_1%' ") + tdSql.checkRows(1) + tdSql.query("show db.tables like 'table%' ") + tdSql.checkRows(2) + + self.cr_tb1 = "create_table_1~!@#$%^&*()-_+=[]{}':,<.>/?stST13579" + tdSql.execute("create table db.`%s` as select avg(`%s`) from db.`%s` where ts > now interval(1m) sliding(30s);" %(self.cr_tb1,self.col_bigint,self.stb1)) + tdSql.query("show db.tables like 'create_table_%' ") + tdSql.checkRows(1) + + print("==============drop\ add\ change\ modify column or tag") + print("==============drop==============") + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_ts)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(21) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_double)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(20) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_float)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(19) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_nchar)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(18) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_binary)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(17) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_bool)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(16) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_tinyint)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(15) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_smallint)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(14) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_bigint)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(13) + tdSql.execute("ALTER TABLE db.`%s` DROP TAG `%s`; " %(self.stb1, self.tag_int)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(12) + + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_ts)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_9(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(11) + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_double)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_8(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(10) + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_float)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_7(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(9) + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_nchar)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_6(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(8) + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_binary)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_5(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(7) + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_bool)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_4(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(6) + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_tinyint)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_3(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(5) + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_smallint)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_2(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(4) + tdSql.execute("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_bigint)) + sql = " select * from db.`%s`; " %self.stb1 + datacheck = self.table1_checkall_1(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(3) + tdSql.error("ALTER TABLE db.`%s` DROP COLUMN `%s`; " %(self.stb1, self.col_int)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(3) + + print("==============add==============") + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` bigint; " %(self.stb1, self.col_bigint)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(4) + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` smallint; " %(self.stb1, self.col_smallint)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(5) + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` tinyint; " %(self.stb1, self.col_tinyint)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(6) + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` bool; " %(self.stb1, self.col_bool)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(7) + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` binary(20); " %(self.stb1, self.col_binary)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(8) + + tdSql.execute("insert into db.`%s` values(now, 1 , 2, 3, 4, 5, 6)" %self.tb1) + sql = "select * from db.`%s` order by ts desc; " %self.tb1 + datacheck = self.table1_checkall_5(sql) + + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` nchar(20); " %(self.stb1, self.col_nchar)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(9) + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` float; " %(self.stb1, self.col_float)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(10) + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` double; " %(self.stb1, self.col_double)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(11) + tdSql.execute("ALTER TABLE db.`%s` ADD COLUMN `%s` timestamp; " %(self.stb1, self.col_ts)) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(12) + + tdSql.execute("insert into db.`%s` values(now, 1 , 2, 3, 4, 5, 6 ,7 ,8 ,9 ,10)" %self.tb1) + sql = "select * from db.`%s` order by ts desc; " %self.tb1 + datacheck = self.table1_checkall(sql) + + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` int; " %(self.stb1, self.tag_int)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(13) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` bigint; " %(self.stb1, self.tag_bigint)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(14) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` smallint; " %(self.stb1, self.tag_smallint)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(15) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` tinyint; " %(self.stb1, self.tag_tinyint)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(16) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` bool; " %(self.stb1, self.tag_bool)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(17) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` binary(20); " %(self.stb1, self.tag_binary)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(18) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` nchar(20); " %(self.stb1, self.tag_nchar)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(19) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` float; " %(self.stb1, self.tag_float)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(20) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` double; " %(self.stb1, self.tag_double)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(21) + tdSql.execute("ALTER TABLE db.`%s` ADD TAG `%s` timestamp; " %(self.stb1, self.tag_ts)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + + print("==============change==============") + self.tag_base_change = "abcdas" + self.tag_int_change = "stable_tag_int%s" %self.tag_base_change + self.tag_bigint_change = "stable_tag_bigint%s" %self.tag_base_change + self.tag_smallint_change = "stable_tag_smallint%s" %self.tag_base_change + self.tag_tinyint_change = "stable_tag_tinyint%s" %self.tag_base_change + self.tag_bool_change = "stable_tag_bool%s" %self.tag_base_change + self.tag_binary_change = "stable_tag_binary%s" %self.tag_base_change + self.tag_nchar_change = "stable_tag_nchar%s" %self.tag_base_change + self.tag_float_change = "stable_tag_float%s" %self.tag_base_change + self.tag_double_change = "stable_tag_double%s" %self.tag_base_change + self.tag_ts_change = "stable_tag_ts%s" %self.tag_base_change + + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_int, self.tag_int_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_bigint, self.tag_bigint_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_smallint, self.tag_smallint_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_tinyint, self.tag_tinyint_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_bool, self.tag_bool_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_binary, self.tag_binary_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_nchar, self.tag_nchar_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_float, self.tag_float_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_double, self.tag_double_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER TABLE db.`%s` CHANGE TAG `%s` `%s`; " %(self.stb1, self.tag_ts, self.tag_ts_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + + print("==============modify==============") + # TD-10810 + tdSql.execute("ALTER STABLE db.`%s` MODIFY TAG `%s` binary(30); ; " %(self.stb1, self.tag_binary_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER STABLE db.`%s` MODIFY TAG `%s` nchar(30); ; " %(self.stb1, self.tag_nchar_change)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + + tdSql.execute("ALTER STABLE db.`%s` MODIFY COLUMN `%s` binary(30); ; " %(self.stb1, self.col_binary)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + tdSql.execute("ALTER STABLE db.`%s` MODIFY COLUMN `%s` nchar(30); ; " %(self.stb1, self.col_nchar)) + sql = " select * from db.`%s` order by ts desc; " %self.stb1 + datacheck = self.table1_checkall(sql) + tdSql.query("describe db.`%s` ; " %self.tb1) + tdSql.checkRows(22) + + print("==============drop table\stable") + try: + tdSql.execute("drop table db.`%s` " %self.tb1) + except Exception as e: + tdLog.exit(e) + + tdSql.error("select * from db.`%s`" %self.tb1) + tdSql.query("show db.stables like 'stable_1%' ") + tdSql.checkRows(1) + + try: + tdSql.execute("drop table db.`%s` " %self.stb1) + except Exception as e: + tdLog.exit(e) + + tdSql.error("select * from db.`%s`" %self.tb1) + tdSql.error("select * from db.`%s`" %self.stb1) + + + print("==============step2,#create stable,table; insert table; show table; select table; drop table") + + self.stb2 = "stable_2~!@#$%^&*()-_+=[]{}';:,<.>/?stST24680~!@#$%^&*()-_+=[]{}" + self.tb2 = "table_2~!@#$%^&*()-_+=[]{}';:,<.>/?stST24680~!@#$%^&*()-_+=[]{}" + + tdSql.execute("create stable `%s` (ts timestamp, i int) tags(j int);" %self.stb2) + tdSql.query("describe `%s` ; "%self.stb2) + tdSql.checkRows(3) + + tdSql.query("select _block_dist() from `%s` ; " %self.stb2) + tdSql.checkRows(0) + + tdSql.query("show create stable `%s` ; " %self.stb2) + tdSql.checkData(0, 0, self.stb2) + tdSql.checkData(0, 1, "create table `%s` (`ts` TIMESTAMP,`i` INT) TAGS (`j` INT)" %self.stb2) + + tdSql.execute("create table `table!2` using `%s` tags(1)" %self.stb2) + tdSql.query("describe `table!2` ; ") + tdSql.checkRows(3) + + time.sleep(10) + + tdSql.query("show create table `table!2` ; ") + tdSql.checkData(0, 0, "table!2") + tdSql.checkData(0, 1, "CREATE TABLE `table!2` USING `%s` TAGS (1)" %self.stb2) + tdSql.execute("insert into `table!2` values(now, 1)") + tdSql.query("select * from `table!2`; ") + tdSql.checkRows(1) + tdSql.query("select count(*) from `table!2`; ") + tdSql.checkData(0, 0, 1) + tdSql.query("select _block_dist() from `%s` ; " %self.stb2) + tdSql.checkRows(1) + + tdSql.execute("create table `%s` using `%s` tags(1)" %(self.tb2,self.stb2)) + tdSql.query("describe `%s` ; " %self.tb2) + tdSql.checkRows(3) + tdSql.query("show create table `%s` ; " %self.tb2) + tdSql.checkData(0, 0, self.tb2) + tdSql.checkData(0, 1, "CREATE TABLE `%s` USING `%s` TAGS (1)" %(self.tb2,self.stb2)) + tdSql.execute("insert into `%s` values(now, 1)" %self.tb2) + tdSql.query("select * from `%s` ; " %self.tb2) + tdSql.checkRows(1) + tdSql.query("select count(*) from `%s`; " %self.tb2) + tdSql.checkData(0, 0, 1) + tdSql.query("select * from `%s` ; " %self.stb2) + tdSql.checkRows(2) + tdSql.query("select count(*) from `%s`; " %self.stb2) + tdSql.checkData(0, 0, 2) + + tdSql.query("select * from (select * from `%s`) ; " %self.stb2) + tdSql.checkRows(2) + tdSql.query("select count(*) from (select * from `%s` ); " %self.stb2) + tdSql.checkData(0, 0, 2) + + tdSql.query("show stables like 'stable_2%' ") + tdSql.checkRows(1) + tdSql.query("show tables like 'table%' ") + tdSql.checkRows(2) + + + #TD-10536 + self.cr_tb2 = "create_table_2~!@#$%^&*()-_+=[]{}';:,<.>/?stST24680~!@#$%^&*()-_+=[]{}" + tdSql.execute("create table `%s` as select * from `%s` ;" %(self.cr_tb2,self.stb2)) + tdSql.query("show db.tables like 'create_table_%' ") + tdSql.checkRows(1) + + print("==============drop table\stable") + try: + tdSql.execute("drop table `%s` " %self.tb2) + except Exception as e: + tdLog.exit(e) + + tdSql.error("select * from `%s`" %self.tb2) + tdSql.query("show stables like 'stable_2%' ") + tdSql.checkRows(1) + + try: + tdSql.execute("drop table `%s` " %self.stb2) + except Exception as e: + tdLog.exit(e) + + tdSql.error("select * from `%s`" %self.tb2) + tdSql.error("select * from `%s`" %self.stb2) + + + print("==============step3,#create regular_table; insert regular_table; show regular_table; select regular_table; drop regular_table") + self.regular_table = "regular_table~!@#$%^&*()-_+=[]{}';:,<.>/?stST24680~!@#$%^&*()-_+=[]{}" + + self.regular_col_base = "123@#$%^&*()-_+=[]{};:,<.>/?~!$%^" + + self.col_int = "regular_table_col_int%s" %self.regular_col_base + print(self.col_int) + self.col_bigint = "regular_table_col_bigint%s" %self.regular_col_base + self.col_smallint = "regular_table_col_smallint%s" %self.regular_col_base + self.col_tinyint = "regular_table_col_tinyint%s" %self.regular_col_base + self.col_bool = "regular_table_col_bool%s" %self.regular_col_base + self.col_binary = "regular_table_col_binary%s" %self.regular_col_base + self.col_nchar = "regular_table_col_nchar%s" %self.regular_col_base + self.col_float = "regular_table_col_float%s" %self.regular_col_base + self.col_double = "regular_table_col_double%s" %self.regular_col_base + self.col_ts = "regular_table_col_ts%s" %self.regular_col_base + + tdSql.execute("create table `%s` (ts timestamp,`%s` int , `%s` bigint , `%s` smallint , `%s` tinyint, `%s` bool , \ + `%s` binary(20) , `%s` nchar(20) ,`%s` float , `%s` double , `%s` timestamp) ;"\ + %(self.regular_table, self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, + self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts)) + tdSql.query("describe `%s` ; "%self.regular_table) + tdSql.checkRows(11) + + tdSql.query("select _block_dist() from `%s` ; " %self.regular_table) + tdSql.checkRows(1) + + tdSql.query("show create table `%s` ; " %self.regular_table) + tdSql.checkData(0, 0, self.regular_table) + tdSql.checkData(0, 1, "create table `%s` (`ts` TIMESTAMP,`%s` INT,`%s` BIGINT,`%s` SMALLINT,`%s` TINYINT,`%s` BOOL,`%s` BINARY(20),`%s` NCHAR(20),`%s` FLOAT,`%s` DOUBLE,`%s` TIMESTAMP)" + %(self.regular_table, self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, + self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts)) + + tdSql.execute("insert into `%s` values(now, 1 , 2, 3, 4, 5, 6 ,7 ,8 ,9 ,10)" %self.regular_table) + sql = "select * from `%s` ; " %self.regular_table + datacheck = self.table1_checkall(sql) + tdSql.checkRows(1) + sql = '''select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from db2.`%s`; '''\ + %(self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts, self.regular_table) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(1) + + time.sleep(1) + tdSql.execute('''insert into db2.`%s` (ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`) values(now, 1 , 2, 3, 4, 5, 6 ,7 ,8 ,9 ,10)'''\ + %(self.regular_table, self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts) ) + sql = " select * from db2.`%s`; " %self.regular_table + datacheck = self.table1_checkall(sql) + tdSql.checkRows(2) + + sql = " select * from db2.`%s` where `%s`=1 and `%s`=2 and `%s`=3 and `%s`=4 and `%s`='True' and `%s`=6 and `%s`=7 and `%s`=8 and `%s`=9 and `%s`=10; " \ + %(self.regular_table, self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(2) + + tdSql.query("select count(*) from `%s`; " %self.regular_table) + tdSql.checkData(0, 0, 2) + tdSql.query("select _block_dist() from `%s` ; " %self.regular_table) + tdSql.checkRows(1) + + sql = "select * from (select * from `%s`) ; " %self.regular_table + datacheck = self.table1_checkall(sql) + tdSql.checkRows(2) + + sql = "select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from (select ts ,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s`,`%s` from db2.`%s`\ + where `%s`=1 and `%s`=2 and `%s`=3 and `%s`=4 and `%s`='True' and `%s`=6 and `%s`=7 and `%s`=8 and `%s`=9 and `%s`=10 ) ; " \ + %(self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts,\ + self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts, self.regular_table, \ + self.col_int, self.col_bigint, self.col_smallint, self.col_tinyint, self.col_bool, self.col_binary, self.col_nchar, self.col_float, self.col_double, self.col_ts) + datacheck = self.table1_checkall(sql) + tdSql.checkRows(2) + + tdSql.query("select count(*) from (select * from `%s` ); " %self.regular_table) + tdSql.checkData(0, 0, 2) + + tdSql.query("show tables like 'regular_table%' ") + tdSql.checkRows(1) + + self.crr_tb = "create_r_table~!@#$%^&*()-_+=[]{}';:,<.>/?stST24680~!@#$%^&*()-_+=[]{}" + tdSql.execute("create table `%s` as select * from `%s` ;" %(self.crr_tb,self.regular_table)) + tdSql.query("show db2.tables like 'create_r_table%' ") + tdSql.checkRows(1) + + + print("==============drop\ add\ change\ modify column ") + print("==============drop==============") + tdSql.execute("ALTER TABLE db2.`%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_ts)) + sql = " select * from db2.`%s`; " %self.regular_table + datacheck = self.table1_checkall_9(sql) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(10) + tdSql.execute("ALTER TABLE `%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_double)) + sql = " select * from `%s`; " %self.regular_table + datacheck = self.table1_checkall_8(sql) + tdSql.query("describe `%s` ; " %self.regular_table) + tdSql.checkRows(9) + tdSql.execute("ALTER TABLE db2.`%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_float)) + sql = " select * from db2.`%s`; " %self.regular_table + datacheck = self.table1_checkall_7(sql) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(8) + tdSql.execute("ALTER TABLE `%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_nchar)) + sql = " select * from `%s`; " %self.regular_table + datacheck = self.table1_checkall_6(sql) + tdSql.query("describe `%s` ; " %self.regular_table) + tdSql.checkRows(7) + tdSql.execute("ALTER TABLE db2.`%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_binary)) + sql = " select * from db2.`%s`; " %self.regular_table + datacheck = self.table1_checkall_5(sql) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(6) + tdSql.execute("ALTER TABLE `%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_bool)) + sql = " select * from `%s`; " %self.regular_table + datacheck = self.table1_checkall_4(sql) + tdSql.query("describe `%s` ; " %self.regular_table) + tdSql.checkRows(5) + tdSql.execute("ALTER TABLE db2.`%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_tinyint)) + sql = " select * from db2.`%s`; " %self.regular_table + datacheck = self.table1_checkall_3(sql) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(4) + tdSql.execute("ALTER TABLE `%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_smallint)) + sql = " select * from `%s`; " %self.regular_table + datacheck = self.table1_checkall_2(sql) + tdSql.query("describe `%s` ; " %self.regular_table) + tdSql.checkRows(3) + tdSql.execute("ALTER TABLE db2.`%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_bigint)) + sql = " select * from db2.`%s`; " %self.regular_table + datacheck = self.table1_checkall_1(sql) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(2) + tdSql.error("ALTER TABLE db2.`%s` DROP COLUMN `%s`; " %(self.regular_table, self.col_int)) + tdSql.query("describe `%s` ; " %self.regular_table) + tdSql.checkRows(2) + + print("==============add==============") + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` bigint; " %(self.regular_table, self.col_bigint)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(3) + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` smallint; " %(self.regular_table, self.col_smallint)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(4) + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` tinyint; " %(self.regular_table, self.col_tinyint)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(5) + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` bool; " %(self.regular_table, self.col_bool)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(6) + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` binary(20); " %(self.regular_table, self.col_binary)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(7) + + tdSql.execute("insert into db2.`%s` values(now, 1 , 2, 3, 4, 5, 6)" %self.regular_table) + sql = "select * from db2.`%s` order by ts desc; " %self.regular_table + datacheck = self.table1_checkall_5(sql) + + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` nchar(20); " %(self.regular_table, self.col_nchar)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(8) + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` float; " %(self.regular_table, self.col_float)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(9) + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` double; " %(self.regular_table, self.col_double)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(10) + tdSql.execute("ALTER TABLE db2.`%s` ADD COLUMN `%s` timestamp; " %(self.regular_table, self.col_ts)) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(11) + + tdSql.execute("insert into db2.`%s` values(now, 1 , 2, 3, 4, 5, 6 ,7 ,8 ,9 ,10)" %self.regular_table) + sql = "select * from db2.`%s` order by ts desc; " %self.regular_table + datacheck = self.table1_checkall(sql) + + + print("==============change, regular not support==============") + + + print("==============modify==============") + # TD-10810 + tdSql.execute("ALTER TABLE db2.`%s` MODIFY COLUMN `%s` binary(30); ; " %(self.regular_table, self.col_binary)) + sql = " select * from db2.`%s` order by ts desc; " %self.regular_table + datacheck = self.table1_checkall(sql) + tdSql.query("describe db2.`%s` ; " %self.regular_table) + tdSql.checkRows(11) + tdSql.execute("ALTER TABLE `%s` MODIFY COLUMN `%s` nchar(30); ; " %(self.regular_table, self.col_nchar)) + sql = " select * from `%s` order by ts desc; " %self.regular_table + datacheck = self.table1_checkall(sql) + tdSql.query("describe `%s` ; " %self.regular_table) + tdSql.checkRows(11) + + + print("==============drop table\stable") + try: + tdSql.execute("drop table `%s` " %self.regular_table) + except Exception as e: + tdLog.exit(e) + + tdSql.error("select * from `%s`" %self.regular_table) + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/system-test/1-insert/0-sql/basic.py b/tests/system-test/1-insert/0-sql/basic.py index cddbc3dc9e9b49d0316105eff09c9684bcfd040d..3604224c512d4a9f85de30a9069136801d343503 100644 --- a/tests/system-test/1-insert/0-sql/basic.py +++ b/tests/system-test/1-insert/0-sql/basic.py @@ -20,9 +20,9 @@ from util.sql import * class TDTestCase: def caseDescription(self): ''' - insert 倒序插入 - 语法解析错误同时meta请求也发出去了导致callback中处理逻辑失效 - insert语句在values之间加入多个逗号 + case1: insert 倒序插入 + case2: 语法解析错误同时meta请求也发出去了导致callback中处理逻辑失效 + case3: [TD-XXXX]insert语句在values之间加入多个逗号 ''' return def init(self, conn, logSql): diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index e71a25659b1e5a2eed92e615f63eb18ace64de92..5040747d3ae4a21ec8fda32793bf06dae98e09e2 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-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 1-insert/0-sql/basic.py +python3 test.py -f 0-management/1-stable/create_col_tag.py \ No newline at end of file