diff --git a/cmake/apr-util_CMakeLists.txt.in b/cmake/apr-util_CMakeLists.txt.in new file mode 100644 index 0000000000000000000000000000000000000000..5a68020dd7d0e6d7ca3020dee9f86925ee77d822 --- /dev/null +++ b/cmake/apr-util_CMakeLists.txt.in @@ -0,0 +1,19 @@ +# apr-util +ExternalProject_Add(aprutil-1 + URL https://dlcdn.apache.org//apr/apr-util-1.6.3.tar.gz + URL_HASH SHA256=2b74d8932703826862ca305b094eef2983c27b39d5c9414442e9976a9acf1983 + DOWNLOAD_NO_PROGRESS 1 + DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download" + #GIT_REPOSITORY https://github.com/apache/apr-util.git + #GIT_TAG 1.5.4 + SOURCE_DIR "${TD_CONTRIB_DIR}/apr-util" + #BINARY_DIR "" + BUILD_IN_SOURCE TRUE + BUILD_ALWAYS 1 + #UPDATE_COMMAND "" + CONFIGURE_COMMAND ./configure --prefix=$ENV{HOME}/.cos-local.1/ --with-apr=$ENV{HOME}/.cos-local.1 + #CONFIGURE_COMMAND ./configure --with-apr=/usr/local/apr + BUILD_COMMAND make + INSTALL_COMMAND make install + TEST_COMMAND "" +) diff --git a/cmake/apr_CMakeLists.txt.in b/cmake/apr_CMakeLists.txt.in new file mode 100644 index 0000000000000000000000000000000000000000..18c4eb62a1f08c998787c851fdb52b2b469b446f --- /dev/null +++ b/cmake/apr_CMakeLists.txt.in @@ -0,0 +1,19 @@ +# apr +ExternalProject_Add(apr-1 + URL https://dlcdn.apache.org//apr/apr-1.7.4.tar.gz + URL_HASH SHA256=a4137dd82a185076fa50ba54232d920a17c6469c30b0876569e1c2a05ff311d9 + DOWNLOAD_NO_PROGRESS 1 + DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download" + #GIT_REPOSITORY https://github.com/apache/apr.git + #GIT_TAG 1.5.2 + SOURCE_DIR "${TD_CONTRIB_DIR}/apr" + BUILD_IN_SOURCE TRUE + UPDATE_DISCONNECTED TRUE + BUILD_ALWAYS 1 + #UPDATE_COMMAND "" + CONFIGURE_COMMAND ./configure --prefix=$ENV{HOME}/.cos-local.1/ --enable-shared=no + #CONFIGURE_COMMAND ./configure + BUILD_COMMAND make + INSTALL_COMMAND make install + TEST_COMMAND "" +) diff --git a/cmake/cmake.define b/cmake/cmake.define index cf7f45099414af86a6fe8bccfbbd8bb477c5b711..edc5dd601a6adbdf4d7a8050f32467692c0f4344 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -1,5 +1,4 @@ cmake_minimum_required(VERSION 3.0) - set(CMAKE_VERBOSE_MAKEFILE ON) set(TD_BUILD_TAOSA_INTERNAL FALSE) @@ -78,6 +77,12 @@ ELSE () SET(TD_TAOS_TOOLS TRUE) ENDIF () +IF (${TD_WINDOWS}) + SET(TAOS_LIB taos_static) +ELSE () + SET(TAOS_LIB taos) +ENDIF () + IF (TD_WINDOWS) MESSAGE("${Yellow} set compiler flag for Windows! ${ColourReset}") SET(COMMON_FLAGS "/w /D_WIN32 /DWIN32 /Zi /MTd") diff --git a/cmake/cmake.options b/cmake/cmake.options index fa0b88841519305ff30b758356e66cf041d8d900..1d4e9ba515f2080e4e82672f03dcba7dd31f7645 100644 --- a/cmake/cmake.options +++ b/cmake/cmake.options @@ -125,6 +125,16 @@ option( ON ) +IF(${TD_LINUX}) + +option( + BUILD_WITH_COS + "If build with cos" + ON +) + +ENDIF () + option( BUILD_WITH_SQLITE "If build with sqlite" diff --git a/cmake/cos_CMakeLists.txt.in b/cmake/cos_CMakeLists.txt.in new file mode 100644 index 0000000000000000000000000000000000000000..ee1e58b50fdb4891716759c817d068e1a77ea187 --- /dev/null +++ b/cmake/cos_CMakeLists.txt.in @@ -0,0 +1,12 @@ +# cos +ExternalProject_Add(cos + GIT_REPOSITORY https://github.com/tencentyun/cos-c-sdk-v5.git + GIT_TAG v5.0.16 + SOURCE_DIR "${TD_CONTRIB_DIR}/cos-c-sdk-v5" + BINARY_DIR "" + #BUILD_IN_SOURCE TRUE + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" +) diff --git a/cmake/curl_CMakeLists.txt.in b/cmake/curl_CMakeLists.txt.in new file mode 100644 index 0000000000000000000000000000000000000000..0fe0c2256f1d791c5429b7ce2c147d0a5309fcc7 --- /dev/null +++ b/cmake/curl_CMakeLists.txt.in @@ -0,0 +1,17 @@ +# curl +ExternalProject_Add(curl + URL https://curl.se/download/curl-8.2.1.tar.gz + DOWNLOAD_NO_PROGRESS 1 + DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download" + #GIT_REPOSITORY https://github.com/curl/curl.git + #GIT_TAG curl-7_88_1 + SOURCE_DIR "${TD_CONTRIB_DIR}/curl" + BUILD_IN_SOURCE TRUE + BUILD_ALWAYS 1 + #UPDATE_COMMAND "" + CONFIGURE_COMMAND ./configure --prefix=$ENV{HOME}/.cos-local.1 --without-ssl --enable-shared=no --disable-ldap --disable-ldaps --without-brotli + #CONFIGURE_COMMAND ./configure --without-ssl + BUILD_COMMAND make + INSTALL_COMMAND make install + TEST_COMMAND "" +) diff --git a/cmake/mxml_CMakeLists.txt.in b/cmake/mxml_CMakeLists.txt.in new file mode 100644 index 0000000000000000000000000000000000000000..9dcb5df665e265178ead3c98eac4d2ce54d8c3f3 --- /dev/null +++ b/cmake/mxml_CMakeLists.txt.in @@ -0,0 +1,14 @@ +# cos +ExternalProject_Add(mxml + GIT_REPOSITORY https://github.com/michaelrsweet/mxml.git + GIT_TAG release-2.10 + SOURCE_DIR "${TD_CONTRIB_DIR}/mxml" + #BINARY_DIR "" + BUILD_IN_SOURCE TRUE + #UPDATE_COMMAND "" + CONFIGURE_COMMAND ./configure --prefix=$ENV{HOME}/.cos-local.1 --enable-shared=no + #CONFIGURE_COMMAND ./configure + BUILD_COMMAND make + INSTALL_COMMAND make install + TEST_COMMAND "" +) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index c60fd33b16187840d2cc27feb8321e14b801ed5d..e3e48ac3a150fdd3e759df8663adbf9e9a38216d 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -6,6 +6,39 @@ function(cat IN_FILE OUT_FILE) file(APPEND ${OUT_FILE} "${CONTENTS}") endfunction(cat IN_FILE OUT_FILE) +if(${TD_LINUX}) + +set(CONTRIB_TMP_FILE3 "${CMAKE_BINARY_DIR}/deps_tmp_CMakeLists.txt.in3") +configure_file("${TD_SUPPORT_DIR}/deps_CMakeLists.txt.in" ${CONTRIB_TMP_FILE3}) + +if(${BUILD_WITH_COS}) + file(MAKE_DIRECTORY $ENV{HOME}/.cos-local.1/) + cat("${TD_SUPPORT_DIR}/mxml_CMakeLists.txt.in" ${CONTRIB_TMP_FILE3}) + cat("${TD_SUPPORT_DIR}/apr_CMakeLists.txt.in" ${CONTRIB_TMP_FILE3}) + cat("${TD_SUPPORT_DIR}/curl_CMakeLists.txt.in" ${CONTRIB_TMP_FILE3}) +endif(${BUILD_WITH_COS}) + +configure_file(${CONTRIB_TMP_FILE3} "${TD_CONTRIB_DIR}/deps-download/CMakeLists.txt") +execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . + WORKING_DIRECTORY "${TD_CONTRIB_DIR}/deps-download") +execute_process(COMMAND "${CMAKE_COMMAND}" --build . + WORKING_DIRECTORY "${TD_CONTRIB_DIR}/deps-download") + +set(CONTRIB_TMP_FILE2 "${CMAKE_BINARY_DIR}/deps_tmp_CMakeLists.txt.in2") +configure_file("${TD_SUPPORT_DIR}/deps_CMakeLists.txt.in" ${CONTRIB_TMP_FILE2}) + +if(${BUILD_WITH_COS}) + cat("${TD_SUPPORT_DIR}/apr-util_CMakeLists.txt.in" ${CONTRIB_TMP_FILE2}) +endif(${BUILD_WITH_COS}) + +configure_file(${CONTRIB_TMP_FILE2} "${TD_CONTRIB_DIR}/deps-download/CMakeLists.txt") +execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" . + WORKING_DIRECTORY "${TD_CONTRIB_DIR}/deps-download") +execute_process(COMMAND "${CMAKE_COMMAND}" --build . + WORKING_DIRECTORY "${TD_CONTRIB_DIR}/deps-download") + +endif(${TD_LINUX}) + set(CONTRIB_TMP_FILE "${CMAKE_BINARY_DIR}/deps_tmp_CMakeLists.txt.in") configure_file("${TD_SUPPORT_DIR}/deps_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) @@ -122,6 +155,16 @@ if(${BUILD_WITH_SQLITE}) cat("${TD_SUPPORT_DIR}/sqlite_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) endif(${BUILD_WITH_SQLITE}) +# cos +if(${BUILD_WITH_COS}) + #cat("${TD_SUPPORT_DIR}/mxml_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) + #cat("${TD_SUPPORT_DIR}/apr_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) + #cat("${TD_SUPPORT_DIR}/apr-util_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) + #cat("${TD_SUPPORT_DIR}/curl_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) + cat("${TD_SUPPORT_DIR}/cos_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) + add_definitions(-DUSE_COS) +endif(${BUILD_WITH_COS}) + # lucene if(${BUILD_WITH_LUCENE}) cat("${TD_SUPPORT_DIR}/lucene_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) @@ -347,6 +390,31 @@ if (${BUILD_WITH_ROCKSDB}) endif() endif() +# cos +if(${BUILD_WITH_COS}) + if(${TD_LINUX}) + set(CMAKE_PREFIX_PATH $ENV{HOME}/.cos-local.1) + #ADD_DEFINITIONS(-DMINIXML_LIBRARY=${CMAKE_BINARY_DIR}/build/lib/libxml.a) + option(ENABLE_TEST "Enable the tests" OFF) + INCLUDE_DIRECTORIES($ENV{HOME}/.cos-local.1/include) + MESSAGE("$ENV{HOME}/.cos-local.1/include") + + set(CMAKE_BUILD_TYPE debug) + set(ORIG_CMAKE_PROJECT_NAME ${CMAKE_PROJECT_NAME}) + set(CMAKE_PROJECT_NAME cos_c_sdk) + + add_subdirectory(cos-c-sdk-v5 EXCLUDE_FROM_ALL) + target_include_directories( + cos_c_sdk + PUBLIC $ + ) + + set(CMAKE_PROJECT_NAME ${ORIG_CMAKE_PROJECT_NAME}) + else() + + endif(${TD_LINUX}) +endif(${BUILD_WITH_COS}) + # lucene # To support build on ubuntu: sudo apt-get install libboost-all-dev if(${BUILD_WITH_LUCENE}) diff --git a/contrib/test/CMakeLists.txt b/contrib/test/CMakeLists.txt index f35cf0d13d7078e6e90f52f3b49a0c579f3d856b..1deff5a67e6e2c537dbe13a4d0e174831861498d 100644 --- a/contrib/test/CMakeLists.txt +++ b/contrib/test/CMakeLists.txt @@ -3,6 +3,11 @@ if(${BUILD_WITH_ROCKSDB}) add_subdirectory(rocksdb) endif(${BUILD_WITH_ROCKSDB}) +# cos +if(${BUILD_WITH_COS}) + add_subdirectory(cos) +endif(${BUILD_WITH_COS}) + if(${BUILD_WITH_LUCENE}) add_subdirectory(lucene) endif(${BUILD_WITH_LUCENE}) diff --git a/contrib/test/cos/CMakeLists.txt b/contrib/test/cos/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f8804033de8a0fcc209d100f7ec0a42d966974f7 --- /dev/null +++ b/contrib/test/cos/CMakeLists.txt @@ -0,0 +1,49 @@ +add_executable(cosTest "") +target_sources(cosTest + PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/main.c" + ) + +#find_path(APR_INCLUDE_DIR apr-1/apr_time.h) +#find_path(APR_UTIL_INCLUDE_DIR apr/include/apr-1/apr_md5.h) +#find_path(MINIXML_INCLUDE_DIR mxml.h) +#find_path(CURL_INCLUDE_DIR curl/curl.h) + +#include_directories (${MINIXML_INCLUDE_DIR}) +#include_directories (${CURL_INCLUDE_DIR}) +FIND_PROGRAM(APR_CONFIG_BIN NAMES apr-config apr-1-config PATHS /usr/bin /usr/local/bin /usr/local/apr/bin/) +#FIND_PROGRAM(APU_CONFIG_BIN NAMES apu-config apu-1-config PATHS /usr/bin /usr/local/bin /usr/local/apr/bin/) + +IF (APR_CONFIG_BIN) + EXECUTE_PROCESS( + COMMAND ${APR_CONFIG_BIN} --includedir + OUTPUT_VARIABLE APR_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +ENDIF() +#IF (APU_CONFIG_BIN) +# EXECUTE_PROCESS( +# COMMAND ${APU_CONFIG_BIN} --includedir +# OUTPUT_VARIABLE APR_UTIL_INCLUDE_DIR +# OUTPUT_STRIP_TRAILING_WHITESPACE +# ) +#ENDIF() + +include_directories (${APR_INCLUDE_DIR}) +#include_directories (${APR_UTIL_INCLUDE_DIR}) + +target_include_directories( + cosTest + PUBLIC "${TD_SOURCE_DIR}/contrib/cos-c-sdk-v5/cos_c_sdk" + ) + +#find_library(APR_LIBRARY apr-1 PATHS /usr/local/apr/lib/) +#find_library(APR_UTIL_LIBRARY aprutil-1 PATHS /usr/local/apr/lib/) +#find_library(MINIXML_LIBRARY mxml) +#find_library(CURL_LIBRARY curl) + +target_link_libraries(cosTest cos_c_sdk) +target_link_libraries(cosTest apr-1}) +target_link_libraries(cosTest aprutil-1}) +target_link_libraries(cosTest mxml) +target_link_libraries(cosTest curl) diff --git a/contrib/test/cos/main.c b/contrib/test/cos/main.c new file mode 100644 index 0000000000000000000000000000000000000000..7e5e7c8c8bb4735af5e3e09cc9a3b3011d823d14 --- /dev/null +++ b/contrib/test/cos/main.c @@ -0,0 +1,3095 @@ +#include +#include +#include +#include + +#include "cos_api.h" +#include "cos_http_io.h" +#include "cos_log.h" + +// endpoint 是 COS 访问域名信息,详情请参见 https://cloud.tencent.com/document/product/436/6224 文档 +// static char TEST_COS_ENDPOINT[] = "cos.ap-guangzhou.myqcloud.com"; +// static char TEST_COS_ENDPOINT[] = "http://oss-cn-beijing.aliyuncs.com"; +static char TEST_COS_ENDPOINT[] = "http://cos.ap-beijing.myqcloud.com"; +// 数据万象的访问域名,详情请参见 https://cloud.tencent.com/document/product/460/31066 文档 +static char TEST_CI_ENDPOINT[] = "https://ci.ap-guangzhou.myqcloud.com"; +// 开发者拥有的项目身份ID/密钥,可在 https://console.cloud.tencent.com/cam/capi 页面获取 +static char *TEST_ACCESS_KEY_ID; // your secret_id +static char *TEST_ACCESS_KEY_SECRET; // your secret_key +// 开发者访问 COS 服务时拥有的用户维度唯一资源标识,用以标识资源,可在 https://console.cloud.tencent.com/cam/capi +// 页面获取 +// static char TEST_APPID[] = ""; // your appid +// static char TEST_APPID[] = "119"; // your appid +static char TEST_APPID[] = "1309024725"; // your appid +// the cos bucket name, syntax: [bucket]-[appid], for example: mybucket-1253666666,可在 +// https://console.cloud.tencent.com/cos5/bucket 查看 static char TEST_BUCKET_NAME[] = ""; +// static char TEST_BUCKET_NAME[] = ""; +// static char TEST_BUCKET_NAME[] = "test-bucket-119"; +static char TEST_BUCKET_NAME[] = "test0711-1309024725"; +// 对象拥有者,比如用户UIN:100000000001 +static char TEST_UIN[] = ""; // your uin +// 地域信息,枚举值可参见 https://cloud.tencent.com/document/product/436/6224 +// 文档,例如:ap-beijing、ap-hongkong、eu-frankfurt 等 +static char TEST_REGION[] = "ap-guangzhou"; // region in endpoint +// 对象键,对象(Object)在存储桶(Bucket)中的唯一标识。有关对象与对象键的进一步说明,请参见 +// https://cloud.tencent.com/document/product/436/13324 文档 +static char TEST_OBJECT_NAME1[] = "1.txt"; +static char TEST_OBJECT_NAME2[] = "test2.dat"; +static char TEST_OBJECT_NAME3[] = "test3.dat"; +static char TEST_OBJECT_NAME4[] = "multipart.txt"; +// static char TEST_DOWNLOAD_NAME2[] = "download_test2.dat"; +static char *TEST_APPEND_NAMES[] = {"test.7z.001", "test.7z.002"}; +static char TEST_DOWNLOAD_NAME3[] = "download_test3.dat"; +static char TEST_MULTIPART_OBJECT[] = "multipart.dat"; +static char TEST_DOWNLOAD_NAME4[] = "multipart_download.dat"; +static char TEST_MULTIPART_FILE[] = "test.zip"; +// static char TEST_MULTIPART_OBJECT2[] = "multipart2.dat"; +static char TEST_MULTIPART_OBJECT3[] = "multipart3.dat"; +static char TEST_MULTIPART_OBJECT4[] = "multipart4.dat"; + +static void print_headers(cos_table_t *headers) { + const cos_array_header_t *tarr; + const cos_table_entry_t *telts; + int i = 0; + + if (apr_is_empty_table(headers)) { + return; + } + + tarr = cos_table_elts(headers); + telts = (cos_table_entry_t *)tarr->elts; + + printf("headers:\n"); + for (; i < tarr->nelts; i++) { + telts = (cos_table_entry_t *)(tarr->elts + i * tarr->elt_size); + printf("%s: %s\n", telts->key, telts->val); + } +} + +void init_test_config(cos_config_t *config, int is_cname) { + cos_str_set(&config->endpoint, TEST_COS_ENDPOINT); + cos_str_set(&config->access_key_id, TEST_ACCESS_KEY_ID); + cos_str_set(&config->access_key_secret, TEST_ACCESS_KEY_SECRET); + cos_str_set(&config->appid, TEST_APPID); + config->is_cname = is_cname; +} + +void init_test_request_options(cos_request_options_t *options, int is_cname) { + options->config = cos_config_create(options->pool); + init_test_config(options->config, is_cname); + options->ctl = cos_http_controller_create(options->pool, 0); +} + +void log_status(cos_status_t *s) { + cos_warn_log("status->code: %d", s->code); + if (s->error_code) cos_warn_log("status->error_code: %s", s->error_code); + if (s->error_msg) cos_warn_log("status->error_msg: %s", s->error_msg); + if (s->req_id) cos_warn_log("status->req_id: %s", s->req_id); +} + +void test_sign() { + cos_pool_t *p = NULL; + const unsigned char secret_key[] = "your secret_key"; + const unsigned char time_str[] = "1480932292;1481012292"; + unsigned char sign_key[40]; + cos_buf_t *fmt_str; + const char *value = NULL; + const char *uri = "/testfile"; + const char *host = "testbucket-125000000.cn-north.myqcloud.com&range=bytes%3d0-3"; + unsigned char fmt_str_hex[40]; + + cos_pool_create(&p, NULL); + fmt_str = cos_create_buf(p, 1024); + + cos_get_hmac_sha1_hexdigest(sign_key, secret_key, sizeof(secret_key) - 1, time_str, sizeof(time_str) - 1); + char *pstr = apr_pstrndup(p, (char *)sign_key, sizeof(sign_key)); + cos_warn_log("sign_key: %s", pstr); + + // method + value = "get"; + cos_buf_append_string(p, fmt_str, value, strlen(value)); + cos_buf_append_string(p, fmt_str, "\n", sizeof("\n") - 1); + + // canonicalized resource(URI) + cos_buf_append_string(p, fmt_str, uri, strlen(uri)); + cos_buf_append_string(p, fmt_str, "\n", sizeof("\n") - 1); + + // query-parameters + cos_buf_append_string(p, fmt_str, "\n", sizeof("\n") - 1); + + // Host + cos_buf_append_string(p, fmt_str, "host=", sizeof("host=") - 1); + cos_buf_append_string(p, fmt_str, host, strlen(host)); + cos_buf_append_string(p, fmt_str, "\n", sizeof("\n") - 1); + + char *pstr3 = apr_pstrndup(p, (char *)fmt_str->pos, cos_buf_size(fmt_str)); + cos_warn_log("Format string: %s", pstr3); + + // Format-String sha1hash + cos_get_sha1_hexdigest(fmt_str_hex, (unsigned char *)fmt_str->pos, cos_buf_size(fmt_str)); + + char *pstr2 = apr_pstrndup(p, (char *)fmt_str_hex, sizeof(fmt_str_hex)); + cos_warn_log("Format string sha1hash: %s", pstr2); + + cos_pool_destroy(p); +} + +void test_bucket() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_acl_e cos_acl = COS_ACL_PRIVATE; + cos_string_t bucket; + cos_table_t *resp_headers = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // create test bucket + s = cos_create_bucket(options, &bucket, cos_acl, &resp_headers); + log_status(s); + + // list object (get bucket) + cos_list_object_params_t *list_params = NULL; + list_params = cos_create_list_object_params(p); + cos_str_set(&list_params->encoding_type, "url"); + s = cos_list_object(options, &bucket, list_params, &resp_headers); + log_status(s); + cos_list_object_content_t *content = NULL; + char *line = NULL; + cos_list_for_each_entry(cos_list_object_content_t, content, &list_params->object_list, node) { + line = apr_psprintf(p, "%.*s\t%.*s\t%.*s\n", content->key.len, content->key.data, content->size.len, + content->size.data, content->last_modified.len, content->last_modified.data); + printf("%s", line); + printf("next marker: %s\n", list_params->next_marker.data); + } + cos_list_object_common_prefix_t *common_prefix = NULL; + cos_list_for_each_entry(cos_list_object_common_prefix_t, common_prefix, &list_params->common_prefix_list, node) { + printf("common prefix: %s\n", common_prefix->prefix.data); + } + + // delete bucket + s = cos_delete_bucket(options, &bucket, &resp_headers); + log_status(s); + + cos_pool_destroy(p); +} + +void test_list_objects() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers = NULL; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //获取对象列表 + cos_list_object_params_t *list_params = NULL; + cos_list_object_content_t *content = NULL; + list_params = cos_create_list_object_params(p); + s = cos_list_object(options, &bucket, list_params, &resp_headers); + if (cos_status_is_ok(s)) { + printf("list object succeeded\n"); + cos_list_for_each_entry(cos_list_object_content_t, content, &list_params->object_list, node) { + printf("object: %.*s\n", content->key.len, content->key.data); + } + } else { + printf("list object failed\n"); + } + + //销毁内存池 + cos_pool_destroy(p); +} + +void test_bucket_lifecycle() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + cos_list_t rule_list; + cos_list_init(&rule_list); + cos_lifecycle_rule_content_t *rule_content = NULL; + + rule_content = cos_create_lifecycle_rule_content(p); + cos_str_set(&rule_content->id, "testrule1"); + cos_str_set(&rule_content->prefix, "abc/"); + cos_str_set(&rule_content->status, "Enabled"); + rule_content->expire.days = 365; + cos_list_add_tail(&rule_content->node, &rule_list); + + rule_content = cos_create_lifecycle_rule_content(p); + cos_str_set(&rule_content->id, "testrule2"); + cos_str_set(&rule_content->prefix, "efg/"); + cos_str_set(&rule_content->status, "Disabled"); + cos_str_set(&rule_content->transition.storage_class, "Standard_IA"); + rule_content->transition.days = 999; + cos_list_add_tail(&rule_content->node, &rule_list); + + rule_content = cos_create_lifecycle_rule_content(p); + cos_str_set(&rule_content->id, "testrule3"); + cos_str_set(&rule_content->prefix, "xxx/"); + cos_str_set(&rule_content->status, "Enabled"); + rule_content->abort.days = 1; + cos_list_add_tail(&rule_content->node, &rule_list); + + s = cos_put_bucket_lifecycle(options, &bucket, &rule_list, &resp_headers); + log_status(s); + + cos_list_t rule_list_ret; + cos_list_init(&rule_list_ret); + s = cos_get_bucket_lifecycle(options, &bucket, &rule_list_ret, &resp_headers); + log_status(s); + + cos_delete_bucket_lifecycle(options, &bucket, &resp_headers); + log_status(s); + + cos_pool_destroy(p); +} + +void test_put_object_with_limit() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + cos_table_t *resp_headers = NULL; + cos_table_t *headers = NULL; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //限速值设置范围为819200 - 838860800,即100KB/s - 100MB/s,如果超出该范围将返回400错误 + headers = cos_table_make(p, 1); + cos_table_add_int(headers, "x-cos-traffic-limit", 819200); + + //上传对象 + cos_str_set(&file, "test_file.bin"); + cos_str_set(&object, TEST_OBJECT_NAME1); + s = cos_put_object_from_file(options, &bucket, &object, &file, headers, &resp_headers); + if (cos_status_is_ok(s)) { + printf("put object succeeded\n"); + } else { + printf("put object failed\n"); + } + + //销毁内存池 + cos_pool_destroy(p); +} + +void test_get_object_with_limit() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + cos_table_t *resp_headers = NULL; + cos_table_t *headers = NULL; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //限速值设置范围为819200 - 838860800,即100KB/s - 100MB/s,如果超出该范围将返回400错误 + headers = cos_table_make(p, 1); + cos_table_add_int(headers, "x-cos-traffic-limit", 819200); + + //下载对象 + cos_str_set(&file, "test_file.bin"); + cos_str_set(&object, TEST_OBJECT_NAME1); + s = cos_get_object_to_file(options, &bucket, &object, headers, NULL, &file, &resp_headers); + if (cos_status_is_ok(s)) { + printf("get object succeeded\n"); + } else { + printf("get object failed\n"); + } + + //销毁内存池 + cos_pool_destroy(p); +} + +void test_gen_object_url() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_OBJECT_NAME1); + + printf("url:%s\n", cos_gen_object_url(options, &bucket, &object)); + + cos_pool_destroy(p); +} + +void test_create_dir() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers; + cos_table_t *headers = NULL; + cos_list_t buffer; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "folder/"); + + //上传文件夹 + cos_list_init(&buffer); + s = cos_put_object_from_buffer(options, &bucket, &object, &buffer, headers, &resp_headers); + if (cos_status_is_ok(s)) { + printf("put object succeeded\n"); + } else { + printf("put object failed\n"); + } + cos_pool_destroy(p); +} + +void test_object() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers; + cos_table_t *headers = NULL; + cos_list_t buffer; + cos_buf_t *content = NULL; + char *str = "This is my test data."; + cos_string_t file; + int traffic_limit = 0; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_OBJECT_NAME1); + + cos_list_init(&buffer); + content = cos_buf_pack(options->pool, str, strlen(str)); + cos_list_add_tail(&content->node, &buffer); + s = cos_put_object_from_buffer(options, &bucket, &object, &buffer, headers, &resp_headers); + log_status(s); + + cos_list_t download_buffer; + cos_list_init(&download_buffer); + if (traffic_limit) { + // 限速值设置范围为819200 - 838860800,即100KB/s - 100MB/s,如果超出该范围将返回400错误 + headers = cos_table_make(p, 1); + cos_table_add_int(headers, "x-cos-traffic-limit", 819200); + } + s = cos_get_object_to_buffer(options, &bucket, &object, headers, NULL, &download_buffer, &resp_headers); + log_status(s); + print_headers(resp_headers); + int64_t len = 0; + int64_t size = 0; + int64_t pos = 0; + cos_list_for_each_entry(cos_buf_t, content, &download_buffer, node) { len += cos_buf_size(content); } + char *buf = cos_pcalloc(p, (apr_size_t)(len + 1)); + buf[len] = '\0'; + cos_list_for_each_entry(cos_buf_t, content, &download_buffer, node) { + size = cos_buf_size(content); + memcpy(buf + pos, content->pos, (size_t)size); + pos += size; + } + cos_warn_log("Download data=%s", buf); + + cos_str_set(&file, TEST_OBJECT_NAME4); + cos_str_set(&object, TEST_OBJECT_NAME4); + s = cos_put_object_from_file(options, &bucket, &object, &file, NULL, &resp_headers); + log_status(s); + + cos_str_set(&file, TEST_DOWNLOAD_NAME3); + cos_str_set(&object, TEST_OBJECT_NAME3); + s = cos_get_object_to_file(options, &bucket, &object, NULL, NULL, &file, &resp_headers); + log_status(s); + + cos_str_set(&object, TEST_OBJECT_NAME2); + s = cos_head_object(options, &bucket, &object, NULL, &resp_headers); + log_status(s); + + cos_str_set(&object, TEST_OBJECT_NAME1); + s = cos_delete_object(options, &bucket, &object, &resp_headers); + log_status(s); + + cos_str_set(&object, TEST_OBJECT_NAME3); + s = cos_delete_object(options, &bucket, &object, &resp_headers); + log_status(s); + + cos_pool_destroy(p); +} + +void test_append_object() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + cos_table_t *resp_headers = NULL; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //追加上传对象 + cos_str_set(&object, TEST_OBJECT_NAME3); + int32_t count = sizeof(TEST_APPEND_NAMES) / sizeof(char *); + int32_t index = 0; + int64_t position = 0; + s = cos_head_object(options, &bucket, &object, NULL, &resp_headers); + if (s->code == 200) { + char *content_length_str = (char *)apr_table_get(resp_headers, COS_CONTENT_LENGTH); + if (content_length_str != NULL) { + position = atol(content_length_str); + } + } + for (; index < count; index++) { + cos_str_set(&file, TEST_APPEND_NAMES[index]); + s = cos_append_object_from_file(options, &bucket, &object, position, &file, NULL, &resp_headers); + log_status(s); + + s = cos_head_object(options, &bucket, &object, NULL, &resp_headers); + if (s->code == 200) { + char *content_length_str = (char *)apr_table_get(resp_headers, COS_CONTENT_LENGTH); + if (content_length_str != NULL) { + position = atol(content_length_str); + } + } + } + + //销毁内存池 + cos_pool_destroy(p); +} + +void test_head_object() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers = NULL; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //获取对象元数据 + cos_str_set(&object, TEST_OBJECT_NAME1); + s = cos_head_object(options, &bucket, &object, NULL, &resp_headers); + print_headers(resp_headers); + if (cos_status_is_ok(s)) { + long size = 0; + char *content_length_str = (char *)apr_table_get(resp_headers, COS_CONTENT_LENGTH); + if (content_length_str != NULL) { + size = atol(content_length_str); + } + printf("head object succeeded: %ld\n", size); + } else { + printf("head object failed\n"); + } + + //销毁内存池 + cos_pool_destroy(p); +} + +void test_check_object_exist() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers; + cos_table_t *headers = NULL; + cos_object_exist_status_e object_exist; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_OBJECT_NAME1); + + // 检查对象是否存在 + s = cos_check_object_exist(options, &bucket, &object, headers, &object_exist, &resp_headers); + if (object_exist == COS_OBJECT_NON_EXIST) { + printf("object: %.*s non exist.\n", object.len, object.data); + } else if (object_exist == COS_OBJECT_EXIST) { + printf("object: %.*s exist.\n", object.len, object.data); + } else { + printf("object: %.*s unknown status.\n", object.len, object.data); + log_status(s); + } + + cos_pool_destroy(p); +} + +void test_object_restore() { + cos_pool_t *p = NULL; + cos_string_t bucket; + cos_string_t object; + int is_cname = 0; + cos_table_t *resp_headers = NULL; + cos_request_options_t *options = NULL; + cos_status_t *s = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "test_restore.dat"); + + cos_object_restore_params_t *restore_params = cos_create_object_restore_params(p); + restore_params->days = 30; + cos_str_set(&restore_params->tier, "Standard"); + s = cos_post_object_restore(options, &bucket, &object, restore_params, NULL, NULL, &resp_headers); + log_status(s); + + cos_pool_destroy(p); +} + +void progress_callback(int64_t consumed_bytes, int64_t total_bytes) { + printf("consumed_bytes = %" APR_INT64_T_FMT ", total_bytes = %" APR_INT64_T_FMT "\n", consumed_bytes, total_bytes); +} + +void test_put_object_from_file() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers; + cos_string_t file; + int traffic_limit = 0; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_table_t *headers = NULL; + if (traffic_limit) { + // 限速值设置范围为819200 - 838860800,即100KB/s - 100MB/s,如果超出该范围将返回400错误 + headers = cos_table_make(p, 1); + cos_table_add_int(headers, "x-cos-traffic-limit", 819200); + } + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&file, TEST_OBJECT_NAME4); + cos_str_set(&object, TEST_OBJECT_NAME4); + s = cos_put_object_from_file(options, &bucket, &object, &file, headers, &resp_headers); + log_status(s); + + cos_pool_destroy(p); +} + +void test_put_object_from_file_with_sse() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers; + cos_string_t file; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_table_t *headers = NULL; + headers = cos_table_make(p, 3); + // apr_table_add(headers, "x-cos-server-side-encryption", "AES256"); + apr_table_add(headers, "x-cos-server-side-encryption-customer-algorithm", "AES256"); + apr_table_add(headers, "x-cos-server-side-encryption-customer-key", "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY="); + apr_table_add(headers, "x-cos-server-side-encryption-customer-key-MD5", "U5L61r7jcwdNvT7frmUG8g=="); + + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&file, "/home/jojoliang/data/test.jpg"); + cos_str_set(&object, "pic"); + + s = cos_put_object_from_file(options, &bucket, &object, &file, headers, &resp_headers); + log_status(s); + { + int i = 0; + apr_array_header_t *pp = (apr_array_header_t *)apr_table_elts(resp_headers); + for (; i < pp->nelts; i++) { + apr_table_entry_t *ele = (apr_table_entry_t *)pp->elts + i; + printf("%s: %s\n", ele->key, ele->val); + } + } + + cos_pool_destroy(p); +} + +void test_get_object_to_file_with_sse() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers; + cos_string_t file; + cos_table_t *headers = NULL; + cos_table_t *params = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + headers = cos_table_make(p, 3); + /* + apr_table_add(headers, "x-cos-server-side-encryption", "AES256"); + */ + /* + apr_table_add(headers, "x-cos-server-side-encryption-customer-algorithm", "AES256"); + apr_table_add(headers, "x-cos-server-side-encryption-customer-key", + "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUY="); apr_table_add(headers, + "x-cos-server-side-encryption-customer-key-MD5", "U5L61r7jcwdNvT7frmUG8g=="); + */ + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&file, "getfile"); + cos_str_set(&object, TEST_OBJECT_NAME1); + + s = cos_get_object_to_file(options, &bucket, &object, headers, params, &file, &resp_headers); + log_status(s); + + { + int i = 0; + apr_array_header_t *pp = (apr_array_header_t *)apr_table_elts(resp_headers); + for (; i < pp->nelts; i++) { + apr_table_entry_t *ele = (apr_table_entry_t *)pp->elts + i; + printf("%s: %s\n", ele->key, ele->val); + } + } + + cos_pool_destroy(p); +} + +void multipart_upload_file_from_file() { + cos_pool_t *p = NULL; + cos_string_t bucket; + cos_string_t object; + int is_cname = 0; + cos_table_t *headers = NULL; + cos_table_t *complete_headers = NULL; + cos_table_t *resp_headers = NULL; + cos_request_options_t *options = NULL; + cos_string_t upload_id; + cos_upload_file_t *upload_file = NULL; + cos_status_t *s = NULL; + cos_list_upload_part_params_t *params = NULL; + cos_list_t complete_part_list; + cos_list_part_content_t *part_content = NULL; + cos_complete_part_content_t *complete_part_content = NULL; + int part_num = 1; + int64_t pos = 0; + int64_t file_length = 0; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + headers = cos_table_make(p, 1); + complete_headers = cos_table_make(p, 1); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_MULTIPART_OBJECT); + + // init mulitipart + s = cos_init_multipart_upload(options, &bucket, &object, &upload_id, headers, &resp_headers); + + if (cos_status_is_ok(s)) { + printf("Init multipart upload succeeded, upload_id:%.*s\n", upload_id.len, upload_id.data); + } else { + printf("Init multipart upload failed\n"); + cos_pool_destroy(p); + return; + } + + // upload part from file + int res = COSE_OK; + cos_file_buf_t *fb = cos_create_file_buf(p); + res = cos_open_file_for_all_read(p, TEST_MULTIPART_FILE, fb); + if (res != COSE_OK) { + cos_error_log("Open read file fail, filename:%s\n", TEST_MULTIPART_FILE); + return; + } + file_length = fb->file_last; + apr_file_close(fb->file); + while (pos < file_length) { + upload_file = cos_create_upload_file(p); + cos_str_set(&upload_file->filename, TEST_MULTIPART_FILE); + upload_file->file_pos = pos; + pos += 2 * 1024 * 1024; + upload_file->file_last = pos < file_length ? pos : file_length; // 2MB + s = cos_upload_part_from_file(options, &bucket, &object, &upload_id, part_num++, upload_file, &resp_headers); + + if (cos_status_is_ok(s)) { + printf("Multipart upload part from file succeeded\n"); + } else { + printf("Multipart upload part from file failed\n"); + } + } + + // list part + params = cos_create_list_upload_part_params(p); + params->max_ret = 1000; + cos_list_init(&complete_part_list); + s = cos_list_upload_part(options, &bucket, &object, &upload_id, params, &resp_headers); + + if (cos_status_is_ok(s)) { + printf("List multipart succeeded\n"); + cos_list_for_each_entry(cos_list_part_content_t, part_content, ¶ms->part_list, node) { + printf("part_number = %s, size = %s, last_modified = %s, etag = %s\n", part_content->part_number.data, + part_content->size.data, part_content->last_modified.data, part_content->etag.data); + } + } else { + printf("List multipart failed\n"); + cos_pool_destroy(p); + return; + } + + cos_list_for_each_entry(cos_list_part_content_t, part_content, ¶ms->part_list, node) { + complete_part_content = cos_create_complete_part_content(p); + cos_str_set(&complete_part_content->part_number, part_content->part_number.data); + cos_str_set(&complete_part_content->etag, part_content->etag.data); + cos_list_add_tail(&complete_part_content->node, &complete_part_list); + } + + // complete multipart + s = cos_complete_multipart_upload(options, &bucket, &object, &upload_id, &complete_part_list, complete_headers, + &resp_headers); + + if (cos_status_is_ok(s)) { + printf("Complete multipart upload from file succeeded, upload_id:%.*s\n", upload_id.len, upload_id.data); + } else { + printf("Complete multipart upload from file failed\n"); + } + + cos_pool_destroy(p); +} + +void multipart_upload_file_from_buffer() { + cos_pool_t *p = NULL; + cos_string_t bucket; + cos_string_t object; + int is_cname = 0; + cos_table_t *headers = NULL; + cos_table_t *complete_headers = NULL; + cos_table_t *resp_headers = NULL; + cos_request_options_t *options = NULL; + cos_string_t upload_id; + cos_status_t *s = NULL; + cos_list_t complete_part_list; + cos_complete_part_content_t *complete_part_content = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + headers = cos_table_make(p, 1); + complete_headers = cos_table_make(p, 1); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_MULTIPART_OBJECT); + + // init mulitipart + s = cos_init_multipart_upload(options, &bucket, &object, &upload_id, headers, &resp_headers); + + if (cos_status_is_ok(s)) { + printf("Init multipart upload succeeded, upload_id:%.*s\n", upload_id.len, upload_id.data); + } else { + printf("Init multipart upload failed\n"); + cos_pool_destroy(p); + return; + } + + // upload part from buffer + char *str = "This is my test data...."; + cos_list_t buffer; + cos_buf_t *content; + + // 上传一个分块 + cos_list_init(&buffer); + content = cos_buf_pack(p, str, strlen(str)); + cos_list_add_tail(&content->node, &buffer); + s = cos_upload_part_from_buffer(options, &bucket, &object, &upload_id, 1, &buffer, &resp_headers); + + // 直接获取etag + char *etag = apr_pstrdup(p, (char *)apr_table_get(resp_headers, "ETag")); + cos_list_init(&complete_part_list); + complete_part_content = cos_create_complete_part_content(p); + cos_str_set(&complete_part_content->part_number, "1"); + cos_str_set(&complete_part_content->etag, etag); + cos_list_add_tail(&complete_part_content->node, &complete_part_list); + + // 也可以通过 list part 获取取etag + /* + //list part + params = cos_create_list_upload_part_params(p); + params->max_ret = 1000; + cos_list_init(&complete_part_list); + s = cos_list_upload_part(options, &bucket, &object, &upload_id, + params, &resp_headers); + + if (cos_status_is_ok(s)) { + printf("List multipart succeeded\n"); + cos_list_for_each_entry(cos_list_part_content_t, part_content, ¶ms->part_list, node) { + printf("part_number = %s, size = %s, last_modified = %s, etag = %s\n", + part_content->part_number.data, + part_content->size.data, + part_content->last_modified.data, + part_content->etag.data); + } + } else { + printf("List multipart failed\n"); + cos_pool_destroy(p); + return; + } + + cos_list_for_each_entry(cos_list_part_content_t, part_content, ¶ms->part_list, node) { + complete_part_content = cos_create_complete_part_content(p); + cos_str_set(&complete_part_content->part_number, part_content->part_number.data); + cos_str_set(&complete_part_content->etag, part_content->etag.data); + cos_list_add_tail(&complete_part_content->node, &complete_part_list); + } + */ + + // complete multipart + s = cos_complete_multipart_upload(options, &bucket, &object, &upload_id, &complete_part_list, complete_headers, + &resp_headers); + + if (cos_status_is_ok(s)) { + printf("Complete multipart upload from file succeeded, upload_id:%.*s\n", upload_id.len, upload_id.data); + } else { + printf("Complete multipart upload from file failed\n"); + } + + cos_pool_destroy(p); +} + +void abort_multipart_upload() { + cos_pool_t *p = NULL; + cos_string_t bucket; + cos_string_t object; + int is_cname = 0; + cos_table_t *headers = NULL; + cos_table_t *resp_headers = NULL; + cos_request_options_t *options = NULL; + cos_string_t upload_id; + cos_status_t *s = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + headers = cos_table_make(p, 1); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_MULTIPART_OBJECT); + + s = cos_init_multipart_upload(options, &bucket, &object, &upload_id, headers, &resp_headers); + + if (cos_status_is_ok(s)) { + printf("Init multipart upload succeeded, upload_id:%.*s\n", upload_id.len, upload_id.data); + } else { + printf("Init multipart upload failed\n"); + cos_pool_destroy(p); + return; + } + + s = cos_abort_multipart_upload(options, &bucket, &object, &upload_id, &resp_headers); + + if (cos_status_is_ok(s)) { + printf("Abort multipart upload succeeded, upload_id::%.*s\n", upload_id.len, upload_id.data); + } else { + printf("Abort multipart upload failed\n"); + } + + cos_pool_destroy(p); +} + +void list_multipart() { + cos_pool_t *p = NULL; + cos_string_t bucket; + cos_string_t object; + int is_cname = 0; + cos_table_t *resp_headers = NULL; + cos_request_options_t *options = NULL; + cos_status_t *s = NULL; + cos_list_multipart_upload_params_t *list_multipart_params = NULL; + cos_list_upload_part_params_t *list_upload_param = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + list_multipart_params = cos_create_list_multipart_upload_params(p); + list_multipart_params->max_ret = 999; + s = cos_list_multipart_upload(options, &bucket, list_multipart_params, &resp_headers); + log_status(s); + + list_upload_param = cos_create_list_upload_part_params(p); + list_upload_param->max_ret = 1000; + cos_string_t upload_id; + cos_str_set(&upload_id, "149373379126aee264fecbf5fe8ddb8b9cd23b76c73ab1af0bcfd50683cc4254f81ebe2386"); + cos_str_set(&object, TEST_MULTIPART_OBJECT); + s = cos_list_upload_part(options, &bucket, &object, &upload_id, list_upload_param, &resp_headers); + if (cos_status_is_ok(s)) { + printf("List upload part succeeded, upload_id::%.*s\n", upload_id.len, upload_id.data); + cos_list_part_content_t *part_content = NULL; + cos_list_for_each_entry(cos_list_part_content_t, part_content, &list_upload_param->part_list, node) { + printf("part_number = %s, size = %s, last_modified = %s, etag = %s\n", part_content->part_number.data, + part_content->size.data, part_content->last_modified.data, part_content->etag.data); + } + } else { + printf("List upload part failed\n"); + } + + cos_pool_destroy(p); +} + +void test_resumable() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t filepath; + cos_resumable_clt_params_t *clt_params; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_MULTIPART_OBJECT4); + cos_str_set(&filepath, TEST_DOWNLOAD_NAME4); + + clt_params = cos_create_resumable_clt_params_content(p, 5 * 1024 * 1024, 3, COS_FALSE, NULL); + s = cos_resumable_download_file(options, &bucket, &object, &filepath, NULL, NULL, clt_params, NULL); + log_status(s); + + cos_pool_destroy(p); +} + +void test_resumable_upload_with_multi_threads() { + cos_pool_t *p = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t filename; + cos_status_t *s = NULL; + int is_cname = 0; + cos_table_t *headers = NULL; + cos_table_t *resp_headers = NULL; + cos_request_options_t *options = NULL; + cos_resumable_clt_params_t *clt_params; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + headers = cos_table_make(p, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_MULTIPART_OBJECT4); + cos_str_set(&filename, TEST_MULTIPART_FILE); + + // upload + clt_params = cos_create_resumable_clt_params_content(p, 1024 * 1024, 8, COS_FALSE, NULL); + s = cos_resumable_upload_file(options, &bucket, &object, &filename, headers, NULL, clt_params, NULL, &resp_headers, + NULL); + + if (cos_status_is_ok(s)) { + printf("upload succeeded\n"); + } else { + printf("upload failed\n"); + } + + cos_pool_destroy(p); +} + +void test_delete_objects() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_string_t bucket; + cos_status_t *s = NULL; + cos_table_t *resp_headers = NULL; + cos_request_options_t *options = NULL; + char *object_name1 = TEST_OBJECT_NAME2; + char *object_name2 = TEST_OBJECT_NAME3; + cos_object_key_t *content1 = NULL; + cos_object_key_t *content2 = NULL; + cos_list_t object_list; + cos_list_t deleted_object_list; + int is_quiet = COS_TRUE; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + cos_list_init(&object_list); + cos_list_init(&deleted_object_list); + content1 = cos_create_cos_object_key(p); + cos_str_set(&content1->key, object_name1); + cos_list_add_tail(&content1->node, &object_list); + content2 = cos_create_cos_object_key(p); + cos_str_set(&content2->key, object_name2); + cos_list_add_tail(&content2->node, &object_list); + + s = cos_delete_objects(options, &bucket, &object_list, is_quiet, &resp_headers, &deleted_object_list); + log_status(s); + + cos_pool_destroy(p); + + if (cos_status_is_ok(s)) { + printf("delete objects succeeded\n"); + } else { + printf("delete objects failed\n"); + } +} + +void test_delete_objects_by_prefix() { + cos_pool_t *p = NULL; + cos_request_options_t *options = NULL; + int is_cname = 0; + cos_string_t bucket; + cos_status_t *s = NULL; + cos_string_t prefix; + char *prefix_str = ""; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&prefix, prefix_str); + + s = cos_delete_objects_by_prefix(options, &bucket, &prefix); + log_status(s); + cos_pool_destroy(p); + + printf("test_delete_object_by_prefix ok\n"); +} + +void test_acl() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_acl_e cos_acl = COS_ACL_PRIVATE; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "test.txt"); + + // put acl + cos_string_t read; + cos_str_set(&read, "id=\"qcs::cam::uin/12345:uin/12345\", id=\"qcs::cam::uin/45678:uin/45678\""); + s = cos_put_bucket_acl(options, &bucket, cos_acl, &read, NULL, NULL, &resp_headers); + log_status(s); + + // get acl + cos_acl_params_t *acl_params = NULL; + acl_params = cos_create_acl_params(p); + s = cos_get_bucket_acl(options, &bucket, acl_params, &resp_headers); + log_status(s); + printf("acl owner id:%s, name:%s\n", acl_params->owner_id.data, acl_params->owner_name.data); + cos_acl_grantee_content_t *acl_content = NULL; + cos_list_for_each_entry(cos_acl_grantee_content_t, acl_content, &acl_params->grantee_list, node) { + printf("acl grantee type:%s, id:%s, name:%s, permission:%s\n", acl_content->type.data, acl_content->id.data, + acl_content->name.data, acl_content->permission.data); + } + + // put acl + s = cos_put_object_acl(options, &bucket, &object, cos_acl, &read, NULL, NULL, &resp_headers); + log_status(s); + + // get acl + cos_acl_params_t *acl_params2 = NULL; + acl_params2 = cos_create_acl_params(p); + s = cos_get_object_acl(options, &bucket, &object, acl_params2, &resp_headers); + log_status(s); + printf("acl owner id:%s, name:%s\n", acl_params2->owner_id.data, acl_params2->owner_name.data); + acl_content = NULL; + cos_list_for_each_entry(cos_acl_grantee_content_t, acl_content, &acl_params2->grantee_list, node) { + printf("acl grantee id:%s, name:%s, permission:%s\n", acl_content->id.data, acl_content->name.data, + acl_content->permission.data); + } + + cos_pool_destroy(p); +} + +void test_copy() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t src_bucket; + cos_string_t src_object; + cos_string_t src_endpoint; + cos_table_t *resp_headers = NULL; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //设置对象复制 + cos_str_set(&object, TEST_OBJECT_NAME2); + cos_str_set(&src_bucket, TEST_BUCKET_NAME); + cos_str_set(&src_endpoint, TEST_COS_ENDPOINT); + cos_str_set(&src_object, TEST_OBJECT_NAME1); + + cos_copy_object_params_t *params = NULL; + params = cos_create_copy_object_params(p); + s = cos_copy_object(options, &src_bucket, &src_object, &src_endpoint, &bucket, &object, NULL, params, &resp_headers); + if (cos_status_is_ok(s)) { + printf("put object copy succeeded\n"); + } else { + printf("put object copy failed\n"); + } + + //销毁内存池 + cos_pool_destroy(p); +} + +void test_modify_storage_class() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t src_bucket; + cos_string_t src_object; + cos_string_t src_endpoint; + cos_table_t *resp_headers = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_OBJECT_NAME1); + cos_str_set(&src_bucket, TEST_BUCKET_NAME); + cos_str_set(&src_endpoint, TEST_COS_ENDPOINT); + cos_str_set(&src_object, TEST_OBJECT_NAME1); + + // 设置x-cos-metadata-directive和x-cos-storage-class头域(替换为自己要更改的存储类型) + cos_table_t *headers = cos_table_make(p, 2); + apr_table_add(headers, "x-cos-metadata-directive", "Replaced"); + // 存储类型包括NTELLIGENT_TIERING,MAZ_INTELLIGENT_TIERING,STANDARD_IA,ARCHIVE,DEEP_ARCHIVE + apr_table_add(headers, "x-cos-storage-class", "ARCHIVE"); + + cos_copy_object_params_t *params = NULL; + params = cos_create_copy_object_params(p); + s = cos_copy_object(options, &src_bucket, &src_object, &src_endpoint, &bucket, &object, headers, params, + &resp_headers); + log_status(s); + + cos_pool_destroy(p); +} + +void test_copy_mt() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t src_bucket; + cos_string_t src_object; + cos_string_t src_endpoint; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "test_copy.txt"); + cos_str_set(&src_bucket, "mybucket-1253685564"); + cos_str_set(&src_endpoint, "cn-south.myqcloud.com"); + cos_str_set(&src_object, "test.txt"); + + s = cos_upload_object_by_part_copy_mt(options, &src_bucket, &src_object, &src_endpoint, &bucket, &object, 1024 * 1024, + 8, NULL); + log_status(s); + + cos_pool_destroy(p); +} + +void test_copy_with_part_copy() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t copy_source; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "test_copy.txt"); + cos_str_set(©_source, "mybucket-1253685564.cn-south.myqcloud.com/test.txt"); + + s = cos_upload_object_by_part_copy(options, ©_source, &bucket, &object, 1024 * 1024); + log_status(s); + + cos_pool_destroy(p); +} + +void make_rand_string(cos_pool_t *p, int len, cos_string_t *data) { + char *str = NULL; + int i = 0; + str = (char *)cos_palloc(p, len + 1); + for (; i < len; i++) { + str[i] = 'a' + rand() % 32; + } + str[len] = '\0'; + cos_str_set(data, str); +} + +unsigned long get_file_size(const char *file_path) { + unsigned long filesize = -1; + struct stat statbuff; + + if (stat(file_path, &statbuff) < 0) { + return filesize; + } else { + filesize = statbuff.st_size; + } + + return filesize; +} + +void test_part_copy() { + cos_pool_t *p = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + int is_cname = 0; + cos_string_t upload_id; + cos_list_upload_part_params_t *list_upload_part_params = NULL; + cos_upload_part_copy_params_t *upload_part_copy_params1 = NULL; + cos_upload_part_copy_params_t *upload_part_copy_params2 = NULL; + cos_table_t *headers = NULL; + cos_table_t *query_params = NULL; + cos_table_t *resp_headers = NULL; + cos_table_t *list_part_resp_headers = NULL; + cos_list_t complete_part_list; + cos_list_part_content_t *part_content = NULL; + cos_complete_part_content_t *complete_content = NULL; + cos_table_t *complete_resp_headers = NULL; + cos_status_t *s = NULL; + int part1 = 1; + int part2 = 2; + char *local_filename = "test_upload_part_copy.file"; + char *download_filename = "test_upload_part_copy.file.download"; + char *source_object_name = "cos_test_upload_part_copy_source_object"; + char *dest_object_name = "cos_test_upload_part_copy_dest_object"; + FILE *fd = NULL; + cos_string_t download_file; + cos_string_t dest_bucket; + cos_string_t dest_object; + int64_t range_start1 = 0; + int64_t range_end1 = 6000000; + int64_t range_start2 = 6000001; + int64_t range_end2; + cos_string_t data; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + + // create multipart upload local file + make_rand_string(p, 10 * 1024 * 1024, &data); + fd = fopen(local_filename, "w"); + fwrite(data.data, sizeof(data.data[0]), data.len, fd); + fclose(fd); + + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, source_object_name); + cos_str_set(&file, local_filename); + s = cos_put_object_from_file(options, &bucket, &object, &file, NULL, &resp_headers); + log_status(s); + + // init mulitipart + cos_str_set(&object, dest_object_name); + s = cos_init_multipart_upload(options, &bucket, &object, &upload_id, NULL, &resp_headers); + log_status(s); + + // upload part copy 1 + upload_part_copy_params1 = cos_create_upload_part_copy_params(p); + cos_str_set(&upload_part_copy_params1->copy_source, + "bucket-appid.cn-south.myqcloud.com/cos_test_upload_part_copy_source_object"); + cos_str_set(&upload_part_copy_params1->dest_bucket, TEST_BUCKET_NAME); + cos_str_set(&upload_part_copy_params1->dest_object, dest_object_name); + cos_str_set(&upload_part_copy_params1->upload_id, upload_id.data); + upload_part_copy_params1->part_num = part1; + upload_part_copy_params1->range_start = range_start1; + upload_part_copy_params1->range_end = range_end1; + headers = cos_table_make(p, 0); + s = cos_upload_part_copy(options, upload_part_copy_params1, headers, &resp_headers); + log_status(s); + printf("last modified:%s, etag:%s\n", upload_part_copy_params1->rsp_content->last_modify.data, + upload_part_copy_params1->rsp_content->etag.data); + + // upload part copy 2 + resp_headers = NULL; + range_end2 = get_file_size(local_filename) - 1; + upload_part_copy_params2 = cos_create_upload_part_copy_params(p); + cos_str_set(&upload_part_copy_params2->copy_source, + "bucket-appid.cn-south.myqcloud.com/cos_test_upload_part_copy_source_object"); + cos_str_set(&upload_part_copy_params2->dest_bucket, TEST_BUCKET_NAME); + cos_str_set(&upload_part_copy_params2->dest_object, dest_object_name); + cos_str_set(&upload_part_copy_params2->upload_id, upload_id.data); + upload_part_copy_params2->part_num = part2; + upload_part_copy_params2->range_start = range_start2; + upload_part_copy_params2->range_end = range_end2; + headers = cos_table_make(p, 0); + s = cos_upload_part_copy(options, upload_part_copy_params2, headers, &resp_headers); + log_status(s); + printf("last modified:%s, etag:%s\n", upload_part_copy_params1->rsp_content->last_modify.data, + upload_part_copy_params1->rsp_content->etag.data); + + // list part + list_upload_part_params = cos_create_list_upload_part_params(p); + list_upload_part_params->max_ret = 10; + cos_list_init(&complete_part_list); + + cos_str_set(&dest_bucket, TEST_BUCKET_NAME); + cos_str_set(&dest_object, dest_object_name); + s = cos_list_upload_part(options, &dest_bucket, &dest_object, &upload_id, list_upload_part_params, + &list_part_resp_headers); + log_status(s); + cos_list_for_each_entry(cos_list_part_content_t, part_content, &list_upload_part_params->part_list, node) { + complete_content = cos_create_complete_part_content(p); + cos_str_set(&complete_content->part_number, part_content->part_number.data); + cos_str_set(&complete_content->etag, part_content->etag.data); + cos_list_add_tail(&complete_content->node, &complete_part_list); + } + + // complete multipart + headers = cos_table_make(p, 0); + s = cos_complete_multipart_upload(options, &dest_bucket, &dest_object, &upload_id, &complete_part_list, headers, + &complete_resp_headers); + log_status(s); + + // check upload copy part content equal to local file + headers = cos_table_make(p, 0); + cos_str_set(&download_file, download_filename); + s = cos_get_object_to_file(options, &dest_bucket, &dest_object, headers, query_params, &download_file, &resp_headers); + log_status(s); + printf("local file len = %" APR_INT64_T_FMT ", download file len = %" APR_INT64_T_FMT, get_file_size(local_filename), + get_file_size(download_filename)); + remove(download_filename); + remove(local_filename); + cos_pool_destroy(p); + + printf("test part copy ok\n"); +} + +void test_cors() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + cos_list_t rule_list; + cos_list_init(&rule_list); + cos_cors_rule_content_t *rule_content = NULL; + + rule_content = cos_create_cors_rule_content(p); + cos_str_set(&rule_content->id, "testrule1"); + cos_str_set(&rule_content->allowed_origin, "http://www.qq1.com"); + cos_str_set(&rule_content->allowed_method, "GET"); + cos_str_set(&rule_content->allowed_header, "*"); + cos_str_set(&rule_content->expose_header, "xxx"); + rule_content->max_age_seconds = 3600; + cos_list_add_tail(&rule_content->node, &rule_list); + + rule_content = cos_create_cors_rule_content(p); + cos_str_set(&rule_content->id, "testrule2"); + cos_str_set(&rule_content->allowed_origin, "http://www.qq2.com"); + cos_str_set(&rule_content->allowed_method, "GET"); + cos_str_set(&rule_content->allowed_header, "*"); + cos_str_set(&rule_content->expose_header, "yyy"); + rule_content->max_age_seconds = 7200; + cos_list_add_tail(&rule_content->node, &rule_list); + + rule_content = cos_create_cors_rule_content(p); + cos_str_set(&rule_content->id, "testrule3"); + cos_str_set(&rule_content->allowed_origin, "http://www.qq3.com"); + cos_str_set(&rule_content->allowed_method, "GET"); + cos_str_set(&rule_content->allowed_header, "*"); + cos_str_set(&rule_content->expose_header, "zzz"); + rule_content->max_age_seconds = 60; + cos_list_add_tail(&rule_content->node, &rule_list); + + // put cors + s = cos_put_bucket_cors(options, &bucket, &rule_list, &resp_headers); + log_status(s); + + // get cors + cos_list_t rule_list_ret; + cos_list_init(&rule_list_ret); + s = cos_get_bucket_cors(options, &bucket, &rule_list_ret, &resp_headers); + log_status(s); + cos_cors_rule_content_t *content = NULL; + cos_list_for_each_entry(cos_cors_rule_content_t, content, &rule_list_ret, node) { + printf( + "cors id:%s, allowed_origin:%s, allowed_method:%s, allowed_header:%s, expose_header:%s, max_age_seconds:%d\n", + content->id.data, content->allowed_origin.data, content->allowed_method.data, content->allowed_header.data, + content->expose_header.data, content->max_age_seconds); + } + + // delete cors + cos_delete_bucket_cors(options, &bucket, &resp_headers); + log_status(s); + + cos_pool_destroy(p); +} + +void test_versioning() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + cos_versioning_content_t *versioning = NULL; + versioning = cos_create_versioning_content(p); + cos_str_set(&versioning->status, "Suspended"); + + // put bucket versioning + s = cos_put_bucket_versioning(options, &bucket, versioning, &resp_headers); + log_status(s); + + // get bucket versioning + cos_str_set(&versioning->status, ""); + s = cos_get_bucket_versioning(options, &bucket, versioning, &resp_headers); + log_status(s); + printf("bucket versioning status: %s\n", versioning->status.data); + + cos_pool_destroy(p); +} + +void test_replication() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_request_options_t *dst_options = NULL; + cos_string_t bucket; + cos_string_t dst_bucket; + cos_table_t *resp_headers = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&dst_bucket, "replicationtest"); + + dst_options = cos_request_options_create(p); + init_test_request_options(dst_options, is_cname); + cos_str_set(&dst_options->config->endpoint, "cn-east.myqcloud.com"); + + // enable bucket versioning + cos_versioning_content_t *versioning = NULL; + versioning = cos_create_versioning_content(p); + cos_str_set(&versioning->status, "Enabled"); + s = cos_put_bucket_versioning(options, &bucket, versioning, &resp_headers); + log_status(s); + s = cos_put_bucket_versioning(dst_options, &dst_bucket, versioning, &resp_headers); + log_status(s); + + cos_replication_params_t *replication_param = NULL; + replication_param = cos_create_replication_params(p); + cos_str_set(&replication_param->role, "qcs::cam::uin/100000616666:uin/100000616666"); + + cos_replication_rule_content_t *rule = NULL; + rule = cos_create_replication_rule_content(p); + cos_str_set(&rule->id, "Rule_01"); + cos_str_set(&rule->status, "Enabled"); + cos_str_set(&rule->prefix, "test1"); + cos_str_set(&rule->dst_bucket, "qcs:id/0:cos:cn-east:appid/1253686666:replicationtest"); + cos_list_add_tail(&rule->node, &replication_param->rule_list); + + rule = cos_create_replication_rule_content(p); + cos_str_set(&rule->id, "Rule_02"); + cos_str_set(&rule->status, "Disabled"); + cos_str_set(&rule->prefix, "test2"); + cos_str_set(&rule->storage_class, "Standard_IA"); + cos_str_set(&rule->dst_bucket, "qcs:id/0:cos:cn-east:appid/1253686666:replicationtest"); + cos_list_add_tail(&rule->node, &replication_param->rule_list); + + rule = cos_create_replication_rule_content(p); + cos_str_set(&rule->id, "Rule_03"); + cos_str_set(&rule->status, "Enabled"); + cos_str_set(&rule->prefix, "test3"); + cos_str_set(&rule->storage_class, "Standard_IA"); + cos_str_set(&rule->dst_bucket, "qcs:id/0:cos:cn-east:appid/1253686666:replicationtest"); + cos_list_add_tail(&rule->node, &replication_param->rule_list); + + // put bucket replication + s = cos_put_bucket_replication(options, &bucket, replication_param, &resp_headers); + log_status(s); + + // get bucket replication + cos_replication_params_t *replication_param2 = NULL; + replication_param2 = cos_create_replication_params(p); + s = cos_get_bucket_replication(options, &bucket, replication_param2, &resp_headers); + log_status(s); + printf("ReplicationConfiguration role: %s\n", replication_param2->role.data); + cos_replication_rule_content_t *content = NULL; + cos_list_for_each_entry(cos_replication_rule_content_t, content, &replication_param2->rule_list, node) { + printf("ReplicationConfiguration rule, id:%s, status:%s, prefix:%s, dst_bucket:%s, storage_class:%s\n", + content->id.data, content->status.data, content->prefix.data, content->dst_bucket.data, + content->storage_class.data); + } + + // delete bucket replication + s = cos_delete_bucket_replication(options, &bucket, &resp_headers); + log_status(s); + + // disable bucket versioning + cos_str_set(&versioning->status, "Suspended"); + s = cos_put_bucket_versioning(options, &bucket, versioning, &resp_headers); + log_status(s); + s = cos_put_bucket_versioning(dst_options, &dst_bucket, versioning, &resp_headers); + log_status(s); + + cos_pool_destroy(p); +} + +void test_presigned_url() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t presigned_url; + cos_table_t *params = NULL; + cos_table_t *headers = NULL; + int sign_host = 1; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_OBJECT_NAME1); + + cos_gen_presigned_url(options, &bucket, &object, 300, HTTP_GET, &presigned_url); + printf("presigned_url: %s\n", presigned_url.data); + + // 添加您自己的params和headers + params = cos_table_make(options->pool, 0); + // cos_table_add(params, "param1", "value"); + headers = cos_table_make(options->pool, 0); + // cos_table_add(headers, "header1", "value"); + + // 强烈建议sign_host为1,这样强制把host头域加入签名列表,防止越权访问问题 + cos_gen_presigned_url_safe(options, &bucket, &object, 300, HTTP_GET, headers, params, sign_host, &presigned_url); + printf("presigned_url_safe: %s\n", presigned_url.data); + + cos_pool_destroy(p); +} + +void test_head_bucket() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers = NULL; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + options->config = cos_config_create(options->pool); + + init_test_request_options(options, is_cname); + + cos_str_set(&bucket, TEST_BUCKET_NAME); + options->ctl = cos_http_controller_create(options->pool, 0); + + status = cos_head_bucket(options, &bucket, &resp_headers); + log_status(status); + + cos_pool_destroy(pool); +} + +void test_check_bucket_exist() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers = NULL; + cos_bucket_exist_status_e bucket_exist; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + init_test_request_options(options, is_cname); + + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // 检查桶是否存在 + status = cos_check_bucket_exist(options, &bucket, &bucket_exist, &resp_headers); + if (bucket_exist == COS_BUCKET_NON_EXIST) { + printf("bucket: %.*s non exist.\n", bucket.len, bucket.data); + } else if (bucket_exist == COS_BUCKET_EXIST) { + printf("bucket: %.*s exist.\n", bucket.len, bucket.data); + } else { + printf("bucket: %.*s unknown status.\n", bucket.len, bucket.data); + log_status(status); + } + + cos_pool_destroy(pool); +} + +void test_get_service() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_get_service_params_t *list_params = NULL; + cos_table_t *resp_headers = NULL; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + options->config = cos_config_create(options->pool); + + init_test_request_options(options, is_cname); + options->ctl = cos_http_controller_create(options->pool, 0); + + //创建get service参数, 默认获取全部bucket + list_params = cos_create_get_service_params(options->pool); + //若将all_region设置为0,则只根据options->config->endpoint的区域进行查询 + // list_params->all_region = 0; + + status = cos_get_service(options, list_params, &resp_headers); + log_status(status); + if (!cos_status_is_ok(status)) { + cos_pool_destroy(pool); + return; + } + + //查看结果 + cos_get_service_content_t *content = NULL; + char *line = NULL; + cos_list_for_each_entry(cos_get_service_content_t, content, &list_params->bucket_list, node) { + line = apr_psprintf(options->pool, "%.*s\t%.*s\t%.*s\n", content->bucket_name.len, content->bucket_name.data, + content->location.len, content->location.data, content->creation_date.len, + content->creation_date.data); + printf("%s", line); + } + + cos_pool_destroy(pool); +} + +void test_website() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_website_params_t *website_params = NULL; + cos_website_params_t *website_result = NULL; + cos_website_rule_content_t *website_content = NULL; + cos_table_t *resp_headers = NULL; + cos_string_t bucket; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //创建website参数 + website_params = cos_create_website_params(options->pool); + cos_str_set(&website_params->index, "index.html"); + cos_str_set(&website_params->redirect_protocol, "https"); + cos_str_set(&website_params->error_document, "Error.html"); + + website_content = cos_create_website_rule_content(options->pool); + cos_str_set(&website_content->condition_errcode, "404"); + cos_str_set(&website_content->redirect_protocol, "https"); + cos_str_set(&website_content->redirect_replace_key, "404.html"); + cos_list_add_tail(&website_content->node, &website_params->rule_list); + + website_content = cos_create_website_rule_content(options->pool); + cos_str_set(&website_content->condition_prefix, "docs/"); + cos_str_set(&website_content->redirect_protocol, "https"); + cos_str_set(&website_content->redirect_replace_key_prefix, "documents/"); + cos_list_add_tail(&website_content->node, &website_params->rule_list); + + website_content = cos_create_website_rule_content(options->pool); + cos_str_set(&website_content->condition_prefix, "img/"); + cos_str_set(&website_content->redirect_protocol, "https"); + cos_str_set(&website_content->redirect_replace_key, "demo.jpg"); + cos_list_add_tail(&website_content->node, &website_params->rule_list); + + status = cos_put_bucket_website(options, &bucket, website_params, &resp_headers); + log_status(status); + + website_result = cos_create_website_params(options->pool); + status = cos_get_bucket_website(options, &bucket, website_result, &resp_headers); + log_status(status); + if (!cos_status_is_ok(status)) { + cos_pool_destroy(pool); + return; + } + + //查看结果 + cos_website_rule_content_t *content = NULL; + char *line = NULL; + line = apr_psprintf(options->pool, "%.*s\n", website_result->index.len, website_result->index.data); + printf("index: %s", line); + line = apr_psprintf(options->pool, "%.*s\n", website_result->redirect_protocol.len, + website_result->redirect_protocol.data); + printf("redirect protocol: %s", line); + line = apr_psprintf(options->pool, "%.*s\n", website_result->error_document.len, website_result->error_document.data); + printf("error document: %s", line); + cos_list_for_each_entry(cos_website_rule_content_t, content, &website_result->rule_list, node) { + line = apr_psprintf(options->pool, "%.*s\t%.*s\t%.*s\t%.*s\t%.*s\n", content->condition_errcode.len, + content->condition_errcode.data, content->condition_prefix.len, content->condition_prefix.data, + content->redirect_protocol.len, content->redirect_protocol.data, + content->redirect_replace_key.len, content->redirect_replace_key.data, + content->redirect_replace_key_prefix.len, content->redirect_replace_key_prefix.data); + printf("%s", line); + } + + status = cos_delete_bucket_website(options, &bucket, &resp_headers); + log_status(status); + + cos_pool_destroy(pool); +} + +void test_domain() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_domain_params_t *domain_params = NULL; + cos_domain_params_t *domain_result = NULL; + cos_table_t *resp_headers = NULL; + cos_string_t bucket; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + options->config = cos_config_create(options->pool); + + init_test_request_options(options, is_cname); + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //创建domain参数 + domain_params = cos_create_domain_params(options->pool); + cos_str_set(&domain_params->status, "ENABLED"); + cos_str_set(&domain_params->name, "www.abc.com"); + cos_str_set(&domain_params->type, "REST"); + cos_str_set(&domain_params->forced_replacement, "CNAME"); + + status = cos_put_bucket_domain(options, &bucket, domain_params, &resp_headers); + log_status(status); + + domain_result = cos_create_domain_params(options->pool); + status = cos_get_bucket_domain(options, &bucket, domain_result, &resp_headers); + log_status(status); + if (!cos_status_is_ok(status)) { + cos_pool_destroy(pool); + return; + } + + //查看结果 + char *line = NULL; + line = apr_psprintf(options->pool, "%.*s\n", domain_result->status.len, domain_result->status.data); + printf("status: %s", line); + line = apr_psprintf(options->pool, "%.*s\n", domain_result->name.len, domain_result->name.data); + printf("name: %s", line); + line = apr_psprintf(options->pool, "%.*s\n", domain_result->type.len, domain_result->type.data); + printf("type: %s", line); + line = apr_psprintf(options->pool, "%.*s\n", domain_result->forced_replacement.len, + domain_result->forced_replacement.data); + printf("forced_replacement: %s", line); + + cos_pool_destroy(pool); +} + +void test_logging() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_logging_params_t *params = NULL; + cos_logging_params_t *result = NULL; + cos_table_t *resp_headers = NULL; + cos_string_t bucket; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //创建logging参数 + params = cos_create_logging_params(options->pool); + cos_str_set(¶ms->target_bucket, TEST_BUCKET_NAME); + cos_str_set(¶ms->target_prefix, "logging/"); + + status = cos_put_bucket_logging(options, &bucket, params, &resp_headers); + log_status(status); + + result = cos_create_logging_params(options->pool); + status = cos_get_bucket_logging(options, &bucket, result, &resp_headers); + log_status(status); + if (!cos_status_is_ok(status)) { + cos_pool_destroy(pool); + return; + } + + //查看结果 + char *line = NULL; + line = apr_psprintf(options->pool, "%.*s\n", result->target_bucket.len, result->target_bucket.data); + printf("target bucket: %s", line); + line = apr_psprintf(options->pool, "%.*s\n", result->target_prefix.len, result->target_prefix.data); + printf("target prefix: %s", line); + + cos_pool_destroy(pool); +} + +void test_inventory() { + cos_pool_t *pool = NULL; + int is_cname = 0; + int inum = 3, i, len; + char buf[inum][32]; + char dest_bucket[128]; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_table_t *resp_headers = NULL; + cos_string_t bucket; + cos_inventory_params_t *get_params = NULL; + cos_inventory_optional_t *optional = NULL; + cos_list_inventory_params_t *list_params = NULL; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + options->config = cos_config_create(options->pool); + + init_test_request_options(options, is_cname); + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // put bucket inventory + len = snprintf(dest_bucket, 128, "qcs::cos:%s::%s", TEST_REGION, TEST_BUCKET_NAME); + dest_bucket[len] = 0; + for (i = 0; i < inum; i++) { + cos_inventory_params_t *params = cos_create_inventory_params(pool); + cos_inventory_optional_t *optional; + len = snprintf(buf[i], 32, "id%d", i); + buf[i][len] = 0; + cos_str_set(¶ms->id, buf[i]); + cos_str_set(¶ms->is_enabled, "true"); + cos_str_set(¶ms->frequency, "Daily"); + cos_str_set(¶ms->filter_prefix, "myPrefix"); + cos_str_set(¶ms->included_object_versions, "All"); + cos_str_set(¶ms->destination.format, "CSV"); + cos_str_set(¶ms->destination.account_id, TEST_UIN); + cos_str_set(¶ms->destination.bucket, dest_bucket); + cos_str_set(¶ms->destination.prefix, "invent"); + params->destination.encryption = 1; + optional = cos_create_inventory_optional(pool); + cos_str_set(&optional->field, "Size"); + cos_list_add_tail(&optional->node, ¶ms->fields); + optional = cos_create_inventory_optional(pool); + cos_str_set(&optional->field, "LastModifiedDate"); + cos_list_add_tail(&optional->node, ¶ms->fields); + optional = cos_create_inventory_optional(pool); + cos_str_set(&optional->field, "ETag"); + cos_list_add_tail(&optional->node, ¶ms->fields); + optional = cos_create_inventory_optional(pool); + cos_str_set(&optional->field, "StorageClass"); + cos_list_add_tail(&optional->node, ¶ms->fields); + optional = cos_create_inventory_optional(pool); + cos_str_set(&optional->field, "ReplicationStatus"); + cos_list_add_tail(&optional->node, ¶ms->fields); + + status = cos_put_bucket_inventory(options, &bucket, params, &resp_headers); + log_status(status); + } + + // get inventory + get_params = cos_create_inventory_params(pool); + cos_str_set(&get_params->id, buf[inum / 2]); + status = cos_get_bucket_inventory(options, &bucket, get_params, &resp_headers); + log_status(status); + + printf("id: %s\nis_enabled: %s\nfrequency: %s\nfilter_prefix: %s\nincluded_object_versions: %s\n", + get_params->id.data, get_params->is_enabled.data, get_params->frequency.data, get_params->filter_prefix.data, + get_params->included_object_versions.data); + printf("destination:\n"); + printf("\tencryption: %d\n", get_params->destination.encryption); + printf("\tformat: %s\n", get_params->destination.format.data); + printf("\taccount_id: %s\n", get_params->destination.account_id.data); + printf("\tbucket: %s\n", get_params->destination.bucket.data); + printf("\tprefix: %s\n", get_params->destination.prefix.data); + cos_list_for_each_entry(cos_inventory_optional_t, optional, &get_params->fields, node) { + printf("field: %s\n", optional->field.data); + } + + // list inventory + list_params = cos_create_list_inventory_params(pool); + status = cos_list_bucket_inventory(options, &bucket, list_params, &resp_headers); + log_status(status); + + get_params = NULL; + cos_list_for_each_entry(cos_inventory_params_t, get_params, &list_params->inventorys, node) { + printf("id: %s\nis_enabled: %s\nfrequency: %s\nfilter_prefix: %s\nincluded_object_versions: %s\n", + get_params->id.data, get_params->is_enabled.data, get_params->frequency.data, get_params->filter_prefix.data, + get_params->included_object_versions.data); + printf("destination:\n"); + printf("\tencryption: %d\n", get_params->destination.encryption); + printf("\tformat: %s\n", get_params->destination.format.data); + printf("\taccount_id: %s\n", get_params->destination.account_id.data); + printf("\tbucket: %s\n", get_params->destination.bucket.data); + printf("\tprefix: %s\n", get_params->destination.prefix.data); + cos_list_for_each_entry(cos_inventory_optional_t, optional, &get_params->fields, node) { + printf("field: %s\n", optional->field.data); + } + } + + // delete inventory + for (i = 0; i < inum; i++) { + cos_string_t id; + cos_str_set(&id, buf[i]); + status = cos_delete_bucket_inventory(options, &bucket, &id, &resp_headers); + log_status(status); + } + + cos_pool_destroy(pool); +} + +void test_bucket_tagging() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_table_t *resp_headers = NULL; + cos_string_t bucket; + cos_tagging_params_t *params = NULL; + cos_tagging_params_t *result = NULL; + cos_tagging_tag_t *tag = NULL; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // put tagging + params = cos_create_tagging_params(pool); + tag = cos_create_tagging_tag(pool); + cos_str_set(&tag->key, "age"); + cos_str_set(&tag->value, "18"); + cos_list_add_tail(&tag->node, ¶ms->node); + + tag = cos_create_tagging_tag(pool); + cos_str_set(&tag->key, "name"); + cos_str_set(&tag->value, "xiaoming"); + cos_list_add_tail(&tag->node, ¶ms->node); + + status = cos_put_bucket_tagging(options, &bucket, params, &resp_headers); + log_status(status); + + // get tagging + result = cos_create_tagging_params(pool); + status = cos_get_bucket_tagging(options, &bucket, result, &resp_headers); + log_status(status); + + tag = NULL; + cos_list_for_each_entry(cos_tagging_tag_t, tag, &result->node, node) { + printf("taging key: %s\n", tag->key.data); + printf("taging value: %s\n", tag->value.data); + } + + // delete tagging + status = cos_delete_bucket_tagging(options, &bucket, &resp_headers); + log_status(status); + + cos_pool_destroy(pool); +} + +void test_object_tagging() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_table_t *resp_headers = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t version_id = cos_string(""); + cos_tagging_params_t *params = NULL; + cos_tagging_params_t *result = NULL; + cos_tagging_tag_t *tag = NULL; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + options->config = cos_config_create(options->pool); + + init_test_request_options(options, is_cname); + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, TEST_OBJECT_NAME1); + + // put object tagging + params = cos_create_tagging_params(pool); + tag = cos_create_tagging_tag(pool); + cos_str_set(&tag->key, "age"); + cos_str_set(&tag->value, "18"); + cos_list_add_tail(&tag->node, ¶ms->node); + + tag = cos_create_tagging_tag(pool); + cos_str_set(&tag->key, "name"); + cos_str_set(&tag->value, "xiaoming"); + cos_list_add_tail(&tag->node, ¶ms->node); + + status = cos_put_object_tagging(options, &bucket, &object, &version_id, NULL, params, &resp_headers); + log_status(status); + + // get object tagging + result = cos_create_tagging_params(pool); + status = cos_get_object_tagging(options, &bucket, &object, &version_id, NULL, result, &resp_headers); + log_status(status); + + tag = NULL; + cos_list_for_each_entry(cos_tagging_tag_t, tag, &result->node, node) { + printf("taging key: %s\n", tag->key.data); + printf("taging value: %s\n", tag->value.data); + } + + // delete tagging + status = cos_delete_object_tagging(options, &bucket, &object, &version_id, NULL, &resp_headers); + log_status(status); + + cos_pool_destroy(pool); +} + +static void log_get_referer(cos_referer_params_t *result) { + int index = 0; + cos_referer_domain_t *domain; + + cos_warn_log("status: %s", result->status.data); + cos_warn_log("referer_type: %s", result->referer_type.data); + cos_warn_log("empty_refer_config: %s", result->empty_refer_config.data); + + cos_list_for_each_entry(cos_referer_domain_t, domain, &result->domain_list, node) { + cos_warn_log("domain index:%d", ++index); + cos_warn_log("domain: %s", domain->domain.data); + } +} + +void test_referer() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_table_t *resp_headers = NULL; + cos_string_t bucket; + cos_referer_params_t *params = NULL; + cos_referer_domain_t *domain = NULL; + cos_referer_params_t *result = NULL; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // 替换为您的配置信息,可参见文档 https://cloud.tencent.com/document/product/436/32492 + params = cos_create_referer_params(pool); + cos_str_set(¶ms->status, "Enabled"); + cos_str_set(¶ms->referer_type, "White-List"); + cos_str_set(¶ms->empty_refer_config, "Allow"); + domain = cos_create_referer_domain(pool); + cos_str_set(&domain->domain, "www.qq.com"); + cos_list_add_tail(&domain->node, ¶ms->domain_list); + domain = cos_create_referer_domain(pool); + cos_str_set(&domain->domain, "*.tencent.com"); + cos_list_add_tail(&domain->node, ¶ms->domain_list); + + // put referer + status = cos_put_bucket_referer(options, &bucket, params, &resp_headers); + log_status(status); + + // get referer + result = cos_create_referer_params(pool); + status = cos_get_bucket_referer(options, &bucket, result, &resp_headers); + log_status(status); + if (status->code == 200) { + log_get_referer(result); + } + + cos_pool_destroy(pool); +} + +void test_intelligenttiering() { + cos_pool_t *pool = NULL; + int is_cname = 0; + cos_status_t *status = NULL; + cos_request_options_t *options = NULL; + cos_table_t *resp_headers = NULL; + cos_string_t bucket; + cos_intelligenttiering_params_t *params = NULL; + cos_intelligenttiering_params_t *result = NULL; + + //创建内存池 + cos_pool_create(&pool, NULL); + + //初始化请求选项 + options = cos_request_options_create(pool); + options->config = cos_config_create(options->pool); + + init_test_request_options(options, is_cname); + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // put intelligenttiering + params = cos_create_intelligenttiering_params(pool); + cos_str_set(¶ms->status, "Enabled"); + params->days = 30; + + status = cos_put_bucket_intelligenttiering(options, &bucket, params, &resp_headers); + log_status(status); + + // get intelligenttiering + result = cos_create_intelligenttiering_params(pool); + status = cos_get_bucket_intelligenttiering(options, &bucket, result, &resp_headers); + log_status(status); + + printf("status: %s\n", result->status.data); + printf("days: %d\n", result->days); + cos_pool_destroy(pool); +} + +void test_delete_directory() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers; + int is_truncated = 1; + cos_string_t marker; + cos_list_t deleted_object_list; + int is_quiet = COS_TRUE; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // list object (get bucket) + cos_list_object_params_t *list_params = NULL; + list_params = cos_create_list_object_params(p); + cos_str_set(&list_params->prefix, "folder/"); + cos_str_set(&marker, ""); + while (is_truncated) { + list_params->marker = marker; + s = cos_list_object(options, &bucket, list_params, &resp_headers); + if (!cos_status_is_ok(s)) { + printf("list object failed, req_id:%s\n", s->req_id); + break; + } + + s = cos_delete_objects(options, &bucket, &list_params->object_list, is_quiet, &resp_headers, &deleted_object_list); + log_status(s); + if (!cos_status_is_ok(s)) { + printf("delete objects failed, req_id:%s\n", s->req_id); + } + + is_truncated = list_params->truncated; + marker = list_params->next_marker; + } + cos_pool_destroy(p); +} + +void test_list_directory() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers; + int is_truncated = 1; + cos_string_t marker; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // list object (get bucket) + cos_list_object_params_t *list_params = NULL; + list_params = cos_create_list_object_params(p); + // prefix表示列出的object的key以prefix开始 + cos_str_set(&list_params->prefix, "folder/"); + // deliter表示分隔符, 设置为/表示列出当前目录下的object, 设置为空表示列出所有的object + cos_str_set(&list_params->delimiter, "/"); + // 设置最大遍历出多少个对象, 一次listobject最大支持1000 + list_params->max_ret = 1000; + cos_str_set(&marker, ""); + while (is_truncated) { + list_params->marker = marker; + s = cos_list_object(options, &bucket, list_params, &resp_headers); + if (!cos_status_is_ok(s)) { + printf("list object failed, req_id:%s\n", s->req_id); + break; + } + // list_params->object_list 返回列出的object对象。 + cos_list_object_content_t *content = NULL; + cos_list_for_each_entry(cos_list_object_content_t, content, &list_params->object_list, node) { + printf("object: %s\n", content->key.data); + } + // list_params->common_prefix_list 表示被delimiter截断的路径, 如delimter设置为/, common prefix则表示所有子目录的路径 + cos_list_object_common_prefix_t *common_prefix = NULL; + cos_list_for_each_entry(cos_list_object_common_prefix_t, common_prefix, &list_params->common_prefix_list, node) { + printf("common prefix: %s\n", common_prefix->prefix.data); + } + + is_truncated = list_params->truncated; + marker = list_params->next_marker; + } + cos_pool_destroy(p); +} + +void test_list_all_objects() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers; + int is_truncated = 1; + cos_string_t marker; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // list object (get bucket) + cos_list_object_params_t *list_params = NULL; + list_params = cos_create_list_object_params(p); + // 设置最大遍历出多少个对象, 一次listobject最大支持1000 + list_params->max_ret = 1000; + cos_str_set(&marker, ""); + while (is_truncated) { + list_params->marker = marker; + cos_list_init(&list_params->object_list); + s = cos_list_object(options, &bucket, list_params, &resp_headers); + if (!cos_status_is_ok(s)) { + printf("list object failed, req_id:%s\n", s->req_id); + break; + } + // list_params->object_list 返回列出的object对象。 + cos_list_object_content_t *content = NULL; + cos_list_for_each_entry(cos_list_object_content_t, content, &list_params->object_list, node) { + printf("object: %s\n", content->key.data); + } + + is_truncated = list_params->truncated; + marker = list_params->next_marker; + } + cos_pool_destroy(p); +} + +void test_download_directory() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t file_name; + cos_string_t suffix = cos_string("/"); + cos_table_t *resp_headers; + cos_table_t *headers = NULL; + cos_table_t *params = NULL; + int is_truncated = 1; + cos_string_t marker; + apr_status_t status; + + //初始化请求选项 + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // list object (get bucket) + cos_list_object_params_t *list_params = NULL; + list_params = cos_create_list_object_params(p); + cos_str_set(&list_params->prefix, "folder/"); //替换为您自己的目录名称 + cos_str_set(&marker, ""); + while (is_truncated) { + list_params->marker = marker; + s = cos_list_object(options, &bucket, list_params, &resp_headers); + log_status(s); + if (!cos_status_is_ok(s)) { + printf("list object failed, req_id:%s\n", s->req_id); + break; + } + cos_list_object_content_t *content = NULL; + cos_list_for_each_entry(cos_list_object_content_t, content, &list_params->object_list, node) { + cos_str_set(&file_name, content->key.data); + if (cos_ends_with(&content->key, &suffix)) { + //如果是目录需要先创建, 0x0755权限可以自己按需修改,参考apr_file_info.h中定义 + status = apr_dir_make(content->key.data, 0x0755, options->pool); + if (status != APR_SUCCESS && !APR_STATUS_IS_EEXIST(status)) { + printf("mkdir: %s failed, status: %d\n", content->key.data, status); + } + } else { + //下载对象到本地目录,这里默认下载在程序运行的当前目录 + s = cos_get_object_to_file(options, &bucket, &content->key, headers, params, &file_name, &resp_headers); + if (!cos_status_is_ok(s)) { + printf("get object[%s] failed, req_id:%s\n", content->key.data, s->req_id); + } + } + } + is_truncated = list_params->truncated; + marker = list_params->next_marker; + } + + //销毁内存池 + cos_pool_destroy(p); +} + +void test_move() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t src_object; + cos_string_t src_endpoint; + cos_table_t *resp_headers = NULL; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + //设置对象复制 + cos_str_set(&object, TEST_OBJECT_NAME1); + cos_str_set(&src_endpoint, TEST_COS_ENDPOINT); + cos_str_set(&src_object, TEST_OBJECT_NAME2); + + cos_copy_object_params_t *params = NULL; + params = cos_create_copy_object_params(p); + s = cos_copy_object(options, &bucket, &src_object, &src_endpoint, &bucket, &object, NULL, params, &resp_headers); + log_status(s); + if (cos_status_is_ok(s)) { + s = cos_delete_object(options, &bucket, &src_object, &resp_headers); + log_status(s); + printf("move object succeeded\n"); + } else { + printf("move object failed\n"); + } + + //销毁内存池 + cos_pool_destroy(p); +} + +// 基础图片处理 +void test_ci_base_image_process() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + cos_table_t *resp_headers; + cos_table_t *params = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + options->config = cos_config_create(options->pool); + cos_str_set(&options->config->endpoint, TEST_COS_ENDPOINT); + cos_str_set(&options->config->access_key_id, TEST_ACCESS_KEY_ID); + cos_str_set(&options->config->access_key_secret, TEST_ACCESS_KEY_SECRET); + cos_str_set(&options->config->appid, TEST_APPID); + options->config->is_cname = is_cname; + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + params = cos_table_make(p, 1); + apr_table_addn(params, "imageMogr2/thumbnail/!50p", ""); + cos_str_set(&file, "test.jpg"); + cos_str_set(&object, "test.jpg"); + s = cos_get_object_to_file(options, &bucket, &object, NULL, params, &file, &resp_headers); + log_status(s); + if (!cos_status_is_ok(s)) { + printf("cos_get_object_to_file fail, req_id:%s\n", s->req_id); + } + cos_pool_destroy(p); +} + +// 持久化处理 +void test_ci_image_process() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + cos_table_t *resp_headers; + cos_table_t *headers = NULL; + ci_operation_result_t *results = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "test.jpg"); + + // 云上数据处理 + headers = cos_table_make(p, 1); + apr_table_addn(headers, "pic-operations", + "{\"is_pic_info\":1,\"rules\":[{\"fileid\":\"test.png\",\"rule\":\"imageView2/format/png\"}]}"); + s = ci_image_process(options, &bucket, &object, headers, &resp_headers, &results); + log_status(s); + printf("origin key: %s\n", results->origin.key.data); + printf("process key: %s\n", results->object.key.data); + + // 上传时处理 + headers = cos_table_make(p, 1); + apr_table_addn(headers, "pic-operations", + "{\"is_pic_info\":1,\"rules\":[{\"fileid\":\"test.png\",\"rule\":\"imageView2/format/png\"}]}"); + cos_str_set(&file, "test.jpg"); + cos_str_set(&object, "test.jpg"); + s = ci_put_object_from_file(options, &bucket, &object, &file, headers, &resp_headers, &results); + log_status(s); + printf("origin key: %s\n", results->origin.key.data); + printf("process key: %s\n", results->object.key.data); + + cos_pool_destroy(p); +} + +// 二维码识别 +void test_ci_image_qrcode() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + cos_table_t *resp_headers; + cos_table_t *headers = NULL; + ci_operation_result_t *results = NULL; + ci_qrcode_info_t *content = NULL; + ci_qrcode_result_t *result2 = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + init_test_request_options(options, is_cname); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "test.jpg"); + + headers = cos_table_make(p, 1); + apr_table_addn(headers, "pic-operations", + "{\"is_pic_info\":1,\"rules\":[{\"fileid\":\"test.png\",\"rule\":\"QRcode/cover/1\"}]}"); + // 上传时识别 + cos_str_set(&file, "test.jpg"); + cos_str_set(&object, "test.jpg"); + s = ci_put_object_from_file(options, &bucket, &object, &file, headers, &resp_headers, &results); + log_status(s); + if (!cos_status_is_ok(s)) { + printf("put object failed\n"); + } + printf("CodeStatus: %d\n", results->object.code_status); + cos_list_for_each_entry(ci_qrcode_info_t, content, &results->object.qrcode_info, node) { + printf("CodeUrl: %s\n", content->code_url.data); + printf("Point: %s\n", content->point[0].data); + printf("Point: %s\n", content->point[1].data); + printf("Point: %s\n", content->point[2].data); + printf("Point: %s\n", content->point[3].data); + } + + // 下载时识别 + s = ci_get_qrcode(options, &bucket, &object, 1, NULL, NULL, &resp_headers, &result2); + log_status(s); + if (!cos_status_is_ok(s)) { + printf("get object failed\n"); + } + printf("CodeStatus: %d\n", result2->code_status); + cos_list_for_each_entry(ci_qrcode_info_t, content, &result2->qrcode_info, node) { + printf("CodeUrl: %s\n", content->code_url.data); + printf("Point: %s\n", content->point[0].data); + printf("Point: %s\n", content->point[1].data); + printf("Point: %s\n", content->point[2].data); + printf("Point: %s\n", content->point[3].data); + } + printf("ImageResult: %s\n", result2->result_image.data); + + //销毁内存池 + cos_pool_destroy(p); +} + +// 图片压缩 +void test_ci_image_compression() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + cos_table_t *resp_headers; + cos_table_t *params = NULL; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + options->config = cos_config_create(options->pool); + cos_str_set(&options->config->endpoint, TEST_COS_ENDPOINT); + cos_str_set(&options->config->access_key_id, TEST_ACCESS_KEY_ID); + cos_str_set(&options->config->access_key_secret, TEST_ACCESS_KEY_SECRET); + cos_str_set(&options->config->appid, TEST_APPID); + options->config->is_cname = is_cname; + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + params = cos_table_make(p, 1); + apr_table_addn(params, "imageMogr2/format/tpg", ""); + cos_str_set(&object, "test.jpg"); + cos_str_set(&file, "test.tpg"); + s = cos_get_object_to_file(options, &bucket, &object, NULL, params, &file, &resp_headers); + log_status(s); + if (!cos_status_is_ok(s)) { + printf("cos_get_object_to_file fail, req_id:%s\n", s->req_id); + } + + params = cos_table_make(p, 1); + apr_table_addn(params, "imageMogr2/format/heif", ""); + cos_str_set(&file, "test.heif"); + s = cos_get_object_to_file(options, &bucket, &object, NULL, params, &file, &resp_headers); + log_status(s); + if (!cos_status_is_ok(s)) { + printf("cos_get_object_to_file fail, req_id:%s\n", s->req_id); + } +} + +static void log_video_auditing_result(ci_video_auditing_job_result_t *result) { + cos_warn_log("jobid: %s", result->jobs_detail.job_id.data); + cos_warn_log("state: %s", result->jobs_detail.state.data); + cos_warn_log("creation_time: %s", result->jobs_detail.creation_time.data); +} + +static void log_get_auditing_result(ci_auditing_job_result_t *result) { + int index = 0; + ci_auditing_snapshot_result_t *snapshot_info; + ci_auditing_audio_section_result_t *audio_section_info; + + cos_warn_log("nonexist_job_ids: %s", result->nonexist_job_ids.data); + cos_warn_log("code: %s", result->jobs_detail.code.data); + cos_warn_log("message: %s", result->jobs_detail.message.data); + cos_warn_log("state: %s", result->jobs_detail.state.data); + cos_warn_log("creation_time: %s", result->jobs_detail.creation_time.data); + cos_warn_log("object: %s", result->jobs_detail.object.data); + cos_warn_log("snapshot_count: %s", result->jobs_detail.snapshot_count.data); + cos_warn_log("result: %d", result->jobs_detail.result); + + cos_warn_log("porn_info.hit_flag: %d", result->jobs_detail.porn_info.hit_flag); + cos_warn_log("porn_info.count: %d", result->jobs_detail.porn_info.count); + cos_warn_log("terrorism_info.hit_flag: %d", result->jobs_detail.terrorism_info.hit_flag); + cos_warn_log("terrorism_info.count: %d", result->jobs_detail.terrorism_info.count); + cos_warn_log("politics_info.hit_flag: %d", result->jobs_detail.politics_info.hit_flag); + cos_warn_log("politics_info.count: %d", result->jobs_detail.politics_info.count); + cos_warn_log("ads_info.hit_flag: %d", result->jobs_detail.ads_info.hit_flag); + cos_warn_log("ads_info.count: %d", result->jobs_detail.ads_info.count); + + cos_list_for_each_entry(ci_auditing_snapshot_result_t, snapshot_info, &result->jobs_detail.snapshot_info_list, node) { + cos_warn_log("snapshot index:%d", ++index); + cos_warn_log("snapshot_info->url: %s", snapshot_info->url.data); + cos_warn_log("snapshot_info->snapshot_time: %d", snapshot_info->snapshot_time); + cos_warn_log("snapshot_info->text: %s", snapshot_info->text.data); + + cos_warn_log("snapshot_info->porn_info.hit_flag: %d", snapshot_info->porn_info.hit_flag); + cos_warn_log("snapshot_info->porn_info.score: %d", snapshot_info->porn_info.score); + cos_warn_log("snapshot_info->porn_info.label: %s", snapshot_info->porn_info.label.data); + cos_warn_log("snapshot_info->porn_info.sub_lable: %s", snapshot_info->porn_info.sub_lable.data); + cos_warn_log("snapshot_info->terrorism_info.hit_flag: %d", snapshot_info->terrorism_info.hit_flag); + cos_warn_log("snapshot_info->terrorism_info.score: %d", snapshot_info->terrorism_info.score); + cos_warn_log("snapshot_info->terrorism_info.label: %s", snapshot_info->terrorism_info.label.data); + cos_warn_log("snapshot_info->terrorism_info.sub_lable: %s", snapshot_info->terrorism_info.sub_lable.data); + cos_warn_log("snapshot_info->politics_info.hit_flag: %d", snapshot_info->politics_info.hit_flag); + cos_warn_log("snapshot_info->politics_info.score: %d", snapshot_info->politics_info.score); + cos_warn_log("snapshot_info->politics_info.label: %s", snapshot_info->politics_info.label.data); + cos_warn_log("snapshot_info->politics_info.sub_lable: %s", snapshot_info->politics_info.sub_lable.data); + cos_warn_log("snapshot_info->ads_info.hit_flag: %d", snapshot_info->ads_info.hit_flag); + cos_warn_log("snapshot_info->ads_info.score: %d", snapshot_info->ads_info.score); + cos_warn_log("snapshot_info->ads_info.label: %s", snapshot_info->ads_info.label.data); + cos_warn_log("snapshot_info->ads_info.sub_lable: %s", snapshot_info->ads_info.sub_lable.data); + } + + index = 0; + cos_list_for_each_entry(ci_auditing_audio_section_result_t, audio_section_info, + &result->jobs_detail.audio_section_info_list, node) { + cos_warn_log("audio_section index:%d", ++index); + cos_warn_log("audio_section_info->url: %s", audio_section_info->url.data); + cos_warn_log("audio_section_info->text: %s", audio_section_info->text.data); + cos_warn_log("audio_section_info->offset_time: %d", audio_section_info->offset_time); + cos_warn_log("audio_section_info->duration: %d", audio_section_info->duration); + + cos_warn_log("audio_section_info->porn_info.hit_flag: %d", audio_section_info->porn_info.hit_flag); + cos_warn_log("audio_section_info->porn_info.score: %d", audio_section_info->porn_info.score); + cos_warn_log("audio_section_info->porn_info.key_words: %s", audio_section_info->porn_info.key_words.data); + cos_warn_log("audio_section_info->terrorism_info.hit_flag: %d", audio_section_info->terrorism_info.hit_flag); + cos_warn_log("audio_section_info->terrorism_info.score: %d", audio_section_info->terrorism_info.score); + cos_warn_log("audio_section_info->terrorism_info.key_words: %s", audio_section_info->terrorism_info.key_words.data); + cos_warn_log("audio_section_info->politics_info.hit_flag: %d", audio_section_info->politics_info.hit_flag); + cos_warn_log("audio_section_info->politics_info.score: %d", audio_section_info->politics_info.score); + cos_warn_log("audio_section_info->politics_info.key_words: %s", audio_section_info->politics_info.key_words.data); + cos_warn_log("audio_section_info->ads_info.hit_flag: %d", audio_section_info->ads_info.hit_flag); + cos_warn_log("audio_section_info->ads_info.score: %d", audio_section_info->ads_info.score); + cos_warn_log("audio_section_info->ads_info.key_words: %s", audio_section_info->ads_info.key_words.data); + } +} + +static void log_media_buckets_result(ci_media_buckets_result_t *result) { + int index = 0; + ci_media_bucket_list_t *media_bucket; + + cos_warn_log("total_count: %d", result->total_count); + cos_warn_log("page_number: %d", result->page_number); + cos_warn_log("page_size: %d", result->page_size); + + cos_list_for_each_entry(ci_media_bucket_list_t, media_bucket, &result->media_bucket_list, node) { + cos_warn_log("media_bucket index:%d", ++index); + cos_warn_log("media_bucket->bucket_id: %s", media_bucket->bucket_id.data); + cos_warn_log("media_bucket->name: %s", media_bucket->name.data); + cos_warn_log("media_bucket->region: %s", media_bucket->region.data); + cos_warn_log("media_bucket->create_time: %s", media_bucket->create_time.data); + } +} + +static void log_media_info_result(ci_media_info_result_t *result) { + // format + cos_warn_log("format.num_stream: %d", result->format.num_stream); + cos_warn_log("format.num_program: %d", result->format.num_program); + cos_warn_log("format.format_name: %s", result->format.format_name.data); + cos_warn_log("format.format_long_name: %s", result->format.format_long_name.data); + cos_warn_log("format.start_time: %f", result->format.start_time); + cos_warn_log("format.duration: %f", result->format.duration); + cos_warn_log("format.bit_rate: %d", result->format.bit_rate); + cos_warn_log("format.size: %d", result->format.size); + + // stream.video + cos_warn_log("stream.video.index: %d", result->stream.video.index); + cos_warn_log("stream.video.codec_name: %s", result->stream.video.codec_name.data); + cos_warn_log("stream.video.codec_long_name: %s", result->stream.video.codec_long_name.data); + cos_warn_log("stream.video.codec_time_base: %s", result->stream.video.codec_time_base.data); + cos_warn_log("stream.video.codec_tag_string: %s", result->stream.video.codec_tag_string.data); + cos_warn_log("stream.video.codec_tag: %s", result->stream.video.codec_tag.data); + cos_warn_log("stream.video.profile: %s", result->stream.video.profile.data); + cos_warn_log("stream.video.height: %d", result->stream.video.height); + cos_warn_log("stream.video.width: %d", result->stream.video.width); + cos_warn_log("stream.video.has_b_frame: %d", result->stream.video.has_b_frame); + cos_warn_log("stream.video.ref_frames: %d", result->stream.video.ref_frames); + cos_warn_log("stream.video.sar: %s", result->stream.video.sar.data); + cos_warn_log("stream.video.dar: %s", result->stream.video.dar.data); + cos_warn_log("stream.video.pix_format: %s", result->stream.video.pix_format.data); + cos_warn_log("stream.video.field_order: %s", result->stream.video.field_order.data); + cos_warn_log("stream.video.level: %d", result->stream.video.level); + cos_warn_log("stream.video.fps: %d", result->stream.video.fps); + cos_warn_log("stream.video.avg_fps: %s", result->stream.video.avg_fps.data); + cos_warn_log("stream.video.timebase: %s", result->stream.video.timebase.data); + cos_warn_log("stream.video.start_time: %f", result->stream.video.start_time); + cos_warn_log("stream.video.duration: %f", result->stream.video.duration); + cos_warn_log("stream.video.bit_rate: %f", result->stream.video.bit_rate); + cos_warn_log("stream.video.num_frames: %d", result->stream.video.num_frames); + cos_warn_log("stream.video.language: %s", result->stream.video.language.data); + + // stream.audio + cos_warn_log("stream.audio.index: %d", result->stream.audio.index); + cos_warn_log("stream.audio.codec_name: %s", result->stream.audio.codec_name.data); + cos_warn_log("stream.audio.codec_long_name: %s", result->stream.audio.codec_long_name.data); + cos_warn_log("stream.audio.codec_time_base: %s", result->stream.audio.codec_time_base.data); + cos_warn_log("stream.audio.codec_tag_string: %s", result->stream.audio.codec_tag_string.data); + cos_warn_log("stream.audio.codec_tag: %s", result->stream.audio.codec_tag.data); + cos_warn_log("stream.audio.sample_fmt: %s", result->stream.audio.sample_fmt.data); + cos_warn_log("stream.audio.sample_rate: %d", result->stream.audio.sample_rate); + cos_warn_log("stream.audio.channel: %d", result->stream.audio.channel); + cos_warn_log("stream.audio.channel_layout: %s", result->stream.audio.channel_layout.data); + cos_warn_log("stream.audio.timebase: %s", result->stream.audio.timebase.data); + cos_warn_log("stream.audio.start_time: %f", result->stream.audio.start_time); + cos_warn_log("stream.audio.duration: %f", result->stream.audio.duration); + cos_warn_log("stream.audio.bit_rate: %f", result->stream.audio.bit_rate); + cos_warn_log("stream.audio.language: %s", result->stream.audio.language.data); + + // stream.subtitle + cos_warn_log("stream.subtitle.index: %d", result->stream.subtitle.index); + cos_warn_log("stream.subtitle.language: %s", result->stream.subtitle.language.data); +} + +void test_ci_video_auditing() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers; + ci_video_auditing_job_options_t *job_options; + ci_video_auditing_job_result_t *job_result; + ci_auditing_job_result_t *auditing_result; + + // 基本配置 + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + options->config = cos_config_create(options->pool); + cos_str_set(&options->config->endpoint, TEST_CI_ENDPOINT); // https://ci..myqcloud.com + cos_str_set(&options->config->access_key_id, TEST_ACCESS_KEY_ID); + cos_str_set(&options->config->access_key_secret, TEST_ACCESS_KEY_SECRET); + cos_str_set(&options->config->appid, TEST_APPID); + options->config->is_cname = is_cname; + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + + // 替换为您的配置信息,可参见文档 https://cloud.tencent.com/document/product/436/47316 + job_options = ci_video_auditing_job_options_create(p); + cos_str_set(&job_options->input_object, "test.mp4"); + cos_str_set(&job_options->job_conf.detect_type, "Porn,Terrorism,Politics,Ads"); + cos_str_set(&job_options->job_conf.callback_version, "Detail"); + job_options->job_conf.detect_content = 1; + cos_str_set(&job_options->job_conf.snapshot.mode, "Interval"); + job_options->job_conf.snapshot.time_interval = 1.5; + job_options->job_conf.snapshot.count = 10; + + // 提交一个视频审核任务 + s = ci_create_video_auditing_job(options, &bucket, job_options, NULL, &resp_headers, &job_result); + log_status(s); + if (s->code == 200) { + log_video_auditing_result(job_result); + } + + // 等待视频审核任务完成,此处可修改您的等待时间 + sleep(300); + + // 获取审核任务结果 + s = ci_get_auditing_job(options, &bucket, &job_result->jobs_detail.job_id, NULL, &resp_headers, &auditing_result); + log_status(s); + if (s->code == 200) { + log_get_auditing_result(auditing_result); + } + + // 销毁内存池 + cos_pool_destroy(p); +} + +void test_ci_media_process_media_bucket() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_table_t *resp_headers; + ci_media_buckets_request_t *media_buckets_request; + ci_media_buckets_result_t *media_buckets_result; + + // 基本配置 + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + options->config = cos_config_create(options->pool); + cos_str_set(&options->config->endpoint, TEST_CI_ENDPOINT); // https://ci..myqcloud.com + cos_str_set(&options->config->access_key_id, TEST_ACCESS_KEY_ID); + cos_str_set(&options->config->access_key_secret, TEST_ACCESS_KEY_SECRET); + cos_str_set(&options->config->appid, TEST_APPID); + options->config->is_cname = is_cname; + options->ctl = cos_http_controller_create(options->pool, 0); + + // 替换为您的配置信息,可参见文档 https://cloud.tencent.com/document/product/436/48988 + media_buckets_request = ci_media_buckets_request_create(p); + cos_str_set(&media_buckets_request->regions, ""); + cos_str_set(&media_buckets_request->bucket_names, ""); + cos_str_set(&media_buckets_request->bucket_name, ""); + cos_str_set(&media_buckets_request->page_number, "1"); + cos_str_set(&media_buckets_request->page_size, "10"); + s = ci_describe_media_buckets(options, media_buckets_request, NULL, &resp_headers, &media_buckets_result); + log_status(s); + if (s->code == 200) { + log_media_buckets_result(media_buckets_result); + } + + // 销毁内存池 + cos_pool_destroy(p); +} + +void test_ci_media_process_snapshot() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers; + cos_list_t download_buffer; + cos_string_t object; + ci_get_snapshot_request_t *snapshot_request; + cos_buf_t *content = NULL; + cos_string_t pic_file = cos_string("snapshot.jpg"); + + // 基本配置 + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + options->config = cos_config_create(options->pool); + cos_str_set(&options->config->endpoint, TEST_COS_ENDPOINT); + cos_str_set(&options->config->access_key_id, TEST_ACCESS_KEY_ID); + cos_str_set(&options->config->access_key_secret, TEST_ACCESS_KEY_SECRET); + cos_str_set(&options->config->appid, TEST_APPID); + options->config->is_cname = is_cname; + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "test.mp4"); + + // 替换为您的配置信息,可参见文档 https://cloud.tencent.com/document/product/436/55671 + snapshot_request = ci_snapshot_request_create(p); + snapshot_request->time = 7.5; + snapshot_request->width = 0; + snapshot_request->height = 0; + cos_str_set(&snapshot_request->format, "jpg"); + cos_str_set(&snapshot_request->rotate, "auto"); + cos_str_set(&snapshot_request->mode, "exactframe"); + cos_list_init(&download_buffer); + + s = ci_get_snapshot_to_buffer(options, &bucket, &object, snapshot_request, NULL, &download_buffer, &resp_headers); + log_status(s); + + int64_t len = 0; + int64_t size = 0; + int64_t pos = 0; + cos_list_for_each_entry(cos_buf_t, content, &download_buffer, node) { len += cos_buf_size(content); } + char *buf = cos_pcalloc(p, (apr_size_t)(len + 1)); + buf[len] = '\0'; + cos_list_for_each_entry(cos_buf_t, content, &download_buffer, node) { + size = cos_buf_size(content); + memcpy(buf + pos, content->pos, (size_t)size); + pos += size; + } + cos_warn_log("Download len:%ld data=%s", len, buf); + + s = ci_get_snapshot_to_file(options, &bucket, &object, snapshot_request, NULL, &pic_file, &resp_headers); + log_status(s); + + // 销毁内存池 + cos_pool_destroy(p); +} + +void test_ci_media_process_media_info() { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_table_t *resp_headers; + ci_media_info_result_t *media_info; + cos_string_t object; + + // 基本配置 + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + options->config = cos_config_create(options->pool); + cos_str_set(&options->config->endpoint, TEST_COS_ENDPOINT); + cos_str_set(&options->config->access_key_id, TEST_ACCESS_KEY_ID); + cos_str_set(&options->config->access_key_secret, TEST_ACCESS_KEY_SECRET); + cos_str_set(&options->config->appid, TEST_APPID); + options->config->is_cname = is_cname; + options->ctl = cos_http_controller_create(options->pool, 0); + cos_str_set(&bucket, TEST_BUCKET_NAME); + cos_str_set(&object, "test.mp4"); + + // 替换为您的配置信息,可参见文档 https://cloud.tencent.com/document/product/436/55672 + s = ci_get_media_info(options, &bucket, &object, NULL, &resp_headers, &media_info); + log_status(s); + if (s->code == 200) { + log_media_info_result(media_info); + } + + // 销毁内存池 + cos_pool_destroy(p); +} + +int main(int argc, char *argv[]) { + // 通过环境变量获取 SECRETID 和 SECRETKEY + // TEST_ACCESS_KEY_ID = getenv("COS_SECRETID"); + // TEST_ACCESS_KEY_SECRET = getenv("COS_SECRETKEY"); + + if (cos_http_io_initialize(NULL, 0) != COSE_OK) { + exit(1); + } + + // set log level, default COS_LOG_WARN + cos_log_set_level(COS_LOG_WARN); + + // set log output, default stderr + cos_log_set_output(NULL); + + // test_intelligenttiering(); + // test_bucket_tagging(); + // test_object_tagging(); + // test_referer(); + // test_logging(); + // test_inventory(); + // test_put_object_from_file_with_sse(); + // test_get_object_to_file_with_sse(); + // test_head_bucket(); + // test_check_bucket_exist(); + // test_get_service(); + // test_website(); + // test_domain(); + // test_delete_objects(); + // test_delete_objects_by_prefix(); + // test_bucket(); + // test_bucket_lifecycle(); + // test_object_restore(); + test_put_object_from_file(); + // test_sign(); + // test_object(); + // test_put_object_with_limit(); + // test_get_object_with_limit(); + test_head_object(); + // test_gen_object_url(); + // test_list_objects(); + // test_list_directory(); + // test_list_all_objects(); + // test_create_dir(); + // test_append_object(); + // test_check_object_exist(); + // multipart_upload_file_from_file(); + // multipart_upload_file_from_buffer(); + // abort_multipart_upload(); + // list_multipart(); + + // pthread_t tid[20]; + // test_resumable_upload_with_multi_threads(); + // test_resumable(); + // test_bucket(); + // test_acl(); + // test_copy(); + // test_modify_storage_class(); + // test_cors(); + // test_versioning(); + // test_replication(); + // test_part_copy(); + // test_copy_with_part_copy(); + // test_move(); + // test_delete_directory(); + // test_download_directory(); + // test_presigned_url(); + // test_ci_base_image_process(); + // test_ci_image_process(); + // test_ci_image_qrcode(); + // test_ci_image_compression(); + // test_ci_video_auditing(); + // test_ci_media_process_media_bucket(); + // test_ci_media_process_snapshot(); + // test_ci_media_process_media_info(); + + // cos_http_io_deinitialize last + cos_http_io_deinitialize(); + + return 0; +} diff --git a/docs/en/07-develop/06-stream.md b/docs/en/07-develop/06-stream.md index 125173e60bae77bbbe782363ebd2103cf7e4b703..59a6b815cfb2f997f5b4d444f27d8cb404943f42 100644 --- a/docs/en/07-develop/06-stream.md +++ b/docs/en/07-develop/06-stream.md @@ -52,7 +52,7 @@ CREATE TABLE d1004 USING meters TAGS ("California.LosAngeles", 3); ### Create a Stream ```sql -create stream current_stream into current_stream_output_stb as select _wstart as start, _wend as end, max(current) as max_current from meters where voltage <= 220 interval (5s); +create stream current_stream trigger at_once into current_stream_output_stb as select _wstart as wstart, _wend as wend, max(current) as max_current from meters where voltage <= 220 interval (5s); ``` ### Write Data diff --git a/docs/en/07-develop/07-tmq.mdx b/docs/en/07-develop/07-tmq.mdx index ccf39ef5818477d7a236e73358691dc859e80447..5af3897afdc3a8ed11fdaa4bc7bcf00a5051d29d 100644 --- a/docs/en/07-develop/07-tmq.mdx +++ b/docs/en/07-develop/07-tmq.mdx @@ -23,7 +23,20 @@ By subscribing to a topic, a consumer can obtain the latest data in that topic i To implement these features, TDengine indexes its write-ahead log (WAL) file for fast random access and provides configurable methods for replacing and retaining this file. You can define a retention period and size for this file. For information, see the CREATE DATABASE statement. In this way, the WAL file is transformed into a persistent storage engine that remembers the order in which events occur. However, note that configuring an overly long retention period for your WAL files makes database compression inefficient. TDengine then uses the WAL file instead of the time-series database as its storage engine for queries in the form of topics. TDengine reads the data from the WAL file; uses a unified query engine instance to perform filtering, transformations, and other operations; and finally pushes the data to consumers. -Tips: Data subscription is to consume data from the wal. If some wal files are deleted according to WAL retention policy, the deleted data can't be consumed any more. So you need to set a reasonable value for parameter `WAL_RETENTION_PERIOD` or `WAL_RETENTION_SIZE` when creating the database and make sure your application consume the data in a timely way to make sure there is no data loss. This behavior is similar to Kafka and other widely used message queue products. +Tips:(c interface for example) +1. A consumption group consumes all data under the same topic, and different consumption groups are independent of each other; +2. A consumption group consumes all vgroups of the same topic, which can be composed of multiple consumers, but a vgroup is only consumed by one consumer. If the number of consumers exceeds the number of vgroups, the excess consumers do not consume data; +3. On the server side, only one offset is saved for each vgroup, and the offsets for each vgroup are monotonically increasing, but not necessarily continuous. There is no correlation between the offsets of various vgroups; +4. Each poll server will return a result block, which belongs to a vgroup and may contain data from multiple versions of wal. This block can be accessed through tmq_get_vgroup_offset. The offset interface obtains the offset of the first record in the block; +5. If a consumer group has never committed an offset, when its member consumers restart and pull data again, they start consuming from the set value of the parameter auto.offset.reset; In a consumer lifecycle, the client locally records the offset of the most recent pull data and will not pull duplicate data; +6. If a consumer terminates abnormally (without calling tmq_close), they need to wait for about 12 seconds to trigger their consumer group rebalance. The consumer's status on the server will change to LOST, and after about 1 day, the consumer will be automatically deleted; Exit normally, and after exiting, the consumer will be deleted; Add a new consumer, wait for about 2 seconds to trigger Rebalance, and the consumer's status on the server will change to ready; +7. The consumer group Rebalance will reassign Vgroups to all consumer members in the ready state of the group, and consumers can only assign/see/commit/poll operations to the Vgroups they are responsible for; +8. Consumers can tmq_position to obtain the offset of the current consumption, seek to the specified offset, and consume again; +9. Seek points the position to the specified offset without executing the commit operation. Once the seek is successful, it can poll the specified offset and subsequent data; +10. Before the seek operation, tmq must be call tmq_get_topic_assignment, The assignment interface obtains the vgroup ID and offset range of the consumer. The seek operation will detect whether the vgroup ID and offset are legal, and if they are illegal, an error will be reported; +11. Due to the existence of a WAL expiration deletion mechanism, even if the seek operation is successful, it is possible that the offset has expired when polling data. If the offset of poll is less than the WAL minimum version number, it will be consumed from the WAL minimum version number; +12. The tmq_get_vgroup_offset interface obtains the offset of the first data in the result block where the record is located. When seeking to this offset, it will consume all the data in this block. Refer to point four; +13. Data subscription is to consume data from the wal. If some wal files are deleted according to WAL retention policy, the deleted data can't be consumed any more. So you need to set a reasonable value for parameter `WAL_RETENTION_PERIOD` or `WAL_RETENTION_SIZE` when creating the database and make sure your application consume the data in a timely way to make sure there is no data loss. This behavior is similar to Kafka and other widely used message queue products. ## Data Schema and API @@ -33,39 +46,58 @@ The related schemas and APIs in various languages are described as follows: ```c -typedef struct tmq_t tmq_t; -typedef struct tmq_conf_t tmq_conf_t; -typedef struct tmq_list_t tmq_list_t; - -typedef void(tmq_commit_cb(tmq_t *, int32_t code, void *param)); - -DLL_EXPORT tmq_list_t *tmq_list_new(); -DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); -DLL_EXPORT void tmq_list_destroy(tmq_list_t *); -DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); -DLL_EXPORT const char *tmq_err2str(int32_t code); - -DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); -DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); -DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); -DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); -DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); -DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); - -enum tmq_conf_res_t { - TMQ_CONF_UNKNOWN = -2, - TMQ_CONF_INVALID = -1, - TMQ_CONF_OK = 0, -}; -typedef enum tmq_conf_res_t tmq_conf_res_t; - -DLL_EXPORT tmq_conf_t *tmq_conf_new(); -DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); -DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); -DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); -``` - -For more information, see [C/C++ Connector](/reference/connector/cpp). + typedef struct tmq_t tmq_t; + typedef struct tmq_conf_t tmq_conf_t; + typedef struct tmq_list_t tmq_list_t; + + typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param)); + + typedef enum tmq_conf_res_t { + TMQ_CONF_UNKNOWN = -2, + TMQ_CONF_INVALID = -1, + TMQ_CONF_OK = 0, + } tmq_conf_res_t; + + typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; // The last version of wal + 1 + } tmq_topic_assignment; + + DLL_EXPORT tmq_conf_t *tmq_conf_new(); + DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); + DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); + DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); + + DLL_EXPORT tmq_list_t *tmq_list_new(); + DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); + DLL_EXPORT void tmq_list_destroy(tmq_list_t *); + DLL_EXPORT int32_t tmq_list_get_size(const tmq_list_t *); + DLL_EXPORT char **tmq_list_to_c_array(const tmq_list_t *); + + DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); + DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); + DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); + DLL_EXPORT int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics); + DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); + DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); + DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); //Commit the msg’s offset + 1 + DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); + DLL_EXPORT int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); + DLL_EXPORT void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param); + DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment,int32_t *numOfAssignment); + DLL_EXPORT void tmq_free_assignment(tmq_topic_assignment* pAssignment); + DLL_EXPORT int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); + DLL_EXPORT int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId); // The current offset is the offset of the last consumed message + 1 + DLL_EXPORT int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId); + + DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res); + DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res); + DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); + DLL_EXPORT int64_t tmq_get_vgroup_offset(TAOS_RES* res); // Get current offset of the result + DLL_EXPORT const char *tmq_err2str(int32_t code); +``` The following example is based on the smart meter table described in Data Models. For complete sample code, see the C language section below. diff --git a/docs/en/12-taos-sql/25-grant.md b/docs/en/12-taos-sql/25-grant.md index c214e11876c77f4c617e1103b14ee46e6d211ca9..5ebed12b59ed03b6e42acaecec3b6ceea050d088 100644 --- a/docs/en/12-taos-sql/25-grant.md +++ b/docs/en/12-taos-sql/25-grant.md @@ -4,7 +4,7 @@ sidebar_label: Access Control description: This document describes how to manage users and permissions in TDengine. --- -This document describes how to manage permissions in TDengine. +User and Access control is a distingguished feature of TDengine enterprise edition. In this section, only the most fundamental functionalities of user and access control are demonstrated. To get the full knowledge of user and access control, please contact the TDengine team. ## Create a User diff --git a/docs/en/14-reference/03-connector/03-cpp.mdx b/docs/en/14-reference/03-connector/03-cpp.mdx index 13029dbe916281d671996254f5dc6069df49db95..0009902425ab5911286a3cd388f3c02998e6d85f 100644 --- a/docs/en/14-reference/03-connector/03-cpp.mdx +++ b/docs/en/14-reference/03-connector/03-cpp.mdx @@ -378,7 +378,7 @@ In addition to writing data using the SQL method or the parameter binding API, w - `TAOS_RES* taos_schemaless_insert(TAOS* taos, const char* lines[], int numLines, int protocol, int precision)` **Function description** - This interface writes the text data of the line protocol to TDengine. + - This interface writes the text data of the line protocol to TDengine. **Parameter description** - taos: database connection, established by the `taos_connect()` function. @@ -387,12 +387,13 @@ In addition to writing data using the SQL method or the parameter binding API, w - protocol: the protocol type of the lines, used to identify the text data format. - precision: precision string for the timestamp in the text data. - **return value** - TAOS_RES structure, application can get error message by using `taos_errstr()` and also error code by using `taos_errno()`. + **Return value** + - TAOS_RES structure, application can get error message by using `taos_errstr()` and also error code by using `taos_errno()`. In some cases, the returned TAOS_RES is `NULL`, and it is still possible to call `taos_errno()` to safely get the error code information. The returned TAOS_RES needs to be freed by the caller in order to avoid memory leaks. **Description** + The protocol type is enumerated and contains the following three formats. - TSDB_SML_LINE_PROTOCOL: InfluxDB line protocol (Line Protocol) @@ -427,3 +428,89 @@ In addition to writing data using the SQL method or the parameter binding API, w - Within _raw interfaces represent data through the passed parameters lines and len. In order to solve the problem that the original interface data contains '\0' and is truncated. The totalRows pointer returns the number of parsed data rows. - Within _ttl interfaces can pass the ttl parameter to control the ttl expiration time of the table. - Within _reqid interfaces can track the entire call chain by passing the reqid parameter. + +### Subscription API + +- `int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, int32_t *numOfAssignment)` +- `void tmq_free_assignment(tmq_topic_assignment* pAssignment)` + + tmq_topic_assignment defined as follows: + ```c + typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; + } tmq_topic_assignment; + ``` + **Function description** + - tmq_get_topic_assignment get the current vgroup information of this consumer + + **Parameter description** + - numOfAssignment:the num of vgroups assigned to this consumer + - assignment:the information of vgroups, needed to be freed by tmq_free_assignment + + **Return value** + - zero success,none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId)` + **Function description** + - get the committed offset + + **Return value** + - the value of committed offset, -2147467247 means no committed value, Other values less than 0 indicate failure + +- `int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg)` +- `void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param)` +- `int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` +- `void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param)` + + **Function description** + + The commit interface is divided into two types, each with synchronous and asynchronous interfaces: + - The first type: based on message submission, submit the progress in the message. If the message passes NULL, submit the current progress of all vgroups consumed by the current consumer: tmq_commit_sync/tmq_commit_async + - The second type: submit based on the offset of a Vgroup in a topic: tmq_commit_offset_sync/tmq_commit_offset_async + + **Parameter description** + - msg:Message consumed, If the message passes NULL, submit the current progress of all vgroups consumed by the current consumer + + **Return value** + - zero success, none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId)` + + **Function description** + - Obtain the current consumption location, which is the next location of the data consumed + + **Return value** + - the current consumption location, none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` + + **Function description** + - Set the offset position of the consumer in a Vgroup of a certain topic to start consumption + + **Return value** + - zero success, none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int32_t int64_t tmq_get_vgroup_offset(TAOS_RES* res)` + + **Function description** + - Obtain the starting offset of the consumed data + + **Parameter description** + - msg:Message consumed + + **Return value** + - the starting offset of the consumed data, none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` + +- `int32_t int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics)` + + **Function description** + - Obtain a list of topics subscribed by consumers + + **Parameter description** + - topics: a list of topics subscribed by consumers,need to be freed by tmq_list_destroy + + **Return value** + - zero success,none zero failed, wrong message can be obtained through `char *tmq_err2str(int32_t code)` \ No newline at end of file diff --git a/docs/en/14-reference/03-connector/04-java.mdx b/docs/en/14-reference/03-connector/04-java.mdx index 69bbd287edbbeae608cee4ec1f1070f10d96532b..b12ef38ea837c81cb5048052666feef91a48b6b6 100644 --- a/docs/en/14-reference/03-connector/04-java.mdx +++ b/docs/en/14-reference/03-connector/04-java.mdx @@ -1091,8 +1091,6 @@ public abstract class ConsumerLoop { config.setProperty("client.id", "1"); config.setProperty("value.deserializer", "com.taosdata.jdbc.tmq.ConsumerTest.ConsumerLoop$ResultDeserializer"); config.setProperty("value.deserializer.encoding", "UTF-8"); - config.setProperty("experimental.snapshot.enable", "true"); - this.consumer = new TaosConsumer<>(config); this.topics = Collections.singletonList("topic_speed"); @@ -1176,7 +1174,6 @@ public abstract class ConsumerLoop { config.setProperty("client.id", "1"); config.setProperty("value.deserializer", "com.taosdata.jdbc.tmq.ConsumerTest.ConsumerLoop$ResultDeserializer"); config.setProperty("value.deserializer.encoding", "UTF-8"); - config.setProperty("experimental.snapshot.enable", "true"); this.consumer = new TaosConsumer<>(config); this.topics = Collections.singletonList("topic_speed"); diff --git a/docs/en/14-reference/08-taos-shell.md b/docs/en/14-reference/08-taos-shell.md index e66da7ec1768227d5ec50ce039bd8f794cf90c48..7e0433a8b2488c52eb7d0a1ea798c775d3123bf5 100644 --- a/docs/en/14-reference/08-taos-shell.md +++ b/docs/en/14-reference/08-taos-shell.md @@ -81,6 +81,14 @@ For example: taos -h h1.taos.com -s "use db; show tables;" ``` +## Export query results to a file + +- You can use ">>" to export the query results to a file, the syntax is like `select * from table >> file`. If there is only file name without path, the file will be generated under the current working directory of TDegnine CLI. + +## Import data from CSV file + +- You can use `insert into table_name file 'fileName'` to import the data from the specified file into the specified table. For example, `insert into d0 file '/root/d0.csv';` means importing the data in file "/root/d0.csv" into table "d0". If there is only file name without path, that means the file is located under current working directory of TDengine CLI. + ## TDengine CLI tips - You can use the up and down keys to iterate the history of commands entered @@ -89,3 +97,5 @@ taos -h h1.taos.com -s "use db; show tables;" - Execute `RESET QUERY CACHE` to clear the local cache of the table schema - Execute SQL statements in batches. You can store a series of shell commands (ending with ;, one line for each SQL command) in a script file and execute the command `source ` in the TDengine CLI to execute all SQL commands in that file automatically - Enter `q` to exit TDengine CLI + + diff --git a/docs/examples/c/tmq_example.c b/docs/examples/c/tmq_example.c index d958428b8ffec9064166ddfd502cc0e2dbd9a200..ca7c23e93b0adb09421761e7681947938cb0f3f9 100644 --- a/docs/examples/c/tmq_example.c +++ b/docs/examples/c/tmq_example.c @@ -227,12 +227,6 @@ tmq_t* build_consumer() { return NULL; } - code = tmq_conf_set(conf, "experimental.snapshot.enable", "false"); - if (TMQ_CONF_OK != code) { - tmq_conf_destroy(conf); - return NULL; - } - tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL); tmq_t* tmq = tmq_consumer_new(conf, NULL, 0); diff --git a/docs/examples/go/sub/main.go b/docs/examples/go/sub/main.go index cb24e351ab8cc5265cefbed9565d9a404aadf08d..ed335cfdea60990596ebb2eb5d4ed950cca3f3aa 100644 --- a/docs/examples/go/sub/main.go +++ b/docs/examples/go/sub/main.go @@ -35,7 +35,6 @@ func main() { "td.connect.port": "6030", "client.id": "test_tmq_client", "enable.auto.commit": "false", - "experimental.snapshot.enable": "true", "msg.with.table.name": "true", }) if err != nil { diff --git a/docs/zh/07-develop/07-tmq.mdx b/docs/zh/07-develop/07-tmq.mdx index 38b91d7cea5a5aa0e18a43044a15136e8d66628e..6852d5551e7d41e8aecdfe571bb186e3c6747b7d 100644 --- a/docs/zh/07-develop/07-tmq.mdx +++ b/docs/zh/07-develop/07-tmq.mdx @@ -25,7 +25,20 @@ import CDemo from "./_sub_c.mdx"; 本文档不对消息队列本身的基础知识做介绍,如果需要了解,请自行搜索。 -注意:数据订阅是从 WAL 消费数据,如果一些 WAL 文件被基于 WAL 保留策略删除,则已经删除的 WAL 文件中的数据就无法再消费到。需要根据业务需要在创建数据库时合理设置 `WAL_RETENTION_PERIOD` 或 `WAL_RETENTION_SIZE` ,并确保应用及时消费数据,这样才不会产生数据丢失的现象。数据订阅的行为与 Kafka 等广泛使用的消息队列类产品的行为相似。 +说明(以c接口为例): +1. 一个消费组消费同一个topic下的所有数据,不同消费组之间相互独立; +2. 一个消费组消费同一个topic所有的vgroup,消费组可由多个消费者组成,但一个vgroup仅被一个消费者消费,如果消费者数量超过了vgroup数量,多余的消费者不消费数据; +3. 在服务端每个vgroup仅保存一个offset,每个vgroup的offset是单调递增的,但不一定连续。各个vgroup的offset之间没有关联; +4. 每次poll服务端会返回一个结果block,该block属于一个vgroup,可能包含多个wal版本的数据,可以通过 tmq_get_vgroup_offset 接口获得是该block第一条记录的offset; +5. 一个消费组如果从未commit过offset,当其成员消费者重启重新拉取数据时,均从参数auto.offset.reset设定值开始消费;在一个消费者生命周期中,客户端本地记录了最近一次拉取数据的offset,不会拉取重复数据; +6. 消费者如果异常终止(没有调用tmq_close),需等约12秒后触发其所属消费组rebalance,该消费者在服务端状态变为LOST,约1天后该消费者自动被删除;正常退出,退出后就会删除消费者;新增消费者,需等约2秒触发rebalance,该消费者在服务端状态变为ready; +7. 消费组rebalance会对该组所有ready状态的消费者成员重新进行vgroup分配,消费者仅能对自己负责的vgroup进行assignment/seek/commit/poll操作; +8. 消费者可利用 tmq_position 获得当前消费的offset,并seek到指定offset,重新消费; +9. seek将position指向指定offset,不执行commit操作,一旦seek成功,可poll拉取指定offset及以后的数据; +10. seek 操作之前须调用 tmq_get_topic_assignment 接口获取该consumer的vgroup ID和offset范围。seek 操作会检测vgroup ID 和 offset是否合法,如非法将报错; +11. tmq_get_vgroup_offset接口获取的是记录所在结果block块里的第一条数据的offset,当seek至该offset时,将消费到这个block里的全部数据。参见第四点; +12. 由于存在 WAL 过期删除机制,即使seek 操作成功,poll数据时有可能offset已失效。如果poll 的offset 小于 WAL 最小版本号,将会从WAL最小版本号消费; +13. 数据订阅是从 WAL 消费数据,如果一些 WAL 文件被基于 WAL 保留策略删除,则已经删除的 WAL 文件中的数据就无法再消费到。需要根据业务需要在创建数据库时合理设置 `WAL_RETENTION_PERIOD` 或 `WAL_RETENTION_SIZE` ,并确保应用及时消费数据,这样才不会产生数据丢失的现象。数据订阅的行为与 Kafka 等广泛使用的消息队列类产品的行为相似; ## 主要数据结构和 API @@ -35,39 +48,60 @@ import CDemo from "./_sub_c.mdx"; ```c -typedef struct tmq_t tmq_t; -typedef struct tmq_conf_t tmq_conf_t; -typedef struct tmq_list_t tmq_list_t; - -typedef void(tmq_commit_cb(tmq_t *, int32_t code, void *param)); - -DLL_EXPORT tmq_list_t *tmq_list_new(); -DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); -DLL_EXPORT void tmq_list_destroy(tmq_list_t *); -DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); -DLL_EXPORT const char *tmq_err2str(int32_t code); - -DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); -DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); -DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); -DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); -DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); -DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); - -enum tmq_conf_res_t { - TMQ_CONF_UNKNOWN = -2, - TMQ_CONF_INVALID = -1, - TMQ_CONF_OK = 0, -}; -typedef enum tmq_conf_res_t tmq_conf_res_t; - -DLL_EXPORT tmq_conf_t *tmq_conf_new(); -DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); -DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); -DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); -``` - -这些 API 的文档请见 [C/C++ Connector](../../connector/cpp),下面介绍一下它们的具体用法(超级表和子表结构请参考“数据建模”一节),完整的示例代码请见下面 C 语言的示例代码。 + typedef struct tmq_t tmq_t; + typedef struct tmq_conf_t tmq_conf_t; + typedef struct tmq_list_t tmq_list_t; + + typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param)); + + typedef enum tmq_conf_res_t { + TMQ_CONF_UNKNOWN = -2, + TMQ_CONF_INVALID = -1, + TMQ_CONF_OK = 0, +} tmq_conf_res_t; + + typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; +} tmq_topic_assignment; + + DLL_EXPORT tmq_conf_t *tmq_conf_new(); + DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); + DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); + DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); + + DLL_EXPORT tmq_list_t *tmq_list_new(); + DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); + DLL_EXPORT void tmq_list_destroy(tmq_list_t *); + DLL_EXPORT int32_t tmq_list_get_size(const tmq_list_t *); + DLL_EXPORT char **tmq_list_to_c_array(const tmq_list_t *); + + DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); + DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); + DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); + DLL_EXPORT int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics); + DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); + DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); + DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); + DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); + DLL_EXPORT int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); + DLL_EXPORT void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param); + DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment,int32_t *numOfAssignment); + DLL_EXPORT void tmq_free_assignment(tmq_topic_assignment* pAssignment); + DLL_EXPORT int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); + DLL_EXPORT int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId); + DLL_EXPORT int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId); + + DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res); + DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res); + DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); + DLL_EXPORT int64_t tmq_get_vgroup_offset(TAOS_RES* res); + DLL_EXPORT const char *tmq_err2str(int32_t code);DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); +``` + +下面介绍一下它们的具体用法(超级表和子表结构请参考“数据建模”一节),完整的示例代码请见下面 C 语言的示例代码。 diff --git a/docs/zh/08-connector/10-cpp.mdx b/docs/zh/08-connector/10-cpp.mdx index 9c5095f09cce0a833757da377e8c19be7a7e310d..c0723cd85c5b13081589a1670a5d2a588fc8930d 100644 --- a/docs/zh/08-connector/10-cpp.mdx +++ b/docs/zh/08-connector/10-cpp.mdx @@ -467,21 +467,22 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 - `TAOS_RES* taos_schemaless_insert(TAOS* taos, const char* lines[], int numLines, int protocol, int precision)` **功能说明** - 该接口将行协议的文本数据写入到 TDengine 中。 + - 该接口将行协议的文本数据写入到 TDengine 中。 **参数说明** - taos: 数据库连接,通过 `taos_connect()` 函数建立的数据库连接。 - lines:文本数据。满足解析格式要求的无模式文本字符串。 - numLines:文本数据的行数,不能为 0 。 - protocol: 行协议类型,用于标识文本数据格式。 - precision:文本数据中的时间戳精度字符串。 + - taos: 数据库连接,通过 `taos_connect()` 函数建立的数据库连接。 + - lines:文本数据。满足解析格式要求的无模式文本字符串。 + - numLines:文本数据的行数,不能为 0 。 + - protocol: 行协议类型,用于标识文本数据格式。 + - precision:文本数据中的时间戳精度字符串。 **返回值** - TAOS_RES 结构体,应用可以通过使用 `taos_errstr()` 获得错误信息,也可以使用 `taos_errno()` 获得错误码。 + - TAOS_RES 结构体,应用可以通过使用 `taos_errstr()` 获得错误信息,也可以使用 `taos_errno()` 获得错误码。 在某些情况下,返回的 TAOS_RES 为 `NULL`,此时仍然可以调用 `taos_errno()` 来安全地获得错误码信息。 返回的 TAOS_RES 需要调用方来负责释放,否则会出现内存泄漏。 **说明** + 协议类型是枚举类型,包含以下三种格式: - TSDB_SML_LINE_PROTOCOL:InfluxDB 行协议(Line Protocol) @@ -515,3 +516,90 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 - 带_raw的接口通过传递的参数lines指针和长度len来表示数据,为了解决原始接口数据包含'\0'而被截断的问题。totalRows指针返回解析出来的数据行数。 - 带_ttl的接口可以传递ttl参数来控制建表的ttl到期时间。 - 带_reqid的接口可以通过传递reqid参数来追踪整个的调用链。 + +### 数据订阅 API + +- `int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, int32_t *numOfAssignment)` +- `void tmq_free_assignment(tmq_topic_assignment* pAssignment)` + + tmq_topic_assignment结构体定义如下: + ```c + typedef struct tmq_topic_assignment { + int32_t vgId; + int64_t currentOffset; + int64_t begin; + int64_t end; + } tmq_topic_assignment; + ``` + **功能说明** + - tmq_get_topic_assignment 接口返回当前consumer分配的vgroup的信息,每个vgroup的信息包括vgId,wal的最大最小offset,以及当前消费到的offset。 + + **参数说明** + - numOfAssignment :分配给该consumer有效的vgroup个数。 + - assignment :分配的信息,数据大小为numOfAssignment,需要通过 tmq_free_assignment 接口释放。 + + **返回值** + - 错误码,0成功,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息。 + +- `int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId)` + **功能说明** + - 获取当前 consumer 在某个 topic 和 vgroup上的 commit 位置。 + + **返回值** + - 当前commit的位置,-2147467247表示没有消费进度,其他小于0的值表示失败,错误码就是返回值 + +- `int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg)` +- `void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param)` +- `int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` +- `void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param)` + + **功能说明** + + commit接口分为两种类型,每种类型有同步和异步接口: + - 第一种类型:根据消息提交,提交消息里的进度,如果消息传NULL,提交当前consumer所有消费的vgroup的当前进度 : tmq_commit_sync/tmq_commit_async + - 第二种类型:根据某个topic的某个vgroup的offset提交 : tmq_commit_offset_sync/tmq_commit_offset_async + + **参数说明** + - msg:消费到的消息结构,如果msg传NULL,提交当前consumer所有消费的vgroup的当前进度 + + **返回值** + - 错误码,0成功,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 + +- `int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId)` + + **功能说明** + - 获取当前消费位置,为消费到的数据位置的下一个位置 + + **返回值** + - 消费位置,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 + +- `int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` + + **功能说明** + - 设置 consumer 在某个topic的某个vgroup的 offset位置,开始消费 + + **返回值** + - 错误码,0成功,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 + +- `int32_t int64_t tmq_get_vgroup_offset(TAOS_RES* res)` + + **功能说明** + + 获取 poll 消费到的数据的起始offset + + **参数说明** + - msg:消费到的消息结构 + + **返回值** + - 消费到的offset,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 + +- `int32_t int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics)` + + **功能说明** + + 获取消费者订阅的 topic 列表 + **参数说明** + - topics: 获取的 topic 列表存储在这个结构中,接口内分配内存,需调用tmq_list_destroy释放 + + **返回值** + - 错误码,0成功,非0失败,可通过 `char *tmq_err2str(int32_t code)` 函数获取错误信息 \ No newline at end of file diff --git a/docs/zh/12-taos-sql/14-stream.md b/docs/zh/12-taos-sql/14-stream.md index 634f50356d5898f1b000c24f3c2a7968a49cc07c..43bdc9b04ae9bd8ee618c4067eabb425c31cc670 100644 --- a/docs/zh/12-taos-sql/14-stream.md +++ b/docs/zh/12-taos-sql/14-stream.md @@ -249,3 +249,12 @@ T = 最新事件时间 - DELETE_MARK - [unique](../function/#unique) - [mode](../function/#mode) +## 暂停、恢复流计算 +1.流计算暂停计算任务 +PAUSE STREAM [IF EXISTS] stream_name; +没有指定IF EXISTS,如果该stream不存在,则报错;如果存在,则暂停流计算。指定了IF EXISTS,如果该stream不存在,则返回成功;如果存在,则暂停流计算 + +2.流计算恢复计算任务 +RESUME STREAM [IF EXISTS] [IGNORE UNTREATED] stream_name; +没有指定IF EXISTS,如果该stream不存在,则报错,如果存在,则恢复流计算;指定了IF EXISTS,如果stream不存在,则返回成功;如果存在,则恢复流计算。如果指定IGNORE UNTREATED,则恢复流计算时,忽略流计算暂停期间写入的数据。 + diff --git a/docs/zh/12-taos-sql/25-grant.md b/docs/zh/12-taos-sql/25-grant.md index a9c3910500d7ad3ba2435eb4bebb74085a10da78..d53f951e677ce527b4a3ef070bee16794da1b73f 100644 --- a/docs/zh/12-taos-sql/25-grant.md +++ b/docs/zh/12-taos-sql/25-grant.md @@ -4,7 +4,7 @@ title: 权限管理 description: 企业版中才具有的权限管理功能 --- -本节讲述如何在 TDengine 中进行权限管理的相关操作。 +本节讲述如何在 TDengine 中进行权限管理的相关操作。权限管理是 TDengine 企业版的特有功能,本节只列举了一些基本的权限管理功能作为示例,更丰富的权限管理请联系 TDengine 销售或市场团队。 ## 创建用户 diff --git a/docs/zh/14-reference/08-taos-shell.md b/docs/zh/14-reference/08-taos-shell.md index 3423cf35bbeb54c526e2bbad7ec3eae230cce07b..1caa580b73945c0c8b38b842e65fd481f54317fd 100644 --- a/docs/zh/14-reference/08-taos-shell.md +++ b/docs/zh/14-reference/08-taos-shell.md @@ -89,3 +89,11 @@ taos -h h1.taos.com -s "use db; show tables;" - 执行 `RESET QUERY CACHE` 可清除本地表 Schema 的缓存 - 批量执行 SQL 语句。可以将一系列的 TDengine CLI 命令(以英文 ; 结尾,每个 SQL 语句为一行)按行存放在文件里,在 TDengine CLI 里执行命令 `source ` 自动执行该文件里所有的 SQL 语句 - 输入 `q` 或 `quit` 或 `exit` 回车,可以退出 TDengine CLI + +## TDengine CLI 导出查询结果到文件中 + +- 可以使用符号 “>>” 导出查询结果到某个文件中,语法为: sql 查询语句 >> ‘输出文件名’; 输出文件如果不写路径的话,将输出至当前目录下。如 select * from d0 >> ‘/root/d0.csv’; 将把查询结果输出到 /root/d0.csv 中。 + +## TDengine CLI 导入文件中的数据到表中 + +- 可以使用 insert into table_name file '输入文件名',把上一步中导出的数据文件再导入到指定表中。如 insert into d0 file '/root/d0.csv'; 表示把上面导出的数据全部再导致至 d0 表中。 diff --git a/examples/c/tmq.c b/examples/c/tmq.c index e1133c109e72873ddcf4b89a818d878d56a628f1..136c54b874dd27fb0e353249c3bdcf48cff71052 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -228,11 +228,6 @@ tmq_t* build_consumer() { tmq_conf_destroy(conf); return NULL; } - code = tmq_conf_set(conf, "experimental.snapshot.enable", "false"); - if (TMQ_CONF_OK != code) { - tmq_conf_destroy(conf); - return NULL; - } tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL); tmq = tmq_consumer_new(conf, NULL, 0); diff --git a/include/client/taos.h b/include/client/taos.h index 3cc2d907ab5ca18d16a9553d336672d67e4f974c..5b7946c9ada8174e7fcf43beb2910b919aa50985 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -260,19 +260,14 @@ typedef struct tmq_t tmq_t; typedef struct tmq_conf_t tmq_conf_t; typedef struct tmq_list_t tmq_list_t; -typedef void(tmq_commit_cb(tmq_t *, int32_t code, void *param)); +typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param)); -DLL_EXPORT tmq_list_t *tmq_list_new(); -DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); -DLL_EXPORT void tmq_list_destroy(tmq_list_t *); -DLL_EXPORT int32_t tmq_list_get_size(const tmq_list_t *); -DLL_EXPORT char **tmq_list_to_c_array(const tmq_list_t *); - -DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); - -DLL_EXPORT const char *tmq_err2str(int32_t code); +typedef enum tmq_conf_res_t { + TMQ_CONF_UNKNOWN = -2, + TMQ_CONF_INVALID = -1, + TMQ_CONF_OK = 0, +} tmq_conf_res_t; -/* ------------------------TMQ CONSUMER INTERFACE------------------------ */ typedef struct tmq_topic_assignment { int32_t vgId; int64_t currentOffset; @@ -280,43 +275,38 @@ typedef struct tmq_topic_assignment { int64_t end; } tmq_topic_assignment; +DLL_EXPORT tmq_conf_t *tmq_conf_new(); +DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); +DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); +DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); + +DLL_EXPORT tmq_list_t *tmq_list_new(); +DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *); +DLL_EXPORT void tmq_list_destroy(tmq_list_t *); +DLL_EXPORT int32_t tmq_list_get_size(const tmq_list_t *); +DLL_EXPORT char **tmq_list_to_c_array(const tmq_list_t *); + +DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen); DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list); DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq); DLL_EXPORT int32_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics); DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout); DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq); -DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); +DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg); //Commit the msg’s offset + 1 DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param); DLL_EXPORT int32_t tmq_commit_offset_sync(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); DLL_EXPORT void tmq_commit_offset_async(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset, tmq_commit_cb *cb, void *param); -DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment, - int32_t *numOfAssignment); +DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char *pTopicName, tmq_topic_assignment **assignment,int32_t *numOfAssignment); DLL_EXPORT void tmq_free_assignment(tmq_topic_assignment* pAssignment); DLL_EXPORT int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset); +DLL_EXPORT int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId); // The current offset is the offset of the last consumed message + 1 +DLL_EXPORT int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId); DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res); DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res); DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); DLL_EXPORT int64_t tmq_get_vgroup_offset(TAOS_RES* res); -DLL_EXPORT int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId); -DLL_EXPORT int64_t tmq_committed(tmq_t *tmq, const char *pTopicName, int32_t vgId); - -/* ----------------------TMQ CONFIGURATION INTERFACE---------------------- */ - -enum tmq_conf_res_t { - TMQ_CONF_UNKNOWN = -2, - TMQ_CONF_INVALID = -1, - TMQ_CONF_OK = 0, -}; - -typedef enum tmq_conf_res_t tmq_conf_res_t; - -DLL_EXPORT tmq_conf_t *tmq_conf_new(); -DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value); -DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf); -DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param); - -/* -------------------------TMQ MSG HANDLE INTERFACE---------------------- */ +DLL_EXPORT const char *tmq_err2str(int32_t code); /* ------------------------------ TAOSX -----------------------------------*/ // note: following apis are unstable diff --git a/include/common/tcommon.h b/include/common/tcommon.h index bdfb1d32b4642e265b468e4f4e3a7bd476b07ff9..8482ba8a7866f396b94246adc7a96d0cd710bc9b 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -152,6 +152,8 @@ enum { STREAM_INPUT__DATA_RETRIEVE, STREAM_INPUT__GET_RES, STREAM_INPUT__CHECKPOINT, + STREAM_INPUT__CHECKPOINT_TRIGGER, + STREAM_INPUT__TRANS_STATE, STREAM_INPUT__REF_DATA_BLOCK, STREAM_INPUT__DESTROY, }; @@ -168,7 +170,9 @@ typedef enum EStreamType { STREAM_PULL_DATA, STREAM_PULL_OVER, STREAM_FILL_OVER, + STREAM_CHECKPOINT, STREAM_CREATE_CHILD_TABLE, + STREAM_TRANS_STATE, } EStreamType; #pragma pack(push, 1) diff --git a/include/common/tdatablock.h b/include/common/tdatablock.h index c0412d2617500196d2d4d31f9ff49f7bede9a08d..dac723aa584605f971f999426b3e2807475a92a9 100644 --- a/include/common/tdatablock.h +++ b/include/common/tdatablock.h @@ -241,7 +241,7 @@ int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols); const char* blockDecode(SSDataBlock* pBlock, const char* pData); // for debug -char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf); +char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf, const char* taskIdStr); int32_t buildSubmitReqFromDataBlock(SSubmitReq2** pReq, const SSDataBlock* pDataBlocks, const STSchema* pTSchema, int64_t uid, int32_t vgId, tb_uid_t suid); diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 0d3852cbab009968133320f1c00899bbf4233b21..5fd174e8737d13155a524be3a55a88e3a912fe56 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -199,6 +199,7 @@ extern bool tsFilterScalarMode; extern int32_t tsKeepTimeOffset; extern int32_t tsMaxStreamBackendCache; extern int32_t tsPQSortMemThreshold; +extern int32_t tsResolveFQDNRetryTime; // #define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index ea3dca06f3485ead43eb416b94ce4a869763e0b4..d7409da126b2044f8216a08c6a90e58fab4a4ad7 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -231,6 +231,7 @@ typedef struct SField { uint8_t type; int8_t flags; int32_t bytes; + char comment[TSDB_COL_COMMENT_LEN]; } SField; typedef struct SRetention { @@ -309,6 +310,7 @@ struct SSchema { col_id_t colId; int32_t bytes; char name[TSDB_COL_NAME_LEN]; + char comment[TSDB_COL_COMMENT_LEN]; }; struct SSchema2 { @@ -2390,6 +2392,9 @@ typedef struct { int8_t type; int8_t flags; int32_t bytes; + bool hasColComment; + char* colComment; + int32_t colCommentLen; // TSDB_ALTER_TABLE_DROP_COLUMN // TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES int8_t colModType; diff --git a/include/common/tmsgdef.h b/include/common/tmsgdef.h index 232551007d2c7ec9c038b9d31420606b95bd5cb9..60172bce3d166c67f06c22163d009d492faf9fa7 100644 --- a/include/common/tmsgdef.h +++ b/include/common/tmsgdef.h @@ -254,7 +254,6 @@ enum { TD_DEF_MSG_TYPE(TDMT_STREAM_RETRIEVE, "stream-retrieve", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_SCAN_HISTORY, "stream-scan-history", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_SCAN_HISTORY_FINISH, "stream-scan-history-finish", NULL, NULL) - TD_DEF_MSG_TYPE(TDMT_STREAM_TRANSFER_STATE, "stream-transfer-state", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_CHECK, "stream-task-check", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_CHECKPOINT, "stream-checkpoint", NULL, NULL) TD_DEF_MSG_TYPE(TDMT_STREAM_TASK_REPORT_CHECKPOINT, "stream-report-checkpoint", NULL, NULL) diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h index 8a6b7b50209e0d35247cc3211f71ad43d991fa14..8225e4692d5b15814b5abd3c93d3fe3e667097c8 100644 --- a/include/common/ttokendef.h +++ b/include/common/ttokendef.h @@ -16,105 +16,105 @@ #ifndef _TD_COMMON_TOKEN_H_ #define _TD_COMMON_TOKEN_H_ -#define TK_OR 1 -#define TK_AND 2 -#define TK_UNION 3 -#define TK_ALL 4 -#define TK_MINUS 5 -#define TK_EXCEPT 6 -#define TK_INTERSECT 7 -#define TK_NK_BITAND 8 -#define TK_NK_BITOR 9 -#define TK_NK_LSHIFT 10 -#define TK_NK_RSHIFT 11 -#define TK_NK_PLUS 12 -#define TK_NK_MINUS 13 -#define TK_NK_STAR 14 -#define TK_NK_SLASH 15 -#define TK_NK_REM 16 -#define TK_NK_CONCAT 17 -#define TK_CREATE 18 -#define TK_ACCOUNT 19 -#define TK_NK_ID 20 -#define TK_PASS 21 -#define TK_NK_STRING 22 -#define TK_ALTER 23 -#define TK_PPS 24 -#define TK_TSERIES 25 -#define TK_STORAGE 26 -#define TK_STREAMS 27 -#define TK_QTIME 28 -#define TK_DBS 29 -#define TK_USERS 30 -#define TK_CONNS 31 -#define TK_STATE 32 -#define TK_USER 33 -#define TK_ENABLE 34 -#define TK_NK_INTEGER 35 -#define TK_SYSINFO 36 -#define TK_DROP 37 -#define TK_GRANT 38 -#define TK_ON 39 -#define TK_TO 40 -#define TK_REVOKE 41 -#define TK_FROM 42 -#define TK_SUBSCRIBE 43 -#define TK_NK_COMMA 44 -#define TK_READ 45 -#define TK_WRITE 46 -#define TK_NK_DOT 47 -#define TK_WITH 48 -#define TK_DNODE 49 -#define TK_PORT 50 -#define TK_DNODES 51 -#define TK_RESTORE 52 -#define TK_NK_IPTOKEN 53 -#define TK_FORCE 54 -#define TK_UNSAFE 55 -#define TK_LOCAL 56 -#define TK_QNODE 57 -#define TK_BNODE 58 -#define TK_SNODE 59 -#define TK_MNODE 60 -#define TK_VNODE 61 -#define TK_DATABASE 62 -#define TK_USE 63 -#define TK_FLUSH 64 -#define TK_TRIM 65 -#define TK_COMPACT 66 -#define TK_IF 67 -#define TK_NOT 68 -#define TK_EXISTS 69 -#define TK_BUFFER 70 -#define TK_CACHEMODEL 71 -#define TK_CACHESIZE 72 -#define TK_COMP 73 -#define TK_DURATION 74 -#define TK_NK_VARIABLE 75 -#define TK_MAXROWS 76 -#define TK_MINROWS 77 -#define TK_KEEP 78 -#define TK_PAGES 79 -#define TK_PAGESIZE 80 -#define TK_TSDB_PAGESIZE 81 -#define TK_PRECISION 82 -#define TK_REPLICA 83 -#define TK_VGROUPS 84 -#define TK_SINGLE_STABLE 85 -#define TK_RETENTIONS 86 -#define TK_SCHEMALESS 87 -#define TK_WAL_LEVEL 88 -#define TK_WAL_FSYNC_PERIOD 89 -#define TK_WAL_RETENTION_PERIOD 90 -#define TK_WAL_RETENTION_SIZE 91 -#define TK_WAL_ROLL_PERIOD 92 -#define TK_WAL_SEGMENT_SIZE 93 -#define TK_STT_TRIGGER 94 -#define TK_TABLE_PREFIX 95 -#define TK_TABLE_SUFFIX 96 -#define TK_NK_COLON 97 -#define TK_MAX_SPEED 98 -#define TK_START 99 +#define TK_OR 1 +#define TK_AND 2 +#define TK_UNION 3 +#define TK_ALL 4 +#define TK_MINUS 5 +#define TK_EXCEPT 6 +#define TK_INTERSECT 7 +#define TK_NK_BITAND 8 +#define TK_NK_BITOR 9 +#define TK_NK_LSHIFT 10 +#define TK_NK_RSHIFT 11 +#define TK_NK_PLUS 12 +#define TK_NK_MINUS 13 +#define TK_NK_STAR 14 +#define TK_NK_SLASH 15 +#define TK_NK_REM 16 +#define TK_NK_CONCAT 17 +#define TK_CREATE 18 +#define TK_ACCOUNT 19 +#define TK_NK_ID 20 +#define TK_PASS 21 +#define TK_NK_STRING 22 +#define TK_ALTER 23 +#define TK_PPS 24 +#define TK_TSERIES 25 +#define TK_STORAGE 26 +#define TK_STREAMS 27 +#define TK_QTIME 28 +#define TK_DBS 29 +#define TK_USERS 30 +#define TK_CONNS 31 +#define TK_STATE 32 +#define TK_USER 33 +#define TK_ENABLE 34 +#define TK_NK_INTEGER 35 +#define TK_SYSINFO 36 +#define TK_DROP 37 +#define TK_GRANT 38 +#define TK_ON 39 +#define TK_TO 40 +#define TK_REVOKE 41 +#define TK_FROM 42 +#define TK_SUBSCRIBE 43 +#define TK_NK_COMMA 44 +#define TK_READ 45 +#define TK_WRITE 46 +#define TK_NK_DOT 47 +#define TK_WITH 48 +#define TK_DNODE 49 +#define TK_PORT 50 +#define TK_DNODES 51 +#define TK_RESTORE 52 +#define TK_NK_IPTOKEN 53 +#define TK_FORCE 54 +#define TK_UNSAFE 55 +#define TK_LOCAL 56 +#define TK_QNODE 57 +#define TK_BNODE 58 +#define TK_SNODE 59 +#define TK_MNODE 60 +#define TK_VNODE 61 +#define TK_DATABASE 62 +#define TK_USE 63 +#define TK_FLUSH 64 +#define TK_TRIM 65 +#define TK_COMPACT 66 +#define TK_IF 67 +#define TK_NOT 68 +#define TK_EXISTS 69 +#define TK_BUFFER 70 +#define TK_CACHEMODEL 71 +#define TK_CACHESIZE 72 +#define TK_COMP 73 +#define TK_DURATION 74 +#define TK_NK_VARIABLE 75 +#define TK_MAXROWS 76 +#define TK_MINROWS 77 +#define TK_KEEP 78 +#define TK_PAGES 79 +#define TK_PAGESIZE 80 +#define TK_TSDB_PAGESIZE 81 +#define TK_PRECISION 82 +#define TK_REPLICA 83 +#define TK_VGROUPS 84 +#define TK_SINGLE_STABLE 85 +#define TK_RETENTIONS 86 +#define TK_SCHEMALESS 87 +#define TK_WAL_LEVEL 88 +#define TK_WAL_FSYNC_PERIOD 89 +#define TK_WAL_RETENTION_PERIOD 90 +#define TK_WAL_RETENTION_SIZE 91 +#define TK_WAL_ROLL_PERIOD 92 +#define TK_WAL_SEGMENT_SIZE 93 +#define TK_STT_TRIGGER 94 +#define TK_TABLE_PREFIX 95 +#define TK_TABLE_SUFFIX 96 +#define TK_NK_COLON 97 +#define TK_MAX_SPEED 98 +#define TK_START 99 #define TK_TIMESTAMP 100 #define TK_END 101 #define TK_TABLE 102 @@ -130,25 +130,25 @@ #define TK_NK_EQ 112 #define TK_USING 113 #define TK_TAGS 114 -#define TK_BOOL 115 -#define TK_TINYINT 116 -#define TK_SMALLINT 117 -#define TK_INT 118 -#define TK_INTEGER 119 -#define TK_BIGINT 120 -#define TK_FLOAT 121 -#define TK_DOUBLE 122 -#define TK_BINARY 123 -#define TK_NCHAR 124 -#define TK_UNSIGNED 125 -#define TK_JSON 126 -#define TK_VARCHAR 127 -#define TK_MEDIUMBLOB 128 -#define TK_BLOB 129 -#define TK_VARBINARY 130 -#define TK_GEOMETRY 131 -#define TK_DECIMAL 132 -#define TK_COMMENT 133 +#define TK_COMMENT 115 +#define TK_BOOL 116 +#define TK_TINYINT 117 +#define TK_SMALLINT 118 +#define TK_INT 119 +#define TK_INTEGER 120 +#define TK_BIGINT 121 +#define TK_FLOAT 122 +#define TK_DOUBLE 123 +#define TK_BINARY 124 +#define TK_NCHAR 125 +#define TK_UNSIGNED 126 +#define TK_JSON 127 +#define TK_VARCHAR 128 +#define TK_MEDIUMBLOB 129 +#define TK_BLOB 130 +#define TK_VARBINARY 131 +#define TK_GEOMETRY 132 +#define TK_DECIMAL 133 #define TK_MAX_DELAY 134 #define TK_WATERMARK 135 #define TK_ROLLUP 136 diff --git a/include/libs/executor/storageapi.h b/include/libs/executor/storageapi.h index 773f373a2d174121a7396bed1f5827e7bb514987..724d6638db2508bf0ddf88f736099848f62f33a6 100644 --- a/include/libs/executor/storageapi.h +++ b/include/libs/executor/storageapi.h @@ -98,6 +98,16 @@ typedef struct SMTbCursor { int8_t paused; } SMTbCursor; +typedef struct SMCtbCursor { + SMeta *pMeta; + void *pCur; + tb_uid_t suid; + void *pKey; + void *pVal; + int kLen; + int vLen; +} SMCtbCursor; + typedef struct SRowBuffPos { void* pRowBuff; void* pKey; @@ -278,13 +288,15 @@ typedef struct SStoreMeta { void (*getBasicInfo)(void* pVnode, const char** dbname, int32_t* vgId, int64_t* numOfTables, int64_t* numOfNormalTables); // vnodeGetInfo(void *pVnode, const char **dbname, int32_t *vgId) & // metaGetTbNum(SMeta *pMeta) & metaGetNtbNum(SMeta *pMeta); - int64_t (*getNumOfRowsInMem)(void* pVnode); /** int32_t vnodeGetCtbIdList(void *pVnode, int64_t suid, SArray *list); int32_t vnodeGetCtbIdListByFilter(void *pVnode, int64_t suid, SArray *list, bool (*filter)(void *arg), void *arg); int32_t vnodeGetStbIdList(void *pVnode, int64_t suid, SArray *list); */ + SMCtbCursor* (*openCtbCursor)(void *pVnode, tb_uid_t uid, int lock); + void (*closeCtbCursor)(SMCtbCursor *pCtbCur, int lock); + tb_uid_t (*ctbCursorNext)(SMCtbCursor* pCur); } SStoreMeta; typedef struct SStoreMetaReader { diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 402b8f03092789b2ead705f3bd93b1bc235e78bc..eebb69e6bac5514d57fa53166e94aa1fcf377020 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -157,6 +157,8 @@ typedef enum EFunctionType { FUNCTION_TYPE_AVG_MERGE, FUNCTION_TYPE_STDDEV_PARTIAL, FUNCTION_TYPE_STDDEV_MERGE, + FUNCTION_TYPE_IRATE_PARTIAL, + FUNCTION_TYPE_IRATE_MERGE, // geometry functions FUNCTION_TYPE_GEOM_FROM_TEXT = 4250, diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index f0a715e6511af931b7e580dae9a83cf7d447e371..ff020708822578310c355f23f090372205c9d47e 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -23,10 +23,11 @@ extern "C" { #include "query.h" #include "querynodes.h" -#define DESCRIBE_RESULT_COLS 4 -#define DESCRIBE_RESULT_FIELD_LEN (TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE) -#define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE) -#define DESCRIBE_RESULT_NOTE_LEN (8 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_COLS 5 +#define DESCRIBE_RESULT_FIELD_LEN (TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_NOTE_LEN (8 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_COL_COMMENT_LEN (TSDB_COL_COMMENT_LEN) #define SHOW_CREATE_DB_RESULT_COLS 2 #define SHOW_CREATE_DB_RESULT_FIELD1_LEN (TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE) @@ -155,7 +156,7 @@ typedef struct SColumnDefNode { ENodeType type; char colName[TSDB_COL_NAME_LEN]; SDataType dataType; - char comments[TSDB_TB_COMMENT_LEN]; + char comments[TSDB_COL_COMMENT_LEN]; bool sma; } SColumnDefNode; @@ -214,6 +215,7 @@ typedef struct SAlterTableStmt { char newColName[TSDB_COL_NAME_LEN]; STableOptions* pOptions; SDataType dataType; + char colComment[TSDB_COL_COMMENT_LEN]; SValueNode* pVal; } SAlterTableStmt; diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 2319643b09f6a93084a527f5f5d6ceb02e6b891e..8eeeff4148540131537205039edac2976932bd11 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -169,7 +169,7 @@ typedef enum ENodeType { QUERY_NODE_REVOKE_STMT, QUERY_NODE_SHOW_DNODES_STMT, QUERY_NODE_SHOW_MNODES_STMT, - QUERY_NODE_SHOW_MODULES_STMT, +// QUERY_NODE_SHOW_MODULES_STMT, QUERY_NODE_SHOW_QNODES_STMT, QUERY_NODE_SHOW_SNODES_STMT, QUERY_NODE_SHOW_BNODES_STMT, diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 063318332a7cdc0a66c983fdfa464ca8f1bf9a8e..b4f0a67fa0de927ae38d58f03c1bbcbd7b4ad70a 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -107,6 +107,7 @@ typedef struct SScanLogicNode { bool sortPrimaryKey; bool igLastNull; bool groupOrderScan; + bool onlyMetaCtbIdx; // for tag scan with no tbname } SScanLogicNode; typedef struct SJoinLogicNode { @@ -334,7 +335,11 @@ typedef struct SScanPhysiNode { bool groupOrderScan; } SScanPhysiNode; -typedef SScanPhysiNode STagScanPhysiNode; +typedef struct STagScanPhysiNode { + SScanPhysiNode scan; + bool onlyMetaCtbIdx; //no tbname, tag index not used. +} STagScanPhysiNode; + typedef SScanPhysiNode SBlockDistScanPhysiNode; typedef struct SLastRowScanPhysiNode { @@ -603,6 +608,8 @@ typedef struct SSubplan { SNode* pTagCond; SNode* pTagIndexCond; bool showRewrite; + int32_t rowsThreshold; + bool dynamicRowThreshold; } SSubplan; typedef enum EExplainMode { EXPLAIN_MODE_DISABLE = 1, EXPLAIN_MODE_STATIC, EXPLAIN_MODE_ANALYZE } EExplainMode; diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index b9b24917f3dcf3a2a31780e1f9980b93da74efd4..02bb65b7622fdd49be72de93a2d0856be159261f 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -122,6 +122,7 @@ typedef struct { int8_t type; int32_t srcVgId; + int32_t srcTaskId; int32_t childId; int64_t sourceVer; int64_t reqId; @@ -251,6 +252,7 @@ typedef struct SStreamChildEpInfo { int32_t nodeId; int32_t childId; int32_t taskId; + int8_t dataAllowed; SEpSet epSet; } SStreamChildEpInfo; @@ -272,6 +274,7 @@ typedef struct SStreamStatus { int8_t schedStatus; int8_t keepTaskStatus; bool transferState; + bool appendTranstateBlock; // has append the transfer state data block already, todo: remove it int8_t timerActive; // timer is active int8_t pauseAllowed; // allowed task status to be set to be paused } SStreamStatus; @@ -399,8 +402,9 @@ typedef struct { typedef struct { int64_t streamId; + int32_t type; int32_t taskId; - int32_t dataSrcVgId; + int32_t srcVgId; int32_t upstreamTaskId; int32_t upstreamChildId; int32_t upstreamNodeId; @@ -570,8 +574,6 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq); int32_t tDecodeStreamRetrieveReq(SDecoder* pDecoder, SStreamRetrieveReq* pReq); void tDeleteStreamRetrieveReq(SStreamRetrieveReq* pReq); -int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, int32_t numOfBlocks, - int64_t dstTaskId); void tDeleteStreamDispatchReq(SStreamDispatchReq* pReq); int32_t streamSetupScheduleTrigger(SStreamTask* pTask); @@ -579,6 +581,8 @@ int32_t streamSetupScheduleTrigger(SStreamTask* pTask); int32_t streamProcessRunReq(SStreamTask* pTask); int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pMsg, bool exec); int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code); +void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId); +void streamTaskOpenAllUpstreamInput(SStreamTask* pTask); int32_t streamProcessRetrieveReq(SStreamTask* pTask, SStreamRetrieveReq* pReq, SRpcMsg* pMsg); @@ -589,7 +593,6 @@ int32_t streamTaskOutputResultBlock(SStreamTask* pTask, SStreamDataBlock* pBlock bool streamTaskShouldStop(const SStreamStatus* pStatus); bool streamTaskShouldPause(const SStreamStatus* pStatus); bool streamTaskIsIdle(const SStreamTask* pTask); -int32_t streamTaskEndScanWAL(SStreamTask* pTask); SStreamChildEpInfo* streamTaskGetUpstreamTaskEpInfo(SStreamTask* pTask, int32_t taskId); int32_t streamScanExec(SStreamTask* pTask, int32_t batchSize); @@ -626,7 +629,7 @@ int32_t streamSetParamForStreamScannerStep2(SStreamTask* pTask, SVersionRange* p int32_t streamSourceScanHistoryData(SStreamTask* pTask); int32_t streamDispatchScanHistoryFinishMsg(SStreamTask* pTask); -int32_t streamDispatchTransferStateMsg(SStreamTask* pTask); +int32_t appendTranstateIntoInputQ(SStreamTask* pTask); // agg level int32_t streamTaskScanHistoryPrepare(SStreamTask* pTask); diff --git a/include/os/osFile.h b/include/os/osFile.h index 0e930027066dbd3f5a0e90810a8a3f5c134637b6..da1f8f8b57378905cd9ba78327858fb59af7d6e0 100644 --- a/include/os/osFile.h +++ b/include/os/osFile.h @@ -76,7 +76,7 @@ int32_t taosUnLockFile(TdFilePtr pFile); int32_t taosUmaskFile(int32_t maskVal); -int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime); +int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime, int32_t *atime); int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno); int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int32_t *mtime); bool taosCheckExistFile(const char *pathname); diff --git a/include/os/osRand.h b/include/os/osRand.h index 27d07e8c6ffe64fe940f592553a20bbe6972ec31..5d907bba154674f1e7db2f5863eb3f715c8226f4 100644 --- a/include/os/osRand.h +++ b/include/os/osRand.h @@ -32,6 +32,8 @@ void taosSeedRand(uint32_t seed); uint32_t taosRand(void); uint32_t taosRandR(uint32_t* pSeed); void taosRandStr(char* str, int32_t size); +void taosRandStr2(char* str, int32_t size); + uint32_t taosSafeRand(void); #ifdef __cplusplus diff --git a/include/util/taoserror.h b/include/util/taoserror.h index b43985074c7d88673f80dac9b02607a66d114b20..a5081f2c7d5949ea6541e07e2b0fa2b7d9ac7d54 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -191,6 +191,7 @@ int32_t* taosGetErrno(); // #define TSDB_CODE_MND_FAILED_TO_CREATE_DIR TAOS_DEF_ERROR_CODE(0, 0x0313) // 2.x // #define TSDB_CODE_MND_FAILED_TO_INIT_STEP TAOS_DEF_ERROR_CODE(0, 0x0314) // 2.x #define TSDB_CODE_MND_USER_DISABLED TAOS_DEF_ERROR_CODE(0, 0x0315) +#define TSDB_CODE_MND_INVALID_PLATFORM TAOS_DEF_ERROR_CODE(0, 0x0316) // mnode-sdb #define TSDB_CODE_SDB_OBJ_ALREADY_THERE TAOS_DEF_ERROR_CODE(0, 0x0320) // internal diff --git a/include/util/tdef.h b/include/util/tdef.h index e4af88bf10291235e07ae7b18674fa064b054683..1e12f12087c426d9cf94cbdb1ac903b0bcabbd27 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -230,6 +230,7 @@ typedef enum ELogicConditionType { #define TSDB_APP_NAME_LEN TSDB_UNI_LEN #define TSDB_TB_COMMENT_LEN 1025 +#define TSDB_COL_COMMENT_LEN 1025 #define TSDB_QUERY_ID_LEN 26 #define TSDB_TRANS_OPER_LEN 16 diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index d0cfd38fb97789543357396590afc30dc3f8ef9a..e45ee9c9329790474f49da163c0486025ab3134e 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -16,7 +16,7 @@ target_include_directories( target_link_libraries( taos INTERFACE api - PRIVATE os util common transport nodes parser command planner catalog scheduler function qcom + PRIVATE os util common transport nodes parser command planner catalog scheduler function qcom geometry ) if(TD_DARWIN_ARM64) @@ -57,7 +57,7 @@ target_include_directories( target_link_libraries( taos_static INTERFACE api - PRIVATE os util common transport nodes parser command planner catalog scheduler function qcom + PRIVATE os util common transport nodes parser command planner catalog scheduler function qcom geometry ) if(${BUILD_TEST}) diff --git a/source/client/inc/clientSml.h b/source/client/inc/clientSml.h index 040064560c20ea267d8d005543a54465d916ee6a..1839c148947462b8770e5875839b31420fb7df97 100644 --- a/source/client/inc/clientSml.h +++ b/source/client/inc/clientSml.h @@ -33,6 +33,7 @@ extern "C" { #include "ttime.h" #include "ttypes.h" #include "cJSON.h" +#include "geosWrapper.h" #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) # define expect(expr,value) (__builtin_expect ((expr),(value)) ) @@ -192,7 +193,7 @@ typedef struct { // SArray *preLineTagKV; SArray *maxTagKVs; - SArray *masColKVs; + SArray *maxColKVs; SSmlLineInfo preLine; STableMeta *currSTableMeta; diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index ffff3df5d02797c0dd6d289e868a12a046d2d9f4..cad32842a0879eab51418ebd2aa0e3d63655d72b 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -1073,6 +1073,7 @@ static int32_t smlModifyDBSchemas(SSmlHandle *info) { return 0; end: + taosHashCancelIterate(info->superTables, tmp); taosHashCleanup(hashTmp); taosMemoryFreeClear(pTableMeta); catalogRefreshTableMeta(info->pCatalog, &conn, &pName, 1); @@ -1191,6 +1192,7 @@ void freeSSmlKv(void *data) { SSmlKv *kv = (SSmlKv *)data; if (kv->keyEscaped) taosMemoryFree((void *)(kv->key)); if (kv->valueEscaped) taosMemoryFree((void *)(kv->value)); + if (kv->type == TSDB_DATA_TYPE_GEOMETRY) geosFreeBuffer((void *)(kv->value)); } void smlDestroyInfo(SSmlHandle *info) { @@ -1433,6 +1435,7 @@ static int32_t smlInsertData(SSmlHandle *info) { code = smlCheckAuth(info, &conn, pName.tname, AUTH_TYPE_WRITE); if(code != TSDB_CODE_SUCCESS){ taosMemoryFree(measure); + taosHashCancelIterate(info->childTables, oneTable); return code; } @@ -1441,6 +1444,7 @@ static int32_t smlInsertData(SSmlHandle *info) { if (code != TSDB_CODE_SUCCESS) { uError("SML:0x%" PRIx64 " catalogGetTableHashVgroup failed. table name: %s", info->id, tableData->childTableName); taosMemoryFree(measure); + taosHashCancelIterate(info->childTables, oneTable); return code; } taosHashPut(info->pVgHash, (const char *)&vg.vgId, sizeof(vg.vgId), (char *)&vg, sizeof(vg)); @@ -1450,6 +1454,7 @@ static int32_t smlInsertData(SSmlHandle *info) { if (unlikely(NULL == pMeta || NULL == (*pMeta)->tableMeta)) { uError("SML:0x%" PRIx64 " NULL == pMeta. table name: %s", info->id, tableData->childTableName); taosMemoryFree(measure); + taosHashCancelIterate(info->childTables, oneTable); return TSDB_CODE_SML_INTERNAL_ERROR; } @@ -1465,6 +1470,7 @@ static int32_t smlInsertData(SSmlHandle *info) { taosMemoryFree(measure); if (code != TSDB_CODE_SUCCESS) { uError("SML:0x%" PRIx64 " smlBindData failed", info->id); + taosHashCancelIterate(info->childTables, oneTable); return code; } oneTable = (SSmlTableInfo **)taosHashIterate(info->childTables, oneTable); diff --git a/source/client/src/clientSmlLine.c b/source/client/src/clientSmlLine.c index 1ee2cfbedf38c17fb557296505323569f590eddc..558c5f4ddbe133cb02fb7d90b26859073457c5d6 100644 --- a/source/client/src/clientSmlLine.c +++ b/source/client/src/clientSmlLine.c @@ -102,6 +102,30 @@ int32_t smlParseValue(SSmlKv *pVal, SSmlMsgBuf *msg) { return TSDB_CODE_TSC_INVALID_VALUE; } + if (pVal->value[0] == 'g' || pVal->value[0] == 'G') { // geometry + if (pVal->value[1] == '"' && pVal->value[pVal->length - 1] == '"' && pVal->length >= sizeof("POINT")+3) { + int32_t code = initCtxGeomFromText(); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + char* tmp = taosMemoryCalloc(pVal->length, 1); + memcpy(tmp, pVal->value + 2, pVal->length - 3); + code = doGeomFromText(tmp, (unsigned char **)&pVal->value, &pVal->length); + taosMemoryFree(tmp); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + pVal->type = TSDB_DATA_TYPE_GEOMETRY; + if (pVal->length > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) { + geosFreeBuffer((void*)(pVal->value)); + return TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN; + } + return TSDB_CODE_SUCCESS; + } + return TSDB_CODE_TSC_INVALID_VALUE; + } + if (pVal->value[0] == 't' || pVal->value[0] == 'T') { if (pVal->length == 1 || (pVal->length == 4 && (pVal->value[1] == 'r' || pVal->value[1] == 'R') && @@ -390,14 +414,14 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin SSmlKv kv = {.key = tag->name, .keyLen = strlen(tag->name), .type = tag->type}; if (tag->type == TSDB_DATA_TYPE_NCHAR) { kv.length = (tag->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE; - } else if (tag->type == TSDB_DATA_TYPE_BINARY) { + } else if (tag->type == TSDB_DATA_TYPE_BINARY || tag->type == TSDB_DATA_TYPE_GEOMETRY) { kv.length = tag->bytes - VARSTR_HEADER_SIZE; } taosArrayPush((*tmp)->cols, &kv); } } info->currSTableMeta = (*tmp)->tableMeta; - info->masColKVs = (*tmp)->cols; + info->maxColKVs = (*tmp)->cols; } } @@ -512,13 +536,13 @@ static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin freeSSmlKv(&kv); return TSDB_CODE_SUCCESS; } - if (cnt >= taosArrayGetSize(info->masColKVs)) { + if (cnt >= taosArrayGetSize(info->maxColKVs)) { info->dataFormat = false; info->reRun = true; freeSSmlKv(&kv); return TSDB_CODE_SUCCESS; } - SSmlKv *maxKV = (SSmlKv *)taosArrayGet(info->masColKVs, cnt); + SSmlKv *maxKV = (SSmlKv *)taosArrayGet(info->maxColKVs, cnt); if (kv.type != maxKV->type) { info->dataFormat = false; info->reRun = true; @@ -663,14 +687,15 @@ int32_t smlParseInfluxString(SSmlHandle *info, char *sql, char *sqlEnd, SSmlLine if (info->dataFormat) { uDebug("SML:0x%" PRIx64 " smlParseInfluxString format true, ts:%" PRId64, info->id, ts); ret = smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, &kv, 0); - if (ret != TSDB_CODE_SUCCESS) { - return ret; + if (ret == TSDB_CODE_SUCCESS) { + ret = smlBuildRow(info->currTableDataCtx); } - ret = smlBuildRow(info->currTableDataCtx); - if (ret != TSDB_CODE_SUCCESS) { + + clearColValArray(info->currTableDataCtx->pValues); + if (unlikely(ret != TSDB_CODE_SUCCESS)) { + smlBuildInvalidDataMsg(&info->msgBuf, "smlBuildCol error", NULL); return ret; } - clearColValArray(info->currTableDataCtx->pValues); } else { uDebug("SML:0x%" PRIx64 " smlParseInfluxString format false, ts:%" PRId64, info->id, ts); taosArraySet(elements->colArray, 0, &kv); diff --git a/source/client/test/CMakeLists.txt b/source/client/test/CMakeLists.txt index 34c377c6eab7ee85749b29dec22c9f776a753356..91f0d1eef86396bb35bd996946043e4b04832418 100644 --- a/source/client/test/CMakeLists.txt +++ b/source/client/test/CMakeLists.txt @@ -20,7 +20,7 @@ TARGET_LINK_LIBRARIES( ADD_EXECUTABLE(smlTest smlTest.cpp) TARGET_LINK_LIBRARIES( smlTest - PUBLIC os util common transport parser catalog scheduler function gtest taos_static qcom + PUBLIC os util common transport parser catalog scheduler function gtest taos_static qcom geometry ) TARGET_INCLUDE_DIRECTORIES( diff --git a/source/common/CMakeLists.txt b/source/common/CMakeLists.txt index 356ea2be1cb35be9ae0cedb6061abfa60b3307a3..b010467f206c515c4101e9a63631590fb80bab4a 100644 --- a/source/common/CMakeLists.txt +++ b/source/common/CMakeLists.txt @@ -16,6 +16,14 @@ ENDIF () IF (TD_STORAGE) ADD_DEFINITIONS(-D_STORAGE) TARGET_LINK_LIBRARIES(common PRIVATE storage) + + IF(${TD_LINUX}) + IF(${BUILD_WITH_COS}) + add_definitions(-DUSE_COS) + ENDIF(${BUILD_WITH_COS}) + + ENDIF(${TD_LINUX}) + ENDIF () target_include_directories( diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 123d1ec33e3eb342a7c27a71dc3b557cd4c93958..66a498d15c4d5530f132eae1f2908145b57a1d62 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -314,7 +314,7 @@ static const SSysDbTableSchema userUserPrivilegesSchema[] = { static const SSysTableMeta infosMeta[] = { {TSDB_INS_TABLE_DNODES, dnodesSchema, tListLen(dnodesSchema), true}, {TSDB_INS_TABLE_MNODES, mnodesSchema, tListLen(mnodesSchema), true}, - {TSDB_INS_TABLE_MODULES, modulesSchema, tListLen(modulesSchema), true}, + // {TSDB_INS_TABLE_MODULES, modulesSchema, tListLen(modulesSchema), true}, {TSDB_INS_TABLE_QNODES, qnodesSchema, tListLen(qnodesSchema), true}, {TSDB_INS_TABLE_SNODES, snodesSchema, tListLen(snodesSchema), true}, {TSDB_INS_TABLE_CLUSTER, clusterSchema, tListLen(clusterSchema), true}, diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 5188b1e27c3b0fcebde8561ac211bcc3c7ba17df..bbbb6c7178d177b1c7aa46e459fe337b9529c4cc 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -26,7 +26,7 @@ int32_t colDataGetLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRo if (pColumnInfoData->reassigned) { int32_t totalSize = 0; for (int32_t row = 0; row < numOfRows; ++row) { - char* pColData = pColumnInfoData->pData + pColumnInfoData->varmeta.offset[row]; + char* pColData = pColumnInfoData->pData + pColumnInfoData->varmeta.offset[row]; int32_t colSize = 0; if (pColumnInfoData->info.type == TSDB_DATA_TYPE_JSON) { colSize = getJsonValueLen(pColData); @@ -142,7 +142,8 @@ int32_t colDataSetVal(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const return 0; } -int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, uint32_t srcRowIdx, const char* pData) { +int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, uint32_t srcRowIdx, + const char* pData) { int32_t type = pColumnInfoData->info.type; if (IS_VAR_DATA_TYPE(type)) { int32_t dataLen = 0; @@ -164,7 +165,6 @@ int32_t colDataReassignVal(SColumnInfoData* pColumnInfoData, uint32_t dstRowIdx, return 0; } - static int32_t colDataReserve(SColumnInfoData* pColumnInfoData, size_t newSize) { if (!IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) { return TSDB_CODE_SUCCESS; @@ -188,16 +188,17 @@ static int32_t colDataReserve(SColumnInfoData* pColumnInfoData, size_t newSize) } static int32_t doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t currentRow, const char* pData, - int32_t itemLen, int32_t numOfRows, bool trimValue) { + int32_t itemLen, int32_t numOfRows, bool trimValue) { if (pColumnInfoData->info.bytes < itemLen) { - uWarn("column/tag actual data len %d is bigger than schema len %d, trim it:%d", itemLen, pColumnInfoData->info.bytes, trimValue); + uWarn("column/tag actual data len %d is bigger than schema len %d, trim it:%d", itemLen, + pColumnInfoData->info.bytes, trimValue); if (trimValue) { itemLen = pColumnInfoData->info.bytes; } else { return TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER; } } - + size_t start = 1; // the first item @@ -230,8 +231,8 @@ static int32_t doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t cur return TSDB_CODE_SUCCESS; } -int32_t colDataSetNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, - uint32_t numOfRows, bool trimValue) { +int32_t colDataSetNItems(SColumnInfoData* pColumnInfoData, uint32_t currentRow, const char* pData, uint32_t numOfRows, + bool trimValue) { int32_t len = pColumnInfoData->info.bytes; if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) { len = varDataTLen(pData); @@ -262,7 +263,7 @@ static void doBitmapMerge(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, c uint8_t* p = (uint8_t*)pSource->nullbitmap; pColumnInfoData->nullbitmap[BitmapLen(numOfRow1) - 1] &= (0B11111111 << shiftBits); // clear remind bits - pColumnInfoData->nullbitmap[BitmapLen(numOfRow1) - 1] |= (p[0] >> remindBits); // copy remind bits + pColumnInfoData->nullbitmap[BitmapLen(numOfRow1) - 1] |= (p[0] >> remindBits); // copy remind bits if (BitmapLen(numOfRow1) == BitmapLen(total)) { return; @@ -350,7 +351,7 @@ int32_t colDataMergeCol(SColumnInfoData* pColumnInfoData, int32_t numOfRow1, int pColumnInfoData->pData = tmp; if (BitmapLen(numOfRow1) < BitmapLen(finalNumOfRows)) { - char* btmp = taosMemoryRealloc(pColumnInfoData->nullbitmap, BitmapLen(finalNumOfRows)); + char* btmp = taosMemoryRealloc(pColumnInfoData->nullbitmap, BitmapLen(finalNumOfRows)); if (btmp == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } @@ -622,7 +623,7 @@ int32_t blockDataToBuf(char* buf, const SSDataBlock* pBlock) { if (pCol->reassigned && IS_VAR_DATA_TYPE(pCol->info.type)) { for (int32_t row = 0; row < numOfRows; ++row) { - char* pColData = pCol->pData + pCol->varmeta.offset[row]; + char* pColData = pCol->pData + pCol->varmeta.offset[row]; int32_t colSize = 0; if (pCol->info.type == TSDB_DATA_TYPE_JSON) { colSize = getJsonValueLen(pColData); @@ -698,8 +699,7 @@ int32_t blockDataFromBuf(SSDataBlock* pBlock, const char* buf) { return TSDB_CODE_SUCCESS; } -static bool colDataIsNNull(const SColumnInfoData* pColumnInfoData, int32_t startIndex, - uint32_t nRows) { +static bool colDataIsNNull(const SColumnInfoData* pColumnInfoData, int32_t startIndex, uint32_t nRows) { if (!pColumnInfoData->hasNull) { return false; } @@ -880,7 +880,6 @@ int32_t dataBlockCompar(const void* p1, const void* p2, const void* param) { } static int32_t blockDataAssign(SColumnInfoData* pCols, const SSDataBlock* pDataBlock, const int32_t* index) { - size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock); for (int32_t i = 0; i < numOfCols; ++i) { SColumnInfoData* pDst = &pCols[i]; @@ -1131,6 +1130,7 @@ static int32_t doEnsureCapacity(SColumnInfoData* pColumn, const SDataBlockInfo* if (tmp == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } + // memset(tmp, 0, numOfRows * pColumn->info.bytes); // copy back the existed data if (pColumn->pData != NULL) { @@ -1474,8 +1474,8 @@ size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize, int int end = nRows; while (start <= end) { int mid = start + (end - start) / 2; - //data size + var data type columns offset + fixed data type columns bitmap len - int midSize = rowSize * mid + numVarCols * sizeof(int32_t) * mid + numFixCols * BitmapLen(mid); + // data size + var data type columns offset + fixed data type columns bitmap len + int midSize = rowSize * mid + numVarCols * sizeof(int32_t) * mid + numFixCols * BitmapLen(mid); if (midSize > payloadSize) { result = mid; end = mid - 1; @@ -1669,7 +1669,7 @@ int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) { if (pColData->reassigned && IS_VAR_DATA_TYPE(pColData->info.type)) { for (int32_t row = 0; row < rows; ++row) { - char* pData = pColData->pData + pColData->varmeta.offset[row]; + char* pData = pColData->pData + pColData->varmeta.offset[row]; int32_t colSize = 0; if (pColData->info.type == TSDB_DATA_TYPE_JSON) { colSize = getJsonValueLen(pData); @@ -1771,8 +1771,8 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) { } // for debug -char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) { - int32_t size = 2048*1024; +char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf, const char* taskIdStr) { + int32_t size = 2048 * 1024; *pDataBuf = taosMemoryCalloc(size, 1); char* dumpBuf = *pDataBuf; char pBuf[128] = {0}; @@ -1780,9 +1780,9 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) int32_t rows = pDataBlock->info.rows; int32_t len = 0; len += snprintf(dumpBuf + len, size - len, - "===stream===%s|block type %d|child id %d|group id:%" PRIu64 "|uid:%" PRId64 + "%s===stream===%s|block type %d|child id %d|group id:%" PRIu64 "|uid:%" PRId64 "|rows:%" PRId64 "|version:%" PRIu64 "|cal start:%" PRIu64 "|cal end:%" PRIu64 "|tbl:%s\n", - flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId, pDataBlock->info.id.groupId, + taskIdStr, flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId, pDataBlock->info.id.groupId, pDataBlock->info.id.uid, pDataBlock->info.rows, pDataBlock->info.version, pDataBlock->info.calWin.skey, pDataBlock->info.calWin.ekey, pDataBlock->info.parTbName); if (len >= size - 1) return dumpBuf; @@ -2156,21 +2156,21 @@ int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols) { data += metaSize; dataLen += metaSize; - if (pColRes->reassigned && IS_VAR_DATA_TYPE(pColRes->info.type)) { - colSizes[col] = 0; - for (int32_t row = 0; row < numOfRows; ++row) { - char* pColData = pColRes->pData + pColRes->varmeta.offset[row]; - int32_t colSize = 0; - if (pColRes->info.type == TSDB_DATA_TYPE_JSON) { - colSize = getJsonValueLen(pColData); - } else { - colSize = varDataTLen(pColData); - } - colSizes[col] += colSize; - dataLen += colSize; - memmove(data, pColData, colSize); - data += colSize; + if (pColRes->reassigned && IS_VAR_DATA_TYPE(pColRes->info.type)) { + colSizes[col] = 0; + for (int32_t row = 0; row < numOfRows; ++row) { + char* pColData = pColRes->pData + pColRes->varmeta.offset[row]; + int32_t colSize = 0; + if (pColRes->info.type == TSDB_DATA_TYPE_JSON) { + colSize = getJsonValueLen(pColData); + } else { + colSize = varDataTLen(pColData); } + colSizes[col] += colSize; + dataLen += colSize; + memmove(data, pColData, colSize); + data += colSize; + } } else { colSizes[col] = colDataGetLength(pColRes, numOfRows); dataLen += colSizes[col]; @@ -2181,7 +2181,8 @@ int32_t blockEncode(const SSDataBlock* pBlock, char* data, int32_t numOfCols) { } colSizes[col] = htonl(colSizes[col]); -// uError("blockEncode col bytes:%d, type:%d, size:%d, htonl size:%d", pColRes->info.bytes, pColRes->info.type, htonl(colSizes[col]), colSizes[col]); + // uError("blockEncode col bytes:%d, type:%d, size:%d, htonl size:%d", pColRes->info.bytes, pColRes->info.type, + // htonl(colSizes[col]), colSizes[col]); } *actualLen = dataLen; @@ -2283,7 +2284,7 @@ const char* blockDecode(SSDataBlock* pBlock, const char* pData) { } void trimDataBlock(SSDataBlock* pBlock, int32_t totalRows, const bool* pBoolList) { -// int32_t totalRows = pBlock->info.rows; + // int32_t totalRows = pBlock->info.rows; int32_t bmLen = BitmapLen(totalRows); char* pBitmap = NULL; int32_t maxRows = 0; @@ -2310,8 +2311,9 @@ void trimDataBlock(SSDataBlock* pBlock, int32_t totalRows, const bool* pBoolList if (colDataIsNull_var(pDst, j)) { colDataSetNull_var(pDst, numOfRows); } else { - // fix address sanitizer error. p1 may point to memory that will change during realloc of colDataSetVal, first copy it to p2 - char* p1 = colDataGetVarData(pDst, j); + // fix address sanitizer error. p1 may point to memory that will change during realloc of colDataSetVal, first + // copy it to p2 + char* p1 = colDataGetVarData(pDst, j); int32_t len = 0; if (pDst->info.type == TSDB_DATA_TYPE_JSON) { len = getJsonValueLen(p1); diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index a772efc33cf8ab1cbae6236921df6e3e624683bf..e080c2d2ec33d2e4b62a065146493dc02e78158c 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -216,7 +216,11 @@ uint32_t tsCurRange = 100; // range char tsCompressor[32] = "ZSTD_COMPRESSOR"; // ZSTD_COMPRESSOR or GZIP_COMPRESSOR // udf -bool tsStartUdfd = true; +#ifdef WINDOWS +bool tsStartUdfd = false; +#else +bool tsStartUdfd = true; +#endif // wal int64_t tsWalFsyncDataSizeLimit = (100 * 1024 * 1024L); @@ -236,6 +240,15 @@ int64_t tsStreamBufferSize = 128 * 1024 * 1024; int64_t tsCheckpointInterval = 3 * 60 * 60 * 1000; bool tsFilterScalarMode = false; int32_t tsKeepTimeOffset = 0; // latency of data migration +int tsResolveFQDNRetryTime = 100; //seconds + +char tsS3Endpoint[TSDB_FQDN_LEN] = ""; +char tsS3AccessKey[TSDB_FQDN_LEN] = ""; +char tsS3AccessKeyId[TSDB_FQDN_LEN] = ""; +char tsS3AccessKeySecret[TSDB_FQDN_LEN] = ""; +char tsS3BucketName[TSDB_FQDN_LEN] = ""; +char tsS3AppId[TSDB_FQDN_LEN] = ""; +int8_t tsS3Enabled = false; #ifndef _STORAGE int32_t taosSetTfsCfg(SConfig *pCfg) { @@ -258,7 +271,43 @@ int32_t taosSetTfsCfg(SConfig *pCfg) { int32_t taosSetTfsCfg(SConfig *pCfg); #endif -struct SConfig *taosGetCfg() { return tsCfg; } +int32_t taosSetS3Cfg(SConfig *pCfg) { + tstrncpy(tsS3AccessKey, cfgGetItem(pCfg, "s3Accesskey")->str, TSDB_FQDN_LEN); + if (tsS3AccessKey[0] == '<') { + return 0; + } + char *colon = strchr(tsS3AccessKey, ':'); + if (!colon) { + uError("invalid access key:%s", tsS3AccessKey); + return -1; + } + *colon = '\0'; + tstrncpy(tsS3AccessKeyId, tsS3AccessKey, TSDB_FQDN_LEN); + tstrncpy(tsS3AccessKeySecret, colon + 1, TSDB_FQDN_LEN); + tstrncpy(tsS3Endpoint, cfgGetItem(pCfg, "s3Endpoint")->str, TSDB_FQDN_LEN); + tstrncpy(tsS3BucketName, cfgGetItem(pCfg, "s3BucketName")->str, TSDB_FQDN_LEN); + char *cos = strstr(tsS3Endpoint, "cos."); + if (cos) { + char *appid = strrchr(tsS3BucketName, '-'); + if (!appid) { + uError("failed to locate appid in bucket:%s", tsS3BucketName); + return -1; + } else { + tstrncpy(tsS3AppId, appid + 1, TSDB_FQDN_LEN); + } + } + if (tsS3BucketName[0] != '<' && tsDiskCfgNum > 1) { +#ifdef USE_COS + tsS3Enabled = true; +#endif + } + + return 0; +} + +struct SConfig *taosGetCfg() { + return tsCfg; +} static int32_t taosLoadCfg(SConfig *pCfg, const char **envCmd, const char *inputCfgDir, const char *envFile, char *apolloUrl) { @@ -580,6 +629,11 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddInt32(pCfg, "keepTimeOffset", tsKeepTimeOffset, 0, 23, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "maxStreamBackendCache", tsMaxStreamBackendCache, 16, 1024, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "pqSortMemThreshold", tsPQSortMemThreshold, 1, 10240, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt32(pCfg, "resolveFQDNRetryTime", tsResolveFQDNRetryTime, 1, 10240, 0) != 0) return -1; + + if (cfgAddString(pCfg, "s3Accesskey", tsS3AccessKey, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddString(pCfg, "s3Endpoint", tsS3Endpoint, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddString(pCfg, "s3BucketName", tsS3BucketName, CFG_SCOPE_SERVER) != 0) return -1; GRANT_CFG_ADD; return 0; @@ -979,6 +1033,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { tsKeepTimeOffset = cfgGetItem(pCfg, "keepTimeOffset")->i32; tsMaxStreamBackendCache = cfgGetItem(pCfg, "maxStreamBackendCache")->i32; tsPQSortMemThreshold = cfgGetItem(pCfg, "pqSortMemThreshold")->i32; + tsResolveFQDNRetryTime = cfgGetItem(pCfg, "resolveFQDNRetryTime")->i32; GRANT_CFG_GET; return 0; @@ -1502,6 +1557,7 @@ int32_t taosInitCfg(const char *cfgDir, const char **envCmd, const char *envFile if (taosSetServerCfg(tsCfg)) return -1; if (taosSetReleaseCfg(tsCfg)) return -1; if (taosSetTfsCfg(tsCfg) != 0) return -1; + if (taosSetS3Cfg(tsCfg) != 0) return -1; } taosSetSystemCfg(tsCfg); diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 7e69184a0077abb0f28d33f959f4c86db74101c3..d6d9e954e81d8ed8c479889bcf213271ccd112ad 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -534,6 +534,7 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq if (tEncodeI8(&encoder, pField->flags) < 0) return -1; if (tEncodeI32(&encoder, pField->bytes) < 0) return -1; if (tEncodeCStr(&encoder, pField->name) < 0) return -1; + if (tEncodeCStr(&encoder, pField->comment) < 0) return -1; } for (int32_t i = 0; i < pReq->numOfTags; ++i) { @@ -542,6 +543,7 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq if (tEncodeI8(&encoder, pField->flags) < 0) return -1; if (tEncodeI32(&encoder, pField->bytes) < 0) return -1; if (tEncodeCStr(&encoder, pField->name) < 0) return -1; + if (tEncodeCStr(&encoder, pField->comment) < 0) return -1; } for (int32_t i = 0; i < pReq->numOfFuncs; ++i) { @@ -608,6 +610,7 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR if (tDecodeI8(&decoder, &field.flags) < 0) return -1; if (tDecodeI32(&decoder, &field.bytes) < 0) return -1; if (tDecodeCStrTo(&decoder, field.name) < 0) return -1; + if (tDecodeCStrTo(&decoder, field.comment) < 0) return -1; if (taosArrayPush(pReq->pColumns, &field) == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; @@ -620,6 +623,7 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR if (tDecodeI8(&decoder, &field.flags) < 0) return -1; if (tDecodeI32(&decoder, &field.bytes) < 0) return -1; if (tDecodeCStrTo(&decoder, field.name) < 0) return -1; + if (tDecodeCStrTo(&decoder, field.comment) < 0) return -1; if (taosArrayPush(pReq->pTags, &field) == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; @@ -2323,7 +2327,7 @@ int32_t tDeserializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp) } int32_t totalCols = pRsp->numOfTags + pRsp->numOfColumns; - pRsp->pSchemas = taosMemoryMalloc(sizeof(SSchema) * totalCols); + pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema)); if (pRsp->pSchemas == NULL) return -1; for (int32_t i = 0; i < totalCols; ++i) { @@ -3706,7 +3710,7 @@ static int32_t tDecodeSTableMetaRsp(SDecoder *pDecoder, STableMetaRsp *pRsp) { int32_t totalCols = pRsp->numOfTags + pRsp->numOfColumns; if (totalCols > 0) { - pRsp->pSchemas = taosMemoryMalloc(sizeof(SSchema) * totalCols); + pRsp->pSchemas = taosMemoryCalloc(totalCols, sizeof(SSchema)); if (pRsp->pSchemas == NULL) return -1; for (int32_t i = 0; i < totalCols; ++i) { diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmFile.c b/source/dnode/mgmt/mgmt_mnode/src/mmFile.c index cb0849f4b96f945a41a2e27a0abcba2244484bba..64e18ef06d6e1f2f4fc37504cc4a8d9f41612436 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmFile.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmFile.c @@ -46,7 +46,7 @@ static int32_t mmDecodeOption(SJson *pJson, SMnodeOpt *pOption) { if (code < 0) return -1; tjsonGetInt32ValueFromDouble(replica, "role", pOption->nodeRoles[i], code); if (code < 0) return -1; - if(pOption->nodeRoles[i] == TAOS_SYNC_ROLE_VOTER){ + if (pOption->nodeRoles[i] == TAOS_SYNC_ROLE_VOTER) { pOption->numOfReplicas++; } } @@ -65,7 +65,7 @@ int32_t mmReadFile(const char *path, SMnodeOpt *pOption) { char file[PATH_MAX] = {0}; snprintf(file, sizeof(file), "%s%smnode.json", path, TD_DIRSEP); - if (taosStatFile(file, NULL, NULL) < 0) { + if (taosStatFile(file, NULL, NULL, NULL) < 0) { dInfo("mnode file:%s not exist", file); return 0; } diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c index da7f4d4a564379cea22dd01e934179aea8bf6851..ed32e75d1831da42956f205eb75da01bd27a7152 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c @@ -97,7 +97,7 @@ int32_t vmGetVnodeListFromFile(SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t SWrapperCfg *pCfgs = NULL; snprintf(file, sizeof(file), "%s%svnodes.json", pMgmt->path, TD_DIRSEP); - if (taosStatFile(file, NULL, NULL) < 0) { + if (taosStatFile(file, NULL, NULL, NULL) < 0) { dInfo("vnode file:%s not exist", file); return 0; } diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index bed9a6730326437a8b67c475d4da45c1b5588e71..cf57deaa22ea6b85127fec34805ea8221175196f 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -742,7 +742,6 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_SCAN_HISTORY_FINISH, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_SCAN_HISTORY_FINISH_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_TRANSFER_STATE, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECK_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TRIGGER, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; diff --git a/source/dnode/mgmt/node_util/src/dmEps.c b/source/dnode/mgmt/node_util/src/dmEps.c index 1564a090357717b4733a5c557fd2c1c248f753ba..88f6b5da4057b7bceaeb09e6d682224d7ced25a5 100644 --- a/source/dnode/mgmt/node_util/src/dmEps.c +++ b/source/dnode/mgmt/node_util/src/dmEps.c @@ -100,7 +100,7 @@ int32_t dmReadEps(SDnodeData *pData) { goto _OVER; } - if (taosStatFile(file, NULL, NULL) < 0) { + if (taosStatFile(file, NULL, NULL, NULL) < 0) { dInfo("dnode file:%s not exist", file); code = 0; goto _OVER; @@ -350,7 +350,7 @@ void dmRotateMnodeEpSet(SDnodeData *pData) { } void dmGetMnodeEpSetForRedirect(SDnodeData *pData, SRpcMsg *pMsg, SEpSet *pEpSet) { - if(!pData->validMnodeEps) return; + if (!pData->validMnodeEps) return; dmGetMnodeEpSet(pData, pEpSet); dTrace("msg is redirected, handle:%p num:%d use:%d", pMsg->info.handle, pEpSet->numOfEps, pEpSet->inUse); for (int32_t i = 0; i < pEpSet->numOfEps; ++i) { @@ -469,7 +469,7 @@ static int32_t dmReadDnodePairs(SDnodeData *pData) { char file[PATH_MAX] = {0}; snprintf(file, sizeof(file), "%s%sdnode%sep.json", tsDataDir, TD_DIRSEP, TD_DIRSEP); - if (taosStatFile(file, NULL, NULL) < 0) { + if (taosStatFile(file, NULL, NULL, NULL) < 0) { dDebug("dnode file:%s not exist", file); code = 0; goto _OVER; diff --git a/source/dnode/mgmt/node_util/src/dmFile.c b/source/dnode/mgmt/node_util/src/dmFile.c index fb05f08c0c5e26130c399e179052c81dae56ebf8..c81efddcc124d71045445a867051d547ba5ea220 100644 --- a/source/dnode/mgmt/node_util/src/dmFile.c +++ b/source/dnode/mgmt/node_util/src/dmFile.c @@ -38,7 +38,7 @@ int32_t dmReadFile(const char *path, const char *name, bool *pDeployed) { char file[PATH_MAX] = {0}; snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name); - if (taosStatFile(file, NULL, NULL) < 0) { + if (taosStatFile(file, NULL, NULL, NULL) < 0) { dInfo("file:%s not exist", file); code = 0; goto _OVER; diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index 1bd629e56f59c4b49bd1027a04ce81ccea166445..4f7e80c0a3ebadf5f7097dd3916e100d0479bdbc 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -666,7 +666,12 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) { terrno = TSDB_CODE_INVALID_MSG; goto _OVER; } - +#ifdef WINDOWS + if (taosArrayGetSize(createReq.pRetensions) > 0) { + terrno = TSDB_CODE_MND_INVALID_PLATFORM; + goto _OVER; + } +#endif mInfo("db:%s, start to create, vgroups:%d", createReq.db, createReq.numOfVgroups); if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DB, NULL) != 0) { goto _OVER; diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index 4ffc7a20c26890451576a68e1f50572bd5a6db15..5eb7abf0260d87fe55ee50c08c4cbdc536e048b6 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -359,7 +359,10 @@ static int32_t mndProcessCreateFuncReq(SRpcMsg *pReq) { terrno = TSDB_CODE_INVALID_MSG; goto _OVER; } - +#ifdef WINDOWS + terrno = TSDB_CODE_MND_INVALID_PLATFORM; + goto _OVER; +#endif mInfo("func:%s, start to create, size:%d", createReq.name, createReq.codeLen); if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_FUNC) != 0) { goto _OVER; diff --git a/source/dnode/mnode/impl/src/mndIndex.c b/source/dnode/mnode/impl/src/mndIndex.c index 2157804559bb54e552e1508a27f37737696953c7..2e78116a86c05ba98bb898c88c9bb7f5d2150960 100644 --- a/source/dnode/mnode/impl/src/mndIndex.c +++ b/source/dnode/mnode/impl/src/mndIndex.c @@ -79,9 +79,12 @@ int32_t mndInitIdx(SMnode *pMnode) { return sdbSetTable(pMnode->pSdb, table); } -static int32_t mndFindSuperTableTagId(const SStbObj *pStb, const char *tagName) { +static int32_t mndFindSuperTableTagId(const SStbObj *pStb, const char *tagName, int8_t *hasIdx) { for (int32_t tag = 0; tag < pStb->numOfTags; tag++) { if (strcasecmp(pStb->pTags[tag].name, tagName) == 0) { + if (IS_IDX_ON(&pStb->pTags[tag])) { + *hasIdx = 1; + } return tag; } } @@ -597,7 +600,8 @@ static int32_t mndSetUpdateIdxStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStb pNew->updateTime = taosGetTimestampMs(); pNew->lock = 0; - int32_t tag = mndFindSuperTableTagId(pOld, tagName); + int8_t hasIdx = 0; + int32_t tag = mndFindSuperTableTagId(pOld, tagName, &hasIdx); if (tag < 0) { terrno = TSDB_CODE_MND_TAG_NOT_EXIST; return -1; @@ -612,14 +616,14 @@ static int32_t mndSetUpdateIdxStbCommitLogs(SMnode *pMnode, STrans *pTrans, SStb SSchema *pTag = pNew->pTags + tag; if (on == 1) { - if (IS_IDX_ON(pTag)) { + if (hasIdx && tag != 0) { terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; return -1; } else { SSCHMEA_SET_IDX_ON(pTag); } } else { - if (!IS_IDX_ON(pTag)) { + if (hasIdx == 0) { terrno = TSDB_CODE_MND_SMA_NOT_EXIST; } else { SSCHMEA_SET_IDX_OFF(pTag); @@ -667,7 +671,42 @@ _OVER: mndTransDrop(pTrans); return code; } +int8_t mndCheckIndexNameByTagName(SMnode *pMnode, SIdxObj *pIdxObj) { + // build index on first tag, and no index name; + int8_t exist = 0; + SDbObj *pDb = NULL; + if (strlen(pIdxObj->db) > 0) { + pDb = mndAcquireDb(pMnode, pIdxObj->db); + if (pDb == NULL) return 0; + } + SSmaAndTagIter *pIter = NULL; + SIdxObj *pIdx = NULL; + SSdb *pSdb = pMnode->pSdb; + + while (1) { + pIter = sdbFetch(pSdb, SDB_IDX, pIter, (void **)&pIdx); + if (pIter == NULL) break; + + if (NULL != pDb && pIdx->dbUid != pDb->uid) { + sdbRelease(pSdb, pIdx); + continue; + } + if (pIdxObj->stbUid != pIdx->stbUid) { + sdbRelease(pSdb, pIdx); + continue; + } + if (strncmp(pIdxObj->colName, pIdx->colName, TSDB_COL_NAME_LEN) == 0) { + sdbCancelFetch(pSdb, pIter); + sdbRelease(pSdb, pIdx); + exist = 1; + break; + } + sdbRelease(pSdb, pIdx); + } + mndReleaseDb(pMnode, pDb); + return exist; +} static int32_t mndAddIndex(SMnode *pMnode, SRpcMsg *pReq, SCreateTagIndexReq *req, SDbObj *pDb, SStbObj *pStb) { int32_t code = -1; SIdxObj idxObj = {0}; @@ -681,11 +720,20 @@ static int32_t mndAddIndex(SMnode *pMnode, SRpcMsg *pReq, SCreateTagIndexReq *re idxObj.stbUid = pStb->uid; idxObj.dbUid = pStb->dbUid; - int32_t tag = mndFindSuperTableTagId(pStb, req->colName); + int8_t hasIdx = 0; + int32_t tag = mndFindSuperTableTagId(pStb, req->colName, &hasIdx); if (tag < 0) { terrno = TSDB_CODE_MND_TAG_NOT_EXIST; return -1; - } else if (tag == 0) { + } + int8_t exist = 0; + if (tag == 0 && hasIdx == 1) { + exist = mndCheckIndexNameByTagName(pMnode, &idxObj); + if (exist) { + terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; + return -1; + } + } else if (hasIdx == 1) { terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; return -1; } @@ -695,11 +743,11 @@ static int32_t mndAddIndex(SMnode *pMnode, SRpcMsg *pReq, SCreateTagIndexReq *re return -1; } - SSchema *pTag = pStb->pTags + tag; - if (IS_IDX_ON(pTag)) { - terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; - return -1; - } + // SSchema *pTag = pStb->pTags + tag; + // if (IS_IDX_ON(pTag)) { + // terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; + // return -1; + // } code = mndAddIndexImpl(pMnode, pReq, pDb, pStb, &idxObj); return code; @@ -806,8 +854,8 @@ int32_t mndDropIdxsByStb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *p if (pIdx->stbUid == pStb->uid) { if (mndSetDropIdxCommitLogs(pMnode, pTrans, pIdx) != 0) { + sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pIdx); - sdbCancelFetch(pSdb, pIdx); return -1; } } diff --git a/source/dnode/mnode/impl/src/mndShow.c b/source/dnode/mnode/impl/src/mndShow.c index 44f47517006c46b5f3cdc69360757402b2e6f352..7d842be7de3ff5dd1c96a4eca9d7717889f79618 100644 --- a/source/dnode/mnode/impl/src/mndShow.c +++ b/source/dnode/mnode/impl/src/mndShow.c @@ -58,8 +58,10 @@ static int32_t convertToRetrieveType(char *name, int32_t len) { type = TSDB_MGMT_TABLE_DNODE; } else if (strncasecmp(name, TSDB_INS_TABLE_MNODES, len) == 0) { type = TSDB_MGMT_TABLE_MNODE; +/* } else if (strncasecmp(name, TSDB_INS_TABLE_MODULES, len) == 0) { type = TSDB_MGMT_TABLE_MODULE; +*/ } else if (strncasecmp(name, TSDB_INS_TABLE_QNODES, len) == 0) { type = TSDB_MGMT_TABLE_QNODE; } else if (strncasecmp(name, TSDB_INS_TABLE_SNODES, len) == 0) { diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c index b84297f6bfd77f33ca2e27b04fd5b2b172a1286c..e186a8742fa5b6a5fef0a1616028f3656adbfce6 100644 --- a/source/dnode/mnode/impl/src/mndSma.c +++ b/source/dnode/mnode/impl/src/mndSma.c @@ -705,7 +705,10 @@ static int32_t mndProcessCreateSmaReq(SRpcMsg *pReq) { terrno = TSDB_CODE_INVALID_MSG; goto _OVER; } - +#ifdef WINDOWS + terrno = TSDB_CODE_MND_INVALID_PLATFORM; + goto _OVER; +#endif mInfo("sma:%s, start to create", createReq.name); if (mndCheckCreateSmaReq(&createReq) != 0) { goto _OVER; diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 70fd74afc0a80b327265e17d2cb5f1a8d0069769..a56ca552f6996965a90d94370ee06b077f919700 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -18,6 +18,7 @@ #include "mndDb.h" #include "mndDnode.h" #include "mndIndex.h" +#include "mndIndexComm.h" #include "mndInfoSchema.h" #include "mndMnode.h" #include "mndPerfSchema.h" @@ -822,7 +823,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat return -1; } - if(pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags){ + if (pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags) { terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW; return -1; } @@ -834,6 +835,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat pSchema->bytes = pField->bytes; pSchema->flags = pField->flags; memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); + memcpy(pSchema->comment, pField->comment, TSDB_COL_COMMENT_LEN); pSchema->colId = pDst->nextColId; pDst->nextColId++; } @@ -847,6 +849,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat SSCHMEA_SET_IDX_ON(pSchema); } memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); + memcpy(pSchema->comment, pField->comment, TSDB_COL_COMMENT_LEN); pSchema->colId = pDst->nextColId; pDst->nextColId++; } @@ -857,11 +860,39 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea SStbObj stbObj = {0}; int32_t code = -1; + char fullIdxName[TSDB_INDEX_FNAME_LEN * 2] = {0}; + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq, "create-stb"); if (pTrans == NULL) goto _OVER; mInfo("trans:%d, used to create stb:%s", pTrans->id, pCreate->name); if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER; + + char randStr[24] = {0}; + taosRandStr2(randStr, tListLen(randStr) - 1); + SSchema *pSchema = &(stbObj.pTags[0]); + sprintf(fullIdxName, "%s.%s_%s", pDb->name, pSchema->name, randStr); + + SSIdx idx = {0}; + if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0 && idx.pIdx != NULL) { + terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST; + mndReleaseIdx(pMnode, idx.pIdx); + + goto _OVER; + } + + SIdxObj idxObj = {0}; + memcpy(idxObj.name, fullIdxName, TSDB_INDEX_FNAME_LEN); + memcpy(idxObj.stb, stbObj.name, TSDB_TABLE_FNAME_LEN); + memcpy(idxObj.db, stbObj.db, TSDB_DB_FNAME_LEN); + memcpy(idxObj.colName, pSchema->name, TSDB_COL_NAME_LEN); + idxObj.createdTime = taosGetTimestampMs(); + idxObj.uid = mndGenerateUid(fullIdxName, strlen(fullIdxName)); + idxObj.stbUid = stbObj.uid; + idxObj.dbUid = stbObj.dbUid; + + if (mndSetCreateIdxCommitLogs(pMnode, pTrans, &idxObj) < 0) goto _OVER; + if (mndAddStbToTrans(pMnode, pTrans, pDb, &stbObj) < 0) goto _OVER; if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; code = 0; @@ -956,7 +987,7 @@ static int32_t mndBuildStbFromAlter(SStbObj *pStb, SStbObj *pDst, SMCreateStbReq return -1; } - if(pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags){ + if (pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags) { terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW; return -1; } @@ -1188,7 +1219,7 @@ static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *p return -1; } - if(pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ntags){ + if (pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ntags) { terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW; return -1; } @@ -1478,7 +1509,8 @@ static int32_t mndAlterStbTagBytes(SMnode *pMnode, const SStbObj *pOld, SStbObj SSchema *pTag = pNew->pTags + tag; - if (!(pTag->type == TSDB_DATA_TYPE_BINARY || pTag->type == TSDB_DATA_TYPE_NCHAR || pTag->type == TSDB_DATA_TYPE_GEOMETRY)) { + if (!(pTag->type == TSDB_DATA_TYPE_BINARY || pTag->type == TSDB_DATA_TYPE_NCHAR || + pTag->type == TSDB_DATA_TYPE_GEOMETRY)) { terrno = TSDB_CODE_MND_INVALID_STB_OPTION; return -1; } @@ -1506,7 +1538,7 @@ static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray return -1; } - if(pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ncols){ + if (pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ncols) { terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW; return -1; } @@ -1598,7 +1630,8 @@ static int32_t mndAlterStbColumnBytes(SMnode *pMnode, const SStbObj *pOld, SStbO } SSchema *pCol = pNew->pColumns + col; - if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR || pCol->type == TSDB_DATA_TYPE_GEOMETRY)) { + if (!(pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR || + pCol->type == TSDB_DATA_TYPE_GEOMETRY)) { terrno = TSDB_CODE_MND_INVALID_STB_OPTION; return -1; } @@ -3182,7 +3215,6 @@ static int32_t mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB SSdb *pSdb = pMnode->pSdb; SStbObj *pStb = NULL; - int32_t numOfRows = 0; if (!pShow->sysDbRsp) { numOfRows = buildSysDbColsInfo(pBlock, pShow->db, pShow->filterTb); @@ -3206,7 +3238,7 @@ static int32_t mndRetrieveStbCol(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB if (pShow->pIter == NULL) break; } else { fetch = true; - void *pKey = taosHashGetKey(pShow->pIter, NULL); + void *pKey = taosHashGetKey(pShow->pIter, NULL); pStb = sdbAcquire(pSdb, SDB_STB, pKey); if (!pStb) continue; } diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index a0d53ec780e26b969d1d543761582261b6251474..427a52af3b1bb6f5eec5198d4c0847a561339f92 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -692,7 +692,10 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) { terrno = TSDB_CODE_INVALID_MSG; goto _OVER; } - +#ifdef WINDOWS + terrno = TSDB_CODE_MND_INVALID_PLATFORM; + goto _OVER; +#endif mInfo("stream:%s, start to create, sql:%s", createStreamReq.name, createStreamReq.sql); if (mndCheckCreateStreamReq(&createStreamReq) != 0) { diff --git a/source/dnode/mnode/impl/src/mndSubscribe.c b/source/dnode/mnode/impl/src/mndSubscribe.c index 53f22f6e60fae17d51ac55406b24efb4558e43f6..d62b9e41745dde32d6288a2c2087f20d2c4c142b 100644 --- a/source/dnode/mnode/impl/src/mndSubscribe.c +++ b/source/dnode/mnode/impl/src/mndSubscribe.c @@ -489,7 +489,7 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR SMqVgEp *pVgEp = taosArrayGetP(pConsumerEpNew->vgs, i); if(pVgEp->vgId == d1->vgId){ jump = true; - mInfo("pSub->offsetRows jump, because consumer id:%"PRIx64 " and vgId:%d not change", pConsumerEp->consumerId, pVgEp->vgId); + mInfo("pSub->offsetRows jump, because consumer id:0x%"PRIx64 " and vgId:%d not change", pConsumerEp->consumerId, pVgEp->vgId); break; } } diff --git a/source/dnode/snode/src/snode.c b/source/dnode/snode/src/snode.c index 4000e728359b7f88f339519474b2033b14502bf6..635fdcf45975d075456e3ffcaf566fe7aec978b0 100644 --- a/source/dnode/snode/src/snode.c +++ b/source/dnode/snode/src/snode.c @@ -77,6 +77,8 @@ int32_t sndExpandTask(SSnode *pSnode, SStreamTask *pTask, int64_t ver) { pTask->chkInfo.version = ver; pTask->pMeta = pSnode->pMeta; + streamTaskOpenAllUpstreamInput(pTask); + pTask->pState = streamStateOpen(pSnode->path, pTask, false, -1, -1); if (pTask->pState == NULL) { return -1; diff --git a/source/dnode/vnode/CMakeLists.txt b/source/dnode/vnode/CMakeLists.txt index 194ffa16f671b8b63466d3bb1de559b470547de4..c70df86e20031ddb9eee8b292f66262c214f6f13 100644 --- a/source/dnode/vnode/CMakeLists.txt +++ b/source/dnode/vnode/CMakeLists.txt @@ -8,6 +8,7 @@ set( "src/vnd/vnodeCommit.c" "src/vnd/vnodeQuery.c" "src/vnd/vnodeModule.c" + "src/vnd/vnodeCos.c" "src/vnd/vnodeSvr.c" "src/vnd/vnodeSync.c" "src/vnd/vnodeSnapshot.c" @@ -155,6 +156,45 @@ target_link_libraries( PUBLIC index ) +if(${TD_LINUX}) +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +find_library(APR_LIBRARY apr-1 PATHS /usr/local/apr/lib/) +find_library(APR_UTIL_LIBRARY aprutil-1 PATHS /usr/local/apr/lib/) +find_library(MINIXML_LIBRARY mxml) +find_library(CURL_LIBRARY curl) +target_link_libraries( + vnode + + # s3 + PUBLIC cos_c_sdk_static + PUBLIC ${APR_UTIL_LIBRARY} + PUBLIC ${APR_LIBRARY} + PUBLIC ${MINIXML_LIBRARY} + PUBLIC ${CURL_LIBRARY} +) + +# s3 +FIND_PROGRAM(APR_CONFIG_BIN NAMES apr-config apr-1-config PATHS /usr/bin /usr/local/bin /usr/local/apr/bin/) +IF (APR_CONFIG_BIN) + EXECUTE_PROCESS( + COMMAND ${APR_CONFIG_BIN} --includedir + OUTPUT_VARIABLE APR_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +ENDIF() +include_directories (${APR_INCLUDE_DIR}) +target_include_directories( + vnode + PUBLIC "${TD_SOURCE_DIR}/contrib/cos-c-sdk-v5/cos_c_sdk" + PUBLIC "$ENV{HOME}/.cos-local.1/include" + ) + +if(${BUILD_WITH_COS}) + add_definitions(-DUSE_COS) +endif(${BUILD_WITH_COS}) + +endif(${TD_LINUX}) + IF (TD_GRANT) TARGET_LINK_LIBRARIES(vnode PUBLIC grant) ENDIF () @@ -169,8 +209,6 @@ if(${BUILD_WITH_ROCKSDB}) add_definitions(-DUSE_ROCKSDB) endif(${BUILD_WITH_ROCKSDB}) - - if(${BUILD_TEST}) add_subdirectory(test) endif(${BUILD_TEST}) diff --git a/source/dnode/vnode/src/inc/vndCos.h b/source/dnode/vnode/src/inc/vndCos.h new file mode 100644 index 0000000000000000000000000000000000000000..cf2c5eb4410589e0d45e8e686134b18d6e71ca1b --- /dev/null +++ b/source/dnode/vnode/src/inc/vndCos.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_VND_COS_H_ +#define _TD_VND_COS_H_ + +#include "vnd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern int8_t tsS3Enabled; + +int32_t s3Init(); +void s3CleanUp(); +int32_t s3PutObjectFromFile(const char *file, const char *object); +void s3DeleteObjects(const char *object_name[], int nobject); +bool s3Exists(const char *object_name); +bool s3Get(const char *object_name, const char *path); +void s3EvictCache(const char *path, long object_size); +long s3Size(const char *object_name); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_VND_COS_H_*/ diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index cd7704940b3a017dae7d12e15647fc61ca8fd542..d37cf833c2658efa90bb27f84ca81e78ba806c9c 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -167,7 +167,7 @@ int metaAddIndexToSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq); int metaDropIndexFromSTable(SMeta* pMeta, int64_t version, SDropIndexReq* pReq); int64_t metaGetTimeSeriesNum(SMeta* pMeta); -SMCtbCursor* metaOpenCtbCursor(SMeta* pMeta, tb_uid_t uid, int lock); +SMCtbCursor* metaOpenCtbCursor(void* pVnode, tb_uid_t uid, int lock); void metaCloseCtbCursor(SMCtbCursor* pCtbCur, int lock); tb_uid_t metaCtbCursorNext(SMCtbCursor* pCtbCur); SMStbCursor* metaOpenStbCursor(SMeta* pMeta, tb_uid_t uid); @@ -250,7 +250,6 @@ int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskRetrieveReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskRetrieveRsp(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg); -int32_t tqProcessTaskTransferStateReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskScanHistoryFinishReq(STQ* pTq, SRpcMsg* pMsg); int32_t tqProcessTaskScanHistoryFinishRsp(STQ* pTq, SRpcMsg* pMsg); int32_t tqCheckLogInWal(STQ* pTq, int64_t version); diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 41fc3b3d7ed5cc9c2e829ce4b84cac63a1ca507d..d5e6a23d5c4f3f4ad6d1bda7900e33f7384d39f5 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -17,8 +17,8 @@ #include "osMemory.h" #include "tencode.h" -void _metaReaderInit(SMetaReader* pReader, void* pVnode, int32_t flags, SStoreMeta* pAPI) { - SMeta* pMeta = ((SVnode*)pVnode)->pMeta; +void _metaReaderInit(SMetaReader *pReader, void *pVnode, int32_t flags, SStoreMeta *pAPI) { + SMeta *pMeta = ((SVnode *)pVnode)->pMeta; metaReaderDoInit(pReader, pMeta, flags); pReader->pAPI = pAPI; } @@ -143,7 +143,7 @@ tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name) { int metaGetTableNameByUid(void *pVnode, uint64_t uid, char *tbName) { int code = 0; SMetaReader mr = {0}; - metaReaderDoInit(&mr, ((SVnode*)pVnode)->pMeta, 0); + metaReaderDoInit(&mr, ((SVnode *)pVnode)->pMeta, 0); code = metaReaderGetTableEntryByUid(&mr, uid); if (code < 0) { metaReaderClear(&mr); @@ -195,7 +195,7 @@ int metaGetTableUidByName(void *pVnode, char *tbName, uint64_t *uid) { int metaGetTableTypeByName(void *pVnode, char *tbName, ETableType *tbType) { int code = 0; SMetaReader mr = {0}; - metaReaderDoInit(&mr, ((SVnode*)pVnode)->pMeta, 0); + metaReaderDoInit(&mr, ((SVnode *)pVnode)->pMeta, 0); code = metaGetTableEntryByName(&mr, tbName); if (code == 0) *tbType = mr.me.type; @@ -244,7 +244,7 @@ SMTbCursor *metaOpenTbCursor(void *pVnode) { return NULL; } - SVnode* pVnodeObj = pVnode; + SVnode *pVnodeObj = pVnode; // tdbTbcMoveToFirst((TBC *)pTbCur->pDbc); pTbCur->pMeta = pVnodeObj->pMeta; pTbCur->paused = 1; @@ -408,17 +408,9 @@ _err: return NULL; } -struct SMCtbCursor { - SMeta *pMeta; - TBC *pCur; - tb_uid_t suid; - void *pKey; - void *pVal; - int kLen; - int vLen; -}; -SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid, int lock) { +SMCtbCursor *metaOpenCtbCursor(void* pVnode, tb_uid_t uid, int lock) { + SMeta* pMeta = ((SVnode*)pVnode)->pMeta; SMCtbCursor *pCtbCur = NULL; SCtbIdxKey ctbIdxKey; int ret = 0; @@ -435,7 +427,7 @@ SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid, int lock) { metaRLock(pMeta); } - ret = tdbTbcOpen(pMeta->pCtbIdx, &pCtbCur->pCur, NULL); + ret = tdbTbcOpen(pMeta->pCtbIdx, (TBC**)&pCtbCur->pCur, NULL); if (ret < 0) { metaULock(pMeta); taosMemoryFree(pCtbCur); @@ -1139,7 +1131,7 @@ int32_t metaFilterTtl(void *pVnode, SMetaFltParam *arg, SArray *pUids) { pCursor->type = param->type; metaRLock(pMeta); - //ret = tdbTbcOpen(pMeta->pTtlIdx, &pCursor->pCur, NULL); + // ret = tdbTbcOpen(pMeta->pTtlIdx, &pCursor->pCur, NULL); END: if (pCursor->pMeta) metaULock(pCursor->pMeta); @@ -1194,7 +1186,7 @@ int32_t metaFilterTableIds(void *pVnode, SMetaFltParam *arg, SArray *pUids) { ret = -1; for (int i = 0; i < oStbEntry.stbEntry.schemaTag.nCols; i++) { SSchema *schema = oStbEntry.stbEntry.schemaTag.pSchema + i; - if (schema->colId == param->cid && param->type == schema->type && (IS_IDX_ON(schema) || i == 0)) { + if (schema->colId == param->cid && param->type == schema->type && (IS_IDX_ON(schema))) { ret = 0; } } @@ -1373,7 +1365,7 @@ int32_t metaGetTableTagsByUids(void *pVnode, int64_t suid, SArray *uidList) { } int32_t metaGetTableTags(void *pVnode, uint64_t suid, SArray *pUidTagInfo) { - SMCtbCursor *pCur = metaOpenCtbCursor(((SVnode *)pVnode)->pMeta, suid, 1); + SMCtbCursor *pCur = metaOpenCtbCursor(pVnode, suid, 1); // If len > 0 means there already have uids, and we only want the // tags of the specified tables, of which uid in the uid list. Otherwise, all table tags are retrieved and kept diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index 632e6dd872be9b7381309653404b88f4dbf5152d..f56837f759cd0859c76418f33ef0972dd059bf10 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -450,12 +450,13 @@ int metaAddIndexToSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) { goto _err; } if (IS_IDX_ON(pNew) && !IS_IDX_ON(pOld)) { - if (diffIdx != -1) goto _err; + // if (diffIdx != -1) goto _err; diffIdx = i; + break; } } - if (diffIdx == -1 || diffIdx == 0) { + if (diffIdx == -1) { goto _err; } @@ -586,7 +587,7 @@ int metaDropIndexFromSTable(SMeta *pMeta, int64_t version, SDropIndexReq *pReq) for (int i = 0; i < oStbEntry.stbEntry.schemaTag.nCols; i++) { SSchema *schema = oStbEntry.stbEntry.schemaTag.pSchema + i; if (0 == strncmp(schema->name, pReq->colName, sizeof(pReq->colName))) { - if (i != 0 || IS_IDX_ON(schema)) { + if (IS_IDX_ON(schema)) { pCol = schema; } break; @@ -2094,7 +2095,7 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) { } else { for (int i = 0; i < pTagSchema->nCols; i++) { pTagColumn = &pTagSchema->pSchema[i]; - if (i != 0 && !IS_IDX_ON(pTagColumn)) continue; + if (!IS_IDX_ON(pTagColumn)) continue; STagVal tagVal = {.cid = pTagColumn->colId}; tTagGet((const STag *)pCtbEntry->ctbEntry.pTags, &tagVal); diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c index 1e7de3c5263049a02984b47d171104bf43ba496c..8da2fff5a62c59bc96d367be038a47d9275a96d5 100644 --- a/source/dnode/vnode/src/sma/smaRollup.c +++ b/source/dnode/vnode/src/sma/smaRollup.c @@ -905,6 +905,7 @@ int32_t tdProcessRSmaSubmit(SSma *pSma, int64_t version, void *pReq, void *pMsg, tb_uid_t *pTbSuid = (tb_uid_t *)taosHashGetKey(pIter, NULL); if (tdExecuteRSmaAsync(pSma, version, pMsg, len, inputType, *pTbSuid) < 0) { smaError("vgId:%d, failed to process rsma submit exec 2 since: %s", SMA_VID(pSma), terrstr()); + taosHashCancelIterate(uidStore.uidHash, pIter); goto _err; } } diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index de34a968367b7d882cd11d2e612c60d9cfd4f2ab..a5f7e0eb686145d117ee2917c280c127c70ecb62 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -930,6 +930,8 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) { pTask->pMsgCb = &pTq->pVnode->msgCb; pTask->pMeta = pTq->pStreamMeta; + streamTaskOpenAllUpstreamInput(pTask); + // backup the initial status, and set it to be TASK_STATUS__INIT pTask->chkInfo.version = ver; pTask->chkInfo.currentVer = ver; @@ -1274,7 +1276,9 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { if (done) { pTask->tsInfo.step2Start = taosGetTimestampMs(); - streamTaskEndScanWAL(pTask); + qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, 0.0); + appendTranstateIntoInputQ(pTask); + streamTryExec(pTask); // exec directly } else { STimeWindow* pWindow = &pTask->dataRange.window; tqDebug("s-task:%s level:%d verRange:%" PRId64 " - %" PRId64 " window:%" PRId64 "-%" PRId64 @@ -1339,44 +1343,6 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { return 0; } -// notify the downstream tasks to transfer executor state after handle all history blocks. -int32_t tqProcessTaskTransferStateReq(STQ* pTq, SRpcMsg* pMsg) { - char* pReq = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); - int32_t len = pMsg->contLen - sizeof(SMsgHead); - - SStreamTransferReq req = {0}; - - SDecoder decoder; - tDecoderInit(&decoder, (uint8_t*)pReq, len); - int32_t code = tDecodeStreamScanHistoryFinishReq(&decoder, &req); - tDecoderClear(&decoder); - - tqDebug("vgId:%d start to process transfer state msg, from s-task:0x%x", pTq->pStreamMeta->vgId, req.downstreamTaskId); - - SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, req.streamId, req.downstreamTaskId); - if (pTask == NULL) { - tqError("failed to find task:0x%x, it may have been dropped already. process transfer state failed", req.downstreamTaskId); - return -1; - } - - int32_t remain = streamAlignTransferState(pTask); - if (remain > 0) { - tqDebug("s-task:%s receive upstream transfer state msg, remain:%d", pTask->id.idStr, remain); - streamMetaReleaseTask(pTq->pStreamMeta, pTask); - return 0; - } - - // transfer the ownership of executor state - tqDebug("s-task:%s all upstream tasks send transfer msg, open transfer state flag", pTask->id.idStr); - ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); - - pTask->status.transferState = true; - - streamSchedExec(pTask); - streamMetaReleaseTask(pTq->pStreamMeta, pTask); - return 0; -} - int32_t tqProcessTaskScanHistoryFinishReq(STQ* pTq, SRpcMsg* pMsg) { char* msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); int32_t msgLen = pMsg->contLen - sizeof(SMsgHead); @@ -1564,7 +1530,7 @@ int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg) { if (pTask) { streamProcessDispatchRsp(pTask, pRsp, pMsg->code); streamMetaReleaseTask(pTq->pStreamMeta, pTask); - return 0; + return TSDB_CODE_SUCCESS; } else { tqDebug("vgId:%d failed to handle the dispatch rsp, since find task:0x%x failed", vgId, taskId); return TSDB_CODE_INVALID_MSG; @@ -1708,6 +1674,8 @@ int32_t tqProcessTaskRetrieveRsp(STQ* pTq, SRpcMsg* pMsg) { int32_t vnodeEnqueueStreamMsg(SVnode* pVnode, SRpcMsg* pMsg) { STQ* pTq = pVnode->pTq; + int32_t vgId = pVnode->config.vgId; + SMsgHead* msgStr = pMsg->pCont; char* msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead)); int32_t msgLen = pMsg->contLen - sizeof(SMsgHead); @@ -1724,7 +1692,9 @@ int32_t vnodeEnqueueStreamMsg(SVnode* pVnode, SRpcMsg* pMsg) { tDecoderClear(&decoder); int32_t taskId = req.taskId; - SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, req.streamId, req.taskId); + tqDebug("vgId:%d receive dispatch msg to s-task:0x%"PRIx64"-0x%x", vgId, req.streamId, taskId); + + SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, req.streamId, taskId); if (pTask != NULL) { SRpcMsg rsp = {.info = pMsg->info, .code = 0}; streamProcessDispatchMsg(pTask, &req, &rsp, false); @@ -1741,7 +1711,7 @@ int32_t vnodeEnqueueStreamMsg(SVnode* pVnode, SRpcMsg* pMsg) { FAIL: if (pMsg->info.handle == NULL) { - tqError("s-task:0x%x vgId:%d msg handle is null, abort enqueue dispatch msg", pTq->pStreamMeta->vgId, taskId); + tqError("s-task:0x%x vgId:%d msg handle is null, abort enqueue dispatch msg", vgId, taskId); return -1; } diff --git a/source/dnode/vnode/src/tq/tqOffsetSnapshot.c b/source/dnode/vnode/src/tq/tqOffsetSnapshot.c index a4428aed4368fec9c96a2faae5fabd33cd8eb8f4..6a66da30c65b65ebb5e814e421991ab81279243e 100644 --- a/source/dnode/vnode/src/tq/tqOffsetSnapshot.c +++ b/source/dnode/vnode/src/tq/tqOffsetSnapshot.c @@ -60,7 +60,7 @@ int32_t tqOffsetSnapRead(STqOffsetReader* pReader, uint8_t** ppData) { } int64_t sz = 0; - if (taosStatFile(fname, &sz, NULL) < 0) { + if (taosStatFile(fname, &sz, NULL, NULL) < 0) { taosCloseFile(&pFile); taosMemoryFree(fname); return -1; diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 252a0642faa35c9b90bae15f4a9039e2f6441dfe..7c58431b57b7a506f01e1602cab8fee349ab0ab0 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -332,8 +332,12 @@ int32_t extractMsgFromWal(SWalReader* pReader, void** pItem, int64_t maxVer, con void* pBody = POINTER_SHIFT(pReader->pHead->head.body, sizeof(SMsgHead)); int32_t len = pReader->pHead->head.bodyLen - sizeof(SMsgHead); - extractDelDataBlock(pBody, len, ver, (SStreamRefDataBlock**)pItem); - tqDebug("s-task:%s delete msg extract from WAL, len:%d, ver:%"PRId64, id, len, ver); + code = extractDelDataBlock(pBody, len, ver, (SStreamRefDataBlock**)pItem); + if (code != TSDB_CODE_SUCCESS) { + tqError("s-task:%s extract delete msg from WAL failed, code:%s", id, tstrerror(code)); + } else { + tqDebug("s-task:%s delete msg extract from WAL, len:%d, ver:%"PRId64, id, len, ver); + } } else { ASSERT(0); } @@ -1088,6 +1092,7 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) { if(ret != TDB_CODE_SUCCESS) { tqError("qGetTableList in tqUpdateTbUidList error:%d handle %s consumer:0x%" PRIx64, ret, pTqHandle->subKey, pTqHandle->consumerId); taosArrayDestroy(list); + taosHashCancelIterate(pTq->pHandle, pIter); return ret; } tqReaderSetTbUidList(pTqHandle->execHandle.pTqReader, list, NULL); diff --git a/source/dnode/vnode/src/tq/tqRestore.c b/source/dnode/vnode/src/tq/tqRestore.c index 3d9a91899cb2f91e811fb66c15610a9d0717ddca..ed612587f5a02c3ae4639b625fd73fa9a0932a2f 100644 --- a/source/dnode/vnode/src/tq/tqRestore.c +++ b/source/dnode/vnode/src/tq/tqRestore.c @@ -210,13 +210,23 @@ int32_t doSetOffsetForWalReader(SStreamTask *pTask, int32_t vgId) { } static void checkForFillHistoryVerRange(SStreamTask* pTask, int64_t ver) { - if ((pTask->info.fillHistory == 1) && ver > pTask->dataRange.range.maxVer) { - qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 - ", not scan wal anymore, set the transfer state flag", - pTask->id.idStr, ver, pTask->dataRange.range.maxVer); - pTask->status.transferState = true; + const char* id = pTask->id.idStr; + int64_t maxVer = pTask->dataRange.range.maxVer; - /*int32_t code = */streamSchedExec(pTask); + if ((pTask->info.fillHistory == 1) && ver > pTask->dataRange.range.maxVer) { + if (!pTask->status.appendTranstateBlock) { + qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 + ", not scan wal anymore, add transfer-state block into inputQ", + id, ver, maxVer); + + double el = (taosGetTimestampMs() - pTask->tsInfo.step2Start) / 1000.0; + qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, el); + appendTranstateIntoInputQ(pTask); + /*int32_t code = */streamSchedExec(pTask); + } else { + qWarn("s-task:%s fill-history scan WAL, currentVer:%" PRId64 " reach the maximum ver:%" PRId64 ", not scan wal", + id, ver, maxVer); + } } } @@ -262,7 +272,7 @@ int32_t createStreamTaskRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { continue; } - if ((pTask->info.fillHistory == 1) && pTask->status.transferState) { + if ((pTask->info.fillHistory == 1) && pTask->status.appendTranstateBlock) { ASSERT(status == TASK_STATUS__NORMAL); // the maximum version of data in the WAL has reached already, the step2 is done tqDebug("s-task:%s fill-history reach the maximum ver:%" PRId64 ", not scan wal anymore", pTask->id.idStr, @@ -277,6 +287,13 @@ int32_t createStreamTaskRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) { continue; } + // downstream task has blocked the output, stopped for a while + if (pTask->inputStatus == TASK_INPUT_STATUS__BLOCKED) { + tqDebug("s-task:%s inputQ is blocked, do nothing", pTask->id.idStr); + streamMetaReleaseTask(pStreamMeta, pTask); + continue; + } + *pScanIdle = false; // seek the stored version and extract data from WAL diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c index b22650d2498c17677607a99fce0dd4cba312d230..cce31688bcc9af2ad4a11cccb7a8d2bf41795a6a 100644 --- a/source/dnode/vnode/src/tq/tqSink.c +++ b/source/dnode/vnode/src/tq/tqSink.c @@ -412,7 +412,7 @@ void tqSinkToTablePipeline(SStreamTask* pTask, void* vnode, int64_t ver, void* d if (k == 0) { SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, dataIndex); void* colData = colDataGetData(pColData, j); - tqTrace("tq sink pipe2, row %d, col %d ts %" PRId64, j, k, *(int64_t*)colData); + tqDebug("tq sink pipe2, row %d, col %d ts %" PRId64, j, k, *(int64_t*)colData); } if (IS_SET_NULL(pCol)) { SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type); diff --git a/source/dnode/vnode/src/tsdb/tsdbFS.c b/source/dnode/vnode/src/tsdb/tsdbFS.c index ec116c717e05bc3a1be7379b18386c20eb8ef67d..c0c74d6b8723f6c34524523af4b4b9ef33da36ac 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFS.c +++ b/source/dnode/vnode/src/tsdb/tsdbFS.c @@ -176,7 +176,7 @@ static int32_t tsdbScanAndTryFixFS(STsdb *pTsdb) { // SDelFile if (pTsdb->fs.pDelFile) { tsdbDelFileName(pTsdb, pTsdb->fs.pDelFile, fname); - if (taosStatFile(fname, &size, NULL)) { + if (taosStatFile(fname, &size, NULL, NULL)) { code = TAOS_SYSTEM_ERROR(errno); TSDB_CHECK_CODE(code, lino, _exit); } @@ -195,7 +195,7 @@ static int32_t tsdbScanAndTryFixFS(STsdb *pTsdb) { // head ========= tsdbHeadFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pHeadF, fname); - if (taosStatFile(fname, &size, NULL)) { + if (taosStatFile(fname, &size, NULL, NULL)) { code = TAOS_SYSTEM_ERROR(errno); TSDB_CHECK_CODE(code, lino, _exit); } @@ -206,7 +206,7 @@ static int32_t tsdbScanAndTryFixFS(STsdb *pTsdb) { // data ========= tsdbDataFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pDataF, fname); - if (taosStatFile(fname, &size, NULL)) { + if (taosStatFile(fname, &size, NULL, NULL)) { code = TAOS_SYSTEM_ERROR(errno); TSDB_CHECK_CODE(code, lino, _exit); } @@ -221,7 +221,7 @@ static int32_t tsdbScanAndTryFixFS(STsdb *pTsdb) { // sma ============= tsdbSmaFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pSmaF, fname); - if (taosStatFile(fname, &size, NULL)) { + if (taosStatFile(fname, &size, NULL, NULL)) { code = TAOS_SYSTEM_ERROR(errno); TSDB_CHECK_CODE(code, lino, _exit); } @@ -237,7 +237,7 @@ static int32_t tsdbScanAndTryFixFS(STsdb *pTsdb) { // stt =========== for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) { tsdbSttFileName(pTsdb, pSet->diskId, pSet->fid, pSet->aSttF[iStt], fname); - if (taosStatFile(fname, &size, NULL)) { + if (taosStatFile(fname, &size, NULL, NULL)) { code = TAOS_SYSTEM_ERROR(errno); TSDB_CHECK_CODE(code, lino, _exit); } diff --git a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c index 89b7d019ae194f11c33151555f1a52c872f7fe5e..4d3b53bc5a949bd524e5b005108fd0a4f4433403 100644 --- a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c +++ b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c @@ -14,6 +14,7 @@ */ #include "tsdb.h" +#include "vndCos.h" // =============== PAGE-WISE FILE =============== int32_t tsdbOpenFile(const char *path, int32_t szPage, int32_t flag, STsdbFD **ppFD) { @@ -34,9 +35,24 @@ int32_t tsdbOpenFile(const char *path, int32_t szPage, int32_t flag, STsdbFD **p pFD->flag = flag; pFD->pFD = taosOpenFile(path, flag); if (pFD->pFD == NULL) { - code = TAOS_SYSTEM_ERROR(errno); - taosMemoryFree(pFD); - goto _exit; + const char *object_name = taosDirEntryBaseName((char *)path); + long s3_size = s3Size(object_name); + if (!strncmp(path + strlen(path) - 5, ".data", 5) && s3_size > 0) { + s3EvictCache(path, s3_size); + s3Get(object_name, path); + + pFD->pFD = taosOpenFile(path, flag); + + if (pFD->pFD == NULL) { + code = TAOS_SYSTEM_ERROR(errno); + taosMemoryFree(pFD); + goto _exit; + } + } else { + code = TAOS_SYSTEM_ERROR(errno); + taosMemoryFree(pFD); + goto _exit; + } } pFD->szPage = szPage; pFD->pgno = 0; @@ -50,7 +66,7 @@ int32_t tsdbOpenFile(const char *path, int32_t szPage, int32_t flag, STsdbFD **p // not check file size when reading data files. if (flag != TD_FILE_READ) { - if (taosStatFile(path, &pFD->szFile, NULL) < 0) { + if (taosStatFile(path, &pFD->szFile, NULL, NULL) < 0) { code = TAOS_SYSTEM_ERROR(errno); taosMemoryFree(pFD->pBuf); taosCloseFile(&pFD->pFD); diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index a4d5715083a2b6d82f048b8950c2a74c8df11f6d..267e8b4117b2c61cd33855ecb14df8857ee31db3 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -15,6 +15,7 @@ #include "tsdb.h" #include "tsdbFS2.h" +#include "vndCos.h" typedef struct { STsdb *tsdb; @@ -41,6 +42,28 @@ static int32_t tsdbDoRemoveFileObject(SRTNer *rtner, const STFileObj *fobj) { return TARRAY2_APPEND(rtner->fopArr, op); } +static int32_t tsdbRemoveFileObjectS3(SRTNer *rtner, const STFileObj *fobj) { + int32_t code = 0, lino = 0; + + STFileOp op = { + .optype = TSDB_FOP_REMOVE, + .fid = fobj->f->fid, + .of = fobj->f[0], + }; + + code = TARRAY2_APPEND(rtner->fopArr, op); + TSDB_CHECK_CODE(code, lino, _exit); + + const char *object_name = taosDirEntryBaseName((char *)fobj->fname); + s3DeleteObjects(&object_name, 1); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(rtner->tsdb->pVnode), lino, code); + } + return code; +} + static int32_t tsdbDoCopyFile(SRTNer *rtner, const STFileObj *from, const STFile *to) { int32_t code = 0; int32_t lino = 0; @@ -76,6 +99,34 @@ _exit: return code; } +static int32_t tsdbCopyFileS3(SRTNer *rtner, const STFileObj *from, const STFile *to) { + int32_t code = 0; + int32_t lino = 0; + + char fname[TSDB_FILENAME_LEN]; + TdFilePtr fdFrom = NULL; + TdFilePtr fdTo = NULL; + + tsdbTFileName(rtner->tsdb, to, fname); + + fdFrom = taosOpenFile(from->fname, TD_FILE_READ); + if (fdFrom == NULL) code = terrno; + TSDB_CHECK_CODE(code, lino, _exit); + + char *object_name = taosDirEntryBaseName(fname); + code = s3PutObjectFromFile(from->fname, object_name); + TSDB_CHECK_CODE(code, lino, _exit); + + taosCloseFile(&fdFrom); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(rtner->tsdb->pVnode), lino, code); + taosCloseFile(&fdFrom); + } + return code; +} + static int32_t tsdbDoMigrateFileObj(SRTNer *rtner, const STFileObj *fobj, const SDiskID *did) { int32_t code = 0; int32_t lino = 0; @@ -123,6 +174,53 @@ _exit: return code; } +static int32_t tsdbMigrateDataFileS3(SRTNer *rtner, const STFileObj *fobj, const SDiskID *did) { + int32_t code = 0; + int32_t lino = 0; + STFileOp op = {0}; + + // remove old + op = (STFileOp){ + .optype = TSDB_FOP_REMOVE, + .fid = fobj->f->fid, + .of = fobj->f[0], + }; + + code = TARRAY2_APPEND(rtner->fopArr, op); + TSDB_CHECK_CODE(code, lino, _exit); + + // create new + op = (STFileOp){ + .optype = TSDB_FOP_CREATE, + .fid = fobj->f->fid, + .nf = + { + .type = fobj->f->type, + .did = did[0], + .fid = fobj->f->fid, + .cid = fobj->f->cid, + .size = fobj->f->size, + .stt[0] = + { + .level = fobj->f->stt[0].level, + }, + }, + }; + + code = TARRAY2_APPEND(rtner->fopArr, op); + TSDB_CHECK_CODE(code, lino, _exit); + + // do copy the file + code = tsdbCopyFileS3(rtner, fobj, &op.nf); + TSDB_CHECK_CODE(code, lino, _exit); + +_exit: + if (code) { + TSDB_ERROR_LOG(TD_VID(rtner->tsdb->pVnode), lino, code); + } + return code; +} + typedef struct { STsdb *tsdb; int32_t sync; @@ -201,8 +299,14 @@ static int32_t tsdbDoRetention2(void *arg) { for (int32_t ftype = 0; (ftype < TSDB_FTYPE_MAX) && (fobj = rtner->ctx->fset->farr[ftype], 1); ++ftype) { if (fobj == NULL) continue; - code = tsdbDoRemoveFileObject(rtner, fobj); - TSDB_CHECK_CODE(code, lino, _exit); + int32_t nlevel = tfsGetLevel(rtner->tsdb->pVnode->pTfs); + if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && fobj->f->did.level == nlevel - 1) { + code = tsdbRemoveFileObjectS3(rtner, fobj); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + code = tsdbDoRemoveFileObject(rtner, fobj); + TSDB_CHECK_CODE(code, lino, _exit); + } } SSttLvl *lvl; @@ -228,8 +332,15 @@ static int32_t tsdbDoRetention2(void *arg) { if (fobj == NULL) continue; if (fobj->f->did.level == did.level) continue; - code = tsdbDoMigrateFileObj(rtner, fobj, &did); - TSDB_CHECK_CODE(code, lino, _exit); + + int32_t nlevel = tfsGetLevel(rtner->tsdb->pVnode->pTfs); + if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && did.level == nlevel - 1) { + code = tsdbMigrateDataFileS3(rtner, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + code = tsdbDoMigrateFileObj(rtner, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); + } } // stt @@ -281,4 +392,4 @@ int32_t tsdbRetention(STsdb *tsdb, int64_t now, int32_t sync) { tsdbFreeRtnArg(arg); } return code; -} \ No newline at end of file +} diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c index bdcf4a87c194c38487576ea796d5d844d0159ab4..f547119f49709384640b6218c81b25b5b363b391 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c +++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c @@ -392,6 +392,9 @@ static int32_t tsdbSnapReadTombData(STsdbSnapReader* reader, uint8_t** data) { code = tTombBlockPut(reader->tombBlock, record); TSDB_CHECK_CODE(code, lino, _exit); + code = tsdbIterMergerNext(reader->tombIterMerger); + TSDB_CHECK_CODE(code, lino, _exit); + if (TOMB_BLOCK_SIZE(reader->tombBlock) >= 81920) { break; } diff --git a/source/dnode/vnode/src/tsdb/tsdbWrite.c b/source/dnode/vnode/src/tsdb/tsdbWrite.c index 2dbac956ed1aacb1e13fd5fdcedfd2ad644755ea..6e89b47adcf425ae3b5a3a08e75294cd7c1b7d85 100644 --- a/source/dnode/vnode/src/tsdb/tsdbWrite.c +++ b/source/dnode/vnode/src/tsdb/tsdbWrite.c @@ -76,7 +76,7 @@ int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq2 *pMsg) { int32_t code = 0; STsdbKeepCfg *pCfg = &pTsdb->keepCfg; TSKEY now = taosGetTimestamp(pCfg->precision); - TSKEY minKey = now - tsTickPerMin[pCfg->precision] * pCfg->keep2; + TSKEY minKey = now - tsTickPerMin[pCfg->precision] * pCfg->keep1; TSKEY maxKey = tsMaxKeyByPrecision[pCfg->precision]; int32_t size = taosArrayGetSize(pMsg->aSubmitTbData); @@ -107,4 +107,4 @@ int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq2 *pMsg) { _exit: return code; -} \ No newline at end of file +} diff --git a/source/dnode/vnode/src/vnd/vnodeCos.c b/source/dnode/vnode/src/vnd/vnodeCos.c new file mode 100644 index 0000000000000000000000000000000000000000..4c76538eb23636449153f77e081d6d19d5c01f92 --- /dev/null +++ b/source/dnode/vnode/src/vnd/vnodeCos.c @@ -0,0 +1,323 @@ +#define ALLOW_FORBID_FUNC + +#include "vndCos.h" + +extern char tsS3Endpoint[]; +extern char tsS3AccessKeyId[]; +extern char tsS3AccessKeySecret[]; +extern char tsS3BucketName[]; +extern char tsS3AppId[]; + +#ifdef USE_COS +#include "cos_api.h" +#include "cos_http_io.h" +#include "cos_log.h" + +int32_t s3Init() { + if (cos_http_io_initialize(NULL, 0) != COSE_OK) { + return -1; + } + + // set log level, default COS_LOG_WARN + cos_log_set_level(COS_LOG_WARN); + + // set log output, default stderr + cos_log_set_output(NULL); + + return 0; +} + +void s3CleanUp() { cos_http_io_deinitialize(); } + +static void log_status(cos_status_t *s) { + cos_warn_log("status->code: %d", s->code); + if (s->error_code) cos_warn_log("status->error_code: %s", s->error_code); + if (s->error_msg) cos_warn_log("status->error_msg: %s", s->error_msg); + if (s->req_id) cos_warn_log("status->req_id: %s", s->req_id); +} + +static void s3InitRequestOptions(cos_request_options_t *options, int is_cname) { + options->config = cos_config_create(options->pool); + + cos_config_t *config = options->config; + + cos_str_set(&config->endpoint, tsS3Endpoint); + cos_str_set(&config->access_key_id, tsS3AccessKeyId); + cos_str_set(&config->access_key_secret, tsS3AccessKeySecret); + cos_str_set(&config->appid, tsS3AppId); + + config->is_cname = is_cname; + + options->ctl = cos_http_controller_create(options->pool, 0); +} + +int32_t s3PutObjectFromFile(const char *file_str, const char *object_str) { + int32_t code = 0; + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket, object, file; + cos_table_t *resp_headers; + int traffic_limit = 0; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + s3InitRequestOptions(options, is_cname); + cos_table_t *headers = NULL; + if (traffic_limit) { + // 限速值设置范围为819200 - 838860800,即100KB/s - 100MB/s,如果超出该范围将返回400错误 + headers = cos_table_make(p, 1); + cos_table_add_int(headers, "x-cos-traffic-limit", 819200); + } + cos_str_set(&bucket, tsS3BucketName); + cos_str_set(&file, file_str); + cos_str_set(&object, object_str); + s = cos_put_object_from_file(options, &bucket, &object, &file, headers, &resp_headers); + log_status(s); + + cos_pool_destroy(p); + + if (s->code != 200) { + return code = s->code; + } + + return code; +} + +void s3DeleteObjects(const char *object_name[], int nobject) { + cos_pool_t *p = NULL; + int is_cname = 0; + cos_string_t bucket; + cos_table_t *resp_headers = NULL; + cos_request_options_t *options = NULL; + cos_list_t object_list; + cos_list_t deleted_object_list; + int is_quiet = COS_TRUE; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + s3InitRequestOptions(options, is_cname); + cos_str_set(&bucket, tsS3BucketName); + + cos_list_init(&object_list); + cos_list_init(&deleted_object_list); + + for (int i = 0; i < nobject; ++i) { + cos_object_key_t *content = cos_create_cos_object_key(p); + cos_str_set(&content->key, object_name[i]); + cos_list_add_tail(&content->node, &object_list); + } + + cos_status_t *s = cos_delete_objects(options, &bucket, &object_list, is_quiet, &resp_headers, &deleted_object_list); + log_status(s); + + cos_pool_destroy(p); + + if (cos_status_is_ok(s)) { + cos_warn_log("delete objects succeeded\n"); + } else { + cos_warn_log("delete objects failed\n"); + } +} + +bool s3Exists(const char *object_name) { + bool ret = false; + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers; + cos_table_t *headers = NULL; + cos_object_exist_status_e object_exist; + + cos_pool_create(&p, NULL); + options = cos_request_options_create(p); + s3InitRequestOptions(options, is_cname); + cos_str_set(&bucket, tsS3BucketName); + cos_str_set(&object, object_name); + + s = cos_check_object_exist(options, &bucket, &object, headers, &object_exist, &resp_headers); + if (object_exist == COS_OBJECT_NON_EXIST) { + cos_warn_log("object: %.*s non exist.\n", object.len, object.data); + } else if (object_exist == COS_OBJECT_EXIST) { + ret = true; + cos_warn_log("object: %.*s exist.\n", object.len, object.data); + } else { + cos_warn_log("object: %.*s unknown status.\n", object.len, object.data); + log_status(s); + } + + cos_pool_destroy(p); + + return ret; +} + +bool s3Get(const char *object_name, const char *path) { + bool ret = false; + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_string_t file; + cos_table_t *resp_headers = NULL; + cos_table_t *headers = NULL; + int traffic_limit = 0; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + s3InitRequestOptions(options, is_cname); + cos_str_set(&bucket, tsS3BucketName); + if (traffic_limit) { + //限速值设置范围为819200 - 838860800,即100KB/s - 100MB/s,如果超出该范围将返回400错误 + headers = cos_table_make(p, 1); + cos_table_add_int(headers, "x-cos-traffic-limit", 819200); + } + + //下载对象 + cos_str_set(&file, path); + cos_str_set(&object, object_name); + s = cos_get_object_to_file(options, &bucket, &object, headers, NULL, &file, &resp_headers); + if (cos_status_is_ok(s)) { + ret = true; + cos_warn_log("get object succeeded\n"); + } else { + cos_warn_log("get object failed\n"); + } + + //销毁内存池 + cos_pool_destroy(p); + + return ret; +} + +typedef struct { + int64_t size; + int32_t atime; + char name[TSDB_FILENAME_LEN]; +} SEvictFile; + +static int32_t evictFileCompareAsce(const void *pLeft, const void *pRight) { + SEvictFile *lhs = (SEvictFile *)pLeft; + SEvictFile *rhs = (SEvictFile *)pRight; + return lhs->atime < rhs->atime ? -1 : 1; +} + +void s3EvictCache(const char *path, long object_size) { + SDiskSize disk_size = {0}; + char dir_name[TSDB_FILENAME_LEN] = "\0"; + + tstrncpy(dir_name, path, TSDB_FILENAME_LEN); + taosDirName(dir_name); + + if (taosGetDiskSize((char *)dir_name, &disk_size) < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + vError("failed to get disk:%s size since %s", path, terrstr()); + return; + } + + if (object_size >= disk_size.avail - (1 << 30)) { + // evict too old files + // 1, list data files' atime under dir(path) + tdbDirPtr pDir = taosOpenDir(dir_name); + if (pDir == NULL) { + terrno = TAOS_SYSTEM_ERROR(errno); + vError("failed to open %s since %s", dir_name, terrstr()); + } + SArray *evict_files = taosArrayInit(16, sizeof(SEvictFile)); + tdbDirEntryPtr pDirEntry; + while ((pDirEntry = taosReadDir(pDir)) != NULL) { + char *name = taosGetDirEntryName(pDirEntry); + if (!strncmp(name + strlen(name) - 5, ".data", 5)) { + SEvictFile e_file = {0}; + char entry_name[TSDB_FILENAME_LEN] = "\0"; + int dir_len = strlen(dir_name); + + memcpy(e_file.name, dir_name, dir_len); + e_file.name[dir_len] = '/'; + memcpy(e_file.name + dir_len + 1, name, strlen(name)); + + taosStatFile(e_file.name, &e_file.size, NULL, &e_file.atime); + + taosArrayPush(evict_files, &e_file); + } + } + taosCloseDir(&pDir); + + // 2, sort by atime + taosArraySort(evict_files, evictFileCompareAsce); + + // 3, remove files ascendingly until we get enough object_size space + long evict_size = 0; + size_t ef_size = TARRAY_SIZE(evict_files); + for (size_t i = 0; i < ef_size; ++i) { + SEvictFile *evict_file = taosArrayGet(evict_files, i); + taosRemoveFile(evict_file->name); + evict_size += evict_file->size; + if (evict_size >= object_size) { + break; + } + } + + taosArrayDestroy(evict_files); + } +} + +long s3Size(const char *object_name) { + long size = 0; + + cos_pool_t *p = NULL; + int is_cname = 0; + cos_status_t *s = NULL; + cos_request_options_t *options = NULL; + cos_string_t bucket; + cos_string_t object; + cos_table_t *resp_headers = NULL; + + //创建内存池 + cos_pool_create(&p, NULL); + + //初始化请求选项 + options = cos_request_options_create(p); + s3InitRequestOptions(options, is_cname); + cos_str_set(&bucket, tsS3BucketName); + + //获取对象元数据 + cos_str_set(&object, object_name); + s = cos_head_object(options, &bucket, &object, NULL, &resp_headers); + // print_headers(resp_headers); + if (cos_status_is_ok(s)) { + char *content_length_str = (char *)apr_table_get(resp_headers, COS_CONTENT_LENGTH); + if (content_length_str != NULL) { + size = atol(content_length_str); + } + cos_warn_log("head object succeeded: %ld\n", size); + } else { + cos_warn_log("head object failed\n"); + } + + //销毁内存池 + cos_pool_destroy(p); + + return size; +} + +#else + +int32_t s3Init() { return 0; } +void s3CleanUp() {} +int32_t s3PutObjectFromFile(const char *file, const char *object) { return 0; } +void s3DeleteObjects(const char *object_name[], int nobject) {} +bool s3Exists(const char *object_name) { return false; } +bool s3Get(const char *object_name, const char *path) { return false; } +void s3EvictCache(const char *path, long object_size) {} +long s3Size(const char *object_name) { return 0; } + +#endif diff --git a/source/dnode/vnode/src/vnd/vnodeInitApi.c b/source/dnode/vnode/src/vnd/vnodeInitApi.c index 5c8d563d73f2d98567b1118b676eb607c5937bf9..dca8dd271ceaa69c80dd2182fa8f180b4f0bc3cb 100644 --- a/source/dnode/vnode/src/vnd/vnodeInitApi.c +++ b/source/dnode/vnode/src/vnd/vnodeInitApi.c @@ -96,6 +96,10 @@ void initMetadataAPI(SStoreMeta* pMeta) { pMeta->metaGetCachedTbGroup = metaGetCachedTbGroup; pMeta->metaPutTbGroupToCache = metaPutTbGroupToCache; + + pMeta->openCtbCursor = metaOpenCtbCursor; + pMeta->closeCtbCursor = metaCloseCtbCursor; + pMeta->ctbCursorNext = metaCtbCursorNext; } void initTqAPI(SStoreTqReader* pTq) { diff --git a/source/dnode/vnode/src/vnd/vnodeModule.c b/source/dnode/vnode/src/vnd/vnodeModule.c index 74a8d14a86c6340c3acedec831524b8ae765b91e..6ccce5c9d7683232c80d4a74008a51d8f85215a2 100644 --- a/source/dnode/vnode/src/vnd/vnodeModule.c +++ b/source/dnode/vnode/src/vnd/vnodeModule.c @@ -14,6 +14,7 @@ */ #include "vnd.h" +#include "vndCos.h" typedef struct SVnodeTask SVnodeTask; struct SVnodeTask { @@ -81,6 +82,9 @@ int vnodeInit(int nthreads) { if (tqInit() < 0) { return -1; } + if (s3Init() < 0) { + return -1; + } return 0; } @@ -112,6 +116,7 @@ void vnodeCleanup() { walCleanUp(); tqCleanUp(); smaCleanUp(); + s3CleanUp(); } int vnodeScheduleTaskEx(int tpid, int (*execute)(void*), void* arg) { diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index ebc2e38a5aea7f1c1801e520ba1eb0c6a4401060..2e13f15a786c81517963f63b987649a3b5b338e4 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -216,7 +216,7 @@ int vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) { cfgRsp.numOfTags = schemaTag.nCols; cfgRsp.numOfColumns = schema.nCols; - cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags)); + cfgRsp.pSchemas = (SSchema *)taosMemoryCalloc(cfgRsp.numOfColumns + cfgRsp.numOfTags, sizeof(SSchema)); memcpy(cfgRsp.pSchemas, schema.pSchema, sizeof(SSchema) * schema.nCols); if (schemaTag.nCols) { @@ -443,7 +443,7 @@ int32_t vnodeGetTableList(void* pVnode, int8_t type, SArray* pList) { } int32_t vnodeGetAllTableList(SVnode *pVnode, uint64_t uid, SArray *list) { - SMCtbCursor *pCur = metaOpenCtbCursor(pVnode->pMeta, uid, 1); + SMCtbCursor *pCur = metaOpenCtbCursor(pVnode, uid, 1); while (1) { tb_uid_t id = metaCtbCursorNext(pCur); @@ -465,7 +465,7 @@ int32_t vnodeGetCtbIdListByFilter(SVnode *pVnode, int64_t suid, SArray *list, bo int32_t vnodeGetCtbIdList(void *pVnode, int64_t suid, SArray *list) { SVnode *pVnodeObj = pVnode; - SMCtbCursor *pCur = metaOpenCtbCursor(pVnodeObj->pMeta, suid, 1); + SMCtbCursor *pCur = metaOpenCtbCursor(pVnodeObj, suid, 1); while (1) { tb_uid_t id = metaCtbCursorNext(pCur); @@ -524,7 +524,7 @@ int32_t vnodeGetStbIdListByFilter(SVnode *pVnode, int64_t suid, SArray *list, bo } int32_t vnodeGetCtbNum(SVnode *pVnode, int64_t suid, int64_t *num) { - SMCtbCursor *pCur = metaOpenCtbCursor(pVnode->pMeta, suid, 0); + SMCtbCursor *pCur = metaOpenCtbCursor(pVnode, suid, 0); if (!pCur) { return TSDB_CODE_FAILED; } diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index 743470aac8372e5647f4fc618685fcc5619a0a9c..f75c779f4bd50935b78d81828cb383e492111000 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -661,8 +661,6 @@ int32_t vnodeProcessStreamMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) return tqProcessTaskRetrieveRsp(pVnode->pTq, pMsg); case TDMT_VND_STREAM_SCAN_HISTORY: return tqProcessTaskScanHistory(pVnode->pTq, pMsg); - case TDMT_STREAM_TRANSFER_STATE: - return tqProcessTaskTransferStateReq(pVnode->pTq, pMsg); case TDMT_STREAM_SCAN_HISTORY_FINISH: return tqProcessTaskScanHistoryFinishReq(pVnode->pTq, pMsg); case TDMT_STREAM_SCAN_HISTORY_FINISH_RSP: diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index 8ddf730d5a884a31377bcb4278ac3927a67e9e31..1fa97904e4c2f97702ac1a29faa31a599a7ac688 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -78,6 +78,10 @@ static int32_t buildDescResultDataBlock(SSDataBlock** pOutput) { infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_NOTE_LEN, 4); code = blockDataAppendColInfo(pBlock, &infoData); } + if (TSDB_CODE_SUCCESS == code) { + infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_COL_COMMENT_LEN, 5); + code = blockDataAppendColInfo(pBlock, &infoData); + } if (TSDB_CODE_SUCCESS == code) { *pOutput = pBlock; @@ -99,7 +103,9 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock, SColumnInfoData* pCol3 = taosArrayGet(pBlock->pDataBlock, 2); // Note SColumnInfoData* pCol4 = taosArrayGet(pBlock->pDataBlock, 3); - char buf[DESCRIBE_RESULT_FIELD_LEN] = {0}; + // Comment + SColumnInfoData* pCol5 = taosArrayGet(pBlock->pDataBlock, 4); + char buf[DESCRIBE_RESULT_COL_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0}; for (int32_t i = 0; i < numOfRows; ++i) { if (invisibleColumn(sysInfoUser, pMeta->tableType, pMeta->schema[i].flags)) { continue; @@ -112,6 +118,8 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock, colDataSetVal(pCol3, pBlock->info.rows, (const char*)&bytes, false); STR_TO_VARSTR(buf, i >= pMeta->tableInfo.numOfColumns ? "TAG" : ""); colDataSetVal(pCol4, pBlock->info.rows, buf, false); + STR_TO_VARSTR(buf, pMeta->schema[i].comment); + colDataSetVal(pCol5, pBlock->info.rows, buf, false); ++(pBlock->info.rows); } if (pBlock->info.rows <= 0) { @@ -456,14 +464,19 @@ void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) { for (int32_t i = 0; i < pCfg->numOfColumns; ++i) { SSchema* pSchema = pCfg->pSchemas + i; char type[32]; + char comments[TSDB_COL_COMMENT_LEN + 16] = {0}; sprintf(type, "%s", tDataTypes[pSchema->type].name); if (TSDB_DATA_TYPE_VARCHAR == pSchema->type || TSDB_DATA_TYPE_GEOMETRY == pSchema->type) { sprintf(type + strlen(type), "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE)); } else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) { sprintf(type + strlen(type), "(%d)", (int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)); } + if (pSchema->comment[0]) { + sprintf(comments, " COMMENT '%s'", pSchema->comment); + } - *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type); + *len += + sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s%s", ((i > 0) ? ", " : ""), pSchema->name, type, comments); } } @@ -471,14 +484,18 @@ void appendTagFields(char* buf, int32_t* len, STableCfg* pCfg) { for (int32_t i = 0; i < pCfg->numOfTags; ++i) { SSchema* pSchema = pCfg->pSchemas + pCfg->numOfColumns + i; char type[32]; + char comments[TSDB_COL_COMMENT_LEN + 16] = {0}; sprintf(type, "%s", tDataTypes[pSchema->type].name); if (TSDB_DATA_TYPE_VARCHAR == pSchema->type || TSDB_DATA_TYPE_GEOMETRY == pSchema->type) { sprintf(type + strlen(type), "(%d)", (int32_t)(pSchema->bytes - VARSTR_HEADER_SIZE)); } else if (TSDB_DATA_TYPE_NCHAR == pSchema->type) { sprintf(type + strlen(type), "(%d)", (int32_t)((pSchema->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)); } + if (pSchema->comment[0]) { + sprintf(comments, " COMMENT '%s'", pSchema->comment); + } - *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type); + *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, "%s`%s` %s%s", ((i > 0) ? ", " : ""), pSchema->name, type, comments); } } @@ -624,7 +641,7 @@ void appendTableOptions(char* buf, int32_t* len, SDbCfgInfo* pDbCfg, STableCfg* } } - if (nSma < pCfg->numOfColumns) { + if (nSma < pCfg->numOfColumns && nSma > 0) { bool smaOn = false; *len += sprintf(buf + VARSTR_HEADER_SIZE + *len, " SMA("); for (int32_t i = 0; i < pCfg->numOfColumns; ++i) { diff --git a/source/libs/command/src/explain.c b/source/libs/command/src/explain.c index e917de33dd3ef81333231096c92efac278db516f..e167b31ef8a64c4fa69779909bf2226cadbce7ac 100644 --- a/source/libs/command/src/explain.c +++ b/source/libs/command/src/explain.c @@ -291,17 +291,17 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i switch (pNode->type) { case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: { STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode; - EXPLAIN_ROW_NEW(level, EXPLAIN_TAG_SCAN_FORMAT, pTagScanNode->tableName.tname); + EXPLAIN_ROW_NEW(level, EXPLAIN_TAG_SCAN_FORMAT, pTagScanNode->scan.tableName.tname); EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); if (pResNode->pExecInfo) { QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen)); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); } - if (pTagScanNode->pScanPseudoCols) { - EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTagScanNode->pScanPseudoCols->length); + if (pTagScanNode->scan.pScanPseudoCols) { + EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pTagScanNode->scan.pScanPseudoCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); } - EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->scan.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level)); @@ -309,11 +309,11 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i if (verbose) { EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, - nodesGetOutputNumFromSlotList(pTagScanNode->node.pOutputDataBlockDesc->pSlots)); + nodesGetOutputNumFromSlotList(pTagScanNode->scan.node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); - EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->outputRowSize); - EXPLAIN_ROW_APPEND_LIMIT(pTagScanNode->node.pLimit); - EXPLAIN_ROW_APPEND_SLIMIT(pTagScanNode->node.pSlimit); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->scan.node.pOutputDataBlockDesc->outputRowSize); + EXPLAIN_ROW_APPEND_LIMIT(pTagScanNode->scan.node.pLimit); + EXPLAIN_ROW_APPEND_SLIMIT(pTagScanNode->scan.node.pSlimit); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); diff --git a/source/libs/executor/inc/executil.h b/source/libs/executor/inc/executil.h index 33c9d845b9bded28acf0c3ec796266bc5476371d..341f4071dff17e71c4db52ce25fbb2b1a59599f1 100644 --- a/source/libs/executor/inc/executil.h +++ b/source/libs/executor/inc/executil.h @@ -183,11 +183,17 @@ void cleanupQueryTableDataCond(SQueryTableDataCond* pCond); int32_t convertFillType(int32_t mode); int32_t resultrowComparAsc(const void* p1, const void* p2); -int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle, bool* pQualified, SStorageAPI *pAPI); - -void printDataBlock(SSDataBlock* pBlock, const char* flag); +int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle, bool* pQualified, SStorageAPI* pAPI); +char* getStreamOpName(uint16_t opType); +void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr); +void printSpecDataBlock(SSDataBlock* pBlock, const char* flag, const char* opStr, const char* taskIdStr); void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order); void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery); +TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols); +void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, int64_t delta); + +SSDataBlock* createTagValBlockForFilter(SArray* pColList, int32_t numOfTables, SArray* pUidTagList, void* pVnode, + SStorageAPI* pStorageAPI); #endif // TDENGINE_EXECUTIL_H diff --git a/source/libs/executor/inc/executorInt.h b/source/libs/executor/inc/executorInt.h index fbca5e29f9b733d71bea68c540f981c09903e3a3..91c45d2bd9313a661ec4e2f40f2caa63aa35a71c 100644 --- a/source/libs/executor/inc/executorInt.h +++ b/source/libs/executor/inc/executorInt.h @@ -251,6 +251,12 @@ typedef struct STableMergeScanInfo { SSortExecInfo sortExecInfo; } STableMergeScanInfo; +typedef struct STagScanFilterContext { + SHashObj* colHash; + int32_t index; + SArray* cInfoList; +} STagScanFilterContext; + typedef struct STagScanInfo { SColumnInfo* pCols; SSDataBlock* pRes; @@ -259,6 +265,14 @@ typedef struct STagScanInfo { SLimitNode* pSlimit; SReadHandle readHandle; STableListInfo* pTableListInfo; + uint64_t suid; + void* pCtbCursor; + SNode* pTagCond; + SNode* pTagIndexCond; + STagScanFilterContext filterCtx; + SArray* aUidTags; // SArray + SArray* aFilterIdxs; // SArray + SStorageAPI* pStorageAPI; } STagScanInfo; typedef enum EStreamScanMode { @@ -456,7 +470,6 @@ typedef struct SStreamIntervalOperatorInfo { SArray* pPullWins; // SPullWindowInfo int32_t pullIndex; SSDataBlock* pPullDataRes; - bool isFinal; SArray* pChildren; int32_t numOfChild; SStreamState* pState; // void @@ -507,7 +520,6 @@ typedef struct SStreamSessionAggOperatorInfo { void* pDelIterator; SArray* pChildren; // cache for children's result; final stream operator SPhysiNode* pPhyNode; // create new child - bool isFinal; bool ignoreExpiredData; bool ignoreExpiredDataSaved; SArray* pUpdated; @@ -695,6 +707,13 @@ uint64_t calcGroupId(char* pData, int32_t len); void streamOpReleaseState(struct SOperatorInfo* pOperator); void streamOpReloadState(struct SOperatorInfo* pOperator); +bool inSlidingWindow(SInterval* pInterval, STimeWindow* pWin, SDataBlockInfo* pBlockInfo); +bool inCalSlidingWindow(SInterval* pInterval, STimeWindow* pWin, TSKEY calStart, TSKEY calEnd, EStreamType blockType); +bool compareVal(const char* v, const SStateKeys* pKey); + +int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, + TSKEY* primaryKeys, int32_t prevPosition, int32_t order); + #ifdef __cplusplus } #endif diff --git a/source/libs/executor/inc/operator.h b/source/libs/executor/inc/operator.h index e6c3405d7ff1b75326601adc0b436ca8295ee78d..38cefc1cc5e3c3a17071f4dfbc7fa7beb7f0b006 100644 --- a/source/libs/executor/inc/operator.h +++ b/source/libs/executor/inc/operator.h @@ -81,7 +81,7 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* readHandle, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode, STableListInfo* pTableListInfo, SNode* pTagCond, SNode*pTagIndexCond, SExecTaskInfo* pTaskInfo); SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode, const char* pUser, SExecTaskInfo* pTaskInfo); diff --git a/source/libs/executor/inc/querytask.h b/source/libs/executor/inc/querytask.h index 7241b015a09321db59af5f212efae85af56959ca..0742b9ba4c283223d6b44650d38f229fbe783fe0 100644 --- a/source/libs/executor/inc/querytask.h +++ b/source/libs/executor/inc/querytask.h @@ -99,7 +99,7 @@ struct SExecTaskInfo { void buildTaskId(uint64_t taskId, uint64_t queryId, char* dst); SExecTaskInfo* doCreateTask(uint64_t queryId, uint64_t taskId, int32_t vgId, EOPTR_EXEC_MODEL model, SStorageAPI* pAPI); void doDestroyTask(SExecTaskInfo* pTaskInfo); -bool isTaskKilled(SExecTaskInfo* pTaskInfo); +bool isTaskKilled(void* pTaskInfo); void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode); void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status); int32_t createExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId, diff --git a/source/libs/executor/inc/tsort.h b/source/libs/executor/inc/tsort.h index 57c8bce27553ab9bb9035e1b55a04c7b2f6bbe97..3180173ca7687aeb43eb2af9410c0fbc54909ad1 100644 --- a/source/libs/executor/inc/tsort.h +++ b/source/libs/executor/inc/tsort.h @@ -191,7 +191,8 @@ int32_t getProperSortPageSize(size_t rowSize, uint32_t numOfCols); bool tsortIsClosed(SSortHandle* pHandle); void tsortSetClosed(SSortHandle* pHandle); -void setSingleTableMerge(SSortHandle* pHandle); +void tsortSetSingleTableMerge(SSortHandle* pHandle); +void tsortSetAbortCheckFn(SSortHandle* pHandle, bool (*checkFn)(void* param), void* param); #ifdef __cplusplus } diff --git a/source/libs/executor/src/eventwindowoperator.c b/source/libs/executor/src/eventwindowoperator.c index bbdc50183e35bf2f40d80f59eb98e79662a0d98d..5c335c116fb03aa218baa6d59c2320d9d6dce00e 100644 --- a/source/libs/executor/src/eventwindowoperator.c +++ b/source/libs/executor/src/eventwindowoperator.c @@ -58,16 +58,6 @@ static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts, uint64_t groupId) { pRowSup->groupId = groupId; } -static void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, bool includeEndpoint) { - int64_t* ts = (int64_t*)pColData->pData; - int32_t delta = includeEndpoint ? 1 : 0; - - int64_t duration = pWin->ekey - pWin->skey + delta; - ts[2] = duration; // set the duration - ts[3] = pWin->skey; // window start key - ts[4] = pWin->ekey + delta; // window end key -} - SOperatorInfo* createEventwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo) { SEventWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SEventWindowOperatorInfo)); @@ -250,7 +240,7 @@ static void doEventWindowAggImpl(SEventWindowOperatorInfo* pInfo, SExprSupp* pSu T_LONG_JMP(pTaskInfo->env, TSDB_CODE_APP_ERROR); } - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, false); + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pRowSup->win, 0); applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, startIndex, numOfRows, pBlock->info.rows, numOfOutput); } diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index aa0c7945b022da5ddd453542eb24975675213853..b87af9ed04a6f292a56450141ca6f8905f577c32 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -47,8 +47,6 @@ static int32_t optimizeTbnameInCondImpl(void* metaHandle, SArray* list, SNode* p static int32_t getTableList(void* pVnode, SScanPhysiNode* pScanNode, SNode* pTagCond, SNode* pTagIndexCond, STableListInfo* pListInfo, uint8_t* digest, const char* idstr, SStorageAPI* pStorageAPI); -static SSDataBlock* createTagValBlockForFilter(SArray* pColList, int32_t numOfTables, SArray* pUidTagList, void* pVnode, - SStorageAPI* pStorageAPI); static int64_t getLimit(const SNode* pLimit) { return NULL == pLimit ? -1 : ((SLimitNode*)pLimit)->limit; } static int64_t getOffset(const SNode* pLimit) { return NULL == pLimit ? -1 : ((SLimitNode*)pLimit)->offset; } @@ -846,7 +844,7 @@ static int32_t optimizeTbnameInCondImpl(void* pVnode, SArray* pExistedUidList, S return -1; } -static SSDataBlock* createTagValBlockForFilter(SArray* pColList, int32_t numOfTables, SArray* pUidTagList, void* pVnode, +SSDataBlock* createTagValBlockForFilter(SArray* pColList, int32_t numOfTables, SArray* pUidTagList, void* pVnode, SStorageAPI* pStorageAPI) { SSDataBlock* pResBlock = createDataBlock(); if (pResBlock == NULL) { @@ -1677,6 +1675,7 @@ SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode) { .intervalUnit = pTableScanNode->intervalUnit, .slidingUnit = pTableScanNode->slidingUnit, .offset = pTableScanNode->offset, + .precision = pTableScanNode->scan.node.pOutputDataBlockDesc->precision, }; return interval; @@ -2178,12 +2177,67 @@ int32_t createScanTableListInfo(SScanPhysiNode* pScanNode, SNodeList* pGroupTags return TSDB_CODE_SUCCESS; } -void printDataBlock(SSDataBlock* pBlock, const char* flag) { +char* getStreamOpName(uint16_t opType) { + switch (opType) { + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: + return "stream scan"; + case QUERY_NODE_PHYSICAL_PLAN_PROJECT: + return "project"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: + return "interval single"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL: + return "interval final"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL: + return "interval semi"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FILL: + return "stream fill"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION: + return "session single"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION: + return "session semi"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION: + return "session final"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE: + return "state single"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION: + return "stream partitionby"; + case QUERY_NODE_PHYSICAL_PLAN_STREAM_EVENT: + return "stream event"; + } + return ""; +} + +void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr) { if (!pBlock || pBlock->info.rows == 0) { - qDebug("===stream===%s: Block is Null or Empty", flag); + qDebug("%s===stream===%s: Block is Null or Empty", taskIdStr, flag); return; } char* pBuf = NULL; - qDebug("%s", dumpBlockData(pBlock, flag, &pBuf)); + qDebug("%s", dumpBlockData(pBlock, flag, &pBuf, taskIdStr)); taosMemoryFree(pBuf); } + +void printSpecDataBlock(SSDataBlock* pBlock, const char* flag, const char* opStr, const char* taskIdStr) { + if (!pBlock || pBlock->info.rows == 0) { + qDebug("%s===stream===%s: Block is Null or Empty", taskIdStr, flag); + return; + } + if (qDebugFlag & DEBUG_DEBUG) { + char* pBuf = NULL; + char flagBuf[64]; + snprintf(flagBuf, sizeof(flagBuf), "%s %s", flag, opStr); + qDebug("%s", dumpBlockData(pBlock, flagBuf, &pBuf, taskIdStr)); + taosMemoryFree(pBuf); + } +} + +TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols) { return tsCols == NULL ? win->skey : tsCols[0]; } + +void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, int64_t delta) { + int64_t* ts = (int64_t*)pColData->pData; + + int64_t duration = pWin->ekey - pWin->skey + delta; + ts[2] = duration; // set the duration + ts[3] = pWin->skey; // window start key + ts[4] = pWin->ekey + delta; // window end key +} diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index a6059c7c4200551c654847cb00c3f738be9e36fc..0ad2b9c1165fd2fc737a0340755c89c3d9c6fbab 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -589,6 +589,10 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo int64_t st = taosGetTimestampUs(); int32_t blockIndex = 0; + int32_t rowsThreshold = pTaskInfo->pSubplan->rowsThreshold; + if (!pTaskInfo->pSubplan->dynamicRowThreshold || 4096 <= pTaskInfo->pSubplan->rowsThreshold) { + rowsThreshold = 4096; + } while ((pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot)) != NULL) { SSDataBlock* p = NULL; if (blockIndex >= taosArrayGetSize(pTaskInfo->pResultBlockList)) { @@ -606,10 +610,13 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo ASSERT(p->info.rows > 0); taosArrayPush(pResList, &p); - if (current >= 4096) { + if (current >= rowsThreshold) { break; } } + if (pTaskInfo->pSubplan->dynamicRowThreshold) { + pTaskInfo->pSubplan->rowsThreshold -= current; + } *hasMore = (pRes != NULL); uint64_t el = (taosGetTimestampUs() - st); diff --git a/source/libs/executor/src/executorInt.c b/source/libs/executor/src/executorInt.c index ebec9aa94e5e8c71b6bc0e6c198cd7234550b0b0..a7f0e0281532bcf9112384f1ede3ca0e7677cafd 100644 --- a/source/libs/executor/src/executorInt.c +++ b/source/libs/executor/src/executorInt.c @@ -1070,3 +1070,15 @@ void streamOpReloadState(SOperatorInfo* pOperator) { downstream->fpSet.reloadStreamStateFn(downstream); } } + +bool compareVal(const char* v, const SStateKeys* pKey) { + if (IS_VAR_DATA_TYPE(pKey->type)) { + if (varDataLen(v) != varDataLen(pKey->pData)) { + return false; + } else { + return memcmp(varDataVal(v), varDataVal(pKey->pData), varDataLen(v)) == 0; + } + } else { + return memcmp(pKey->pData, v, pKey->bytes) == 0; + } +} diff --git a/source/libs/executor/src/filloperator.c b/source/libs/executor/src/filloperator.c index 80c88a803effb72588097c4b86acd808dde78354..1788027bd6cdb630315ed6722b4a5ad6b9406b0a 100644 --- a/source/libs/executor/src/filloperator.c +++ b/source/libs/executor/src/filloperator.c @@ -1292,14 +1292,14 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { (pInfo->pFillInfo->pos != FILL_POS_INVALID && pInfo->pFillInfo->needFill == true)) { doStreamFillRange(pInfo->pFillInfo, pInfo->pFillSup, pInfo->pRes); if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill"); + printDataBlock(pInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pRes; } } if (pOperator->status == OP_RES_TO_RETURN) { doDeleteFillFinalize(pOperator); if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill"); + printDataBlock(pInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pRes; } setOperatorCompleted(pOperator); @@ -1317,12 +1317,12 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { pOperator->status = OP_RES_TO_RETURN; pInfo->pFillInfo->preRowKey = INT64_MIN; if (pInfo->pRes->info.rows > 0) { - printDataBlock(pInfo->pRes, "stream fill"); + printDataBlock(pInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pRes; } break; } - printDataBlock(pBlock, "stream fill recv"); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); if (pInfo->pFillInfo->curGroupId != pBlock->info.id.groupId) { pInfo->pFillInfo->curGroupId = pBlock->info.id.groupId; @@ -1339,7 +1339,7 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { pInfo->pFillSup->hasDelete = true; doDeleteFillResult(pOperator); if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "stream fill delete"); + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } continue; @@ -1378,7 +1378,7 @@ static SSDataBlock* doStreamFill(SOperatorInfo* pOperator) { } pOperator->resultInfo.totalRows += pInfo->pRes->info.rows; - printDataBlock(pInfo->pRes, "stream fill"); + printDataBlock(pInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pRes; } diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c index 9228c923a6893ccacbbf51cf3ab90958f7b02bb4..d097c588351b571f233c53ceafe012fd54e8741d 100644 --- a/source/libs/executor/src/groupoperator.c +++ b/source/libs/executor/src/groupoperator.c @@ -956,7 +956,8 @@ static bool hasRemainPartion(SStreamPartitionOperatorInfo* pInfo) { return pInfo static bool hasRemainTbName(SStreamPartitionOperatorInfo* pInfo) { return pInfo->pTbNameIte != NULL; } static SSDataBlock* buildStreamPartitionResult(SOperatorInfo* pOperator) { - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SStreamPartitionOperatorInfo* pInfo = pOperator->info; SSDataBlock* pDest = pInfo->binfo.pRes; @@ -994,7 +995,7 @@ static SSDataBlock* buildStreamPartitionResult(SOperatorInfo* pOperator) { pOperator->resultInfo.totalRows += pDest->info.rows; pInfo->parIte = taosHashIterate(pInfo->pPartitions, pInfo->parIte); ASSERT(pDest->info.rows > 0); - printDataBlock(pDest, "stream partitionby"); + printDataBlock(pDest, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pDest; } @@ -1115,7 +1116,7 @@ static SSDataBlock* doStreamHashPartition(SOperatorInfo* pOperator) { setOperatorCompleted(pOperator); return NULL; } - printDataBlock(pBlock, "stream partitionby recv"); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); switch (pBlock->info.type) { case STREAM_NORMAL: case STREAM_PULL_DATA: @@ -1125,7 +1126,7 @@ static SSDataBlock* doStreamHashPartition(SOperatorInfo* pOperator) { case STREAM_DELETE_DATA: { copyDataBlock(pInfo->pDelRes, pBlock); pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; - printDataBlock(pInfo->pDelRes, "stream partitionby delete"); + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pInfo->pDelRes; } break; default: diff --git a/source/libs/executor/src/operator.c b/source/libs/executor/src/operator.c index 8ddcc8fd150b7cb6ef17252e62fc1fff9d5fecd2..7f0c5baa361585e38b573e622b7bd0a18d941761 100644 --- a/source/libs/executor/src/operator.c +++ b/source/libs/executor/src/operator.c @@ -370,17 +370,18 @@ SOperatorInfo* createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SR STableCountScanPhysiNode* pTblCountScanNode = (STableCountScanPhysiNode*)pPhyNode; pOperator = createTableCountScanOperatorInfo(pHandle, pTblCountScanNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN == type) { - STagScanPhysiNode* pScanPhyNode = (STagScanPhysiNode*)pPhyNode; + STagScanPhysiNode* pTagScanPhyNode = (STagScanPhysiNode*)pPhyNode; STableListInfo* pTableListInfo = tableListCreate(); - int32_t code = createScanTableListInfo(pScanPhyNode, NULL, false, pHandle, pTableListInfo, pTagCond, - pTagIndexCond, pTaskInfo); - if (code != TSDB_CODE_SUCCESS) { - pTaskInfo->code = code; - qError("failed to getTableList, code: %s", tstrerror(code)); - return NULL; + if (!pTagScanPhyNode->onlyMetaCtbIdx) { + int32_t code = createScanTableListInfo((SScanPhysiNode*)pTagScanPhyNode, NULL, false, pHandle, pTableListInfo, pTagCond, + pTagIndexCond, pTaskInfo); + if (code != TSDB_CODE_SUCCESS) { + pTaskInfo->code = code; + qError("failed to getTableList, code: %s", tstrerror(code)); + return NULL; + } } - - pOperator = createTagScanOperatorInfo(pHandle, pScanPhyNode, pTableListInfo, pTaskInfo); + pOperator = createTagScanOperatorInfo(pHandle, pTagScanPhyNode, pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN == type) { SBlockDistScanPhysiNode* pBlockNode = (SBlockDistScanPhysiNode*)pPhyNode; STableListInfo* pTableListInfo = tableListCreate(); diff --git a/source/libs/executor/src/projectoperator.c b/source/libs/executor/src/projectoperator.c index 1cc377b3ee9320c79e30c34a45d0289936da5918..8e31bc042f92ed14e1e063d24fd2a39a0d504a7f 100644 --- a/source/libs/executor/src/projectoperator.c +++ b/source/libs/executor/src/projectoperator.c @@ -372,6 +372,10 @@ SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) { pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0; } + if (pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM) { + printDataBlock(p, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + } + return (p->info.rows > 0) ? p : NULL; } diff --git a/source/libs/executor/src/querytask.c b/source/libs/executor/src/querytask.c index 22d171e74a5117f13ee648701211d2fff2d9da26..980ef1a61a6f4fcb75624372919a088ae52e2aa8 100644 --- a/source/libs/executor/src/querytask.c +++ b/source/libs/executor/src/querytask.c @@ -59,7 +59,7 @@ SExecTaskInfo* doCreateTask(uint64_t queryId, uint64_t taskId, int32_t vgId, EOP return pTaskInfo; } -bool isTaskKilled(SExecTaskInfo* pTaskInfo) { return (0 != pTaskInfo->code); } +bool isTaskKilled(void* pTaskInfo) { return (0 != ((SExecTaskInfo*)pTaskInfo)->code); } void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode) { pTaskInfo->code = rspCode; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 9a836caa8c6fc6a2d4a50c4e3da14cfb8803a431..a106a8e383067fd1197dd90939d3c42143ea4054 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1343,7 +1343,7 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS if (rows == 0) { return TSDB_CODE_SUCCESS; } - + SExecTaskInfo* pTaskInfo = pInfo->pStreamScanOp->pTaskInfo; SColumnInfoData* pSrcStartTsCol = (SColumnInfoData*)taosArrayGet(pSrcBlock->pDataBlock, START_TS_COLUMN_INDEX); SColumnInfoData* pSrcEndTsCol = (SColumnInfoData*)taosArrayGet(pSrcBlock->pDataBlock, END_TS_COLUMN_INDEX); SColumnInfoData* pSrcUidCol = taosArrayGet(pSrcBlock->pDataBlock, UID_COLUMN_INDEX); @@ -1360,7 +1360,7 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS TSKEY startTs = srcStartTsCol[0]; TSKEY endTs = srcEndTsCol[0]; SSDataBlock* pPreRes = readPreVersionData(pInfo->pTableScanOp, srcUid, startTs, endTs, ver); - printDataBlock(pPreRes, "pre res"); + printDataBlock(pPreRes, "pre res", GET_TASKID(pTaskInfo)); blockDataCleanup(pSrcBlock); int32_t code = blockDataEnsureCapacity(pSrcBlock, pPreRes->info.rows); if (code != TSDB_CODE_SUCCESS) { @@ -1375,7 +1375,7 @@ static int32_t generateIntervalScanRange(SStreamScanInfo* pInfo, SSDataBlock* pS appendOneRowToStreamSpecialBlock(pSrcBlock, ((TSKEY*)pTsCol->pData) + i, ((TSKEY*)pTsCol->pData) + i, &srcUid, &groupId, NULL); } - printDataBlock(pSrcBlock, "new delete"); + printDataBlock(pSrcBlock, "new delete", GET_TASKID(pTaskInfo)); } uint64_t* srcGp = (uint64_t*)pSrcGpCol->pData; srcStartTsCol = (TSKEY*)pSrcStartTsCol->pData; @@ -1921,38 +1921,9 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { switch (pInfo->scanMode) { case STREAM_SCAN_FROM_RES: { pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; - printDataBlock(pInfo->pRecoverRes, "scan recover"); + printSpecDataBlock(pInfo->pRecoverRes, getStreamOpName(pOperator->operatorType), "recover", GET_TASKID(pTaskInfo)); return pInfo->pRecoverRes; } break; - // case STREAM_SCAN_FROM_UPDATERES: { - // generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes); - // prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex); - // pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE; - // printDataBlock(pInfo->pUpdateRes, "recover update"); - // return pInfo->pUpdateRes; - // } break; - // case STREAM_SCAN_FROM_DELETE_DATA: { - // generateScanRange(pInfo, pInfo->pUpdateDataRes, pInfo->pUpdateRes); - // prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex); - // pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RANGE; - // copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes); - // pInfo->pDeleteDataRes->info.type = STREAM_DELETE_DATA; - // printDataBlock(pInfo->pDeleteDataRes, "recover delete"); - // return pInfo->pDeleteDataRes; - // } break; - // case STREAM_SCAN_FROM_DATAREADER_RANGE: { - // SSDataBlock* pSDB = doRangeScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex); - // if (pSDB) { - // STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info; - // pSDB->info.type = pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RANGE ? STREAM_NORMAL : STREAM_PULL_DATA; - // checkUpdateData(pInfo, true, pSDB, false); - // printDataBlock(pSDB, "scan recover update"); - // calBlockTbName(pInfo, pSDB); - // return pSDB; - // } - // blockDataCleanup(pInfo->pUpdateDataRes); - // pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; - // } break; default: break; } @@ -1961,22 +1932,17 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { if (pInfo->pRecoverRes != NULL) { calBlockTbName(pInfo, pInfo->pRecoverRes); if (!pInfo->igCheckUpdate && pInfo->pUpdateInfo) { - // if (pStreamInfo->recoverStep == STREAM_RECOVER_STEP__SCAN1) { TSKEY maxTs = pAPI->stateStore.updateInfoFillBlockData(pInfo->pUpdateInfo, pInfo->pRecoverRes, pInfo->primaryTsIndex); pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); - // } else { - // pInfo->pUpdateInfo->maxDataVersion = TMAX(pInfo->pUpdateInfo->maxDataVersion, pStreamInfo->fillHistoryVer.maxVer); - // doCheckUpdate(pInfo, pInfo->pRecoverRes->info.window.ekey, pInfo->pRecoverRes); - // } } if (pInfo->pCreateTbRes->info.rows > 0) { pInfo->scanMode = STREAM_SCAN_FROM_RES; - printDataBlock(pInfo->pCreateTbRes, "recover createTbl"); + printSpecDataBlock(pInfo->pCreateTbRes, getStreamOpName(pOperator->operatorType), "recover", GET_TASKID(pTaskInfo)); return pInfo->pCreateTbRes; } qDebug("stream recover scan get block, rows %" PRId64, pInfo->pRecoverRes->info.rows); - printDataBlock(pInfo->pRecoverRes, "scan recover"); + printSpecDataBlock(pInfo->pRecoverRes, getStreamOpName(pOperator->operatorType), "recover", GET_TASKID(pTaskInfo)); return pInfo->pRecoverRes; } pStreamInfo->recoverStep = STREAM_RECOVER_STEP__NONE; @@ -2032,7 +1998,7 @@ FETCH_NEXT_BLOCK: pAPI->stateStore.updateInfoAddCloseWindowSBF(pInfo->pUpdateInfo); } break; case STREAM_DELETE_DATA: { - printDataBlock(pBlock, "stream scan delete recv"); + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "delete recv", GET_TASKID(pTaskInfo)); SSDataBlock* pDelBlock = NULL; if (pInfo->tqReader) { pDelBlock = createSpecialDataBlock(STREAM_DELETE_DATA); @@ -2043,7 +2009,7 @@ FETCH_NEXT_BLOCK: setBlockGroupIdByUid(pInfo, pDelBlock); rebuildDeleteBlockData(pDelBlock, &pStreamInfo->fillHistoryWindow, id); - printDataBlock(pDelBlock, "stream scan delete recv filtered"); + printSpecDataBlock(pDelBlock, getStreamOpName(pOperator->operatorType), "delete recv filtered", GET_TASKID(pTaskInfo)); if (pDelBlock->info.rows == 0) { if (pInfo->tqReader) { blockDataDestroy(pDelBlock); @@ -2054,7 +2020,7 @@ FETCH_NEXT_BLOCK: if (!isIntervalWindow(pInfo) && !isSessionWindow(pInfo) && !isStateWindow(pInfo)) { generateDeleteResultBlock(pInfo, pDelBlock, pInfo->pDeleteDataRes); pInfo->pDeleteDataRes->info.type = STREAM_DELETE_RESULT; - printDataBlock(pDelBlock, "stream scan delete result"); + printSpecDataBlock(pDelBlock, getStreamOpName(pOperator->operatorType), "delete result", GET_TASKID(pTaskInfo)); blockDataDestroy(pDelBlock); if (pInfo->pDeleteDataRes->info.rows > 0) { @@ -2069,7 +2035,7 @@ FETCH_NEXT_BLOCK: prepareRangeScan(pInfo, pInfo->pUpdateRes, &pInfo->updateResIndex); copyDataBlock(pInfo->pDeleteDataRes, pInfo->pUpdateRes); pInfo->pDeleteDataRes->info.type = STREAM_DELETE_DATA; - printDataBlock(pDelBlock, "stream scan delete data"); + printSpecDataBlock(pDelBlock, getStreamOpName(pOperator->operatorType), "delete result", GET_TASKID(pTaskInfo)); if (pInfo->tqReader) { blockDataDestroy(pDelBlock); } @@ -2084,7 +2050,7 @@ FETCH_NEXT_BLOCK: default: break; } - // printDataBlock(pBlock, "stream scan recv"); + printDataBlock(pBlock, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); return pBlock; } else if (pInfo->blockType == STREAM_INPUT__DATA_SUBMIT) { qDebug("stream scan mode:%d, %s", pInfo->scanMode, id); @@ -2120,7 +2086,7 @@ FETCH_NEXT_BLOCK: STableScanInfo* pTableScanInfo = pInfo->pTableScanOp->info; pSDB->info.type = pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RANGE ? STREAM_NORMAL : STREAM_PULL_DATA; checkUpdateData(pInfo, true, pSDB, false); - printDataBlock(pSDB, "stream scan update"); + printSpecDataBlock(pSDB, getStreamOpName(pOperator->operatorType), "update", GET_TASKID(pTaskInfo)); calBlockTbName(pInfo, pSDB); return pSDB; } @@ -2688,7 +2654,236 @@ static void doTagScanOneTable(SOperatorInfo* pOperator, const SSDataBlock* pRes, } } -static SSDataBlock* doTagScan(SOperatorInfo* pOperator) { +static void tagScanFreeUidTag(void* p) { + STUidTagInfo* pInfo = p; + if (pInfo->pTagVal != NULL) { + taosMemoryFree(pInfo->pTagVal); + } +} + +static int32_t tagScanCreateResultData(SDataType* pType, int32_t numOfRows, SScalarParam* pParam) { + SColumnInfoData* pColumnData = taosMemoryCalloc(1, sizeof(SColumnInfoData)); + if (pColumnData == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return terrno; + } + + pColumnData->info.type = pType->type; + pColumnData->info.bytes = pType->bytes; + pColumnData->info.scale = pType->scale; + pColumnData->info.precision = pType->precision; + + int32_t code = colInfoDataEnsureCapacity(pColumnData, numOfRows, true); + if (code != TSDB_CODE_SUCCESS) { + terrno = code; + taosMemoryFree(pColumnData); + return terrno; + } + + pParam->columnData = pColumnData; + pParam->colAlloced = true; + return TSDB_CODE_SUCCESS; +} + +static EDealRes tagScanRewriteTagColumn(SNode** pNode, void* pContext) { + SColumnNode* pSColumnNode = NULL; + if (QUERY_NODE_COLUMN == nodeType((*pNode))) { + pSColumnNode = *(SColumnNode**)pNode; + } else if (QUERY_NODE_FUNCTION == nodeType((*pNode))) { + SFunctionNode* pFuncNode = *(SFunctionNode**)(pNode); + if (pFuncNode->funcType == FUNCTION_TYPE_TBNAME) { + pSColumnNode = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); + if (NULL == pSColumnNode) { + return DEAL_RES_ERROR; + } + pSColumnNode->colId = -1; + pSColumnNode->colType = COLUMN_TYPE_TBNAME; + pSColumnNode->node.resType.type = TSDB_DATA_TYPE_VARCHAR; + pSColumnNode->node.resType.bytes = TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE; + nodesDestroyNode(*pNode); + *pNode = (SNode*)pSColumnNode; + } else { + return DEAL_RES_CONTINUE; + } + } else { + return DEAL_RES_CONTINUE; + } + + STagScanFilterContext* pCtx = (STagScanFilterContext*)pContext; + void* data = taosHashGet(pCtx->colHash, &pSColumnNode->colId, sizeof(pSColumnNode->colId)); + if (!data) { + taosHashPut(pCtx->colHash, &pSColumnNode->colId, sizeof(pSColumnNode->colId), pNode, sizeof((*pNode))); + pSColumnNode->slotId = pCtx->index++; + SColumnInfo cInfo = {.colId = pSColumnNode->colId, + .type = pSColumnNode->node.resType.type, + .bytes = pSColumnNode->node.resType.bytes}; + taosArrayPush(pCtx->cInfoList, &cInfo); + } else { + SColumnNode* col = *(SColumnNode**)data; + pSColumnNode->slotId = col->slotId; + } + + return DEAL_RES_CONTINUE; +} + + +static void tagScanFilterByTagCond(SArray* aUidTags, SNode* pTagCond, SArray* aFilterIdxs, void* pVnode, SStorageAPI* pAPI, STagScanInfo* pInfo) { + int32_t code = 0; + int32_t numOfTables = taosArrayGetSize(aUidTags); + + SSDataBlock* pResBlock = createTagValBlockForFilter(pInfo->filterCtx.cInfoList, numOfTables, aUidTags, pVnode, pAPI); + + SArray* pBlockList = taosArrayInit(1, POINTER_BYTES); + taosArrayPush(pBlockList, &pResBlock); + SDataType type = {.type = TSDB_DATA_TYPE_BOOL, .bytes = sizeof(bool)}; + + SScalarParam output = {0}; + tagScanCreateResultData(&type, numOfTables, &output); + + scalarCalculate(pTagCond, pBlockList, &output); + + bool* result = (bool*)output.columnData->pData; + for (int32_t i = 0 ; i < numOfTables; ++i) { + if (result[i]) { + taosArrayPush(aFilterIdxs, &i); + } + } + + colDataDestroy(output.columnData); + taosMemoryFreeClear(output.columnData); + + blockDataDestroy(pResBlock); + taosArrayDestroy(pBlockList); + + +} + +static void tagScanFillOneCellWithTag(const STUidTagInfo* pUidTagInfo, SExprInfo* pExprInfo, SColumnInfoData* pColInfo, int rowIndex, const SStorageAPI* pAPI, void* pVnode) { + if (fmIsScanPseudoColumnFunc(pExprInfo->pExpr->_function.functionId)) { // tbname + char str[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; +// if (pUidTagInfo->name != NULL) { +// STR_TO_VARSTR(str, pUidTagInfo->name); +// } else { // name is not retrieved during filter +// pAPI->metaFn.getTableNameByUid(pVnode, pUidTagInfo->uid, str); +// } + STR_TO_VARSTR(str, "ctbidx"); + + colDataSetVal(pColInfo, rowIndex, str, false); + } else { + STagVal tagVal = {0}; + tagVal.cid = pExprInfo->base.pParam[0].pCol->colId; + if (pUidTagInfo->pTagVal == NULL) { + colDataSetNULL(pColInfo, rowIndex); + } else { + const char* p = pAPI->metaFn.extractTagVal(pUidTagInfo->pTagVal, pColInfo->info.type, &tagVal); + + if (p == NULL || (pColInfo->info.type == TSDB_DATA_TYPE_JSON && ((STag*)p)->nTag == 0)) { + colDataSetNULL(pColInfo, rowIndex); + } else if (pColInfo->info.type == TSDB_DATA_TYPE_JSON) { + colDataSetVal(pColInfo, rowIndex, p, false); + } else if (IS_VAR_DATA_TYPE(pColInfo->info.type)) { + char* tmp = taosMemoryMalloc(tagVal.nData + VARSTR_HEADER_SIZE + 1); + varDataSetLen(tmp, tagVal.nData); + memcpy(tmp + VARSTR_HEADER_SIZE, tagVal.pData, tagVal.nData); + colDataSetVal(pColInfo, rowIndex, tmp, false); + taosMemoryFree(tmp); + } else { + colDataSetVal(pColInfo, rowIndex, (const char*)&tagVal.i64, false); + } + } + } +} + +static int32_t tagScanFillResultBlock(SOperatorInfo* pOperator, SSDataBlock* pRes, SArray* aUidTags, SArray* aFilterIdxs, bool ignoreFilterIdx, + SStorageAPI* pAPI) { + STagScanInfo* pInfo = pOperator->info; + SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[0]; + if (!ignoreFilterIdx) { + size_t szTables = taosArrayGetSize(aFilterIdxs); + for (int i = 0; i < szTables; ++i) { + int32_t idx = *(int32_t*)taosArrayGet(aFilterIdxs, i); + STUidTagInfo* pUidTagInfo = taosArrayGet(aUidTags, idx); + for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { + SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, pExprInfo[j].base.resSchema.slotId); + tagScanFillOneCellWithTag(pUidTagInfo, &pExprInfo[j], pDst, i, pAPI, pInfo->readHandle.vnode); + } + } + } else { + size_t szTables = taosArrayGetSize(aUidTags); + for (int i = 0; i < szTables; ++i) { + STUidTagInfo* pUidTagInfo = taosArrayGet(aUidTags, i); + for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) { + SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, pExprInfo[j].base.resSchema.slotId); + tagScanFillOneCellWithTag(pUidTagInfo, &pExprInfo[j], pDst, i, pAPI, pInfo->readHandle.vnode); + } + } + } + return 0; +} + +static SSDataBlock* doTagScanFromCtbIdx(SOperatorInfo* pOperator) { + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pTaskInfo->storageAPI; + + STagScanInfo* pInfo = pOperator->info; + SSDataBlock* pRes = pInfo->pRes; + blockDataCleanup(pRes); + + if (pInfo->pCtbCursor == NULL) { + pInfo->pCtbCursor = pAPI->metaFn.openCtbCursor(pInfo->readHandle.vnode, pInfo->suid, 1); + } + + SArray* aUidTags = pInfo->aUidTags; + SArray* aFilterIdxs = pInfo->aFilterIdxs; + int32_t count = 0; + + while (1) { + taosArrayClearEx(aUidTags, tagScanFreeUidTag); + taosArrayClear(aFilterIdxs); + + int32_t numTables = 0; + while (numTables < pOperator->resultInfo.capacity) { + SMCtbCursor* pCur = pInfo->pCtbCursor; + tb_uid_t uid = pAPI->metaFn.ctbCursorNext(pInfo->pCtbCursor); + if (uid == 0) { + break; + } + STUidTagInfo info = {.uid = uid, .pTagVal = pCur->pVal}; + info.pTagVal = taosMemoryMalloc(pCur->vLen); + memcpy(info.pTagVal, pCur->pVal, pCur->vLen); + taosArrayPush(aUidTags, &info); + ++numTables; + } + + if (numTables == 0) { + break; + } + bool ignoreFilterIdx = true; + if (pInfo->pTagCond != NULL) { + ignoreFilterIdx = false; + tagScanFilterByTagCond(aUidTags, pInfo->pTagCond, aFilterIdxs, pInfo->readHandle.vnode, pAPI, pInfo); + } else { + ignoreFilterIdx = true; + } + + tagScanFillResultBlock(pOperator, pRes, aUidTags, aFilterIdxs, ignoreFilterIdx, pAPI); + + count = ignoreFilterIdx ? taosArrayGetSize(aUidTags): taosArrayGetSize(aFilterIdxs); + + if (count != 0) { + break; + } + } + + pRes->info.rows = count; + pOperator->resultInfo.totalRows += count; + return (pRes->info.rows == 0) ? NULL : pInfo->pRes; +} + +static SSDataBlock* doTagScanFromMetaEntry(SOperatorInfo* pOperator) { if (pOperator->status == OP_EXEC_DONE) { return NULL; } @@ -2746,14 +2941,23 @@ static SSDataBlock* doTagScan(SOperatorInfo* pOperator) { static void destroyTagScanOperatorInfo(void* param) { STagScanInfo* pInfo = (STagScanInfo*)param; + if (pInfo->pCtbCursor != NULL) { + pInfo->pStorageAPI->metaFn.closeCtbCursor(pInfo->pCtbCursor, 1); + } + taosHashCleanup(pInfo->filterCtx.colHash); + taosArrayDestroy(pInfo->filterCtx.cInfoList); + taosArrayDestroy(pInfo->aFilterIdxs); + taosArrayDestroyEx(pInfo->aUidTags, tagScanFreeUidTag); + pInfo->pRes = blockDataDestroy(pInfo->pRes); taosArrayDestroy(pInfo->matchInfo.pList); pInfo->pTableListInfo = tableListDestroy(pInfo->pTableListInfo); taosMemoryFreeClear(param); } -SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode, - STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo) { +SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pTagScanNode, + STableListInfo* pTableListInfo, SNode* pTagCond, SNode* pTagIndexCond, SExecTaskInfo* pTaskInfo) { + SScanPhysiNode* pPhyNode = (SScanPhysiNode*)pTagScanNode; STagScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STagScanInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { @@ -2775,6 +2979,11 @@ SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysi goto _error; } + pInfo->pTagCond = pTagCond; + pInfo->pTagIndexCond = pTagIndexCond; + pInfo->suid = pPhyNode->suid; + pInfo->pStorageAPI = &pTaskInfo->storageAPI; + pInfo->pTableListInfo = pTableListInfo; pInfo->pRes = createDataBlockFromDescNode(pDescNode); pInfo->readHandle = *pReadHandle; @@ -2786,8 +2995,18 @@ SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysi initResultSizeInfo(&pOperator->resultInfo, 4096); blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); + if (pTagScanNode->onlyMetaCtbIdx) { + pInfo->aUidTags = taosArrayInit(pOperator->resultInfo.capacity, sizeof(STUidTagInfo)); + pInfo->aFilterIdxs = taosArrayInit(pOperator->resultInfo.capacity, sizeof(int32_t)); + pInfo->filterCtx.colHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_SMALLINT), false, HASH_NO_LOCK); + pInfo->filterCtx.cInfoList = taosArrayInit(4, sizeof(SColumnInfo)); + if (pInfo->pTagCond != NULL) { + nodesRewriteExprPostOrder(&pTagCond, tagScanRewriteTagColumn, (void*)&pInfo->filterCtx); + } + } + __optr_fn_t tagScanNextFn = (pTagScanNode->onlyMetaCtbIdx) ? doTagScanFromCtbIdx : doTagScanFromMetaEntry; pOperator->fpSet = - createOperatorFpSet(optrDummyOpenFn, doTagScan, NULL, destroyTagScanOperatorInfo, optrDefaultBufFn, NULL); + createOperatorFpSet(optrDummyOpenFn, tagScanNextFn, NULL, destroyTagScanOperatorInfo, optrDefaultBufFn, NULL); return pOperator; @@ -2928,8 +3147,9 @@ int32_t startGroupTableMergeScan(SOperatorInfo* pOperator) { int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize; pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_BLOCK_TS_MERGE, pInfo->bufPageSize, numOfBufPage, pInfo->pSortInputBlock, pTaskInfo->id.str, 0, 0, 0); - + tsortSetMergeLimit(pInfo->pSortHandle, mergeLimit); + tsortSetAbortCheckFn(pInfo->pSortHandle, isTaskKilled, pOperator->pTaskInfo); } tsortSetFetchRawDataFp(pInfo->pSortHandle, getBlockForTableMergeScan, NULL, NULL); @@ -2949,7 +3169,7 @@ int32_t startGroupTableMergeScan(SOperatorInfo* pOperator) { int32_t code = TSDB_CODE_SUCCESS; if (numOfTable == 1) { - setSingleTableMerge(pInfo->pSortHandle); + tsortSetSingleTableMerge(pInfo->pSortHandle); } else { code = tsortOpen(pInfo->pSortHandle); } diff --git a/source/libs/executor/src/streamtimewindowoperator.c b/source/libs/executor/src/streamtimewindowoperator.c new file mode 100644 index 0000000000000000000000000000000000000000..a718373f60531182c9c5901f9b5ae120ee80d2d7 --- /dev/null +++ b/source/libs/executor/src/streamtimewindowoperator.c @@ -0,0 +1,3195 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#include "executorInt.h" +#include "filter.h" +#include "function.h" +#include "functionMgt.h" +#include "operator.h" +#include "querytask.h" +#include "tcommon.h" +#include "tcompare.h" +#include "tdatablock.h" +#include "tfill.h" +#include "tglobal.h" +#include "tlog.h" +#include "ttime.h" + +#define IS_FINAL_INTERVAL_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) +#define IS_FINAL_SESSION_OP(op) ((op)->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) +#define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL); +#define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState" +#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState" +#define STREAM_STATE_OP_STATE_NAME "StreamStateHistoryState" + +typedef struct SStateWindowInfo { + SResultWindowInfo winInfo; + SStateKeys* pStateKey; +} SStateWindowInfo; + +typedef struct SPullWindowInfo { + STimeWindow window; + uint64_t groupId; + STimeWindow calWin; +} SPullWindowInfo; + +typedef int32_t (*__compare_fn_t)(void* pKey, void* data, int32_t index); + +static int32_t binarySearchCom(void* keyList, int num, void* pKey, int order, __compare_fn_t comparefn) { + int firstPos = 0, lastPos = num - 1, midPos = -1; + int numOfRows = 0; + + if (num <= 0) return -1; + if (order == TSDB_ORDER_DESC) { + // find the first position which is smaller or equal than the key + while (1) { + if (comparefn(pKey, keyList, lastPos) >= 0) return lastPos; + if (comparefn(pKey, keyList, firstPos) == 0) return firstPos; + if (comparefn(pKey, keyList, firstPos) < 0) return firstPos - 1; + + numOfRows = lastPos - firstPos + 1; + midPos = (numOfRows >> 1) + firstPos; + + if (comparefn(pKey, keyList, midPos) < 0) { + lastPos = midPos - 1; + } else if (comparefn(pKey, keyList, midPos) > 0) { + firstPos = midPos + 1; + } else { + break; + } + } + + } else { + // find the first position which is bigger or equal than the key + while (1) { + if (comparefn(pKey, keyList, firstPos) <= 0) return firstPos; + if (comparefn(pKey, keyList, lastPos) == 0) return lastPos; + + if (comparefn(pKey, keyList, lastPos) > 0) { + lastPos = lastPos + 1; + if (lastPos >= num) + return -1; + else + return lastPos; + } + + numOfRows = lastPos - firstPos + 1; + midPos = (numOfRows >> 1) + firstPos; + + if (comparefn(pKey, keyList, midPos) < 0) { + lastPos = midPos - 1; + } else if (comparefn(pKey, keyList, midPos) > 0) { + firstPos = midPos + 1; + } else { + break; + } + } + } + + return midPos; +} + +static int32_t comparePullWinKey(void* pKey, void* data, int32_t index) { + SArray* res = (SArray*)data; + SPullWindowInfo* pos = taosArrayGet(res, index); + SPullWindowInfo* pData = (SPullWindowInfo*)pKey; + if (pData->groupId > pos->groupId) { + return 1; + } else if (pData->groupId < pos->groupId) { + return -1; + } + + if (pData->window.skey > pos->window.ekey) { + return 1; + } else if (pData->window.ekey < pos->window.skey) { + return -1; + } + return 0; +} + +static int32_t savePullWindow(SPullWindowInfo* pPullInfo, SArray* pPullWins) { + int32_t size = taosArrayGetSize(pPullWins); + int32_t index = binarySearchCom(pPullWins, size, pPullInfo, TSDB_ORDER_DESC, comparePullWinKey); + if (index == -1) { + index = 0; + } else { + int32_t code = comparePullWinKey(pPullInfo, pPullWins, index); + if (code == 0) { + SPullWindowInfo* pos = taosArrayGet(pPullWins, index); + pos->window.skey = TMIN(pos->window.skey, pPullInfo->window.skey); + pos->window.ekey = TMAX(pos->window.ekey, pPullInfo->window.ekey); + pos->calWin.skey = TMIN(pos->calWin.skey, pPullInfo->calWin.skey); + pos->calWin.ekey = TMAX(pos->calWin.ekey, pPullInfo->calWin.ekey); + return TSDB_CODE_SUCCESS; + } else if (code > 0) { + index++; + } + } + if (taosArrayInsert(pPullWins, index, pPullInfo) == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + return TSDB_CODE_SUCCESS; +} + +static int32_t saveResult(SResultWindowInfo winInfo, SSHashObj* pStUpdated) { + winInfo.sessionWin.win.ekey = winInfo.sessionWin.win.skey; + return tSimpleHashPut(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); +} + +static int32_t saveWinResult(SWinKey* pKey, SRowBuffPos* pPos, SSHashObj* pUpdatedMap) { + tSimpleHashPut(pUpdatedMap, pKey, sizeof(SWinKey), &pPos, POINTER_BYTES); + return TSDB_CODE_SUCCESS; +} + +static int32_t saveWinResultInfo(TSKEY ts, uint64_t groupId, SRowBuffPos* pPos, SSHashObj* pUpdatedMap) { + SWinKey key = {.ts = ts, .groupId = groupId}; + saveWinResult(&key, pPos, pUpdatedMap); + return TSDB_CODE_SUCCESS; +} + +static void removeResults(SArray* pWins, SSHashObj* pUpdatedMap) { + int32_t size = taosArrayGetSize(pWins); + for (int32_t i = 0; i < size; i++) { + SWinKey* pW = taosArrayGet(pWins, i); + void* tmp = tSimpleHashGet(pUpdatedMap, pW, sizeof(SWinKey)); + if (tmp) { + void* value = *(void**)tmp; + taosMemoryFree(value); + tSimpleHashRemove(pUpdatedMap, pW, sizeof(SWinKey)); + } + } +} + +static int32_t compareWinKey(void* pKey, void* data, int32_t index) { + void* pDataPos = taosArrayGet((SArray*)data, index); + return winKeyCmprImpl(pKey, pDataPos); +} + +static void removeDeleteResults(SSHashObj* pUpdatedMap, SArray* pDelWins) { + taosArraySort(pDelWins, winKeyCmprImpl); + taosArrayRemoveDuplicate(pDelWins, winKeyCmprImpl, NULL); + int32_t delSize = taosArrayGetSize(pDelWins); + if (tSimpleHashGetSize(pUpdatedMap) == 0 || delSize == 0) { + return; + } + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pUpdatedMap, pIte, &iter)) != NULL) { + SWinKey* pResKey = tSimpleHashGetKey(pIte, NULL); + int32_t index = binarySearchCom(pDelWins, delSize, pResKey, TSDB_ORDER_DESC, compareWinKey); + if (index >= 0 && 0 == compareWinKey(pResKey, pDelWins, index)) { + taosArrayRemove(pDelWins, index); + delSize = taosArrayGetSize(pDelWins); + } + } +} + +bool isOverdue(TSKEY ekey, STimeWindowAggSupp* pTwSup) { + ASSERTS(pTwSup->maxTs == INT64_MIN || pTwSup->maxTs > 0, "maxts should greater than 0"); + return pTwSup->maxTs != INT64_MIN && ekey < pTwSup->maxTs - pTwSup->waterMark; +} + +bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pTwSup) { return isOverdue(pWin->ekey, pTwSup); } + +static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId) { + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SWinKey key = {.ts = ts, .groupId = groupId}; + tSimpleHashRemove(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey)); + pAPI->stateStore.streamStateDel(pInfo->pState, &key); + return true; +} + +static int32_t getChildIndex(SSDataBlock* pBlock) { return pBlock->info.childId; } + +static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDataBlock* pBlock, SArray* pUpWins, + SSHashObj* pUpdatedMap) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + TSKEY* startTsCols = (TSKEY*)pStartTsCol->pData; + SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + TSKEY* endTsCols = (TSKEY*)pEndTsCol->pData; + SColumnInfoData* pCalStTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + TSKEY* calStTsCols = (TSKEY*)pCalStTsCol->pData; + SColumnInfoData* pCalEnTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + TSKEY* calEnTsCols = (TSKEY*)pCalEnTsCol->pData; + SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* pGpDatas = (uint64_t*)pGpCol->pData; + for (int32_t i = 0; i < pBlock->info.rows; i++) { + SResultRowInfo dumyInfo = {0}; + dumyInfo.cur.pageId = -1; + + STimeWindow win = {0}; + if (IS_FINAL_INTERVAL_OP(pOperator)) { + win.skey = startTsCols[i]; + win.ekey = endTsCols[i]; + } else { + win = getActiveTimeWindow(NULL, &dumyInfo, startTsCols[i], pInterval, TSDB_ORDER_ASC); + } + + do { + if (!inCalSlidingWindow(pInterval, &win, calStTsCols[i], calEnTsCols[i], pBlock->info.type)) { + getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); + continue; + } + uint64_t winGpId = pGpDatas[i]; + SWinKey winRes = {.ts = win.skey, .groupId = winGpId}; + void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); + if (chIds) { + int32_t childId = getChildIndex(pBlock); + SArray* chArray = *(void**)chIds; + int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); + if (index != -1) { + qDebug("===stream===try push delete window%" PRId64 "chId:%d ,continue", win.skey, childId); + getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); + continue; + } + } + bool res = doDeleteWindow(pOperator, win.skey, winGpId); + if (pUpWins && res) { + taosArrayPush(pUpWins, &winRes); + } + if (pUpdatedMap) { + tSimpleHashRemove(pUpdatedMap, &winRes, sizeof(SWinKey)); + } + getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); + } while (win.ekey <= endTsCols[i]); + } +} + +static int32_t getAllIntervalWindow(SSHashObj* pHashMap, SSHashObj* resWins) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { + SWinKey* pKey = tSimpleHashGetKey(pIte, NULL); + uint64_t groupId = pKey->groupId; + TSKEY ts = pKey->ts; + int32_t code = saveWinResultInfo(ts, groupId, *(SRowBuffPos**)pIte, resWins); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + return TSDB_CODE_SUCCESS; +} + +static int32_t closeStreamIntervalWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SInterval* pInterval, + SHashObj* pPullDataMap, SSHashObj* closeWins, SArray* pDelWins, + SOperatorInfo* pOperator) { + qDebug("===stream===close interval window"); + void* pIte = NULL; + int32_t iter = 0; + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + int32_t delSize = taosArrayGetSize(pDelWins); + while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { + void* key = tSimpleHashGetKey(pIte, NULL); + SWinKey* pWinKey = (SWinKey*)key; + if (delSize > 0) { + int32_t index = binarySearchCom(pDelWins, delSize, pWinKey, TSDB_ORDER_DESC, compareWinKey); + if (index >= 0 && 0 == compareWinKey(pWinKey, pDelWins, index)) { + taosArrayRemove(pDelWins, index); + delSize = taosArrayGetSize(pDelWins); + } + } + + void* chIds = taosHashGet(pPullDataMap, pWinKey, sizeof(SWinKey)); + STimeWindow win = { + .skey = pWinKey->ts, + .ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1, + }; + if (isCloseWindow(&win, pTwSup)) { + if (chIds && pPullDataMap) { + SArray* chAy = *(SArray**)chIds; + int32_t size = taosArrayGetSize(chAy); + qDebug("===stream===window %" PRId64 " wait child size:%d", pWinKey->ts, size); + for (int32_t i = 0; i < size; i++) { + qDebug("===stream===window %" PRId64 " wait child id:%d", pWinKey->ts, *(int32_t*)taosArrayGet(chAy, i)); + } + continue; + } else if (pPullDataMap) { + qDebug("===stream===close window %" PRId64, pWinKey->ts); + } + + if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + int32_t code = saveWinResult(pWinKey, *(SRowBuffPos**)pIte, closeWins); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + tSimpleHashIterateRemove(pHashMap, pWinKey, sizeof(SWinKey), &pIte, &iter); + } + } + return TSDB_CODE_SUCCESS; +} + +STimeWindow getFinalTimeWindow(int64_t ts, SInterval* pInterval) { + STimeWindow w = {.skey = ts, .ekey = INT64_MAX}; + w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1; + return w; +} + +static void doBuildDeleteResult(SStreamIntervalOperatorInfo* pInfo, SArray* pWins, int32_t* index, + SSDataBlock* pBlock) { + blockDataCleanup(pBlock); + int32_t size = taosArrayGetSize(pWins); + if (*index == size) { + *index = 0; + taosArrayClear(pWins); + return; + } + blockDataEnsureCapacity(pBlock, size - *index); + uint64_t uid = 0; + for (int32_t i = *index; i < size; i++) { + SWinKey* pWin = taosArrayGet(pWins, i); + void* tbname = NULL; + pInfo->statestore.streamStateGetParName(pInfo->pState, pWin->groupId, &tbname); + if (tbname == NULL) { + appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, NULL); + } else { + char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN]; + STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName)); + appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, parTbName); + } + pInfo->statestore.streamStateFreeVal(tbname); + (*index)++; + } +} + +void destroyStreamFinalIntervalOperatorInfo(void* param) { + SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)param; + cleanupBasicInfo(&pInfo->binfo); + cleanupAggSup(&pInfo->aggSup); + // it should be empty. + void* pIte = NULL; + while ((pIte = taosHashIterate(pInfo->pPullDataMap, pIte)) != NULL) { + taosArrayDestroy(*(void**)pIte); + } + taosHashCleanup(pInfo->pPullDataMap); + taosHashCleanup(pInfo->pFinalPullDataMap); + taosArrayDestroy(pInfo->pPullWins); + blockDataDestroy(pInfo->pPullDataRes); + taosArrayDestroy(pInfo->pDelWins); + blockDataDestroy(pInfo->pDelRes); + pInfo->statestore.streamFileStateDestroy(pInfo->pState->pFileState); + taosMemoryFreeClear(pInfo->pState); + + nodesDestroyNode((SNode*)pInfo->pPhyNode); + colDataDestroy(&pInfo->twAggSup.timeWindowData); + pInfo->groupResInfo.pRows = taosArrayDestroy(pInfo->groupResInfo.pRows); + cleanupExprSupp(&pInfo->scalarSupp); + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated); + + taosMemoryFreeClear(param); +} + +static bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) { + for (int32_t i = 0; i < numOfCols; i++) { + if (fmIsUserDefinedFunc(pFCtx[i].functionId) || !fmIsInvertible(pFCtx[i].functionId)) { + return false; + } + } + return true; +} + +void initIntervalDownStream(SOperatorInfo* downstream, uint16_t type, SStreamIntervalOperatorInfo* pInfo) { + SStateStore* pAPI = &downstream->pTaskInfo->storageAPI.stateStore; + + if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { + initIntervalDownStream(downstream->pDownstream[0], type, pInfo); + return; + } + + SStreamScanInfo* pScanInfo = downstream->info; + pScanInfo->windowSup.parentType = type; + pScanInfo->windowSup.pIntervalAggSup = &pInfo->aggSup; + if (!pScanInfo->pUpdateInfo) { + pScanInfo->pUpdateInfo = pAPI->updateInfoInitP(&pInfo->interval, pInfo->twAggSup.waterMark); + } + + pScanInfo->interval = pInfo->interval; + pScanInfo->twAggSup = pInfo->twAggSup; + pScanInfo->pState = pInfo->pState; +} + +void compactFunctions(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx, int32_t numOfOutput, + SExecTaskInfo* pTaskInfo, SColumnInfoData* pTimeWindowData) { + for (int32_t k = 0; k < numOfOutput; ++k) { + if (fmIsWindowPseudoColumnFunc(pDestCtx[k].functionId)) { + if (!pTimeWindowData) { + continue; + } + + SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pDestCtx[k]); + char* p = GET_ROWCELL_INTERBUF(pEntryInfo); + SColumnInfoData idata = {0}; + idata.info.type = TSDB_DATA_TYPE_BIGINT; + idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; + idata.pData = p; + + SScalarParam out = {.columnData = &idata}; + SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData}; + pDestCtx[k].sfp.process(&tw, 1, &out); + pEntryInfo->numOfRes = 1; + } else if (functionNeedToExecute(&pDestCtx[k]) && pDestCtx[k].fpSet.combine != NULL) { + int32_t code = pDestCtx[k].fpSet.combine(&pDestCtx[k], &pSourceCtx[k]); + if (code != TSDB_CODE_SUCCESS) { + qError("%s apply combine functions error, code: %s", GET_TASKID(pTaskInfo), tstrerror(code)); + } + } else if (pDestCtx[k].fpSet.combine == NULL) { + char* funName = fmGetFuncName(pDestCtx[k].functionId); + qError("%s error, combine funcion for %s is not implemented", GET_TASKID(pTaskInfo), funName); + taosMemoryFreeClear(funName); + } + } +} + +bool hasIntervalWindow(void* pState, SWinKey* pKey, SStateStore* pStore) { + return pStore->streamStateCheck(pState, pKey); +} + +int32_t setIntervalOutputBuf(void* pState, STimeWindow* win, SRowBuffPos** pResult, int64_t groupId, + SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, + SAggSupporter* pAggSup, SStateStore* pStore) { + SWinKey key = {.ts = win->skey, .groupId = groupId}; + char* value = NULL; + int32_t size = pAggSup->resultRowSize; + + if (pStore->streamStateAddIfNotExist(pState, &key, (void**)&value, &size) < 0) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + *pResult = (SRowBuffPos*)value; + SResultRow* res = (SResultRow*)((*pResult)->pRowBuff); + + // set time window for current result + res->win = (*win); + setResultRowInitCtx(res, pCtx, numOfOutput, rowEntryInfoOffset); + return TSDB_CODE_SUCCESS; +} + +bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, STimeWindowAggSupp* pTwSup, + SStateStore* pStore) { + if (pTwSup->maxTs != INT64_MIN && pWin->ekey < pTwSup->maxTs - pTwSup->deleteMark) { + SWinKey key = {.ts = pWin->skey, .groupId = groupId}; + if (!hasIntervalWindow(pState, &key, pStore)) { + return true; + } + return false; + } + return false; +} + +int32_t getNexWindowPos(SInterval* pInterval, SDataBlockInfo* pBlockInfo, TSKEY* tsCols, int32_t startPos, TSKEY eKey, + STimeWindow* pNextWin) { + int32_t forwardRows = + getNumOfRowsInTimeWindow(pBlockInfo, tsCols, startPos, eKey, binarySearchForKey, NULL, TSDB_ORDER_ASC); + int32_t prevEndPos = forwardRows - 1 + startPos; + return getNextQualifiedWindow(pInterval, pNextWin, pBlockInfo, tsCols, prevEndPos, TSDB_ORDER_ASC); +} + +void addPullWindow(SHashObj* pMap, SWinKey* pWinRes, int32_t size) { + SArray* childIds = taosArrayInit(8, sizeof(int32_t)); + for (int32_t i = 0; i < size; i++) { + taosArrayPush(childIds, &i); + } + taosHashPut(pMap, pWinRes, sizeof(SWinKey), &childIds, sizeof(void*)); +} + +static void clearStreamIntervalOperator(SStreamIntervalOperatorInfo* pInfo) { + tSimpleHashClear(pInfo->aggSup.pResultRowHashTable); + clearDiskbasedBuf(pInfo->aggSup.pResultBuf); + initResultRowInfo(&pInfo->binfo.resultRowInfo); + pInfo->aggSup.currentPageId = -1; + pInfo->statestore.streamStateClear(pInfo->pState); +} + +static void clearSpecialDataBlock(SSDataBlock* pBlock) { + if (pBlock->info.rows <= 0) { + return; + } + blockDataCleanup(pBlock); +} + +static void doBuildPullDataBlock(SArray* array, int32_t* pIndex, SSDataBlock* pBlock) { + clearSpecialDataBlock(pBlock); + int32_t size = taosArrayGetSize(array); + if (size - (*pIndex) == 0) { + return; + } + blockDataEnsureCapacity(pBlock, size - (*pIndex)); + SColumnInfoData* pStartTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + SColumnInfoData* pEndTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + SColumnInfoData* pGroupId = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + SColumnInfoData* pCalStartTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + SColumnInfoData* pCalEndTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + for (; (*pIndex) < size; (*pIndex)++) { + SPullWindowInfo* pWin = taosArrayGet(array, (*pIndex)); + colDataSetVal(pStartTs, pBlock->info.rows, (const char*)&pWin->window.skey, false); + colDataSetVal(pEndTs, pBlock->info.rows, (const char*)&pWin->window.ekey, false); + colDataSetVal(pGroupId, pBlock->info.rows, (const char*)&pWin->groupId, false); + colDataSetVal(pCalStartTs, pBlock->info.rows, (const char*)&pWin->calWin.skey, false); + colDataSetVal(pCalEndTs, pBlock->info.rows, (const char*)&pWin->calWin.ekey, false); + pBlock->info.rows++; + } + if ((*pIndex) == size) { + *pIndex = 0; + taosArrayClear(array); + } + blockDataUpdateTsWindow(pBlock, 0); +} + +void processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFinalMap, SInterval* pInterval, SArray* pPullWins, + int32_t numOfCh, SOperatorInfo* pOperator) { + SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + TSKEY* tsData = (TSKEY*)pStartCol->pData; + SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + TSKEY* tsEndData = (TSKEY*)pEndCol->pData; + SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* groupIdData = (uint64_t*)pGroupCol->pData; + int32_t chId = getChildIndex(pBlock); + for (int32_t i = 0; i < pBlock->info.rows; i++) { + TSKEY winTs = tsData[i]; + while (winTs <= tsEndData[i]) { + SWinKey winRes = {.ts = winTs, .groupId = groupIdData[i]}; + void* chIds = taosHashGet(pMap, &winRes, sizeof(SWinKey)); + if (chIds) { + SArray* chArray = *(SArray**)chIds; + int32_t index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ); + if (index != -1) { + qDebug("===stream===retrive window %" PRId64 " delete child id %d", winRes.ts, chId); + taosArrayRemove(chArray, index); + if (taosArrayGetSize(chArray) == 0) { + // pull data is over + taosArrayDestroy(chArray); + taosHashRemove(pMap, &winRes, sizeof(SWinKey)); + qDebug("===stream===retrive pull data over.window %" PRId64, winRes.ts); + + void* pFinalCh = taosHashGet(pFinalMap, &winRes, sizeof(SWinKey)); + if (pFinalCh) { + taosHashRemove(pFinalMap, &winRes, sizeof(SWinKey)); + doDeleteWindow(pOperator, winRes.ts, winRes.groupId); + STimeWindow nextWin = getFinalTimeWindow(winRes.ts, pInterval); + SPullWindowInfo pull = {.window = nextWin, + .groupId = winRes.groupId, + .calWin.skey = nextWin.skey, + .calWin.ekey = nextWin.skey}; + // add pull data request + if (savePullWindow(&pull, pPullWins) == TSDB_CODE_SUCCESS) { + addPullWindow(pMap, &winRes, numOfCh); + qDebug("===stream===prepare final retrive for delete %" PRId64 ", size:%d", winRes.ts, numOfCh); + } + } + } + } + } + winTs = taosTimeAdd(winTs, pInterval->sliding, pInterval->slidingUnit, pInterval->precision); + } + } +} + +static void addRetriveWindow(SArray* wins, SStreamIntervalOperatorInfo* pInfo, int32_t childId) { + int32_t size = taosArrayGetSize(wins); + for (int32_t i = 0; i < size; i++) { + SWinKey* winKey = taosArrayGet(wins, i); + STimeWindow nextWin = getFinalTimeWindow(winKey->ts, &pInfo->interval); + if (isOverdue(nextWin.ekey, &pInfo->twAggSup) && pInfo->ignoreExpiredData) { + continue; + } + void* chIds = taosHashGet(pInfo->pPullDataMap, winKey, sizeof(SWinKey)); + if (!chIds) { + SPullWindowInfo pull = { + .window = nextWin, .groupId = winKey->groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; + // add pull data request + if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) { + addPullWindow(pInfo->pPullDataMap, winKey, pInfo->numOfChild); + qDebug("===stream===prepare retrive for delete %" PRId64 ", size:%d", winKey->ts, pInfo->numOfChild); + } + } else { + SArray* chArray = *(void**)chIds; + int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); + qDebug("===stream===check final retrive %" PRId64 ",chid:%d", winKey->ts, index); + if (index == -1) { + qDebug("===stream===add final retrive %" PRId64, winKey->ts); + taosHashPut(pInfo->pFinalPullDataMap, winKey, sizeof(SWinKey), NULL, 0); + } + } + } +} + +static void clearFunctionContext(SExprSupp* pSup) { + for (int32_t i = 0; i < pSup->numOfExprs; i++) { + pSup->pCtx[i].saveHandle.currentPage = -1; + } +} + +int32_t getOutputBuf(void* pState, SRowBuffPos* pPos, SResultRow** pResult, SStateStore* pStore) { + return pStore->streamStateGetByPos(pState, pPos, (void**)pResult); +} + +int32_t buildDataBlockFromGroupRes(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, SExprSupp* pSup, + SGroupResInfo* pGroupResInfo) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SExprInfo* pExprInfo = pSup->pExprInfo; + int32_t numOfExprs = pSup->numOfExprs; + int32_t* rowEntryOffset = pSup->rowEntryInfoOffset; + SqlFunctionCtx* pCtx = pSup->pCtx; + + int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); + + for (int32_t i = pGroupResInfo->index; i < numOfRows; i += 1) { + SRowBuffPos* pPos = *(SRowBuffPos**)taosArrayGet(pGroupResInfo->pRows, i); + SResultRow* pRow = NULL; + int32_t code = getOutputBuf(pState, pPos, &pRow, &pAPI->stateStore); + uint64_t groupId = ((SWinKey*)pPos->pKey)->groupId; + ASSERT(code == 0); + doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowEntryOffset); + // no results, continue to check the next one + if (pRow->numOfRows == 0) { + pGroupResInfo->index += 1; + continue; + } + if (pBlock->info.id.groupId == 0) { + pBlock->info.id.groupId = groupId; + void* tbname = NULL; + if (pAPI->stateStore.streamStateGetParName(pTaskInfo->streamInfo.pState, pBlock->info.id.groupId, &tbname) < 0) { + pBlock->info.parTbName[0] = 0; + } else { + memcpy(pBlock->info.parTbName, tbname, TSDB_TABLE_NAME_LEN); + } + pAPI->stateStore.streamStateFreeVal(tbname); + } else { + // current value belongs to different group, it can't be packed into one datablock + if (pBlock->info.id.groupId != groupId) { + break; + } + } + + if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) { + ASSERT(pBlock->info.rows > 0); + break; + } + pGroupResInfo->index += 1; + + for (int32_t j = 0; j < numOfExprs; ++j) { + int32_t slotId = pExprInfo[j].base.resSchema.slotId; + + pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowEntryOffset); + SResultRowEntryInfo* pEnryInfo = pCtx[j].resultInfo; + + if (pCtx[j].fpSet.finalize) { + int32_t code1 = pCtx[j].fpSet.finalize(&pCtx[j], pBlock); + if (TAOS_FAILED(code1)) { + qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code1)); + T_LONG_JMP(pTaskInfo->env, code1); + } + } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) { + // do nothing, todo refactor + } else { + // expand the result into multiple rows. E.g., _wstart, top(k, 20) + // the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows. + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId); + char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo); + for (int32_t k = 0; k < pRow->numOfRows; ++k) { + colDataSetVal(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes); + } + } + } + + pBlock->info.rows += pRow->numOfRows; + } + + pBlock->info.dataLoad = 1; + blockDataUpdateTsWindow(pBlock, 0); + return TSDB_CODE_SUCCESS; +} + +void doBuildStreamIntervalResult(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, + SGroupResInfo* pGroupResInfo) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + // set output datablock version + pBlock->info.version = pTaskInfo->version; + + blockDataCleanup(pBlock); + if (!hasRemainResults(pGroupResInfo)) { + return; + } + + // clear the existed group id + pBlock->info.id.groupId = 0; + buildDataBlockFromGroupRes(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); +} + +static int32_t getNextQualifiedFinalWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, + TSKEY* primaryKeys, int32_t prevPosition) { + int32_t startPos = prevPosition + 1; + if (startPos == pDataBlockInfo->rows) { + startPos = -1; + } else { + *pNext = getFinalTimeWindow(primaryKeys[startPos], pInterval); + } + return startPos; +} + +static void setStreamDataVersion(SExecTaskInfo* pTaskInfo, int64_t version, int64_t ckId) { + pTaskInfo->streamInfo.dataVersion = version; + pTaskInfo->streamInfo.checkPointId = ckId; +} + +static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, uint64_t groupId, + SSHashObj* pUpdatedMap) { + SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)pOperator->info; + pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); + + SResultRowInfo* pResultRowInfo = &(pInfo->binfo.resultRowInfo); + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SExprSupp* pSup = &pOperator->exprSupp; + int32_t numOfOutput = pSup->numOfExprs; + int32_t step = 1; + TSKEY* tsCols = NULL; + SRowBuffPos* pResPos = NULL; + SResultRow* pResult = NULL; + int32_t forwardRows = 0; + + SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); + tsCols = (int64_t*)pColDataInfo->pData; + + int32_t startPos = 0; + TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols); + STimeWindow nextWin = {0}; + if (IS_FINAL_INTERVAL_OP(pOperator)) { + nextWin = getFinalTimeWindow(ts, &pInfo->interval); + } else { + nextWin = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, TSDB_ORDER_ASC); + } + while (1) { + bool isClosed = isCloseWindow(&nextWin, &pInfo->twAggSup); + if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_INTERVAL_OP(pOperator)) || + !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) { + startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin); + if (startPos < 0) { + break; + } + continue; + } + + if (IS_FINAL_INTERVAL_OP(pOperator) && pInfo->numOfChild > 0) { + bool ignore = true; + SWinKey winRes = { + .ts = nextWin.skey, + .groupId = groupId, + }; + void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); + if (isDeletedStreamWindow(&nextWin, groupId, pInfo->pState, &pInfo->twAggSup, &pInfo->statestore) && isClosed && + !chIds) { + SPullWindowInfo pull = { + .window = nextWin, .groupId = groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; + // add pull data request + if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) { + addPullWindow(pInfo->pPullDataMap, &winRes, pInfo->numOfChild); + } + } else { + int32_t index = -1; + SArray* chArray = NULL; + int32_t chId = 0; + if (chIds) { + chArray = *(void**)chIds; + chId = getChildIndex(pSDataBlock); + index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ); + } + if (index == -1 || pSDataBlock->info.type == STREAM_PULL_DATA) { + ignore = false; + } + } + + if (ignore) { + startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, startPos); + if (startPos < 0) { + break; + } + continue; + } + } + + int32_t code = setIntervalOutputBuf(pInfo->pState, &nextWin, &pResPos, groupId, pSup->pCtx, numOfOutput, + pSup->rowEntryInfoOffset, &pInfo->aggSup, &pInfo->statestore); + pResult = (SResultRow*)pResPos->pRowBuff; + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + if (IS_FINAL_INTERVAL_OP(pOperator)) { + forwardRows = 1; + } else { + forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, + NULL, TSDB_ORDER_ASC); + } + + SWinKey key = { + .ts = pResult->win.skey, + .groupId = groupId, + }; + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdatedMap) { + saveWinResult(&key, pResPos, pUpdatedMap); + } + + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + tSimpleHashPut(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey), &pResPos, POINTER_BYTES); + } + + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, 1); + applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, + pSDataBlock->info.rows, numOfOutput); + key.ts = nextWin.skey; + + if (pInfo->delKey.ts > key.ts) { + pInfo->delKey = key; + } + int32_t prevEndPos = (forwardRows - 1) * step + startPos; + if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) { + qError("table uid %" PRIu64 " data block timestamp range may not be calculated! minKey %" PRId64 + ",maxKey %" PRId64, + pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey); + blockDataUpdateTsWindow(pSDataBlock, 0); + + // timestamp of the data is incorrect + if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) { + qError("table uid %" PRIu64 " data block timestamp is out of range! minKey %" PRId64 ",maxKey %" PRId64, + pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey); + } + } + + if (IS_FINAL_INTERVAL_OP(pOperator)) { + startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos); + } else { + startPos = + getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, TSDB_ORDER_ASC); + } + if (startPos < 0) { + break; + } + } +} + +static inline int winPosCmprImpl(const void* pKey1, const void* pKey2) { + SRowBuffPos* pos1 = *(SRowBuffPos**)pKey1; + SRowBuffPos* pos2 = *(SRowBuffPos**)pKey2; + SWinKey* pWin1 = (SWinKey*)pos1->pKey; + SWinKey* pWin2 = (SWinKey*)pos2->pKey; + + if (pWin1->groupId > pWin2->groupId) { + return 1; + } else if (pWin1->groupId < pWin2->groupId) { + return -1; + } + + if (pWin1->ts > pWin2->ts) { + return 1; + } else if (pWin1->ts < pWin2->ts) { + return -1; + } + + return 0; +} + +static void resetUnCloseWinInfo(SSHashObj* winMap) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(winMap, pIte, &iter)) != NULL) { + SRowBuffPos* pPos = *(SRowBuffPos**)pIte; + pPos->beUsed = true; + } +} + + +static SSDataBlock* buildIntervalResult(SOperatorInfo* pOperator) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + uint16_t opType = pOperator->operatorType; + if (IS_FINAL_INTERVAL_OP(pOperator)) { + doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); + if (pInfo->pPullDataRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pPullDataRes, getStreamOpName(opType), GET_TASKID(pTaskInfo)); + return pInfo->pPullDataRes; + } + } + + doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pDelRes, getStreamOpName(opType), GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); + if (pInfo->binfo.pRes->info.rows != 0) { + printDataBlock(pInfo->binfo.pRes, getStreamOpName(opType), GET_TASKID(pTaskInfo)); + return pInfo->binfo.pRes; + } + return NULL; +} + +static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + SExprSupp* pSup = &pOperator->exprSupp; + + qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } else if (pOperator->status == OP_RES_TO_RETURN) { + SSDataBlock* resBlock = buildIntervalResult(pOperator); + if (resBlock != NULL) { + return resBlock; + } + + if (pInfo->recvGetAll) { + pInfo->recvGetAll = false; + resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable); + } + + setOperatorCompleted(pOperator); + if (!IS_FINAL_INTERVAL_OP(pOperator)) { + clearFunctionContext(&pOperator->exprSupp); + // semi interval operator clear disk buffer + clearStreamIntervalOperator(pInfo); + setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); + qDebug("stask:%s ===stream===%s clear", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType)); + } else { + if (pInfo->twAggSup.maxTs > 0 && + pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { + pAPI->stateStore.streamStateCommit(pInfo->pState); + pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); + pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; + } + qDebug("stask:%s ===stream===%s close", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType)); + } + return NULL; + } else { + if (!IS_FINAL_INTERVAL_OP(pOperator)) { + doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + } + } + + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(4096, POINTER_BYTES); + } + if (!pInfo->pUpdatedMap) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pUpdatedMap = tSimpleHashInit(4096, hashFn); + } + + while (1) { + if (isTaskKilled(pTaskInfo)) { + if (pInfo->pUpdated != NULL) { + pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated); + } + + if (pInfo->pUpdatedMap != NULL) { + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + } + + T_LONG_JMP(pTaskInfo->env, pTaskInfo->code); + } + + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + pOperator->status = OP_RES_TO_RETURN; + qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, getStreamOpName(pOperator->operatorType), + pInfo->numOfDatapack); + pInfo->numOfDatapack = 0; + break; + } + pInfo->numOfDatapack++; + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { + pInfo->binfo.pRes->info.type = pBlock->info.type; + } else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + SArray* delWins = taosArrayInit(8, sizeof(SWinKey)); + doDeleteWindows(pOperator, &pInfo->interval, pBlock, delWins, pInfo->pUpdatedMap); + if (IS_FINAL_INTERVAL_OP(pOperator)) { + int32_t chId = getChildIndex(pBlock); + addRetriveWindow(delWins, pInfo, chId); + if (pBlock->info.type != STREAM_CLEAR) { + taosArrayAddAll(pInfo->pDelWins, delWins); + } + taosArrayDestroy(delWins); + continue; + } + removeResults(delWins, pInfo->pUpdatedMap); + taosArrayAddAll(pInfo->pDelWins, delWins); + taosArrayDestroy(delWins); + + doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); + if (pInfo->pDelRes->info.rows != 0) { + // process the rest of the data + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + if (pBlock->info.type == STREAM_CLEAR) { + pInfo->pDelRes->info.type = STREAM_CLEAR; + } else { + pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; + } + return pInfo->pDelRes; + } + + break; + } else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_INTERVAL_OP(pOperator)) { + pInfo->recvGetAll = true; + getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); + continue; + } else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_INTERVAL_OP(pOperator)) { + doDeleteWindows(pOperator, &pInfo->interval, pBlock, NULL, pInfo->pUpdatedMap); + if (taosArrayGetSize(pInfo->pUpdated) > 0) { + break; + } + continue; + } else if (pBlock->info.type == STREAM_PULL_OVER && IS_FINAL_INTERVAL_OP(pOperator)) { + processPullOver(pBlock, pInfo->pPullDataMap, pInfo->pFinalPullDataMap, &pInfo->interval, pInfo->pPullWins, + pInfo->numOfChild, pOperator); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark); + pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey); + } + + removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); + if (IS_FINAL_INTERVAL_OP(pOperator)) { + closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, + pInfo->pPullDataMap, pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); + } + pInfo->binfo.pRes->info.watermark = pInfo->twAggSup.maxTs; + + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pInfo->pUpdatedMap, pIte, &iter)) != NULL) { + taosArrayPush(pInfo->pUpdated, pIte); + } + + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + taosArraySort(pInfo->pUpdated, winPosCmprImpl); + + initMultiResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + + return buildIntervalResult(pOperator); +} + +static int64_t getDeleteMark(SIntervalPhysiNode* pIntervalPhyNode) { + if (pIntervalPhyNode->window.deleteMark <= 0) { + return DEAULT_DELETE_MARK; + } + int64_t deleteMark = TMAX(pIntervalPhyNode->window.deleteMark, pIntervalPhyNode->window.watermark); + deleteMark = TMAX(deleteMark, pIntervalPhyNode->interval); + return deleteMark; +} + +static TSKEY compareTs(void* pKey) { + SWinKey* pWinKey = (SWinKey*)pKey; + return pWinKey->ts; +} + +static int32_t getSelectivityBufSize(SqlFunctionCtx* pCtx) { + if (pCtx->subsidiaries.rowLen == 0) { + int32_t rowLen = 0; + for (int32_t j = 0; j < pCtx->subsidiaries.num; ++j) { + SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j]; + rowLen += pc->pExpr->base.resSchema.bytes; + } + + return rowLen + pCtx->subsidiaries.num * sizeof(bool); + } else { + return pCtx->subsidiaries.rowLen; + } +} + +static int32_t getMaxFunResSize(SExprSupp* pSup, int32_t numOfCols) { + int32_t size = 0; + for (int32_t i = 0; i < numOfCols; ++i) { + int32_t resSize = getSelectivityBufSize(pSup->pCtx + i); + size = TMAX(size, resSize); + } + return size; +} + +static void streamIntervalReleaseState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + int32_t resSize = sizeof(TSKEY); + pInfo->statestore.streamStateSaveInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, + strlen(STREAM_INTERVAL_OP_STATE_NAME), &pInfo->twAggSup.maxTs, resSize); + } + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + pAPI->stateStore.streamStateCommit(pInfo->pState); + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +void streamIntervalReloadState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pInfo->statestore.streamStateGetInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, + strlen(STREAM_INTERVAL_OP_STATE_NAME), &pBuf, &size); + TSKEY ts = *(TSKEY*)pBuf; + taosMemoryFree(pBuf); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, ts); + pInfo->statestore.streamStateReloadInfo(pInfo->pState, ts); + } + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + +SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, int32_t numOfChild) { + SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode; + SStreamIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamIntervalOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + pOperator->pTaskInfo = pTaskInfo; + SStorageAPI* pAPI = &pTaskInfo->storageAPI; + + pInfo->interval = (SInterval){.interval = pIntervalPhyNode->interval, + .sliding = pIntervalPhyNode->sliding, + .intervalUnit = pIntervalPhyNode->intervalUnit, + .slidingUnit = pIntervalPhyNode->slidingUnit, + .offset = pIntervalPhyNode->offset, + .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision}; + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pIntervalPhyNode->window.watermark, + .calTrigger = pIntervalPhyNode->window.triggerType, + .maxTs = INT64_MIN, + .minTs = INT64_MAX, + .deleteMark = getDeleteMark(pIntervalPhyNode), + .deleteMarkSaved = 0, + .calTriggerSaved = 0, + .checkPointTs = 0, + .checkPointInterval = + convertTimePrecision(tsCheckpointInterval, TSDB_TIME_PRECISION_MILLI, pInfo->interval.precision), + }; + ASSERTS(pInfo->twAggSup.calTrigger != STREAM_TRIGGER_MAX_DELAY, "trigger type should not be max delay"); + pInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; + initResultSizeInfo(&pOperator->resultInfo, 4096); + if (pIntervalPhyNode->window.pExprs != NULL) { + int32_t numOfScalar = 0; + SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); + int32_t code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + } + + int32_t numOfCols = 0; + SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &numOfCols); + SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); + initBasicInfo(&pInfo->binfo, pResBlock); + + pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState)); + *(pInfo->pState) = *(pTaskInfo->streamInfo.pState); + + pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); + int32_t code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, + pInfo->pState, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); + initResultRowInfo(&pInfo->binfo.resultRowInfo); + + pInfo->numOfChild = numOfChild; + pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode); + + pInfo->pPullWins = taosArrayInit(8, sizeof(SPullWindowInfo)); + pInfo->pullIndex = 0; + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK); + pInfo->pFinalPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK); + pInfo->pPullDataRes = createSpecialDataBlock(STREAM_RETRIEVE); + pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; + pInfo->ignoreExpiredDataSaved = false; + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + pInfo->delIndex = 0; + pInfo->pDelWins = taosArrayInit(4, sizeof(SWinKey)); + pInfo->delKey.ts = INT64_MAX; + pInfo->delKey.groupId = 0; + pInfo->numOfDatapack = 0; + pInfo->pUpdated = NULL; + pInfo->pUpdatedMap = NULL; + int32_t funResSize = getMaxFunResSize(&pOperator->exprSupp, numOfCols); + pInfo->pState->pFileState = + pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, + compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); + pInfo->dataVersion = 0; + pInfo->statestore = pTaskInfo->storageAPI.stateStore; + pInfo->recvGetAll = false; + + pOperator->operatorType = pPhyNode->type; + if (!IS_FINAL_INTERVAL_OP(pOperator) || numOfChild == 0) { + pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; + } + pOperator->name = getStreamOpName(pOperator->operatorType); + pOperator->blocking = true; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; + + pOperator->fpSet = createOperatorFpSet(NULL, doStreamFinalIntervalAgg, NULL, destroyStreamFinalIntervalOperatorInfo, + optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); + if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { + initIntervalDownStream(downstream, pPhyNode->type, pInfo); + } + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + return pOperator; + +_error: + destroyStreamFinalIntervalOperatorInfo(pInfo); + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +void destroyStreamAggSupporter(SStreamAggSupporter* pSup) { + tSimpleHashCleanup(pSup->pResultRows); + destroyDiskbasedBuf(pSup->pResultBuf); + blockDataDestroy(pSup->pScanBlock); + taosMemoryFreeClear(pSup->pState); + taosMemoryFreeClear(pSup->pDummyCtx); +} + +void destroyStreamSessionAggOperatorInfo(void* param) { + SStreamSessionAggOperatorInfo* pInfo = (SStreamSessionAggOperatorInfo*)param; + cleanupBasicInfo(&pInfo->binfo); + destroyStreamAggSupporter(&pInfo->streamAggSup); + + if (pInfo->pChildren != NULL) { + int32_t size = taosArrayGetSize(pInfo->pChildren); + for (int32_t i = 0; i < size; i++) { + SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i); + destroyOperator(pChild); + } + taosArrayDestroy(pInfo->pChildren); + } + + colDataDestroy(&pInfo->twAggSup.timeWindowData); + blockDataDestroy(pInfo->pDelRes); + blockDataDestroy(pInfo->pWinBlock); + blockDataDestroy(pInfo->pUpdateRes); + tSimpleHashCleanup(pInfo->pStUpdated); + tSimpleHashCleanup(pInfo->pStDeleted); + + taosArrayDestroy(pInfo->historyWins); + taosMemoryFreeClear(param); +} + +int32_t initBasicInfoEx(SOptrBasicInfo* pBasicInfo, SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfCols, + SSDataBlock* pResultBlock, SFunctionStateStore* pStore) { + initBasicInfo(pBasicInfo, pResultBlock); + int32_t code = initExprSupp(pSup, pExprInfo, numOfCols, pStore); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + for (int32_t i = 0; i < numOfCols; ++i) { + pSup->pCtx[i].saveHandle.pBuf = NULL; + } + + ASSERT(numOfCols > 0); + return TSDB_CODE_SUCCESS; +} + +void initDummyFunction(SqlFunctionCtx* pDummy, SqlFunctionCtx* pCtx, int32_t nums) { + for (int i = 0; i < nums; i++) { + pDummy[i].functionId = pCtx[i].functionId; + pDummy[i].isNotNullFunc = pCtx[i].isNotNullFunc; + pDummy[i].isPseudoFunc = pCtx[i].isPseudoFunc; + } +} + +void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uint16_t type, int32_t tsColIndex, + STimeWindowAggSupp* pTwSup) { + if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION) { + SStreamPartitionOperatorInfo* pScanInfo = downstream->info; + pScanInfo->tsColIndex = tsColIndex; + } + + if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { + initDownStream(downstream->pDownstream[0], pAggSup, type, tsColIndex, pTwSup); + return; + } + SStreamScanInfo* pScanInfo = downstream->info; + pScanInfo->windowSup = (SWindowSupporter){.pStreamAggSup = pAggSup, .gap = pAggSup->gap, .parentType = type}; + pScanInfo->pState = pAggSup->pState; + if (!pScanInfo->pUpdateInfo) { + pScanInfo->pUpdateInfo = pAggSup->stateStore.updateInfoInit(60000, TSDB_TIME_PRECISION_MILLI, pTwSup->waterMark); + } + pScanInfo->twAggSup = *pTwSup; +} + +int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, int64_t gap, + SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore, + SReadHandle* pHandle, SStorageAPI* pApi) { + pSup->resultRowSize = keySize + getResultRowSize(pCtx, numOfOutput); + pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR); + pSup->gap = gap; + pSup->stateKeySize = keySize; + pSup->stateKeyType = keyType; + pSup->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx)); + if (pSup->pDummyCtx == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + pSup->stateStore = *pStore; + + initDummyFunction(pSup->pDummyCtx, pCtx, numOfOutput); + pSup->pState = taosMemoryCalloc(1, sizeof(SStreamState)); + *(pSup->pState) = *pState; + pSup->stateStore.streamStateSetNumber(pSup->pState, -1); + + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pSup->pResultRows = tSimpleHashInit(32, hashFn); + + int32_t pageSize = 4096; + while (pageSize < pSup->resultRowSize * 4) { + pageSize <<= 1u; + } + // at least four pages need to be in buffer + int32_t bufSize = 4096 * 256; + if (bufSize <= pageSize) { + bufSize = pageSize * 4; + } + + if (!osTempSpaceAvailable()) { + terrno = TSDB_CODE_NO_DISKSPACE; + qError("Init stream agg supporter failed since %s, tempDir:%s", terrstr(), tsTempDir); + return terrno; + } + + int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, "function", tsTempDir); + for (int32_t i = 0; i < numOfOutput; ++i) { + pCtx[i].saveHandle.pBuf = pSup->pResultBuf; + } + + pSup->pSessionAPI = pApi; + + return TSDB_CODE_SUCCESS; +} + +bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap) { + if (ts + gap >= pWin->skey && ts - gap <= pWin->ekey) { + return true; + } + return false; +} + +bool isInWindow(SResultWindowInfo* pWinInfo, TSKEY ts, int64_t gap) { + return isInTimeWindow(&pWinInfo->sessionWin.win, ts, gap); +} + +void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, + SSessionKey* pKey) { + pKey->win.skey = startTs; + pKey->win.ekey = endTs; + pKey->groupId = groupId; + int32_t code = pAggSup->stateStore.streamStateSessionGetKeyByRange(pAggSup->pState, pKey, pKey); + if (code != TSDB_CODE_SUCCESS) { + SET_SESSION_WIN_KEY_INVALID(pKey); + } +} + +bool isInvalidSessionWin(SResultWindowInfo* pWinInfo) { return pWinInfo->sessionWin.win.skey == 0; } + +bool inWinRange(STimeWindow* range, STimeWindow* cur) { + if (cur->skey >= range->skey && cur->ekey <= range->ekey) { + return true; + } + return false; +} + +void setSessionOutputBuf(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, + SResultWindowInfo* pCurWin) { + pCurWin->sessionWin.groupId = groupId; + pCurWin->sessionWin.win.skey = startTs; + pCurWin->sessionWin.win.ekey = endTs; + int32_t size = pAggSup->resultRowSize; + int32_t code = pAggSup->stateStore.streamStateSessionAddIfNotExist(pAggSup->pState, &pCurWin->sessionWin, + pAggSup->gap, &pCurWin->pOutputBuf, &size); + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->sessionWin.win)) { + code = TSDB_CODE_FAILED; + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->pOutputBuf, &pAggSup->pSessionAPI->stateStore); + pCurWin->pOutputBuf = taosMemoryCalloc(1, size); + } + + if (code == TSDB_CODE_SUCCESS) { + pCurWin->isOutput = true; + pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->sessionWin); + } else { + pCurWin->sessionWin.win.skey = startTs; + pCurWin->sessionWin.win.ekey = endTs; + } +} + +int32_t getSessionWinBuf(SStreamAggSupporter* pAggSup, SStreamStateCur* pCur, SResultWindowInfo* pWinInfo) { + int32_t size = 0; + int32_t code = + pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pWinInfo->sessionWin, &pWinInfo->pOutputBuf, &size); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pCur); + return TSDB_CODE_SUCCESS; +} +void saveDeleteInfo(SArray* pWins, SSessionKey key) { + // key.win.ekey = key.win.skey; + taosArrayPush(pWins, &key); +} + +void saveDeleteRes(SSHashObj* pStDelete, SSessionKey key) { + key.win.ekey = key.win.skey; + tSimpleHashPut(pStDelete, &key, sizeof(SSessionKey), NULL, 0); +} + +static void removeSessionResult(SSHashObj* pHashMap, SSHashObj* pResMap, SSessionKey key) { + key.win.ekey = key.win.skey; + tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey)); + tSimpleHashRemove(pResMap, &key, sizeof(SSessionKey)); +} + +static void getSessionHashKey(const SSessionKey* pKey, SSessionKey* pHashKey) { + *pHashKey = *pKey; + pHashKey->win.ekey = pKey->win.skey; +} + +static void removeSessionResults(SSHashObj* pHashMap, SArray* pWins) { + if (tSimpleHashGetSize(pHashMap) == 0) { + return; + } + int32_t size = taosArrayGetSize(pWins); + for (int32_t i = 0; i < size; i++) { + SSessionKey* pWin = taosArrayGet(pWins, i); + if (!pWin) continue; + SSessionKey key = {0}; + getSessionHashKey(pWin, &key); + tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey)); + } +} + +int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t groupId, + int32_t rows, int32_t start, int64_t gap, SSHashObj* pResultRows, SSHashObj* pStUpdated, + SSHashObj* pStDeleted) { + for (int32_t i = start; i < rows; ++i) { + if (!isInWindow(pWinInfo, pStartTs[i], gap) && (!pEndTs || !isInWindow(pWinInfo, pEndTs[i], gap))) { + return i - start; + } + if (pWinInfo->sessionWin.win.skey > pStartTs[i]) { + if (pStDeleted && pWinInfo->isOutput) { + saveDeleteRes(pStDeleted, pWinInfo->sessionWin); + } + removeSessionResult(pStUpdated, pResultRows, pWinInfo->sessionWin); + pWinInfo->sessionWin.win.skey = pStartTs[i]; + } + pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pStartTs[i]); + if (pEndTs) { + pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pEndTs[i]); + } + } + return rows - start; +} + +static int32_t initSessionOutputBuf(SResultWindowInfo* pWinInfo, SResultRow** pResult, SqlFunctionCtx* pCtx, + int32_t numOfOutput, int32_t* rowEntryInfoOffset) { + ASSERT(pWinInfo->sessionWin.win.skey <= pWinInfo->sessionWin.win.ekey); + *pResult = (SResultRow*)pWinInfo->pOutputBuf; + // set time window for current result + (*pResult)->win = pWinInfo->sessionWin.win; + setResultRowInitCtx(*pResult, pCtx, numOfOutput, rowEntryInfoOffset); + return TSDB_CODE_SUCCESS; +} + +static int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo* pCurWin, SResultRow** pResult, + int32_t startIndex, int32_t winRows, int32_t rows, int32_t numOutput, + SOperatorInfo* pOperator, int64_t winDelta) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + int32_t code = initSessionOutputBuf(pCurWin, pResult, pSup->pCtx, numOutput, pSup->rowEntryInfoOffset); + if (code != TSDB_CODE_SUCCESS || (*pResult) == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + updateTimeWindowInfo(pTimeWindowData, &pCurWin->sessionWin.win, winDelta); + applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, pTimeWindowData, startIndex, winRows, rows, numOutput); + return TSDB_CODE_SUCCESS; +} + +static bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKey) { + pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, pKey); + SSessionKey hashKey = {0}; + getSessionHashKey(pKey, &hashKey); + tSimpleHashRemove(pAggSup->pResultRows, &hashKey, sizeof(SSessionKey)); + return true; +} + +static int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* pWinInfo) { + void* pVal = tSimpleHashGet(pStUpdated, &pWinInfo->sessionWin, sizeof(SSessionKey)); + if (pVal) { + SResultWindowInfo* pWin = pVal; + pWinInfo->isOutput = pWin->isOutput; + } + return TSDB_CODE_SUCCESS; +} + +SStreamStateCur* getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* pStUpdated, SResultWindowInfo* pCurWin, + SResultWindowInfo* pNextWin) { + SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pCurWin->sessionWin); + pNextWin->isOutput = true; + setSessionWinOutputInfo(pStUpdated, pNextWin); + int32_t size = 0; + pNextWin->sessionWin = pCurWin->sessionWin; + int32_t code = + pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->sessionWin, &pNextWin->pOutputBuf, &size); + if (code != TSDB_CODE_SUCCESS) { + taosMemoryFreeClear(pNextWin->pOutputBuf); + SET_SESSION_WIN_INVALID(*pNextWin); + } + return pCur; +} + +static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SSHashObj* pStUpdated, + SSHashObj* pStDeleted, bool addGap) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + int32_t winNum = 0; + + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SResultRow* pCurResult = NULL; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); + // Just look for the window behind StartIndex + while (1) { + SResultWindowInfo winInfo = {0}; + SStreamStateCur* pCur = getNextSessionWinInfo(pAggSup, pStUpdated, pCurWin, &winInfo); + if (!IS_VALID_SESSION_WIN(winInfo) || !isInWindow(pCurWin, winInfo.sessionWin.win.skey, pAggSup->gap) || + !inWinRange(&pAggSup->winRange, &winInfo.sessionWin.win)) { + taosMemoryFree(winInfo.pOutputBuf); + pAPI->stateStore.streamStateFreeCur(pCur); + break; + } + SResultRow* pWinResult = NULL; + initSessionOutputBuf(&winInfo, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); + pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, winInfo.sessionWin.win.ekey); + int64_t winDelta = 0; + if (addGap) { + winDelta = pAggSup->gap; + } + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, winDelta); + compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); + tSimpleHashRemove(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey)); + if (winInfo.isOutput && pStDeleted) { + saveDeleteRes(pStDeleted, winInfo.sessionWin); + } + removeSessionResult(pStUpdated, pAggSup->pResultRows, winInfo.sessionWin); + doDeleteSessionWindow(pAggSup, &winInfo.sessionWin); + pAPI->stateStore.streamStateFreeCur(pCur); + taosMemoryFree(winInfo.pOutputBuf); + winNum++; + } + return winNum; +} + +int32_t saveSessionOutputBuf(SStreamAggSupporter* pAggSup, SResultWindowInfo* pWinInfo) { + saveSessionDiscBuf(pAggSup->pState, &pWinInfo->sessionWin, pWinInfo->pOutputBuf, pAggSup->resultRowSize, + &pAggSup->stateStore); + pWinInfo->pOutputBuf = NULL; + return TSDB_CODE_SUCCESS; +} + +static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pStUpdated, + SSHashObj* pStDeleted, bool hasEndTs, bool addGap) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + uint64_t groupId = pSDataBlock->info.id.groupId; + int64_t code = TSDB_CODE_SUCCESS; + SResultRow* pResult = NULL; + int32_t rows = pSDataBlock->info.rows; + int32_t winRows = 0; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + + pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); + pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow; + if (pAggSup->winRange.ekey <= 0) { + pAggSup->winRange.ekey = INT64_MAX; + } + + SColumnInfoData* pStartTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); + TSKEY* startTsCols = (int64_t*)pStartTsCol->pData; + SColumnInfoData* pEndTsCol = NULL; + if (hasEndTs) { + pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->endTsIndex); + } else { + pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); + } + + TSKEY* endTsCols = (int64_t*)pEndTsCol->pData; + for (int32_t i = 0; i < rows;) { + if (pInfo->ignoreExpiredData && isOverdue(endTsCols[i], &pInfo->twAggSup)) { + i++; + continue; + } + SResultWindowInfo winInfo = {0}; + setSessionOutputBuf(pAggSup, startTsCols[i], endTsCols[i], groupId, &winInfo); + setSessionWinOutputInfo(pStUpdated, &winInfo); + winRows = updateSessionWindowInfo(&winInfo, startTsCols, endTsCols, groupId, rows, i, pAggSup->gap, + pAggSup->pResultRows, pStUpdated, pStDeleted); + // coverity scan error + if (!winInfo.pOutputBuf) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + + int64_t winDelta = 0; + if (addGap) { + winDelta = pAggSup->gap; + } + code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &winInfo, &pResult, i, winRows, rows, numOfOutput, + pOperator, winDelta); + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + compactSessionWindow(pOperator, &winInfo, pStUpdated, pStDeleted, addGap); + saveSessionOutputBuf(pAggSup, &winInfo); + + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) { + code = saveResult(winInfo, pStUpdated); + if (code != TSDB_CODE_SUCCESS) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + } + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + SSessionKey key = {0}; + getSessionHashKey(&winInfo.sessionWin, &key); + tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); + } + + i += winRows; + } +} + +static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result) { + SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + TSKEY* startDatas = (TSKEY*)pStartTsCol->pData; + SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + TSKEY* endDatas = (TSKEY*)pEndTsCol->pData; + SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + uint64_t* gpDatas = (uint64_t*)pGroupCol->pData; + for (int32_t i = 0; i < pBlock->info.rows; i++) { + while (1) { + SSessionKey curWin = {0}; + getCurSessionWindow(pAggSup, startDatas[i], endDatas[i], gpDatas[i], &curWin); + if (IS_INVALID_SESSION_WIN_KEY(curWin)) { + break; + } + doDeleteSessionWindow(pAggSup, &curWin); + if (result) { + saveDeleteInfo(result, curWin); + } + } + } +} + +static inline int32_t sessionKeyCompareAsc(const void* pKey1, const void* pKey2) { + SSessionKey* pWin1 = (SSessionKey*)pKey1; + SSessionKey* pWin2 = (SSessionKey*)pKey2; + + if (pWin1->groupId > pWin2->groupId) { + return 1; + } else if (pWin1->groupId < pWin2->groupId) { + return -1; + } + + if (pWin1->win.skey > pWin2->win.skey) { + return 1; + } else if (pWin1->win.skey < pWin2->win.skey) { + return -1; + } + + return 0; +} + +static int32_t copyUpdateResult(SSHashObj* pStUpdated, SArray* pUpdated) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pStUpdated, pIte, &iter)) != NULL) { + void* key = tSimpleHashGetKey(pIte, NULL); + taosArrayPush(pUpdated, key); + } + taosArraySort(pUpdated, sessionKeyCompareAsc); + return TSDB_CODE_SUCCESS; +} + +void doBuildDeleteDataBlock(SOperatorInfo* pOp, SSHashObj* pStDeleted, SSDataBlock* pBlock, void** Ite) { + SStorageAPI* pAPI = &pOp->pTaskInfo->storageAPI; + + blockDataCleanup(pBlock); + int32_t size = tSimpleHashGetSize(pStDeleted); + if (size == 0) { + return; + } + blockDataEnsureCapacity(pBlock, size); + int32_t iter = 0; + while (((*Ite) = tSimpleHashIterate(pStDeleted, *Ite, &iter)) != NULL) { + if (pBlock->info.rows + 1 > pBlock->info.capacity) { + break; + } + SSessionKey* res = tSimpleHashGetKey(*Ite, NULL); + SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); + colDataSetVal(pStartTsCol, pBlock->info.rows, (const char*)&res->win.skey, false); + SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); + colDataSetVal(pEndTsCol, pBlock->info.rows, (const char*)&res->win.skey, false); + SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX); + colDataSetNULL(pUidCol, pBlock->info.rows); + SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); + colDataSetVal(pGpCol, pBlock->info.rows, (const char*)&res->groupId, false); + SColumnInfoData* pCalStCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); + colDataSetNULL(pCalStCol, pBlock->info.rows); + SColumnInfoData* pCalEdCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); + colDataSetNULL(pCalEdCol, pBlock->info.rows); + + SColumnInfoData* pTableCol = taosArrayGet(pBlock->pDataBlock, TABLE_NAME_COLUMN_INDEX); + + void* tbname = NULL; + pAPI->stateStore.streamStateGetParName(pOp->pTaskInfo->streamInfo.pState, res->groupId, &tbname); + if (tbname == NULL) { + colDataSetNULL(pTableCol, pBlock->info.rows); + } else { + char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN]; + STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName)); + colDataSetVal(pTableCol, pBlock->info.rows, (const char*)parTbName, false); + pAPI->stateStore.streamStateFreeVal(tbname); + } + pBlock->info.rows += 1; + } + if ((*Ite) == NULL) { + tSimpleHashClear(pStDeleted); + } +} + +static void rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, SSHashObj* pStUpdated) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + int32_t size = taosArrayGetSize(pWinArray); + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + int32_t numOfOutput = pSup->numOfExprs; + int32_t numOfChild = taosArrayGetSize(pInfo->pChildren); + + for (int32_t i = 0; i < size; i++) { + SSessionKey* pWinKey = taosArrayGet(pWinArray, i); + int32_t num = 0; + SResultWindowInfo parentWin = {0}; + for (int32_t j = 0; j < numOfChild; j++) { + SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, j); + SStreamSessionAggOperatorInfo* pChInfo = pChild->info; + SStreamAggSupporter* pChAggSup = &pChInfo->streamAggSup; + SSessionKey chWinKey = {0}; + getSessionHashKey(pWinKey, &chWinKey); + SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyCurrentNext(pChAggSup->pState, &chWinKey); + SResultRow* pResult = NULL; + SResultRow* pChResult = NULL; + while (1) { + SResultWindowInfo childWin = {0}; + childWin.sessionWin = *pWinKey; + int32_t code = getSessionWinBuf(pChAggSup, pCur, &childWin); + + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &childWin.sessionWin.win)) { + continue; + } + + if (code == TSDB_CODE_SUCCESS && inWinRange(&pWinKey->win, &childWin.sessionWin.win)) { + if (num == 0) { + setSessionOutputBuf(pAggSup, pWinKey->win.skey, pWinKey->win.ekey, pWinKey->groupId, &parentWin); + code = initSessionOutputBuf(&parentWin, &pResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + break; + } + } + num++; + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &parentWin.sessionWin.win, pAggSup->gap); + initSessionOutputBuf(&childWin, &pChResult, pChild->exprSupp.pCtx, numOfOutput, + pChild->exprSupp.rowEntryInfoOffset); + compactFunctions(pSup->pCtx, pChild->exprSupp.pCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); + compactSessionWindow(pOperator, &parentWin, pStUpdated, NULL, true); + saveResult(parentWin, pStUpdated); + } else { + break; + } + } + pAPI->stateStore.streamStateFreeCur(pCur); + } + if (num > 0) { + saveSessionOutputBuf(pAggSup, &parentWin); + } + } +} + +int32_t closeSessionWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SSHashObj* pClosed) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { + SResultWindowInfo* pWinInfo = pIte; + if (isCloseWindow(&pWinInfo->sessionWin.win, pTwSup)) { + if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE && pClosed) { + int32_t code = saveResult(*pWinInfo, pClosed); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + SSessionKey* pKey = tSimpleHashGetKey(pIte, NULL); + tSimpleHashIterateRemove(pHashMap, pKey, sizeof(SSessionKey), &pIte, &iter); + } + } + return TSDB_CODE_SUCCESS; +} + +static void closeChildSessionWindow(SArray* pChildren, TSKEY maxTs) { + int32_t size = taosArrayGetSize(pChildren); + for (int32_t i = 0; i < size; i++) { + SOperatorInfo* pChildOp = taosArrayGetP(pChildren, i); + SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info; + pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, maxTs); + closeSessionWindow(pChInfo->streamAggSup.pResultRows, &pChInfo->twAggSup, NULL); + } +} + +int32_t getAllSessionWindow(SSHashObj* pHashMap, SSHashObj* pStUpdated) { + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { + SResultWindowInfo* pWinInfo = pIte; + saveResult(*pWinInfo, pStUpdated); + } + return TSDB_CODE_SUCCESS; +} + +static void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted) { + int32_t size = taosArrayGetSize(pResWins); + for (int32_t i = 0; i < size; i++) { + SSessionKey* pWinKey = taosArrayGet(pResWins, i); + if (!pWinKey) continue; + SSessionKey winInfo = {0}; + getSessionHashKey(pWinKey, &winInfo); + tSimpleHashPut(pStDeleted, &winInfo, sizeof(SSessionKey), NULL, 0); + } +} + +// the allocated memory comes from outer function. +void initGroupResInfoFromArrayList(SGroupResInfo* pGroupResInfo, SArray* pArrayList) { + pGroupResInfo->pRows = pArrayList; + pGroupResInfo->index = 0; + pGroupResInfo->pBuf = NULL; +} + +void doBuildSessionResult(SOperatorInfo* pOperator, void* pState, SGroupResInfo* pGroupResInfo, SSDataBlock* pBlock) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + // set output datablock version + pBlock->info.version = pTaskInfo->version; + + blockDataCleanup(pBlock); + if (!hasRemainResults(pGroupResInfo)) { + cleanupGroupResInfo(pGroupResInfo); + return; + } + + // clear the existed group id + pBlock->info.id.groupId = 0; + buildSessionResultDataBlock(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); + if (pBlock->info.rows == 0) { + cleanupGroupResInfo(pGroupResInfo); + } +} + +static SSDataBlock* buildSessionResult(SOperatorInfo* pOperator) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + return NULL; +} + +void getMaxTsWins(const SArray* pAllWins, SArray* pMaxWins) { + int32_t size = taosArrayGetSize(pAllWins); + if (size == 0) { + return; + } + + SSessionKey* pSeKey = taosArrayGet(pAllWins, size - 1); + taosArrayPush(pMaxWins, pSeKey); + if (pSeKey->groupId == 0) { + return; + } + uint64_t preGpId = pSeKey->groupId; + for (int32_t i = size - 2; i >= 0; i--) { + pSeKey = taosArrayGet(pAllWins, i); + if (preGpId != pSeKey->groupId) { + taosArrayPush(pMaxWins, pSeKey); + preGpId = pSeKey->groupId; + } + } +} + +static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { + SExprSupp* pSup = &pOperator->exprSupp; + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } else if (pOperator->status == OP_RES_TO_RETURN) { + SSDataBlock* opRes = buildSessionResult(pOperator); + if (opRes) { + return opRes; + } + setOperatorCompleted(pOperator); + return NULL; + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); + } + if (!pInfo->pStUpdated) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pStUpdated = tSimpleHashInit(64, hashFn); + } + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + break; + } + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); + // gap must be 0 + doDeleteTimeWindows(pAggSup, pBlock, pWins); + removeSessionResults(pInfo->pStUpdated, pWins); + if (IS_FINAL_SESSION_OP(pOperator)) { + int32_t childIndex = getChildIndex(pBlock); + SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex); + SStreamSessionAggOperatorInfo* pChildInfo = pChildOp->info; + // gap must be 0 + doDeleteTimeWindows(&pChildInfo->streamAggSup, pBlock, NULL); + rebuildSessionWindow(pOperator, pWins, pInfo->pStUpdated); + } + copyDeleteWindowInfo(pWins, pInfo->pStDeleted); + taosArrayDestroy(pWins); + continue; + } else if (pBlock->info.type == STREAM_GET_ALL) { + getAllSessionWindow(pAggSup->pResultRows, pInfo->pStUpdated); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, IS_FINAL_SESSION_OP(pOperator), + true); + if (IS_FINAL_SESSION_OP(pOperator)) { + int32_t chIndex = getChildIndex(pBlock); + int32_t size = taosArrayGetSize(pInfo->pChildren); + // if chIndex + 1 - size > 0, add new child + for (int32_t i = 0; i < chIndex + 1 - size; i++) { + SOperatorInfo* pChildOp = + createStreamFinalSessionAggOperatorInfo(NULL, pInfo->pPhyNode, pOperator->pTaskInfo, 0, NULL); + if (!pChildOp) { + T_LONG_JMP(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + taosArrayPush(pInfo->pChildren, &pChildOp); + } + SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, chIndex); + setInputDataBlock(&pChildOp->exprSupp, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamSessionAggImpl(pChildOp, pBlock, NULL, NULL, true, false); + } + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark); + } + // restore the value + pOperator->status = OP_RES_TO_RETURN; + + closeSessionWindow(pAggSup->pResultRows, &pInfo->twAggSup, pInfo->pStUpdated); + closeChildSessionWindow(pInfo->pChildren, pInfo->twAggSup.maxTs); + copyUpdateResult(pInfo->pStUpdated, pInfo->pUpdated); + removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); + tSimpleHashCleanup(pInfo->pStUpdated); + pInfo->pStUpdated = NULL; + if (pInfo->isHistoryOp) { + getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); + } + initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + + SSDataBlock* opRes = buildSessionResult(pOperator); + if (opRes) { + return opRes; + } + + setOperatorCompleted(pOperator); + return NULL; +} + +void streamSessionReleaseState(SOperatorInfo* pOperator) { + if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); + pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_SESSION_OP_STATE_NAME, + strlen(STREAM_SESSION_OP_STATE_NAME), pInfo->historyWins->pData, + resSize); + } + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +void resetWinRange(STimeWindow* winRange) { + winRange->skey = INT64_MIN; + winRange->ekey = INT64_MAX; +} + +void streamSessionReloadState(SOperatorInfo* pOperator) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + resetWinRange(&pAggSup->winRange); + + SResultWindowInfo winInfo = {0}; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_SESSION_OP_STATE_NAME, + strlen(STREAM_SESSION_OP_STATE_NAME), &pBuf, &size); + int32_t num = size / sizeof(SSessionKey); + SSessionKey* pSeKeyBuf = (SSessionKey*)pBuf; + ASSERT(size == num * sizeof(SSessionKey)); + if (!pInfo->pStUpdated && num > 0) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pStUpdated = tSimpleHashInit(64, hashFn); + } + for (int32_t i = 0; i < num; i++) { + SResultWindowInfo winInfo = {0}; + setSessionOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].win.ekey, pSeKeyBuf[i].groupId, &winInfo); + int32_t winNum = compactSessionWindow(pOperator, &winInfo, pInfo->pStUpdated, pInfo->pStDeleted, true); + if (winNum > 0) { + qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, winInfo.sessionWin.win.skey, + winInfo.sessionWin.groupId); + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { + saveResult(winInfo, pInfo->pStUpdated); + } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + if (!isCloseWindow(&winInfo.sessionWin.win, &pInfo->twAggSup)) { + saveDeleteRes(pInfo->pStDeleted, winInfo.sessionWin); + } + SSessionKey key = {0}; + getSessionHashKey(&winInfo.sessionWin, &key); + tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); + } + } + saveSessionOutputBuf(pAggSup, &winInfo); + } + taosMemoryFree(pBuf); + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + +SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { + SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode; + int32_t numOfCols = 0; + int32_t code = TSDB_CODE_OUT_OF_MEMORY; + SStreamSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamSessionAggOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + + pOperator->pTaskInfo = pTaskInfo; + + initResultSizeInfo(&pOperator->resultInfo, 4096); + if (pSessionNode->window.pExprs != NULL) { + int32_t numOfScalar = 0; + SExprInfo* pScalarExprInfo = createExprInfo(pSessionNode->window.pExprs, NULL, &numOfScalar); + code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + } + SExprSupp* pSup = &pOperator->exprSupp; + + SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &numOfCols); + SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); + code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, pSessionNode->gap, + pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle, + &pTaskInfo->storageAPI); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pSessionNode->window.watermark, + .calTrigger = pSessionNode->window.triggerType, + .maxTs = INT64_MIN, + .minTs = INT64_MAX, + }; + + initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); + + pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId; + if (pSessionNode->window.pTsEnd) { + pInfo->endTsIndex = ((SColumnNode*)pSessionNode->window.pTsEnd)->slotId; + } + pInfo->binfo.pRes = pResBlock; + pInfo->order = TSDB_ORDER_ASC; + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pStDeleted = tSimpleHashInit(64, hashFn); + pInfo->pDelIterator = NULL; + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + pInfo->pChildren = NULL; + pInfo->pPhyNode = pPhyNode; + pInfo->ignoreExpiredData = pSessionNode->window.igExpired; + pInfo->ignoreExpiredDataSaved = false; + pInfo->pUpdated = NULL; + pInfo->pStUpdated = NULL; + pInfo->dataVersion = 0; + pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); + if (!pInfo->historyWins) { + goto _error; + } + if (pHandle) { + pInfo->isHistoryOp = pHandle->fillHistory; + } + pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION; + setOperatorInfo(pOperator, getStreamOpName(pOperator->operatorType), QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, true, + OP_NOT_OPENED, pInfo, pTaskInfo); + pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionAgg, NULL, destroyStreamSessionAggOperatorInfo, + optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); + + if (downstream) { + initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); + code = appendDownstream(pOperator, &downstream, 1); + } + return pOperator; + +_error: + if (pInfo != NULL) { + destroyStreamSessionAggOperatorInfo(pInfo); + } + + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +static void clearStreamSessionOperator(SStreamSessionAggOperatorInfo* pInfo) { + tSimpleHashClear(pInfo->streamAggSup.pResultRows); + pInfo->streamAggSup.stateStore.streamStateSessionClear(pInfo->streamAggSup.pState); +} + +static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + TSKEY maxTs = INT64_MIN; + SExprSupp* pSup = &pOperator->exprSupp; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + { + SSDataBlock* opRes = buildSessionResult(pOperator); + if (opRes) { + return opRes; + } + + if (pOperator->status == OP_RES_TO_RETURN) { + clearFunctionContext(&pOperator->exprSupp); + // semi interval operator clear disk buffer + clearStreamSessionOperator(pInfo); + setOperatorCompleted(pOperator); + return NULL; + } + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); + } + if (!pInfo->pStUpdated) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pStUpdated = tSimpleHashInit(64, hashFn); + } + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + clearSpecialDataBlock(pInfo->pUpdateRes); + pOperator->status = OP_RES_TO_RETURN; + break; + } + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + // gap must be 0 + SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); + doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins); + removeSessionResults(pInfo->pStUpdated, pWins); + copyDeleteWindowInfo(pWins, pInfo->pStDeleted); + taosArrayDestroy(pWins); + break; + } else if (pBlock->info.type == STREAM_GET_ALL) { + getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pStUpdated); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, NULL, false, false); + maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + } + + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); + pBInfo->pRes->info.watermark = pInfo->twAggSup.maxTs; + + copyUpdateResult(pInfo->pStUpdated, pInfo->pUpdated); + removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); + tSimpleHashCleanup(pInfo->pStUpdated); + pInfo->pStUpdated = NULL; + initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity); + + SSDataBlock* opRes = buildSessionResult(pOperator); + if (opRes) { + return opRes; + } + + clearFunctionContext(&pOperator->exprSupp); + // semi interval operator clear disk buffer + clearStreamSessionOperator(pInfo); + setOperatorCompleted(pOperator); + return NULL; +} + +SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, int32_t numOfChild, + SReadHandle* pHandle) { + int32_t code = TSDB_CODE_OUT_OF_MEMORY; + SOperatorInfo* pOperator = createStreamSessionAggOperatorInfo(downstream, pPhyNode, pTaskInfo, pHandle); + if (pOperator == NULL) { + goto _error; + } + + SStorageAPI* pAPI = &pTaskInfo->storageAPI; + SStreamSessionAggOperatorInfo* pInfo = pOperator->info; + pOperator->operatorType = pPhyNode->type; + + if (pPhyNode->type != QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) { + pInfo->pUpdateRes = createSpecialDataBlock(STREAM_CLEAR); + blockDataEnsureCapacity(pInfo->pUpdateRes, 128); + pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionSemiAgg, NULL, + destroyStreamSessionAggOperatorInfo, optrDefaultBufFn, NULL); + } + setOperatorInfo(pOperator, getStreamOpName(pOperator->operatorType), pPhyNode->type, false, OP_NOT_OPENED, pInfo, pTaskInfo); + + if (numOfChild > 0) { + pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); + for (int32_t i = 0; i < numOfChild; i++) { + SOperatorInfo* pChildOp = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0, NULL); + if (pChildOp == NULL) { + goto _error; + } + SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info; + pChInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; + pAPI->stateStore.streamStateSetNumber(pChInfo->streamAggSup.pState, i); + taosArrayPush(pInfo->pChildren, &pChildOp); + } + } + + if (!IS_FINAL_SESSION_OP(pOperator) || numOfChild == 0) { + pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; + } + + return pOperator; + +_error: + if (pInfo != NULL) { + destroyStreamSessionAggOperatorInfo(pInfo); + } + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +void destroyStreamStateOperatorInfo(void* param) { + SStreamStateAggOperatorInfo* pInfo = (SStreamStateAggOperatorInfo*)param; + cleanupBasicInfo(&pInfo->binfo); + destroyStreamAggSupporter(&pInfo->streamAggSup); + cleanupGroupResInfo(&pInfo->groupResInfo); + if (pInfo->pChildren != NULL) { + int32_t size = taosArrayGetSize(pInfo->pChildren); + for (int32_t i = 0; i < size; i++) { + SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i); + destroyOperator(pChild); + } + taosArrayDestroy(pInfo->pChildren); + } + colDataDestroy(&pInfo->twAggSup.timeWindowData); + blockDataDestroy(pInfo->pDelRes); + taosArrayDestroy(pInfo->historyWins); + tSimpleHashCleanup(pInfo->pSeUpdated); + tSimpleHashCleanup(pInfo->pSeDeleted); + taosMemoryFreeClear(param); +} + +bool isTsInWindow(SStateWindowInfo* pWin, TSKEY ts) { + if (pWin->winInfo.sessionWin.win.skey <= ts && ts <= pWin->winInfo.sessionWin.win.ekey) { + return true; + } + return false; +} + +bool isEqualStateKey(SStateWindowInfo* pWin, char* pKeyData) { + return pKeyData && compareVal(pKeyData, pWin->pStateKey); +} + +bool compareStateKey(void* data, void* key) { + if (!data || !key) { + return true; + } + SStateKeys* stateKey = (SStateKeys*)key; + stateKey->pData = (char*)key + sizeof(SStateKeys); + return compareVal(data, stateKey); +} + +bool compareWinStateKey(SStateKeys* left, SStateKeys* right) { + if (!left || !right) { + return false; + } + return compareVal(left->pData, right); +} + +void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, char* pKeyData, + SStateWindowInfo* pCurWin, SStateWindowInfo* pNextWin) { + int32_t size = pAggSup->resultRowSize; + pCurWin->winInfo.sessionWin.groupId = groupId; + pCurWin->winInfo.sessionWin.win.skey = ts; + pCurWin->winInfo.sessionWin.win.ekey = ts; + int32_t code = pAggSup->stateStore.streamStateStateAddIfNotExist(pAggSup->pState, &pCurWin->winInfo.sessionWin, + pKeyData, pAggSup->stateKeySize, compareStateKey, + &pCurWin->winInfo.pOutputBuf, &size); + pCurWin->pStateKey = + (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); + pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); + pCurWin->pStateKey->type = pAggSup->stateKeyType; + pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); + pCurWin->pStateKey->isNull = false; + + if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->winInfo.sessionWin.win)) { + code = TSDB_CODE_FAILED; + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->winInfo.pOutputBuf, + &pAggSup->pSessionAPI->stateStore); + pCurWin->winInfo.pOutputBuf = taosMemoryCalloc(1, size); + pCurWin->pStateKey = + (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); + pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); + pCurWin->pStateKey->type = pAggSup->stateKeyType; + pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); + pCurWin->pStateKey->isNull = false; + pCurWin->winInfo.sessionWin.groupId = groupId; + pCurWin->winInfo.sessionWin.win.skey = ts; + pCurWin->winInfo.sessionWin.win.ekey = ts; + qDebug("===stream===reset state win key. skey:%" PRId64 ", endkey:%" PRId64, pCurWin->winInfo.sessionWin.win.skey, + pCurWin->winInfo.sessionWin.win.ekey); + } + + if (code == TSDB_CODE_SUCCESS) { + pCurWin->winInfo.isOutput = true; + pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->winInfo.sessionWin); + } else if (pKeyData) { + if (IS_VAR_DATA_TYPE(pAggSup->stateKeyType)) { + varDataCopy(pCurWin->pStateKey->pData, pKeyData); + } else { + memcpy(pCurWin->pStateKey->pData, pKeyData, pCurWin->pStateKey->bytes); + } + } + + pNextWin->winInfo.sessionWin = pCurWin->winInfo.sessionWin; + SStreamStateCur* pCur = + pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pNextWin->winInfo.sessionWin); + int32_t nextSize = pAggSup->resultRowSize; + code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->winInfo.sessionWin, + &pNextWin->winInfo.pOutputBuf, &nextSize); + if (code != TSDB_CODE_SUCCESS) { + SET_SESSION_WIN_INVALID(pNextWin->winInfo); + } else { + pNextWin->pStateKey = + (SStateKeys*)((char*)pNextWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); + pNextWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); + pNextWin->pStateKey->type = pAggSup->stateKeyType; + pNextWin->pStateKey->pData = (char*)pNextWin->pStateKey + sizeof(SStateKeys); + pNextWin->pStateKey->isNull = false; + pNextWin->winInfo.isOutput = true; + } + pAggSup->stateStore.streamStateFreeCur(pCur); +} + +int32_t updateStateWindowInfo(SStateWindowInfo* pWinInfo, SStateWindowInfo* pNextWin, TSKEY* pTs, uint64_t groupId, + SColumnInfoData* pKeyCol, int32_t rows, int32_t start, bool* allEqual, + SSHashObj* pResultRows, SSHashObj* pSeUpdated, SSHashObj* pSeDeleted) { + *allEqual = true; + for (int32_t i = start; i < rows; ++i) { + char* pKeyData = colDataGetData(pKeyCol, i); + if (!isTsInWindow(pWinInfo, pTs[i])) { + if (isEqualStateKey(pWinInfo, pKeyData)) { + if (IS_VALID_SESSION_WIN(pNextWin->winInfo)) { + // ts belongs to the next window + if (pTs[i] >= pNextWin->winInfo.sessionWin.win.skey) { + return i - start; + } + } + } else { + return i - start; + } + } + + if (pWinInfo->winInfo.sessionWin.win.skey > pTs[i]) { + if (pSeDeleted && pWinInfo->winInfo.isOutput) { + saveDeleteRes(pSeDeleted, pWinInfo->winInfo.sessionWin); + } + removeSessionResult(pSeUpdated, pResultRows, pWinInfo->winInfo.sessionWin); + pWinInfo->winInfo.sessionWin.win.skey = pTs[i]; + } + pWinInfo->winInfo.sessionWin.win.ekey = TMAX(pWinInfo->winInfo.sessionWin.win.ekey, pTs[i]); + if (!isEqualStateKey(pWinInfo, pKeyData)) { + *allEqual = false; + } + } + return rows - start; +} + +static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pSeUpdated, + SSHashObj* pStDeleted) { + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + uint64_t groupId = pSDataBlock->info.id.groupId; + int64_t code = TSDB_CODE_SUCCESS; + TSKEY* tsCols = NULL; + SResultRow* pResult = NULL; + int32_t winRows = 0; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + + pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); + pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow; + if (pAggSup->winRange.ekey <= 0) { + pAggSup->winRange.ekey = INT64_MAX; + } + + if (pSDataBlock->pDataBlock != NULL) { + SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); + tsCols = (int64_t*)pColDataInfo->pData; + } else { + return; + } + + int32_t rows = pSDataBlock->info.rows; + blockDataEnsureCapacity(pAggSup->pScanBlock, rows); + SColumnInfoData* pKeyColInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->stateCol.slotId); + for (int32_t i = 0; i < rows; i += winRows) { + if (pInfo->ignoreExpiredData && isOverdue(tsCols[i], &pInfo->twAggSup) || colDataIsNull_s(pKeyColInfo, i)) { + i++; + continue; + } + char* pKeyData = colDataGetData(pKeyColInfo, i); + int32_t winIndex = 0; + bool allEqual = true; + SStateWindowInfo curWin = {0}; + SStateWindowInfo nextWin = {0}; + setStateOutputBuf(pAggSup, tsCols[i], groupId, pKeyData, &curWin, &nextWin); + if (IS_VALID_SESSION_WIN(nextWin.winInfo)) { + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextWin.winInfo.pOutputBuf, &pAPI->stateStore); + } + setSessionWinOutputInfo(pSeUpdated, &curWin.winInfo); + winRows = updateStateWindowInfo(&curWin, &nextWin, tsCols, groupId, pKeyColInfo, rows, i, &allEqual, + pAggSup->pResultRows, pSeUpdated, pStDeleted); + if (!allEqual) { + uint64_t uid = 0; + appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey, + &curWin.winInfo.sessionWin.win.ekey, &uid, &groupId, NULL); + tSimpleHashRemove(pSeUpdated, &curWin.winInfo.sessionWin, sizeof(SSessionKey)); + doDeleteSessionWindow(pAggSup, &curWin.winInfo.sessionWin); + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)curWin.winInfo.pOutputBuf, &pAPI->stateStore); + continue; + } + code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput, + pOperator, 0); + if (code != TSDB_CODE_SUCCESS || pResult == NULL) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + saveSessionOutputBuf(pAggSup, &curWin.winInfo); + + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { + code = saveResult(curWin.winInfo, pSeUpdated); + if (code != TSDB_CODE_SUCCESS) { + T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); + } + } + + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + SSessionKey key = {0}; + getSessionHashKey(&curWin.winInfo.sessionWin, &key); + tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curWin.winInfo, sizeof(SResultWindowInfo)); + } + } +} + +static SSDataBlock* buildStateResult(SOperatorInfo* pOperator) { + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + + doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); + if (pInfo->pDelRes->info.rows > 0) { + printDataBlock(pInfo->pDelRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pInfo->pDelRes; + } + + doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); + if (pBInfo->pRes->info.rows > 0) { + printDataBlock(pBInfo->pRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pBInfo->pRes; + } + return NULL; +} + +static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SExprSupp* pSup = &pOperator->exprSupp; + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SOptrBasicInfo* pBInfo = &pInfo->binfo; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + qDebug("===stream=== stream state agg"); + if (pOperator->status == OP_RES_TO_RETURN) { + SSDataBlock* resBlock = buildStateResult(pOperator); + if (resBlock != NULL) { + return resBlock; + } + + setOperatorCompleted(pOperator); + return NULL; + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); + } + if (!pInfo->pSeUpdated) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pSeUpdated = tSimpleHashInit(64, hashFn); + } + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + break; + } + printDataBlock(pBlock, "single state recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); + doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins); + removeSessionResults(pInfo->pSeUpdated, pWins); + copyDeleteWindowInfo(pWins, pInfo->pSeDeleted); + taosArrayDestroy(pWins); + continue; + } else if (pBlock->info.type == STREAM_GET_ALL) { + getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pSeUpdated); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + doStreamStateAggImpl(pOperator, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + } + // restore the value + pOperator->status = OP_RES_TO_RETURN; + + closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pInfo->pSeUpdated); + copyUpdateResult(pInfo->pSeUpdated, pInfo->pUpdated); + removeSessionResults(pInfo->pSeDeleted, pInfo->pUpdated); + tSimpleHashCleanup(pInfo->pSeUpdated); + pInfo->pSeUpdated = NULL; + + if (pInfo->isHistoryOp) { + getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); + } + + initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + + SSDataBlock* resBlock = buildStateResult(pOperator); + if (resBlock != NULL) { + return resBlock; + } + setOperatorCompleted(pOperator); + return NULL; +} + +void streamStateReleaseState(SOperatorInfo* pOperator) { + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); + qDebug("===stream=== relase state. save result count:%d", (int32_t)taosArrayGetSize(pInfo->historyWins)); + pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_STATE_OP_STATE_NAME, + strlen(STREAM_STATE_OP_STATE_NAME), pInfo->historyWins->pData, + resSize); + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.releaseStreamStateFn) { + downstream->fpSet.releaseStreamStateFn(downstream); + } +} + +static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SResultWindowInfo* pNextWin, + SSHashObj* pStUpdated, SSHashObj* pStDeleted) { + SExprSupp* pSup = &pOperator->exprSupp; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SResultRow* pCurResult = NULL; + int32_t numOfOutput = pOperator->exprSupp.numOfExprs; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); + SResultRow* pWinResult = NULL; + initSessionOutputBuf(pNextWin, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); + pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, pNextWin->sessionWin.win.ekey); + + updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, 1); + compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); + tSimpleHashRemove(pStUpdated, &pNextWin->sessionWin, sizeof(SSessionKey)); + if (pNextWin->isOutput && pStDeleted) { + qDebug("===stream=== save delete window info %" PRId64 ", %" PRIu64, pNextWin->sessionWin.win.skey, + pNextWin->sessionWin.groupId); + saveDeleteRes(pStDeleted, pNextWin->sessionWin); + } + removeSessionResult(pStUpdated, pAggSup->pResultRows, pNextWin->sessionWin); + doDeleteSessionWindow(pAggSup, &pNextWin->sessionWin); + taosMemoryFree(pNextWin->pOutputBuf); +} + +void streamStateReloadState(SOperatorInfo* pOperator) { + SStreamStateAggOperatorInfo* pInfo = pOperator->info; + SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; + resetWinRange(&pAggSup->winRange); + + SSessionKey seKey = {.win.skey = INT64_MIN, .win.ekey = INT64_MIN, .groupId = 0}; + int32_t size = 0; + void* pBuf = NULL; + int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_STATE_OP_STATE_NAME, + strlen(STREAM_STATE_OP_STATE_NAME), &pBuf, &size); + int32_t num = size / sizeof(SSessionKey); + qDebug("===stream=== reload state. get result count:%d", num); + SSessionKey* pSeKeyBuf = (SSessionKey*)pBuf; + ASSERT(size == num * sizeof(SSessionKey)); + if (!pInfo->pSeUpdated && num > 0) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pSeUpdated = tSimpleHashInit(64, hashFn); + } + if (!pInfo->pSeDeleted && num > 0) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pSeDeleted = tSimpleHashInit(64, hashFn); + } + for (int32_t i = 0; i < num; i++) { + SStateWindowInfo curInfo = {0}; + SStateWindowInfo nextInfo = {0}; + SStateWindowInfo dummy = {0}; + qDebug("===stream=== reload state. try process result %" PRId64 ", %" PRIu64 ", index:%d", pSeKeyBuf[i].win.skey, + pSeKeyBuf[i].groupId, i); + setStateOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, NULL, &curInfo, &nextInfo); + bool cpRes = compareWinStateKey(curInfo.pStateKey, nextInfo.pStateKey); + qDebug("===stream=== reload state. next window info %" PRId64 ", %" PRIu64 ", compare:%d", + nextInfo.winInfo.sessionWin.win.skey, nextInfo.winInfo.sessionWin.groupId, cpRes); + if (cpRes) { + compactStateWindow(pOperator, &curInfo.winInfo, &nextInfo.winInfo, pInfo->pSeUpdated, pInfo->pSeDeleted); + qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, curInfo.winInfo.sessionWin.win.skey, + curInfo.winInfo.sessionWin.groupId); + if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { + saveResult(curInfo.winInfo, pInfo->pSeUpdated); + } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { + if (!isCloseWindow(&curInfo.winInfo.sessionWin.win, &pInfo->twAggSup)) { + saveDeleteRes(pInfo->pSeDeleted, curInfo.winInfo.sessionWin); + } + SSessionKey key = {0}; + getSessionHashKey(&curInfo.winInfo.sessionWin, &key); + tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curInfo.winInfo, sizeof(SResultWindowInfo)); + } + } else if (IS_VALID_SESSION_WIN(nextInfo.winInfo)) { + releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextInfo.winInfo.pOutputBuf, + &pAggSup->pSessionAPI->stateStore); + } + + if (IS_VALID_SESSION_WIN(curInfo.winInfo)) { + saveSessionOutputBuf(pAggSup, &curInfo.winInfo); + } + } + taosMemoryFree(pBuf); + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + if (downstream->fpSet.reloadStreamStateFn) { + downstream->fpSet.reloadStreamStateFn(downstream); + } +} + +SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { + SStreamStateWinodwPhysiNode* pStateNode = (SStreamStateWinodwPhysiNode*)pPhyNode; + int32_t tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId; + SColumnNode* pColNode = (SColumnNode*)(pStateNode->pStateKey); + int32_t code = TSDB_CODE_SUCCESS; + + SStreamStateAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamStateAggOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _error; + } + + pInfo->stateCol = extractColumnFromColumnNode(pColNode); + initResultSizeInfo(&pOperator->resultInfo, 4096); + if (pStateNode->window.pExprs != NULL) { + int32_t numOfScalar = 0; + SExprInfo* pScalarExprInfo = createExprInfo(pStateNode->window.pExprs, NULL, &numOfScalar); + code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + } + + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pStateNode->window.watermark, + .calTrigger = pStateNode->window.triggerType, + .maxTs = INT64_MIN, + .minTs = INT64_MAX, + }; + + initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); + + SExprSupp* pSup = &pOperator->exprSupp; + int32_t numOfCols = 0; + SExprInfo* pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &numOfCols); + SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); + code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + int32_t keySize = sizeof(SStateKeys) + pColNode->node.resType.bytes; + int16_t type = pColNode->node.resType.type; + code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, 0, pTaskInfo->streamInfo.pState, keySize, + type, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + pInfo->primaryTsIndex = tsSlotId; + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pSeDeleted = tSimpleHashInit(64, hashFn); + pInfo->pDelIterator = NULL; + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + pInfo->pChildren = NULL; + pInfo->ignoreExpiredData = pStateNode->window.igExpired; + pInfo->ignoreExpiredDataSaved = false; + pInfo->pUpdated = NULL; + pInfo->pSeUpdated = NULL; + pInfo->dataVersion = 0; + pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); + if (!pInfo->historyWins) { + goto _error; + } + if (pHandle) { + pInfo->isHistoryOp = pHandle->fillHistory; + } + + setOperatorInfo(pOperator, "StreamStateAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE, true, OP_NOT_OPENED, + pInfo, pTaskInfo); + pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamStateAgg, NULL, destroyStreamStateOperatorInfo, + optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamStateReleaseState, streamStateReloadState); + initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + return pOperator; + +_error: + destroyStreamStateOperatorInfo(pInfo); + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} + +static void cleanupAfterGroupResultGen(SMergeAlignedIntervalAggOperatorInfo* pMiaInfo, SSDataBlock* pRes) { + pRes->info.id.groupId = pMiaInfo->groupId; + pMiaInfo->curTs = INT64_MIN; + pMiaInfo->groupId = 0; +} + +static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type) { + for (int i = 0; i < num; i++) { + if (type == STREAM_INVERT) { + fmSetInvertFunc(pCtx[i].functionId, &(pCtx[i].fpSet)); + } else if (type == STREAM_NORMAL) { + fmSetNormalFunc(pCtx[i].functionId, &(pCtx[i].fpSet)); + } + } +} + +static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { + SStreamIntervalOperatorInfo* pInfo = pOperator->info; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + SExprSupp* pSup = &pOperator->exprSupp; + + qDebug("stask:%s %s status: %d", GET_TASKID(pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status); + + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + if (pOperator->status == OP_RES_TO_RETURN) { + SSDataBlock* resBlock = buildIntervalResult(pOperator); + if (resBlock != NULL) { + return resBlock; + } + + if (pInfo->recvGetAll) { + pInfo->recvGetAll = false; + resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable); + } + + setOperatorCompleted(pOperator); + if (pInfo->twAggSup.maxTs > 0 && + pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { + pAPI->stateStore.streamStateCommit(pInfo->pState); + pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); + setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); + pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; + } + return NULL; + } + + SOperatorInfo* downstream = pOperator->pDownstream[0]; + + if (!pInfo->pUpdated) { + pInfo->pUpdated = taosArrayInit(4096, POINTER_BYTES); + } + + if (!pInfo->pUpdatedMap) { + _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); + pInfo->pUpdatedMap = tSimpleHashInit(4096, hashFn); + } + + while (1) { + SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); + if (pBlock == NULL) { + qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, getStreamOpName(pOperator->operatorType), + pInfo->numOfDatapack); + pInfo->numOfDatapack = 0; + break; + } + + pInfo->numOfDatapack++; + printSpecDataBlock(pBlock, getStreamOpName(pOperator->operatorType), "recv", GET_TASKID(pTaskInfo)); + + if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || + pBlock->info.type == STREAM_CLEAR) { + doDeleteWindows(pOperator, &pInfo->interval, pBlock, pInfo->pDelWins, pInfo->pUpdatedMap); + continue; + } else if (pBlock->info.type == STREAM_GET_ALL) { + qDebug("===stream===%s recv|block type STREAM_GET_ALL", getStreamOpName(pOperator->operatorType)); + pInfo->recvGetAll = true; + getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); + continue; + } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { + printDataBlock(pBlock, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo)); + return pBlock; + } else { + ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); + } + + if (pBlock->info.type == STREAM_NORMAL && pBlock->info.version != 0) { + // set input version + pTaskInfo->version = pBlock->info.version; + } + + if (pInfo->scalarSupp.pExprInfo != NULL) { + SExprSupp* pExprSup = &pInfo->scalarSupp; + projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); + } + + // The timewindow that overlaps the timestamps of the input pBlock need to be recalculated and return to the + // caller. Note that all the time window are not close till now. + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); + if (pInfo->invertible) { + setInverFunction(pSup->pCtx, pOperator->exprSupp.numOfExprs, pBlock->info.type); + } + + doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap); + pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); + pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey); + } + pOperator->status = OP_RES_TO_RETURN; + removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); + closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, + pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); + + void* pIte = NULL; + int32_t iter = 0; + while ((pIte = tSimpleHashIterate(pInfo->pUpdatedMap, pIte, &iter)) != NULL) { + taosArrayPush(pInfo->pUpdated, pIte); + } + taosArraySort(pInfo->pUpdated, winPosCmprImpl); + + initMultiResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); + pInfo->pUpdated = NULL; + blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); + tSimpleHashCleanup(pInfo->pUpdatedMap); + pInfo->pUpdatedMap = NULL; + + return buildIntervalResult(pOperator); +} + +SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, + SExecTaskInfo* pTaskInfo) { + SStreamIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamIntervalOperatorInfo)); + SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); + if (pInfo == NULL || pOperator == NULL) { + goto _error; + } + SStreamIntervalPhysiNode* pIntervalPhyNode = (SStreamIntervalPhysiNode*)pPhyNode; + + int32_t code = TSDB_CODE_SUCCESS; + int32_t numOfCols = 0; + SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &numOfCols); + + SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); + pInfo->interval = (SInterval){ + .interval = pIntervalPhyNode->interval, + .sliding = pIntervalPhyNode->sliding, + .intervalUnit = pIntervalPhyNode->intervalUnit, + .slidingUnit = pIntervalPhyNode->slidingUnit, + .offset = pIntervalPhyNode->offset, + .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision, + }; + + pInfo->twAggSup = (STimeWindowAggSupp){ + .waterMark = pIntervalPhyNode->window.watermark, + .calTrigger = pIntervalPhyNode->window.triggerType, + .maxTs = INT64_MIN, + .minTs = INT64_MAX, + .deleteMark = getDeleteMark(pIntervalPhyNode), + .checkPointTs = 0, + .checkPointInterval = + convertTimePrecision(tsCheckpointInterval, TSDB_TIME_PRECISION_MILLI, pInfo->interval.precision), + }; + + ASSERTS(pInfo->twAggSup.calTrigger != STREAM_TRIGGER_MAX_DELAY, "trigger type should not be max delay"); + + pOperator->pTaskInfo = pTaskInfo; + SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; + + pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; + pInfo->ignoreExpiredDataSaved = false; + + SExprSupp* pSup = &pOperator->exprSupp; + initBasicInfo(&pInfo->binfo, pResBlock); + initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); + + pInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; + initResultSizeInfo(&pOperator->resultInfo, 4096); + + pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState)); + *(pInfo->pState) = *(pTaskInfo->streamInfo.pState); + pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); + + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; + code = initAggSup(pSup, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, pInfo->pState, + &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + if (pIntervalPhyNode->window.pExprs != NULL) { + int32_t numOfScalar = 0; + SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); + code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + } + + pInfo->invertible = false; + pInfo->pDelWins = taosArrayInit(4, sizeof(SWinKey)); + pInfo->delIndex = 0; + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); + initResultRowInfo(&pInfo->binfo.resultRowInfo); + + pInfo->pPhyNode = NULL; // create new child + pInfo->pPullDataMap = NULL; + pInfo->pFinalPullDataMap = NULL; + pInfo->pPullWins = NULL; // SPullWindowInfo + pInfo->pullIndex = 0; + pInfo->pPullDataRes = NULL; + pInfo->numOfChild = 0; + pInfo->delKey.ts = INT64_MAX; + pInfo->delKey.groupId = 0; + pInfo->numOfDatapack = 0; + pInfo->pUpdated = NULL; + pInfo->pUpdatedMap = NULL; + int32_t funResSize = getMaxFunResSize(pSup, numOfCols); + + pInfo->pState->pFileState = pTaskInfo->storageAPI.stateStore.streamFileStateInit( + tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, compareTs, pInfo->pState, + pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); + + setOperatorInfo(pOperator, "StreamIntervalOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL, true, OP_NOT_OPENED, + pInfo, pTaskInfo); + pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamIntervalAgg, NULL, + destroyStreamFinalIntervalOperatorInfo, optrDefaultBufFn, NULL); + setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); + + pInfo->statestore = pTaskInfo->storageAPI.stateStore; + pInfo->recvGetAll = false; + + initIntervalDownStream(downstream, pPhyNode->type, pInfo); + code = appendDownstream(pOperator, &downstream, 1); + if (code != TSDB_CODE_SUCCESS) { + goto _error; + } + + return pOperator; + +_error: + destroyStreamFinalIntervalOperatorInfo(pInfo); + taosMemoryFreeClear(pOperator); + pTaskInfo->code = code; + return NULL; +} diff --git a/source/libs/executor/src/sysscanoperator.c b/source/libs/executor/src/sysscanoperator.c index a1f83dda2f051f7ea09b4048b0fa5a2634c49d22..9048dd43d70e3fb24373b75d8e3c83e9fe60b1a8 100644 --- a/source/libs/executor/src/sysscanoperator.c +++ b/source/libs/executor/src/sysscanoperator.c @@ -1601,6 +1601,11 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) { SSysTableScanInfo* pInfo = pOperator->info; char dbName[TSDB_DB_NAME_LEN] = {0}; + if (isTaskKilled(pOperator->pTaskInfo)) { + setOperatorCompleted(pOperator); + return NULL; + } + blockDataCleanup(pInfo->pRes); const char* name = tNameGetTableName(&pInfo->name); diff --git a/source/libs/executor/src/timesliceoperator.c b/source/libs/executor/src/timesliceoperator.c index b01998564513d20d17267a64776d0d20f2461c96..c9824ff2d67a289d0b347c55d528d77973baacc5 100644 --- a/source/libs/executor/src/timesliceoperator.c +++ b/source/libs/executor/src/timesliceoperator.c @@ -848,6 +848,10 @@ static void doHandleTimeslice(SOperatorInfo* pOperator, SSDataBlock* pBlock) { bool ignoreNull = getIgoreNullRes(pSup); int32_t order = TSDB_ORDER_ASC; + if (checkWindowBoundReached(pSliceInfo)) { + return; + } + int32_t code = initKeeperInfo(pSliceInfo, pBlock, &pOperator->exprSupp); if (code != TSDB_CODE_SUCCESS) { T_LONG_JMP(pTaskInfo->env, code); diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 3abb4f44f4e250cf9b05ad906a4b36eddfa0aea8..9e5cea2afd9f053cdad8a6e247a1049763438034 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -26,17 +26,6 @@ #include "tlog.h" #include "ttime.h" -#define IS_FINAL_OP(op) ((op)->isFinal) -#define DEAULT_DELETE_MARK (1000LL * 60LL * 60LL * 24LL * 365LL * 10LL); -#define STREAM_INTERVAL_OP_STATE_NAME "StreamIntervalHistoryState" -#define STREAM_SESSION_OP_STATE_NAME "StreamSessionHistoryState" -#define STREAM_STATE_OP_STATE_NAME "StreamStateHistoryState" - -typedef struct SStateWindowInfo { - SResultWindowInfo winInfo; - SStateKeys* pStateKey; -} SStateWindowInfo; - typedef struct SSessionAggOperatorInfo { SOptrBasicInfo binfo; SAggSupporter aggSup; @@ -66,11 +55,6 @@ typedef enum SResultTsInterpType { RESULT_ROW_END_INTERP = 2, } SResultTsInterpType; -typedef struct SPullWindowInfo { - STimeWindow window; - uint64_t groupId; - STimeWindow calWin; -} SPullWindowInfo; typedef struct SOpenWindowInfo { SResultRowPosition pos; @@ -83,8 +67,6 @@ static SResultRowPosition addToOpenWindowList(SResultRowInfo* pResultRowInfo, co uint64_t groupId); static void doCloseWindow(SResultRowInfo* pResultRowInfo, const SIntervalAggOperatorInfo* pInfo, SResultRow* pResult); -static TSKEY getStartTsKey(STimeWindow* win, const TSKEY* tsCols) { return tsCols == NULL ? win->skey : tsCols[0]; } - static int32_t setTimeWindowOutputBuf(SResultRowInfo* pResultRowInfo, STimeWindow* win, bool masterscan, SResultRow** pResult, int64_t tableGroupId, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, SAggSupporter* pAggSup, @@ -106,15 +88,6 @@ static int32_t setTimeWindowOutputBuf(SResultRowInfo* pResultRowInfo, STimeWindo return TSDB_CODE_SUCCESS; } -static void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, int64_t delta) { - int64_t* ts = (int64_t*)pColData->pData; - - int64_t duration = pWin->ekey - pWin->skey + delta; - ts[2] = duration; // set the duration - ts[3] = pWin->skey; // window start key - ts[4] = pWin->ekey + delta; // window end key -} - static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts, uint64_t groupId) { pRowSup->win.ekey = ts; pRowSup->prevTs = ts; @@ -426,7 +399,7 @@ bool inSlidingWindow(SInterval* pInterval, STimeWindow* pWin, SDataBlockInfo* pB return inCalSlidingWindow(pInterval, pWin, pBlockInfo->calWin.skey, pBlockInfo->calWin.ekey, pBlockInfo->type); } -static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, +int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, TSKEY* primaryKeys, int32_t prevPosition, int32_t order) { bool ascQuery = (order == TSDB_ORDER_ASC); @@ -658,224 +631,6 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num } } -typedef int32_t (*__compare_fn_t)(void* pKey, void* data, int32_t index); - -int32_t binarySearchCom(void* keyList, int num, void* pKey, int order, __compare_fn_t comparefn) { - int firstPos = 0, lastPos = num - 1, midPos = -1; - int numOfRows = 0; - - if (num <= 0) return -1; - if (order == TSDB_ORDER_DESC) { - // find the first position which is smaller or equal than the key - while (1) { - if (comparefn(pKey, keyList, lastPos) >= 0) return lastPos; - if (comparefn(pKey, keyList, firstPos) == 0) return firstPos; - if (comparefn(pKey, keyList, firstPos) < 0) return firstPos - 1; - - numOfRows = lastPos - firstPos + 1; - midPos = (numOfRows >> 1) + firstPos; - - if (comparefn(pKey, keyList, midPos) < 0) { - lastPos = midPos - 1; - } else if (comparefn(pKey, keyList, midPos) > 0) { - firstPos = midPos + 1; - } else { - break; - } - } - - } else { - // find the first position which is bigger or equal than the key - while (1) { - if (comparefn(pKey, keyList, firstPos) <= 0) return firstPos; - if (comparefn(pKey, keyList, lastPos) == 0) return lastPos; - - if (comparefn(pKey, keyList, lastPos) > 0) { - lastPos = lastPos + 1; - if (lastPos >= num) - return -1; - else - return lastPos; - } - - numOfRows = lastPos - firstPos + 1; - midPos = (numOfRows >> 1) + firstPos; - - if (comparefn(pKey, keyList, midPos) < 0) { - lastPos = midPos - 1; - } else if (comparefn(pKey, keyList, midPos) > 0) { - firstPos = midPos + 1; - } else { - break; - } - } - } - - return midPos; -} - -typedef int64_t (*__get_value_fn_t)(void* data, int32_t index); - -int32_t binarySearch(void* keyList, int num, TSKEY key, int order, __get_value_fn_t getValuefn) { - int firstPos = 0, lastPos = num - 1, midPos = -1; - int numOfRows = 0; - - if (num <= 0) return -1; - if (order == TSDB_ORDER_DESC) { - // find the first position which is smaller or equal than the key - while (1) { - if (key >= getValuefn(keyList, lastPos)) return lastPos; - if (key == getValuefn(keyList, firstPos)) return firstPos; - if (key < getValuefn(keyList, firstPos)) return firstPos - 1; - - numOfRows = lastPos - firstPos + 1; - midPos = (numOfRows >> 1) + firstPos; - - if (key < getValuefn(keyList, midPos)) { - lastPos = midPos - 1; - } else if (key > getValuefn(keyList, midPos)) { - firstPos = midPos + 1; - } else { - break; - } - } - - } else { - // find the first position which is bigger or equal than the key - while (1) { - if (key <= getValuefn(keyList, firstPos)) return firstPos; - if (key == getValuefn(keyList, lastPos)) return lastPos; - - if (key > getValuefn(keyList, lastPos)) { - lastPos = lastPos + 1; - if (lastPos >= num) - return -1; - else - return lastPos; - } - - numOfRows = lastPos - firstPos + 1; - midPos = (numOfRows >> 1) + firstPos; - - if (key < getValuefn(keyList, midPos)) { - lastPos = midPos - 1; - } else if (key > getValuefn(keyList, midPos)) { - firstPos = midPos + 1; - } else { - break; - } - } - } - - return midPos; -} - -int32_t comparePullWinKey(void* pKey, void* data, int32_t index) { - SArray* res = (SArray*)data; - SPullWindowInfo* pos = taosArrayGet(res, index); - SPullWindowInfo* pData = (SPullWindowInfo*)pKey; - if (pData->groupId > pos->groupId) { - return 1; - } else if (pData->groupId < pos->groupId) { - return -1; - } - - if (pData->window.skey > pos->window.ekey) { - return 1; - } else if (pData->window.ekey < pos->window.skey) { - return -1; - } - return 0; -} - -static int32_t savePullWindow(SPullWindowInfo* pPullInfo, SArray* pPullWins) { - int32_t size = taosArrayGetSize(pPullWins); - int32_t index = binarySearchCom(pPullWins, size, pPullInfo, TSDB_ORDER_DESC, comparePullWinKey); - if (index == -1) { - index = 0; - } else { - int32_t code = comparePullWinKey(pPullInfo, pPullWins, index); - if (code == 0) { - SPullWindowInfo* pos = taosArrayGet(pPullWins, index); - pos->window.skey = TMIN(pos->window.skey, pPullInfo->window.skey); - pos->window.ekey = TMAX(pos->window.ekey, pPullInfo->window.ekey); - pos->calWin.skey = TMIN(pos->calWin.skey, pPullInfo->calWin.skey); - pos->calWin.ekey = TMAX(pos->calWin.ekey, pPullInfo->calWin.ekey); - return TSDB_CODE_SUCCESS; - } else if (code > 0) { - index++; - } - } - if (taosArrayInsert(pPullWins, index, pPullInfo) == NULL) { - return TSDB_CODE_OUT_OF_MEMORY; - } - return TSDB_CODE_SUCCESS; -} - -static int32_t saveResult(SResultWindowInfo winInfo, SSHashObj* pStUpdated) { - winInfo.sessionWin.win.ekey = winInfo.sessionWin.win.skey; - return tSimpleHashPut(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); -} - -static int32_t saveWinResult(SWinKey* pKey, SRowBuffPos* pPos, SSHashObj* pUpdatedMap) { - tSimpleHashPut(pUpdatedMap, pKey, sizeof(SWinKey), &pPos, POINTER_BYTES); - return TSDB_CODE_SUCCESS; -} - -static int32_t saveWinResultInfo(TSKEY ts, uint64_t groupId, SRowBuffPos* pPos, SSHashObj* pUpdatedMap) { - SWinKey key = {.ts = ts, .groupId = groupId}; - saveWinResult(&key, pPos, pUpdatedMap); - return TSDB_CODE_SUCCESS; -} - -static void removeResults(SArray* pWins, SSHashObj* pUpdatedMap) { - int32_t size = taosArrayGetSize(pWins); - for (int32_t i = 0; i < size; i++) { - SWinKey* pW = taosArrayGet(pWins, i); - void* tmp = tSimpleHashGet(pUpdatedMap, pW, sizeof(SWinKey)); - if (tmp) { - void* value = *(void**)tmp; - taosMemoryFree(value); - tSimpleHashRemove(pUpdatedMap, pW, sizeof(SWinKey)); - } - } -} - -int32_t compareWinKey(void* pKey, void* data, int32_t index) { - void* pDataPos = taosArrayGet((SArray*)data, index); - return winKeyCmprImpl(pKey, pDataPos); -} - -static void removeDeleteResults(SSHashObj* pUpdatedMap, SArray* pDelWins) { - taosArraySort(pDelWins, winKeyCmprImpl); - taosArrayRemoveDuplicate(pDelWins, winKeyCmprImpl, NULL); - int32_t delSize = taosArrayGetSize(pDelWins); - if (tSimpleHashGetSize(pUpdatedMap) == 0 || delSize == 0) { - return; - } - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pUpdatedMap, pIte, &iter)) != NULL) { - SWinKey* pResKey = tSimpleHashGetKey(pIte, NULL); - int32_t index = binarySearchCom(pDelWins, delSize, pResKey, TSDB_ORDER_DESC, compareWinKey); - if (index >= 0 && 0 == compareWinKey(pResKey, pDelWins, index)) { - taosArrayRemove(pDelWins, index); - delSize = taosArrayGetSize(pDelWins); - } - } -} - -bool isOverdue(TSKEY ekey, STimeWindowAggSupp* pTwSup) { - ASSERTS(pTwSup->maxTs == INT64_MIN || pTwSup->maxTs > 0, "maxts should greater than 0"); - return pTwSup->maxTs != INT64_MIN && ekey < pTwSup->maxTs - pTwSup->waterMark; -} - -bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pTwSup) { return isOverdue(pWin->ekey, pTwSup); } - -bool needDeleteWindowBuf(STimeWindow* pWin, STimeWindowAggSupp* pTwSup) { - return pTwSup->maxTs != INT64_MIN && pWin->ekey < pTwSup->maxTs - pTwSup->deleteMark; -} - static bool tsKeyCompFn(void* l, void* r, void* param) { TSKEY* lTS = (TSKEY*)l; TSKEY* rTS = (TSKEY*)r; @@ -1127,18 +882,6 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) { return TSDB_CODE_SUCCESS; } -static bool compareVal(const char* v, const SStateKeys* pKey) { - if (IS_VAR_DATA_TYPE(pKey->type)) { - if (varDataLen(v) != varDataLen(pKey->pData)) { - return false; - } else { - return memcmp(varDataVal(v), varDataVal(pKey->pData), varDataLen(v)) == 0; - } - } else { - return memcmp(pKey->pData, v, pKey->bytes) == 0; - } -} - static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pBlock) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExprSupp* pSup = &pOperator->exprSupp; @@ -1373,169 +1116,6 @@ static void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf, releaseBufPage(pResultBuf, bufPage); } -static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId) { - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SWinKey key = {.ts = ts, .groupId = groupId}; - tSimpleHashRemove(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey)); - pAPI->stateStore.streamStateDel(pInfo->pState, &key); - return true; -} - -static int32_t getChildIndex(SSDataBlock* pBlock) { return pBlock->info.childId; } - -static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDataBlock* pBlock, SArray* pUpWins, - SSHashObj* pUpdatedMap) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); - TSKEY* startTsCols = (TSKEY*)pStartTsCol->pData; - SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); - TSKEY* endTsCols = (TSKEY*)pEndTsCol->pData; - SColumnInfoData* pCalStTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); - TSKEY* calStTsCols = (TSKEY*)pCalStTsCol->pData; - SColumnInfoData* pCalEnTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); - TSKEY* calEnTsCols = (TSKEY*)pCalEnTsCol->pData; - SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - uint64_t* pGpDatas = (uint64_t*)pGpCol->pData; - for (int32_t i = 0; i < pBlock->info.rows; i++) { - SResultRowInfo dumyInfo = {0}; - dumyInfo.cur.pageId = -1; - - STimeWindow win = {0}; - if (IS_FINAL_OP(pInfo)) { - win.skey = startTsCols[i]; - win.ekey = endTsCols[i]; - } else { - win = getActiveTimeWindow(NULL, &dumyInfo, startTsCols[i], pInterval, TSDB_ORDER_ASC); - } - - do { - if (!inCalSlidingWindow(pInterval, &win, calStTsCols[i], calEnTsCols[i], pBlock->info.type)) { - getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); - continue; - } - uint64_t winGpId = pGpDatas[i]; - SWinKey winRes = {.ts = win.skey, .groupId = winGpId}; - void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); - if (chIds) { - int32_t childId = getChildIndex(pBlock); - SArray* chArray = *(void**)chIds; - int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); - if (index != -1) { - qDebug("===stream===try push delete window%" PRId64 "chId:%d ,continue", win.skey, childId); - getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); - continue; - } - } - bool res = doDeleteWindow(pOperator, win.skey, winGpId); - if (pUpWins && res) { - taosArrayPush(pUpWins, &winRes); - } - if (pUpdatedMap) { - tSimpleHashRemove(pUpdatedMap, &winRes, sizeof(SWinKey)); - } - getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC); - } while (win.ekey <= endTsCols[i]); - } -} - -static int32_t getAllIntervalWindow(SSHashObj* pHashMap, SSHashObj* resWins) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { - SWinKey* pKey = tSimpleHashGetKey(pIte, NULL); - uint64_t groupId = pKey->groupId; - TSKEY ts = pKey->ts; - int32_t code = saveWinResultInfo(ts, groupId, *(SRowBuffPos**)pIte, resWins); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - return TSDB_CODE_SUCCESS; -} - -static int32_t closeStreamIntervalWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SInterval* pInterval, - SHashObj* pPullDataMap, SSHashObj* closeWins, SArray* pDelWins, - SOperatorInfo* pOperator) { - qDebug("===stream===close interval window"); - void* pIte = NULL; - int32_t iter = 0; - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - int32_t delSize = taosArrayGetSize(pDelWins); - while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { - void* key = tSimpleHashGetKey(pIte, NULL); - SWinKey* pWinKey = (SWinKey*)key; - if (delSize > 0) { - int32_t index = binarySearchCom(pDelWins, delSize, pWinKey, TSDB_ORDER_DESC, compareWinKey); - if (index >= 0 && 0 == compareWinKey(pWinKey, pDelWins, index)) { - taosArrayRemove(pDelWins, index); - delSize = taosArrayGetSize(pDelWins); - } - } - - void* chIds = taosHashGet(pPullDataMap, pWinKey, sizeof(SWinKey)); - STimeWindow win = { - .skey = pWinKey->ts, - .ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1, - }; - if (isCloseWindow(&win, pTwSup)) { - if (chIds && pPullDataMap) { - SArray* chAy = *(SArray**)chIds; - int32_t size = taosArrayGetSize(chAy); - qDebug("===stream===window %" PRId64 " wait child size:%d", pWinKey->ts, size); - for (int32_t i = 0; i < size; i++) { - qDebug("===stream===window %" PRId64 " wait child id:%d", pWinKey->ts, *(int32_t*)taosArrayGet(chAy, i)); - } - continue; - } else if (pPullDataMap) { - qDebug("===stream===close window %" PRId64, pWinKey->ts); - } - - if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - int32_t code = saveWinResult(pWinKey, *(SRowBuffPos**)pIte, closeWins); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - tSimpleHashIterateRemove(pHashMap, pWinKey, sizeof(SWinKey), &pIte, &iter); - } - } - return TSDB_CODE_SUCCESS; -} - -STimeWindow getFinalTimeWindow(int64_t ts, SInterval* pInterval) { - STimeWindow w = {.skey = ts, .ekey = INT64_MAX}; - w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1; - return w; -} - -static void doBuildDeleteResult(SStreamIntervalOperatorInfo* pInfo, SArray* pWins, int32_t* index, - SSDataBlock* pBlock) { - blockDataCleanup(pBlock); - int32_t size = taosArrayGetSize(pWins); - if (*index == size) { - *index = 0; - taosArrayClear(pWins); - return; - } - blockDataEnsureCapacity(pBlock, size - *index); - uint64_t uid = 0; - for (int32_t i = *index; i < size; i++) { - SWinKey* pWin = taosArrayGet(pWins, i); - void* tbname = NULL; - pInfo->statestore.streamStateGetParName(pInfo->pState, pWin->groupId, &tbname); - if (tbname == NULL) { - appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, NULL); - } else { - char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN]; - STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName)); - appendOneRowToStreamSpecialBlock(pBlock, &pWin->ts, &pWin->ts, &uid, &pWin->groupId, parTbName); - } - pInfo->statestore.streamStateFreeVal(tbname); - (*index)++; - } -} static void destroyStateWindowOperatorInfo(void* param) { SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*)param; @@ -1573,40 +1153,6 @@ void destroyIntervalOperatorInfo(void* param) { taosMemoryFreeClear(param); } -void destroyStreamFinalIntervalOperatorInfo(void* param) { - SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)param; - cleanupBasicInfo(&pInfo->binfo); - cleanupAggSup(&pInfo->aggSup); - // it should be empty. - void* pIte = NULL; - while ((pIte = taosHashIterate(pInfo->pPullDataMap, pIte)) != NULL) { - taosArrayDestroy(*(void**)pIte); - } - taosHashCleanup(pInfo->pPullDataMap); - taosHashCleanup(pInfo->pFinalPullDataMap); - taosArrayDestroy(pInfo->pPullWins); - blockDataDestroy(pInfo->pPullDataRes); - taosArrayDestroy(pInfo->pDelWins); - blockDataDestroy(pInfo->pDelRes); - pInfo->statestore.streamFileStateDestroy(pInfo->pState->pFileState); - taosMemoryFreeClear(pInfo->pState); - - nodesDestroyNode((SNode*)pInfo->pPhyNode); - colDataDestroy(&pInfo->twAggSup.timeWindowData); - pInfo->groupResInfo.pRows = taosArrayDestroy(pInfo->groupResInfo.pRows); - cleanupExprSupp(&pInfo->scalarSupp); - - taosMemoryFreeClear(param); -} - -static bool allInvertible(SqlFunctionCtx* pFCtx, int32_t numOfCols) { - for (int32_t i = 0; i < numOfCols; i++) { - if (fmIsUserDefinedFunc(pFCtx[i].functionId) || !fmIsInvertible(pFCtx[i].functionId)) { - return false; - } - } - return true; -} static bool timeWindowinterpNeeded(SqlFunctionCtx* pCtx, int32_t numOfCols, SIntervalAggOperatorInfo* pInfo) { // the primary timestamp column @@ -1662,25 +1208,6 @@ static bool timeWindowinterpNeeded(SqlFunctionCtx* pCtx, int32_t numOfCols, SInt return needed; } -void initIntervalDownStream(SOperatorInfo* downstream, uint16_t type, SStreamIntervalOperatorInfo* pInfo) { - SStateStore* pAPI = &downstream->pTaskInfo->storageAPI.stateStore; - - if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { - initIntervalDownStream(downstream->pDownstream[0], type, pInfo); - return; - } - - SStreamScanInfo* pScanInfo = downstream->info; - pScanInfo->windowSup.parentType = type; - pScanInfo->windowSup.pIntervalAggSup = &pInfo->aggSup; - if (!pScanInfo->pUpdateInfo) { - pScanInfo->pUpdateInfo = pAPI->updateInfoInitP(&pInfo->interval, pInfo->twAggSup.waterMark); - } - - pScanInfo->interval = pInfo->interval; - pScanInfo->twAggSup = pInfo->twAggSup; - pScanInfo->pState = pInfo->pState; -} void initStreamFunciton(SqlFunctionCtx* pCtx, int32_t numOfExpr) { for (int32_t i = 0; i < numOfExpr; i++) { @@ -2088,2584 +1615,50 @@ _error: return NULL; } -void compactFunctions(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx, int32_t numOfOutput, - SExecTaskInfo* pTaskInfo, SColumnInfoData* pTimeWindowData) { - for (int32_t k = 0; k < numOfOutput; ++k) { - if (fmIsWindowPseudoColumnFunc(pDestCtx[k].functionId)) { - if (!pTimeWindowData) { - continue; - } - SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pDestCtx[k]); - char* p = GET_ROWCELL_INTERBUF(pEntryInfo); - SColumnInfoData idata = {0}; - idata.info.type = TSDB_DATA_TYPE_BIGINT; - idata.info.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - idata.pData = p; - - SScalarParam out = {.columnData = &idata}; - SScalarParam tw = {.numOfRows = 5, .columnData = pTimeWindowData}; - pDestCtx[k].sfp.process(&tw, 1, &out); - pEntryInfo->numOfRes = 1; - } else if (functionNeedToExecute(&pDestCtx[k]) && pDestCtx[k].fpSet.combine != NULL) { - int32_t code = pDestCtx[k].fpSet.combine(&pDestCtx[k], &pSourceCtx[k]); - if (code != TSDB_CODE_SUCCESS) { - qError("%s apply combine functions error, code: %s", GET_TASKID(pTaskInfo), tstrerror(code)); - } - } else if (pDestCtx[k].fpSet.combine == NULL) { - char* funName = fmGetFuncName(pDestCtx[k].functionId); - qError("%s error, combine funcion for %s is not implemented", GET_TASKID(pTaskInfo), funName); - taosMemoryFreeClear(funName); - } - } +void destroyMAIOperatorInfo(void* param) { + SMergeAlignedIntervalAggOperatorInfo* miaInfo = (SMergeAlignedIntervalAggOperatorInfo*)param; + destroyIntervalOperatorInfo(miaInfo->intervalAggOperatorInfo); + taosMemoryFreeClear(param); } -bool hasIntervalWindow(void* pState, SWinKey* pKey, SStateStore* pStore) { return pStore->streamStateCheck(pState, pKey); } - -int32_t setIntervalOutputBuf(void* pState, STimeWindow* win, SRowBuffPos** pResult, int64_t groupId, - SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowEntryInfoOffset, - SAggSupporter* pAggSup, SStateStore* pStore) { - - SWinKey key = { .ts = win->skey, .groupId = groupId }; - char* value = NULL; - int32_t size = pAggSup->resultRowSize; - - if (pStore->streamStateAddIfNotExist(pState, &key, (void**)&value, &size) < 0) { - return TSDB_CODE_OUT_OF_MEMORY; +static SResultRow* doSetSingleOutputTupleBuf(SResultRowInfo* pResultRowInfo, SAggSupporter* pSup) { + SResultRow* pResult = getNewResultRow(pSup->pResultBuf, &pSup->currentPageId, pSup->resultRowSize); + if (NULL == pResult) { + return pResult; } - - *pResult = (SRowBuffPos*)value; - SResultRow* res = (SResultRow*)((*pResult)->pRowBuff); - - // set time window for current result - res->win = (*win); - setResultRowInitCtx(res, pCtx, numOfOutput, rowEntryInfoOffset); - return TSDB_CODE_SUCCESS; + pResultRowInfo->cur = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset}; + return pResult; } -bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, void* pState, STimeWindowAggSupp* pTwSup, SStateStore* pStore) { - if (pTwSup->maxTs != INT64_MIN && pWin->ekey < pTwSup->maxTs - pTwSup->deleteMark) { - SWinKey key = {.ts = pWin->skey, .groupId = groupId}; - if (!hasIntervalWindow(pState, &key, pStore)) { - return true; +static int32_t setSingleOutputTupleBuf(SResultRowInfo* pResultRowInfo, STimeWindow* win, SResultRow** pResult, + SExprSupp* pExprSup, SAggSupporter* pAggSup) { + if (*pResult == NULL) { + *pResult = doSetSingleOutputTupleBuf(pResultRowInfo, pAggSup); + if (*pResult == NULL) { + return terrno; } - return false; } - return false; -} -int32_t getNexWindowPos(SInterval* pInterval, SDataBlockInfo* pBlockInfo, TSKEY* tsCols, int32_t startPos, TSKEY eKey, - STimeWindow* pNextWin) { - int32_t forwardRows = - getNumOfRowsInTimeWindow(pBlockInfo, tsCols, startPos, eKey, binarySearchForKey, NULL, TSDB_ORDER_ASC); - int32_t prevEndPos = forwardRows - 1 + startPos; - return getNextQualifiedWindow(pInterval, pNextWin, pBlockInfo, tsCols, prevEndPos, TSDB_ORDER_ASC); + // set time window for current result + (*pResult)->win = (*win); + setResultRowInitCtx((*pResult), pExprSup->pCtx, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset); + return TSDB_CODE_SUCCESS; } -void addPullWindow(SHashObj* pMap, SWinKey* pWinRes, int32_t size) { - SArray* childIds = taosArrayInit(8, sizeof(int32_t)); - for (int32_t i = 0; i < size; i++) { - taosArrayPush(childIds, &i); - } - taosHashPut(pMap, pWinRes, sizeof(SWinKey), &childIds, sizeof(void*)); -} +static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, + SSDataBlock* pBlock, SSDataBlock* pResultBlock) { + SMergeAlignedIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; + SIntervalAggOperatorInfo* iaInfo = miaInfo->intervalAggOperatorInfo; -static void clearStreamIntervalOperator(SStreamIntervalOperatorInfo* pInfo) { - tSimpleHashClear(pInfo->aggSup.pResultRowHashTable); - clearDiskbasedBuf(pInfo->aggSup.pResultBuf); - initResultRowInfo(&pInfo->binfo.resultRowInfo); - pInfo->aggSup.currentPageId = -1; - pInfo->statestore.streamStateClear(pInfo->pState); -} + SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; + SExprSupp* pSup = &pOperatorInfo->exprSupp; + SInterval* pInterval = &iaInfo->interval; -static void clearSpecialDataBlock(SSDataBlock* pBlock) { - if (pBlock->info.rows <= 0) { - return; - } - blockDataCleanup(pBlock); -} + int32_t startPos = 0; + int64_t* tsCols = extractTsCol(pBlock, iaInfo); -static void doBuildPullDataBlock(SArray* array, int32_t* pIndex, SSDataBlock* pBlock) { - clearSpecialDataBlock(pBlock); - int32_t size = taosArrayGetSize(array); - if (size - (*pIndex) == 0) { - return; - } - blockDataEnsureCapacity(pBlock, size - (*pIndex)); - SColumnInfoData* pStartTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); - SColumnInfoData* pEndTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); - SColumnInfoData* pGroupId = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - SColumnInfoData* pCalStartTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); - SColumnInfoData* pCalEndTs = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); - for (; (*pIndex) < size; (*pIndex)++) { - SPullWindowInfo* pWin = taosArrayGet(array, (*pIndex)); - colDataSetVal(pStartTs, pBlock->info.rows, (const char*)&pWin->window.skey, false); - colDataSetVal(pEndTs, pBlock->info.rows, (const char*)&pWin->window.ekey, false); - colDataSetVal(pGroupId, pBlock->info.rows, (const char*)&pWin->groupId, false); - colDataSetVal(pCalStartTs, pBlock->info.rows, (const char*)&pWin->calWin.skey, false); - colDataSetVal(pCalEndTs, pBlock->info.rows, (const char*)&pWin->calWin.ekey, false); - pBlock->info.rows++; - } - if ((*pIndex) == size) { - *pIndex = 0; - taosArrayClear(array); - } - blockDataUpdateTsWindow(pBlock, 0); -} - -void processPullOver(SSDataBlock* pBlock, SHashObj* pMap, SHashObj* pFinalMap, SInterval* pInterval, SArray* pPullWins, int32_t numOfCh, SOperatorInfo* pOperator) { - SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); - TSKEY* tsData = (TSKEY*)pStartCol->pData; - SColumnInfoData* pEndCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); - TSKEY* tsEndData = (TSKEY*)pEndCol->pData; - SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - uint64_t* groupIdData = (uint64_t*)pGroupCol->pData; - int32_t chId = getChildIndex(pBlock); - for (int32_t i = 0; i < pBlock->info.rows; i++) { - TSKEY winTs = tsData[i]; - while (winTs <= tsEndData[i]) { - SWinKey winRes = {.ts = winTs, .groupId = groupIdData[i]}; - void* chIds = taosHashGet(pMap, &winRes, sizeof(SWinKey)); - if (chIds) { - SArray* chArray = *(SArray**)chIds; - int32_t index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ); - if (index != -1) { - qDebug("===stream===retrive window %" PRId64 " delete child id %d", winRes.ts, chId); - taosArrayRemove(chArray, index); - if (taosArrayGetSize(chArray) == 0) { - // pull data is over - taosArrayDestroy(chArray); - taosHashRemove(pMap, &winRes, sizeof(SWinKey)); - qDebug("===stream===retrive pull data over.window %" PRId64 , winRes.ts); - - void* pFinalCh = taosHashGet(pFinalMap, &winRes, sizeof(SWinKey)); - if (pFinalCh) { - taosHashRemove(pFinalMap, &winRes, sizeof(SWinKey)); - doDeleteWindow(pOperator, winRes.ts, winRes.groupId); - STimeWindow nextWin = getFinalTimeWindow(winRes.ts, pInterval); - SPullWindowInfo pull = {.window = nextWin, - .groupId = winRes.groupId, - .calWin.skey = nextWin.skey, - .calWin.ekey = nextWin.skey}; - // add pull data request - if (savePullWindow(&pull, pPullWins) == TSDB_CODE_SUCCESS) { - addPullWindow(pMap, &winRes, numOfCh); - qDebug("===stream===prepare final retrive for delete %" PRId64 ", size:%d", winRes.ts, numOfCh); - } - } - } - } - } - winTs = taosTimeAdd(winTs, pInterval->sliding, pInterval->slidingUnit, pInterval->precision); - } - } -} - -static void addRetriveWindow(SArray* wins, SStreamIntervalOperatorInfo* pInfo, int32_t childId) { - int32_t size = taosArrayGetSize(wins); - for (int32_t i = 0; i < size; i++) { - SWinKey* winKey = taosArrayGet(wins, i); - STimeWindow nextWin = getFinalTimeWindow(winKey->ts, &pInfo->interval); - if (isOverdue(nextWin.ekey, &pInfo->twAggSup) && pInfo->ignoreExpiredData) { - continue; - } - void* chIds = taosHashGet(pInfo->pPullDataMap, winKey, sizeof(SWinKey)); - if (!chIds) { - SPullWindowInfo pull = { - .window = nextWin, .groupId = winKey->groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; - // add pull data request - if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) { - addPullWindow(pInfo->pPullDataMap, winKey, pInfo->numOfChild); - qDebug("===stream===prepare retrive for delete %" PRId64 ", size:%d", winKey->ts, pInfo->numOfChild); - } - } else { - SArray* chArray = *(void**)chIds; - int32_t index = taosArraySearchIdx(chArray, &childId, compareInt32Val, TD_EQ); - qDebug("===stream===check final retrive %" PRId64",chid:%d", winKey->ts, index); - if (index == -1) { - qDebug("===stream===add final retrive %" PRId64, winKey->ts); - taosHashPut(pInfo->pFinalPullDataMap, winKey, sizeof(SWinKey), NULL, 0); - } - } - } -} - -static void clearFunctionContext(SExprSupp* pSup) { - for (int32_t i = 0; i < pSup->numOfExprs; i++) { - pSup->pCtx[i].saveHandle.currentPage = -1; - } -} - -int32_t getOutputBuf(void* pState, SRowBuffPos* pPos, SResultRow** pResult, SStateStore* pStore) { - return pStore->streamStateGetByPos(pState, pPos, (void**)pResult); -} - -int32_t buildDataBlockFromGroupRes(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, SExprSupp* pSup, - SGroupResInfo* pGroupResInfo) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SExprInfo* pExprInfo = pSup->pExprInfo; - int32_t numOfExprs = pSup->numOfExprs; - int32_t* rowEntryOffset = pSup->rowEntryInfoOffset; - SqlFunctionCtx* pCtx = pSup->pCtx; - - int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); - - for (int32_t i = pGroupResInfo->index; i < numOfRows; i += 1) { - SRowBuffPos* pPos = *(SRowBuffPos**)taosArrayGet(pGroupResInfo->pRows, i); - SResultRow* pRow = NULL; - int32_t code = getOutputBuf(pState, pPos, &pRow, &pAPI->stateStore); - uint64_t groupId = ((SWinKey*)pPos->pKey)->groupId; - ASSERT(code == 0); - doUpdateNumOfRows(pCtx, pRow, numOfExprs, rowEntryOffset); - // no results, continue to check the next one - if (pRow->numOfRows == 0) { - pGroupResInfo->index += 1; - continue; - } - if (pBlock->info.id.groupId == 0) { - pBlock->info.id.groupId = groupId; - void* tbname = NULL; - if (pAPI->stateStore.streamStateGetParName(pTaskInfo->streamInfo.pState, pBlock->info.id.groupId, &tbname) < 0) { - pBlock->info.parTbName[0] = 0; - } else { - memcpy(pBlock->info.parTbName, tbname, TSDB_TABLE_NAME_LEN); - } - pAPI->stateStore.streamStateFreeVal(tbname); - } else { - // current value belongs to different group, it can't be packed into one datablock - if (pBlock->info.id.groupId != groupId) { - break; - } - } - - if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) { - ASSERT(pBlock->info.rows > 0); - break; - } - pGroupResInfo->index += 1; - - for (int32_t j = 0; j < numOfExprs; ++j) { - int32_t slotId = pExprInfo[j].base.resSchema.slotId; - - pCtx[j].resultInfo = getResultEntryInfo(pRow, j, rowEntryOffset); - SResultRowEntryInfo* pEnryInfo = pCtx[j].resultInfo; - - if (pCtx[j].fpSet.finalize) { - int32_t code1 = pCtx[j].fpSet.finalize(&pCtx[j], pBlock); - if (TAOS_FAILED(code1)) { - qError("%s build result data block error, code %s", GET_TASKID(pTaskInfo), tstrerror(code1)); - T_LONG_JMP(pTaskInfo->env, code1); - } - } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) { - // do nothing, todo refactor - } else { - // expand the result into multiple rows. E.g., _wstart, top(k, 20) - // the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows. - SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId); - char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo); - for (int32_t k = 0; k < pRow->numOfRows; ++k) { - colDataSetVal(pColInfoData, pBlock->info.rows + k, in, pCtx[j].resultInfo->isNullRes); - } - } - } - - pBlock->info.rows += pRow->numOfRows; - } - - pBlock->info.dataLoad = 1; - blockDataUpdateTsWindow(pBlock, 0); - return TSDB_CODE_SUCCESS; -} - -void doBuildStreamIntervalResult(SOperatorInfo* pOperator, void* pState, SSDataBlock* pBlock, - SGroupResInfo* pGroupResInfo) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - // set output datablock version - pBlock->info.version = pTaskInfo->version; - - blockDataCleanup(pBlock); - if (!hasRemainResults(pGroupResInfo)) { - return; - } - - // clear the existed group id - pBlock->info.id.groupId = 0; - buildDataBlockFromGroupRes(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); -} - -static int32_t getNextQualifiedFinalWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, - TSKEY* primaryKeys, int32_t prevPosition) { - int32_t startPos = prevPosition + 1; - if (startPos == pDataBlockInfo->rows) { - startPos = -1; - } else { - *pNext = getFinalTimeWindow(primaryKeys[startPos], pInterval); - } - return startPos; -} - -static void setStreamDataVersion(SExecTaskInfo* pTaskInfo, int64_t version, int64_t ckId) { - pTaskInfo->streamInfo.dataVersion = version; - pTaskInfo->streamInfo.checkPointId = ckId; -} - -static void doStreamIntervalAggImpl(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBlock, uint64_t groupId, - SSHashObj* pUpdatedMap) { - SStreamIntervalOperatorInfo* pInfo = (SStreamIntervalOperatorInfo*)pOperatorInfo->info; - pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); - - SResultRowInfo* pResultRowInfo = &(pInfo->binfo.resultRowInfo); - SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; - SExprSupp* pSup = &pOperatorInfo->exprSupp; - int32_t numOfOutput = pSup->numOfExprs; - int32_t step = 1; - TSKEY* tsCols = NULL; - SRowBuffPos* pResPos = NULL; - SResultRow* pResult = NULL; - int32_t forwardRows = 0; - - SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - tsCols = (int64_t*)pColDataInfo->pData; - - int32_t startPos = 0; - TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols); - STimeWindow nextWin = {0}; - if (IS_FINAL_OP(pInfo)) { - nextWin = getFinalTimeWindow(ts, &pInfo->interval); - } else { - nextWin = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval, TSDB_ORDER_ASC); - } - while (1) { - bool isClosed = isCloseWindow(&nextWin, &pInfo->twAggSup); - if ((pInfo->ignoreExpiredData && isClosed && !IS_FINAL_OP(pInfo)) || !inSlidingWindow(&pInfo->interval, &nextWin, &pSDataBlock->info)) { - startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin); - if (startPos < 0) { - break; - } - continue; - } - - if (IS_FINAL_OP(pInfo) && pInfo->numOfChild > 0) { - bool ignore = true; - SWinKey winRes = { - .ts = nextWin.skey, - .groupId = groupId, - }; - void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinKey)); - if (isDeletedStreamWindow(&nextWin, groupId, pInfo->pState, &pInfo->twAggSup, &pInfo->statestore) && isClosed && !chIds) { - SPullWindowInfo pull = { - .window = nextWin, .groupId = groupId, .calWin.skey = nextWin.skey, .calWin.ekey = nextWin.skey}; - // add pull data request - if (savePullWindow(&pull, pInfo->pPullWins) == TSDB_CODE_SUCCESS) { - addPullWindow(pInfo->pPullDataMap, &winRes, pInfo->numOfChild); - } - } else { - int32_t index = -1; - SArray* chArray = NULL; - int32_t chId = 0; - if (chIds) { - chArray = *(void**)chIds; - chId = getChildIndex(pSDataBlock); - index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ); - } - if (index == -1 || pSDataBlock->info.type == STREAM_PULL_DATA) { - ignore = false; - } - } - - if (ignore) { - startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, startPos); - if (startPos < 0) { - break; - } - continue; - } - } - - int32_t code = setIntervalOutputBuf(pInfo->pState, &nextWin, &pResPos, groupId, pSup->pCtx, numOfOutput, - pSup->rowEntryInfoOffset, &pInfo->aggSup, &pInfo->statestore); - pResult = (SResultRow*)pResPos->pRowBuff; - if (code != TSDB_CODE_SUCCESS || pResult == NULL) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - if (IS_FINAL_OP(pInfo)) { - forwardRows = 1; - } else { - forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, - NULL, TSDB_ORDER_ASC); - } - - SWinKey key = { - .ts = pResult->win.skey, - .groupId = groupId, - }; - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdatedMap) { - saveWinResult(&key, pResPos, pUpdatedMap); - } - - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - tSimpleHashPut(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey), &pResPos, POINTER_BYTES); - } - - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &nextWin, 1); - applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, &pInfo->twAggSup.timeWindowData, startPos, forwardRows, - pSDataBlock->info.rows, numOfOutput); - key.ts = nextWin.skey; - - if (pInfo->delKey.ts > key.ts) { - pInfo->delKey = key; - } - int32_t prevEndPos = (forwardRows - 1) * step + startPos; - if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) { - qError("table uid %" PRIu64 " data block timestamp range may not be calculated! minKey %" PRId64 - ",maxKey %" PRId64, - pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey); - blockDataUpdateTsWindow(pSDataBlock, 0); - - // timestamp of the data is incorrect - if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) { - qError("table uid %" PRIu64 " data block timestamp is out of range! minKey %" PRId64 ",maxKey %" PRId64, - pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey); - } - } - - if (IS_FINAL_OP(pInfo)) { - startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos); - } else { - startPos = - getNextQualifiedWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos, TSDB_ORDER_ASC); - } - if (startPos < 0) { - break; - } - } -} - -static inline int winPosCmprImpl(const void* pKey1, const void* pKey2) { - SRowBuffPos* pos1 = *(SRowBuffPos**)pKey1; - SRowBuffPos* pos2 = *(SRowBuffPos**)pKey2; - SWinKey* pWin1 = (SWinKey*)pos1->pKey; - SWinKey* pWin2 = (SWinKey*)pos2->pKey; - - if (pWin1->groupId > pWin2->groupId) { - return 1; - } else if (pWin1->groupId < pWin2->groupId) { - return -1; - } - - if (pWin1->ts > pWin2->ts) { - return 1; - } else if (pWin1->ts < pWin2->ts) { - return -1; - } - - return 0; -} - -static void resetUnCloseWinInfo(SSHashObj* winMap) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(winMap, pIte, &iter)) != NULL) { - SRowBuffPos* pPos = *(SRowBuffPos**)pIte; - pPos->beUsed = true; - } -} - -static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - SExprSupp* pSup = &pOperator->exprSupp; - - qDebug("interval status %d %s", pOperator->status, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } else if (pOperator->status == OP_RES_TO_RETURN) { - doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); - if (pInfo->pPullDataRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->pPullDataRes; - } - - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows != 0) { - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->binfo.pRes; - } - - if (pInfo->recvGetAll) { - pInfo->recvGetAll = false; - resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable); - } - - setOperatorCompleted(pOperator); - if (!IS_FINAL_OP(pInfo)) { - clearFunctionContext(&pOperator->exprSupp); - // semi interval operator clear disk buffer - clearStreamIntervalOperator(pInfo); - setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); - qDebug("===stream===clear semi operator"); - } else { - if (pInfo->twAggSup.maxTs > 0 && - pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { - pAPI->stateStore.streamStateCommit(pInfo->pState); - pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); - pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; - } - qDebug("===stream===interval final close"); - } - return NULL; - } else { - if (!IS_FINAL_OP(pInfo)) { - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->pDelRes; - } - } - } - - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(4096, POINTER_BYTES); - } - if (!pInfo->pUpdatedMap) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pUpdatedMap = tSimpleHashInit(4096, hashFn); - } - - while (1) { - if (isTaskKilled(pTaskInfo)) { - if (pInfo->pUpdated != NULL) { - pInfo->pUpdated = taosArrayDestroy(pInfo->pUpdated); - } - - if (pInfo->pUpdatedMap != NULL) { - tSimpleHashCleanup(pInfo->pUpdatedMap); - pInfo->pUpdatedMap = NULL; - } - - T_LONG_JMP(pTaskInfo->env, pTaskInfo->code); - } - - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - pOperator->status = OP_RES_TO_RETURN; - qDebug("===stream===return data:%s. recv datablock num:%" PRIu64, - IS_FINAL_OP(pInfo) ? "interval final" : "interval semi", pInfo->numOfDatapack); - pInfo->numOfDatapack = 0; - break; - } - pInfo->numOfDatapack++; - printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "interval final recv" : "interval semi recv"); - - if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { - pInfo->binfo.pRes->info.type = pBlock->info.type; - } else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - SArray* delWins = taosArrayInit(8, sizeof(SWinKey)); - doDeleteWindows(pOperator, &pInfo->interval, pBlock, delWins, pInfo->pUpdatedMap); - if (IS_FINAL_OP(pInfo)) { - int32_t chId = getChildIndex(pBlock); - addRetriveWindow(delWins, pInfo, chId); - if (pBlock->info.type != STREAM_CLEAR) { - taosArrayAddAll(pInfo->pDelWins, delWins); - } - taosArrayDestroy(delWins); - continue; - } - removeResults(delWins, pInfo->pUpdatedMap); - taosArrayAddAll(pInfo->pDelWins, delWins); - taosArrayDestroy(delWins); - - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - if (pBlock->info.type == STREAM_CLEAR) { - pInfo->pDelRes->info.type = STREAM_CLEAR; - } else { - pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; - } - return pInfo->pDelRes; - } - - break; - } else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_OP(pInfo)) { - pInfo->recvGetAll = true; - getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); - continue; - } else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) { - doDeleteWindows(pOperator, &pInfo->interval, pBlock, NULL, pInfo->pUpdatedMap); - if (taosArrayGetSize(pInfo->pUpdated) > 0) { - break; - } - continue; - } else if (pBlock->info.type == STREAM_PULL_OVER && IS_FINAL_OP(pInfo)) { - processPullOver(pBlock, pInfo->pPullDataMap, pInfo->pFinalPullDataMap, &pInfo->interval, pInfo->pPullWins, pInfo->numOfChild, pOperator); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark); - pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey); - } - - removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); - if (IS_FINAL_OP(pInfo)) { - closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, - pInfo->pPullDataMap, pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); - } - pInfo->binfo.pRes->info.watermark = pInfo->twAggSup.maxTs; - - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pInfo->pUpdatedMap, pIte, &iter)) != NULL) { - taosArrayPush(pInfo->pUpdated, pIte); - } - - tSimpleHashCleanup(pInfo->pUpdatedMap); - pInfo->pUpdatedMap = NULL; - taosArraySort(pInfo->pUpdated, winPosCmprImpl); - - initMultiResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - - doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes); - if (pInfo->pPullDataRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->pPullDataRes; - } - - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows != 0) { - // process the rest of the data - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows != 0) { - printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); - return pInfo->binfo.pRes; - } - - return NULL; -} - -int64_t getDeleteMark(SIntervalPhysiNode* pIntervalPhyNode) { - if (pIntervalPhyNode->window.deleteMark <= 0) { - return DEAULT_DELETE_MARK; - } - int64_t deleteMark = TMAX(pIntervalPhyNode->window.deleteMark, pIntervalPhyNode->window.watermark); - deleteMark = TMAX(deleteMark, pIntervalPhyNode->interval); - return deleteMark; -} - -TSKEY compareTs(void* pKey) { - SWinKey* pWinKey = (SWinKey*)pKey; - return pWinKey->ts; -} - -int32_t getSelectivityBufSize(SqlFunctionCtx* pCtx) { - if (pCtx->subsidiaries.rowLen == 0) { - int32_t rowLen = 0; - for (int32_t j = 0; j < pCtx->subsidiaries.num; ++j) { - SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j]; - rowLen += pc->pExpr->base.resSchema.bytes; - } - - return rowLen + pCtx->subsidiaries.num * sizeof(bool); - } else { - return pCtx->subsidiaries.rowLen; - } -} - -int32_t getMaxFunResSize(SExprSupp* pSup, int32_t numOfCols) { - int32_t size = 0; - for (int32_t i = 0; i < numOfCols; ++i) { - int32_t resSize = getSelectivityBufSize(pSup->pCtx + i); - size = TMAX(size, resSize); - } - return size; -} - -void streamIntervalReleaseState(SOperatorInfo* pOperator) { - if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - int32_t resSize = sizeof(TSKEY); - pInfo->statestore.streamStateSaveInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, strlen(STREAM_INTERVAL_OP_STATE_NAME), &pInfo->twAggSup.maxTs, resSize); - } - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - pAPI->stateStore.streamStateCommit(pInfo->pState); - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.releaseStreamStateFn) { - downstream->fpSet.releaseStreamStateFn(downstream); - } -} - -void streamIntervalReloadState(SOperatorInfo* pOperator) { - if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - int32_t size = 0; - void* pBuf = NULL; - int32_t code = pInfo->statestore.streamStateGetInfo(pInfo->pState, STREAM_INTERVAL_OP_STATE_NAME, - strlen(STREAM_INTERVAL_OP_STATE_NAME), &pBuf, &size); - TSKEY ts = *(TSKEY*)pBuf; - taosMemoryFree(pBuf); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, ts); - pInfo->statestore.streamStateReloadInfo(pInfo->pState, ts); - } - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.reloadStreamStateFn) { - downstream->fpSet.reloadStreamStateFn(downstream); - } -} - -SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, int32_t numOfChild) { - SIntervalPhysiNode* pIntervalPhyNode = (SIntervalPhysiNode*)pPhyNode; - SStreamIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamIntervalOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL) { - goto _error; - } - - pOperator->pTaskInfo = pTaskInfo; - SStorageAPI* pAPI = &pTaskInfo->storageAPI; - - pInfo->interval = (SInterval){.interval = pIntervalPhyNode->interval, - .sliding = pIntervalPhyNode->sliding, - .intervalUnit = pIntervalPhyNode->intervalUnit, - .slidingUnit = pIntervalPhyNode->slidingUnit, - .offset = pIntervalPhyNode->offset, - .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision}; - pInfo->twAggSup = (STimeWindowAggSupp){ - .waterMark = pIntervalPhyNode->window.watermark, - .calTrigger = pIntervalPhyNode->window.triggerType, - .maxTs = INT64_MIN, - .minTs = INT64_MAX, - .deleteMark = getDeleteMark(pIntervalPhyNode), - .deleteMarkSaved = 0, - .calTriggerSaved = 0, - .checkPointTs = 0, - .checkPointInterval = - convertTimePrecision(tsCheckpointInterval, TSDB_TIME_PRECISION_MILLI, pInfo->interval.precision), - }; - ASSERTS(pInfo->twAggSup.calTrigger != STREAM_TRIGGER_MAX_DELAY, "trigger type should not be max delay"); - pInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; - size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; - initResultSizeInfo(&pOperator->resultInfo, 4096); - if (pIntervalPhyNode->window.pExprs != NULL) { - int32_t numOfScalar = 0; - SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); - int32_t code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - } - - int32_t numOfCols = 0; - SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &numOfCols); - SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); - initBasicInfo(&pInfo->binfo, pResBlock); - - pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState)); - *(pInfo->pState) = *(pTaskInfo->streamInfo.pState); - - pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); - int32_t code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, - pInfo->pState, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - initStreamFunciton(pOperator->exprSupp.pCtx, pOperator->exprSupp.numOfExprs); - initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - initResultRowInfo(&pInfo->binfo.resultRowInfo); - - pInfo->numOfChild = numOfChild; - - pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode); - - if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) { - pInfo->isFinal = true; - pOperator->name = "StreamFinalIntervalOperator"; - } else { - // semi interval operator does not catch result - pInfo->isFinal = false; - pOperator->name = "StreamSemiIntervalOperator"; - } - - if (!IS_FINAL_OP(pInfo) || numOfChild == 0) { - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - } - - pInfo->pPullWins = taosArrayInit(8, sizeof(SPullWindowInfo)); - pInfo->pullIndex = 0; - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK); - pInfo->pFinalPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK); - pInfo->pPullDataRes = createSpecialDataBlock(STREAM_RETRIEVE); - pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; - pInfo->ignoreExpiredDataSaved = false; - pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - pInfo->delIndex = 0; - pInfo->pDelWins = taosArrayInit(4, sizeof(SWinKey)); - pInfo->delKey.ts = INT64_MAX; - pInfo->delKey.groupId = 0; - pInfo->numOfDatapack = 0; - pInfo->pUpdated = NULL; - pInfo->pUpdatedMap = NULL; - int32_t funResSize= getMaxFunResSize(&pOperator->exprSupp, numOfCols); - pInfo->pState->pFileState = pAPI->stateStore.streamFileStateInit(tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, - compareTs, pInfo->pState, pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); - pInfo->dataVersion = 0; - pInfo->statestore = pTaskInfo->storageAPI.stateStore; - pInfo->recvGetAll = false; - - pOperator->operatorType = pPhyNode->type; - pOperator->blocking = true; - pOperator->status = OP_NOT_OPENED; - pOperator->info = pInfo; - - pOperator->fpSet = createOperatorFpSet(NULL, doStreamFinalIntervalAgg, NULL, destroyStreamFinalIntervalOperatorInfo, - optrDefaultBufFn, NULL); - setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); - if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_INTERVAL) { - initIntervalDownStream(downstream, pPhyNode->type, pInfo); - } - code = appendDownstream(pOperator, &downstream, 1); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - return pOperator; - -_error: - destroyStreamFinalIntervalOperatorInfo(pInfo); - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} - -void destroyStreamAggSupporter(SStreamAggSupporter* pSup) { - tSimpleHashCleanup(pSup->pResultRows); - destroyDiskbasedBuf(pSup->pResultBuf); - blockDataDestroy(pSup->pScanBlock); - taosMemoryFreeClear(pSup->pState); - taosMemoryFreeClear(pSup->pDummyCtx); -} - -void destroyStreamSessionAggOperatorInfo(void* param) { - SStreamSessionAggOperatorInfo* pInfo = (SStreamSessionAggOperatorInfo*)param; - cleanupBasicInfo(&pInfo->binfo); - destroyStreamAggSupporter(&pInfo->streamAggSup); - - if (pInfo->pChildren != NULL) { - int32_t size = taosArrayGetSize(pInfo->pChildren); - for (int32_t i = 0; i < size; i++) { - SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i); - destroyOperator(pChild); - } - taosArrayDestroy(pInfo->pChildren); - } - - colDataDestroy(&pInfo->twAggSup.timeWindowData); - blockDataDestroy(pInfo->pDelRes); - blockDataDestroy(pInfo->pWinBlock); - blockDataDestroy(pInfo->pUpdateRes); - tSimpleHashCleanup(pInfo->pStUpdated); - tSimpleHashCleanup(pInfo->pStDeleted); - - taosArrayDestroy(pInfo->historyWins); - taosMemoryFreeClear(param); -} - -int32_t initBasicInfoEx(SOptrBasicInfo* pBasicInfo, SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfCols, - SSDataBlock* pResultBlock, SFunctionStateStore* pStore) { - initBasicInfo(pBasicInfo, pResultBlock); - int32_t code = initExprSupp(pSup, pExprInfo, numOfCols, pStore); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - initStreamFunciton(pSup->pCtx, pSup->numOfExprs); - for (int32_t i = 0; i < numOfCols; ++i) { - pSup->pCtx[i].saveHandle.pBuf = NULL; - } - - ASSERT(numOfCols > 0); - return TSDB_CODE_SUCCESS; -} - -void initDummyFunction(SqlFunctionCtx* pDummy, SqlFunctionCtx* pCtx, int32_t nums) { - for (int i = 0; i < nums; i++) { - pDummy[i].functionId = pCtx[i].functionId; - pDummy[i].isNotNullFunc = pCtx[i].isNotNullFunc; - pDummy[i].isPseudoFunc = pCtx[i].isPseudoFunc; - } -} - -void initDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup, uint16_t type, int32_t tsColIndex, - STimeWindowAggSupp* pTwSup) { - if (downstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION) { - SStreamPartitionOperatorInfo* pScanInfo = downstream->info; - pScanInfo->tsColIndex = tsColIndex; - } - - if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) { - initDownStream(downstream->pDownstream[0], pAggSup, type, tsColIndex, pTwSup); - return; - } - SStreamScanInfo* pScanInfo = downstream->info; - pScanInfo->windowSup = (SWindowSupporter){.pStreamAggSup = pAggSup, .gap = pAggSup->gap, .parentType = type}; - pScanInfo->pState = pAggSup->pState; - if (!pScanInfo->pUpdateInfo) { - pScanInfo->pUpdateInfo = pAggSup->stateStore.updateInfoInit(60000, TSDB_TIME_PRECISION_MILLI, pTwSup->waterMark); - } - pScanInfo->twAggSup = *pTwSup; -} - -int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx, int32_t numOfOutput, int64_t gap, - SStreamState* pState, int32_t keySize, int16_t keyType, SStateStore* pStore, SReadHandle* pHandle, SStorageAPI* pApi) { - pSup->resultRowSize = keySize + getResultRowSize(pCtx, numOfOutput); - pSup->pScanBlock = createSpecialDataBlock(STREAM_CLEAR); - pSup->gap = gap; - pSup->stateKeySize = keySize; - pSup->stateKeyType = keyType; - pSup->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfOutput, sizeof(SqlFunctionCtx)); - if (pSup->pDummyCtx == NULL) { - return TSDB_CODE_OUT_OF_MEMORY; - } - - pSup->stateStore = *pStore; - - initDummyFunction(pSup->pDummyCtx, pCtx, numOfOutput); - pSup->pState = taosMemoryCalloc(1, sizeof(SStreamState)); - *(pSup->pState) = *pState; - pSup->stateStore.streamStateSetNumber(pSup->pState, -1); - - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pSup->pResultRows = tSimpleHashInit(32, hashFn); - - int32_t pageSize = 4096; - while (pageSize < pSup->resultRowSize * 4) { - pageSize <<= 1u; - } - // at least four pages need to be in buffer - int32_t bufSize = 4096 * 256; - if (bufSize <= pageSize) { - bufSize = pageSize * 4; - } - - if (!osTempSpaceAvailable()) { - terrno = TSDB_CODE_NO_DISKSPACE; - qError("Init stream agg supporter failed since %s, tempDir:%s", terrstr(), tsTempDir); - return terrno; - } - - int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, "function", tsTempDir); - for (int32_t i = 0; i < numOfOutput; ++i) { - pCtx[i].saveHandle.pBuf = pSup->pResultBuf; - } - - pSup->pSessionAPI = pApi; - - return TSDB_CODE_SUCCESS; -} - -bool isInTimeWindow(STimeWindow* pWin, TSKEY ts, int64_t gap) { - if (ts + gap >= pWin->skey && ts - gap <= pWin->ekey) { - return true; - } - return false; -} - -bool isInWindow(SResultWindowInfo* pWinInfo, TSKEY ts, int64_t gap) { - return isInTimeWindow(&pWinInfo->sessionWin.win, ts, gap); -} - -void getCurSessionWindow(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, - SSessionKey* pKey) { - pKey->win.skey = startTs; - pKey->win.ekey = endTs; - pKey->groupId = groupId; - int32_t code = pAggSup->stateStore.streamStateSessionGetKeyByRange(pAggSup->pState, pKey, pKey); - if (code != TSDB_CODE_SUCCESS) { - SET_SESSION_WIN_KEY_INVALID(pKey); - } -} - -bool isInvalidSessionWin(SResultWindowInfo* pWinInfo) { return pWinInfo->sessionWin.win.skey == 0; } - -bool inWinRange(STimeWindow* range, STimeWindow* cur) { - if (cur->skey >= range->skey && cur->ekey <= range->ekey) { - return true; - } - return false; -} - -void setSessionOutputBuf(SStreamAggSupporter* pAggSup, TSKEY startTs, TSKEY endTs, uint64_t groupId, - SResultWindowInfo* pCurWin) { - pCurWin->sessionWin.groupId = groupId; - pCurWin->sessionWin.win.skey = startTs; - pCurWin->sessionWin.win.ekey = endTs; - int32_t size = pAggSup->resultRowSize; - int32_t code = pAggSup->stateStore.streamStateSessionAddIfNotExist(pAggSup->pState, &pCurWin->sessionWin, - pAggSup->gap, &pCurWin->pOutputBuf, &size); - if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->sessionWin.win)) { - code = TSDB_CODE_FAILED; - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->pOutputBuf, &pAggSup->pSessionAPI->stateStore); - pCurWin->pOutputBuf = taosMemoryCalloc(1, size); - } - - if (code == TSDB_CODE_SUCCESS) { - pCurWin->isOutput = true; - pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->sessionWin); - } else { - pCurWin->sessionWin.win.skey = startTs; - pCurWin->sessionWin.win.ekey = endTs; - } -} - -int32_t getSessionWinBuf(SStreamAggSupporter* pAggSup, SStreamStateCur* pCur, SResultWindowInfo* pWinInfo) { - int32_t size = 0; - int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pWinInfo->sessionWin, &pWinInfo->pOutputBuf, &size); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - pAggSup->stateStore.streamStateCurNext(pAggSup->pState, pCur); - return TSDB_CODE_SUCCESS; -} -void saveDeleteInfo(SArray* pWins, SSessionKey key) { - // key.win.ekey = key.win.skey; - taosArrayPush(pWins, &key); -} - -void saveDeleteRes(SSHashObj* pStDelete, SSessionKey key) { - key.win.ekey = key.win.skey; - tSimpleHashPut(pStDelete, &key, sizeof(SSessionKey), NULL, 0); -} - -static void removeSessionResult(SSHashObj* pHashMap, SSHashObj* pResMap, SSessionKey key) { - key.win.ekey = key.win.skey; - tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey)); - tSimpleHashRemove(pResMap, &key, sizeof(SSessionKey)); -} - -static void getSessionHashKey(const SSessionKey* pKey, SSessionKey* pHashKey) { - *pHashKey = *pKey; - pHashKey->win.ekey = pKey->win.skey; -} - -static void removeSessionResults(SSHashObj* pHashMap, SArray* pWins) { - if (tSimpleHashGetSize(pHashMap) == 0) { - return; - } - int32_t size = taosArrayGetSize(pWins); - for (int32_t i = 0; i < size; i++) { - SSessionKey* pWin = taosArrayGet(pWins, i); - if (!pWin) continue; - SSessionKey key = {0}; - getSessionHashKey(pWin, &key); - tSimpleHashRemove(pHashMap, &key, sizeof(SSessionKey)); - } -} - -int32_t updateSessionWindowInfo(SResultWindowInfo* pWinInfo, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t groupId, - int32_t rows, int32_t start, int64_t gap, SSHashObj* pResultRows, SSHashObj* pStUpdated, - SSHashObj* pStDeleted) { - for (int32_t i = start; i < rows; ++i) { - if (!isInWindow(pWinInfo, pStartTs[i], gap) && (!pEndTs || !isInWindow(pWinInfo, pEndTs[i], gap))) { - return i - start; - } - if (pWinInfo->sessionWin.win.skey > pStartTs[i]) { - if (pStDeleted && pWinInfo->isOutput) { - saveDeleteRes(pStDeleted, pWinInfo->sessionWin); - } - removeSessionResult(pStUpdated, pResultRows, pWinInfo->sessionWin); - pWinInfo->sessionWin.win.skey = pStartTs[i]; - } - pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pStartTs[i]); - if (pEndTs) { - pWinInfo->sessionWin.win.ekey = TMAX(pWinInfo->sessionWin.win.ekey, pEndTs[i]); - } - } - return rows - start; -} - -static int32_t initSessionOutputBuf(SResultWindowInfo* pWinInfo, SResultRow** pResult, SqlFunctionCtx* pCtx, - int32_t numOfOutput, int32_t* rowEntryInfoOffset) { - ASSERT(pWinInfo->sessionWin.win.skey <= pWinInfo->sessionWin.win.ekey); - *pResult = (SResultRow*)pWinInfo->pOutputBuf; - // set time window for current result - (*pResult)->win = pWinInfo->sessionWin.win; - setResultRowInitCtx(*pResult, pCtx, numOfOutput, rowEntryInfoOffset); - return TSDB_CODE_SUCCESS; -} - -static int32_t doOneWindowAggImpl(SColumnInfoData* pTimeWindowData, SResultWindowInfo* pCurWin, SResultRow** pResult, - int32_t startIndex, int32_t winRows, int32_t rows, int32_t numOutput, - SOperatorInfo* pOperator, int64_t winDelta) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - int32_t code = initSessionOutputBuf(pCurWin, pResult, pSup->pCtx, numOutput, pSup->rowEntryInfoOffset); - if (code != TSDB_CODE_SUCCESS || (*pResult) == NULL) { - return TSDB_CODE_OUT_OF_MEMORY; - } - updateTimeWindowInfo(pTimeWindowData, &pCurWin->sessionWin.win, winDelta); - applyAggFunctionOnPartialTuples(pTaskInfo, pSup->pCtx, pTimeWindowData, startIndex, winRows, rows, numOutput); - return TSDB_CODE_SUCCESS; -} - -static bool doDeleteSessionWindow(SStreamAggSupporter* pAggSup, SSessionKey* pKey) { - pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, pKey); - SSessionKey hashKey = {0}; - getSessionHashKey(pKey, &hashKey); - tSimpleHashRemove(pAggSup->pResultRows, &hashKey, sizeof(SSessionKey)); - return true; -} - -static int32_t setSessionWinOutputInfo(SSHashObj* pStUpdated, SResultWindowInfo* pWinInfo) { - void* pVal = tSimpleHashGet(pStUpdated, &pWinInfo->sessionWin, sizeof(SSessionKey)); - if (pVal) { - SResultWindowInfo* pWin = pVal; - pWinInfo->isOutput = pWin->isOutput; - } - return TSDB_CODE_SUCCESS; -} - -SStreamStateCur* getNextSessionWinInfo(SStreamAggSupporter* pAggSup, SSHashObj* pStUpdated, SResultWindowInfo* pCurWin, - SResultWindowInfo* pNextWin) { - SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pCurWin->sessionWin); - pNextWin->isOutput = true; - setSessionWinOutputInfo(pStUpdated, pNextWin); - int32_t size = 0; - pNextWin->sessionWin = pCurWin->sessionWin; - int32_t code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->sessionWin, &pNextWin->pOutputBuf, &size); - if (code != TSDB_CODE_SUCCESS) { - taosMemoryFreeClear(pNextWin->pOutputBuf); - SET_SESSION_WIN_INVALID(*pNextWin); - } - return pCur; -} - -static int32_t compactSessionWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SSHashObj* pStUpdated, - SSHashObj* pStDeleted, bool addGap) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - int32_t winNum = 0; - - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SResultRow* pCurResult = NULL; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); - // Just look for the window behind StartIndex - while (1) { - SResultWindowInfo winInfo = {0}; - SStreamStateCur* pCur = getNextSessionWinInfo(pAggSup, pStUpdated, pCurWin, &winInfo); - if (!IS_VALID_SESSION_WIN(winInfo) || !isInWindow(pCurWin, winInfo.sessionWin.win.skey, pAggSup->gap) || - !inWinRange(&pAggSup->winRange, &winInfo.sessionWin.win)) { - taosMemoryFree(winInfo.pOutputBuf); - pAPI->stateStore.streamStateFreeCur(pCur); - break; - } - SResultRow* pWinResult = NULL; - initSessionOutputBuf(&winInfo, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); - pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, winInfo.sessionWin.win.ekey); - int64_t winDelta = 0; - if (addGap) { - winDelta = pAggSup->gap; - } - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, winDelta); - compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); - tSimpleHashRemove(pStUpdated, &winInfo.sessionWin, sizeof(SSessionKey)); - if (winInfo.isOutput && pStDeleted) { - saveDeleteRes(pStDeleted, winInfo.sessionWin); - } - removeSessionResult(pStUpdated, pAggSup->pResultRows, winInfo.sessionWin); - doDeleteSessionWindow(pAggSup, &winInfo.sessionWin); - pAPI->stateStore.streamStateFreeCur(pCur); - taosMemoryFree(winInfo.pOutputBuf); - winNum++; - } - return winNum; -} - -int32_t saveSessionOutputBuf(SStreamAggSupporter* pAggSup, SResultWindowInfo* pWinInfo) { - saveSessionDiscBuf(pAggSup->pState, &pWinInfo->sessionWin, pWinInfo->pOutputBuf, pAggSup->resultRowSize, &pAggSup->stateStore); - pWinInfo->pOutputBuf = NULL; - return TSDB_CODE_SUCCESS; -} - -static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pStUpdated, - SSHashObj* pStDeleted, bool hasEndTs, bool addGap) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - uint64_t groupId = pSDataBlock->info.id.groupId; - int64_t code = TSDB_CODE_SUCCESS; - SResultRow* pResult = NULL; - int32_t rows = pSDataBlock->info.rows; - int32_t winRows = 0; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - - pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); - pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow; - if (pAggSup->winRange.ekey <= 0) { - pAggSup->winRange.ekey = INT64_MAX; - } - - SColumnInfoData* pStartTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - TSKEY* startTsCols = (int64_t*)pStartTsCol->pData; - SColumnInfoData* pEndTsCol = NULL; - if (hasEndTs) { - pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->endTsIndex); - } else { - pEndTsCol = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - } - - TSKEY* endTsCols = (int64_t*)pEndTsCol->pData; - for (int32_t i = 0; i < rows;) { - if (pInfo->ignoreExpiredData && isOverdue(endTsCols[i], &pInfo->twAggSup)) { - i++; - continue; - } - SResultWindowInfo winInfo = {0}; - setSessionOutputBuf(pAggSup, startTsCols[i], endTsCols[i], groupId, &winInfo); - setSessionWinOutputInfo(pStUpdated, &winInfo); - winRows = updateSessionWindowInfo(&winInfo, startTsCols, endTsCols, groupId, rows, i, pAggSup->gap, - pAggSup->pResultRows, pStUpdated, pStDeleted); - // coverity scan error - if (!winInfo.pOutputBuf) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - - int64_t winDelta = 0; - if (addGap) { - winDelta = pAggSup->gap; - } - code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &winInfo, &pResult, i, winRows, rows, numOfOutput, - pOperator, winDelta); - if (code != TSDB_CODE_SUCCESS || pResult == NULL) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - compactSessionWindow(pOperator, &winInfo, pStUpdated, pStDeleted, addGap); - saveSessionOutputBuf(pAggSup, &winInfo); - - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pStUpdated) { - code = saveResult(winInfo, pStUpdated); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - } - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - SSessionKey key = {0}; - getSessionHashKey(&winInfo.sessionWin, &key); - tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); - } - - i += winRows; - } -} - -static void doDeleteTimeWindows(SStreamAggSupporter* pAggSup, SSDataBlock* pBlock, SArray* result) { - SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); - TSKEY* startDatas = (TSKEY*)pStartTsCol->pData; - SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); - TSKEY* endDatas = (TSKEY*)pEndTsCol->pData; - SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - uint64_t* gpDatas = (uint64_t*)pGroupCol->pData; - for (int32_t i = 0; i < pBlock->info.rows; i++) { - while (1) { - SSessionKey curWin = {0}; - getCurSessionWindow(pAggSup, startDatas[i], endDatas[i], gpDatas[i], &curWin); - if (IS_INVALID_SESSION_WIN_KEY(curWin)) { - break; - } - doDeleteSessionWindow(pAggSup, &curWin); - if (result) { - saveDeleteInfo(result, curWin); - } - } - } -} - -static inline int32_t sessionKeyCompareAsc(const void* pKey1, const void* pKey2) { - SSessionKey* pWin1 = (SSessionKey*)pKey1; - SSessionKey* pWin2 = (SSessionKey*)pKey2; - - if (pWin1->groupId > pWin2->groupId) { - return 1; - } else if (pWin1->groupId < pWin2->groupId) { - return -1; - } - - if (pWin1->win.skey > pWin2->win.skey) { - return 1; - } else if (pWin1->win.skey < pWin2->win.skey) { - return -1; - } - - return 0; -} - -static int32_t copyUpdateResult(SSHashObj* pStUpdated, SArray* pUpdated) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pStUpdated, pIte, &iter)) != NULL) { - void* key = tSimpleHashGetKey(pIte, NULL); - taosArrayPush(pUpdated, key); - } - taosArraySort(pUpdated, sessionKeyCompareAsc); - return TSDB_CODE_SUCCESS; -} - -void doBuildDeleteDataBlock(SOperatorInfo* pOp, SSHashObj* pStDeleted, SSDataBlock* pBlock, void** Ite) { - SStorageAPI* pAPI = &pOp->pTaskInfo->storageAPI; - - blockDataCleanup(pBlock); - int32_t size = tSimpleHashGetSize(pStDeleted); - if (size == 0) { - return; - } - blockDataEnsureCapacity(pBlock, size); - int32_t iter = 0; - while (((*Ite) = tSimpleHashIterate(pStDeleted, *Ite, &iter)) != NULL) { - if (pBlock->info.rows + 1 > pBlock->info.capacity) { - break; - } - SSessionKey* res = tSimpleHashGetKey(*Ite, NULL); - SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); - colDataSetVal(pStartTsCol, pBlock->info.rows, (const char*)&res->win.skey, false); - SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); - colDataSetVal(pEndTsCol, pBlock->info.rows, (const char*)&res->win.skey, false); - SColumnInfoData* pUidCol = taosArrayGet(pBlock->pDataBlock, UID_COLUMN_INDEX); - colDataSetNULL(pUidCol, pBlock->info.rows); - SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); - colDataSetVal(pGpCol, pBlock->info.rows, (const char*)&res->groupId, false); - SColumnInfoData* pCalStCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX); - colDataSetNULL(pCalStCol, pBlock->info.rows); - SColumnInfoData* pCalEdCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX); - colDataSetNULL(pCalEdCol, pBlock->info.rows); - - SColumnInfoData* pTableCol = taosArrayGet(pBlock->pDataBlock, TABLE_NAME_COLUMN_INDEX); - - void* tbname = NULL; - pAPI->stateStore.streamStateGetParName(pOp->pTaskInfo->streamInfo.pState, res->groupId, &tbname); - if (tbname == NULL) { - colDataSetNULL(pTableCol, pBlock->info.rows); - } else { - char parTbName[VARSTR_HEADER_SIZE + TSDB_TABLE_NAME_LEN]; - STR_WITH_MAXSIZE_TO_VARSTR(parTbName, tbname, sizeof(parTbName)); - colDataSetVal(pTableCol, pBlock->info.rows, (const char*)parTbName, false); - pAPI->stateStore.streamStateFreeVal(tbname); - } - pBlock->info.rows += 1; - } - if ((*Ite) == NULL) { - tSimpleHashClear(pStDeleted); - } -} - -static void rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, SSHashObj* pStUpdated) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - int32_t size = taosArrayGetSize(pWinArray); - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - int32_t numOfOutput = pSup->numOfExprs; - int32_t numOfChild = taosArrayGetSize(pInfo->pChildren); - - for (int32_t i = 0; i < size; i++) { - SSessionKey* pWinKey = taosArrayGet(pWinArray, i); - int32_t num = 0; - SResultWindowInfo parentWin = {0}; - for (int32_t j = 0; j < numOfChild; j++) { - SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, j); - SStreamSessionAggOperatorInfo* pChInfo = pChild->info; - SStreamAggSupporter* pChAggSup = &pChInfo->streamAggSup; - SSessionKey chWinKey = {0}; - getSessionHashKey(pWinKey, &chWinKey); - SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyCurrentNext(pChAggSup->pState, &chWinKey); - SResultRow* pResult = NULL; - SResultRow* pChResult = NULL; - while (1) { - SResultWindowInfo childWin = {0}; - childWin.sessionWin = *pWinKey; - int32_t code = getSessionWinBuf(pChAggSup, pCur, &childWin); - - if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &childWin.sessionWin.win)) { - continue; - } - - if (code == TSDB_CODE_SUCCESS && inWinRange(&pWinKey->win, &childWin.sessionWin.win)) { - if (num == 0) { - setSessionOutputBuf(pAggSup, pWinKey->win.skey, pWinKey->win.ekey, pWinKey->groupId, &parentWin); - code = initSessionOutputBuf(&parentWin, &pResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); - if (code != TSDB_CODE_SUCCESS || pResult == NULL) { - break; - } - } - num++; - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &parentWin.sessionWin.win, pAggSup->gap); - initSessionOutputBuf(&childWin, &pChResult, pChild->exprSupp.pCtx, numOfOutput, - pChild->exprSupp.rowEntryInfoOffset); - compactFunctions(pSup->pCtx, pChild->exprSupp.pCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); - compactSessionWindow(pOperator, &parentWin, pStUpdated, NULL, true); - saveResult(parentWin, pStUpdated); - } else { - break; - } - } - pAPI->stateStore.streamStateFreeCur(pCur); - } - if (num > 0) { - saveSessionOutputBuf(pAggSup, &parentWin); - } - } -} - -int32_t closeSessionWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SSHashObj* pClosed) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { - SResultWindowInfo* pWinInfo = pIte; - if (isCloseWindow(&pWinInfo->sessionWin.win, pTwSup)) { - if (pTwSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE && pClosed) { - int32_t code = saveResult(*pWinInfo, pClosed); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - SSessionKey* pKey = tSimpleHashGetKey(pIte, NULL); - tSimpleHashIterateRemove(pHashMap, pKey, sizeof(SSessionKey), &pIte, &iter); - } - } - return TSDB_CODE_SUCCESS; -} - -static void closeChildSessionWindow(SArray* pChildren, TSKEY maxTs) { - int32_t size = taosArrayGetSize(pChildren); - for (int32_t i = 0; i < size; i++) { - SOperatorInfo* pChildOp = taosArrayGetP(pChildren, i); - SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info; - pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, maxTs); - closeSessionWindow(pChInfo->streamAggSup.pResultRows, &pChInfo->twAggSup, NULL); - } -} - -int32_t getAllSessionWindow(SSHashObj* pHashMap, SSHashObj* pStUpdated) { - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { - SResultWindowInfo* pWinInfo = pIte; - saveResult(*pWinInfo, pStUpdated); - } - return TSDB_CODE_SUCCESS; -} - -static void copyDeleteWindowInfo(SArray* pResWins, SSHashObj* pStDeleted) { - int32_t size = taosArrayGetSize(pResWins); - for (int32_t i = 0; i < size; i++) { - SSessionKey* pWinKey = taosArrayGet(pResWins, i); - if (!pWinKey) continue; - SSessionKey winInfo = {0}; - getSessionHashKey(pWinKey, &winInfo); - tSimpleHashPut(pStDeleted, &winInfo, sizeof(SSessionKey), NULL, 0); - } -} - -// the allocated memory comes from outer function. -void initGroupResInfoFromArrayList(SGroupResInfo* pGroupResInfo, SArray* pArrayList) { - pGroupResInfo->pRows = pArrayList; - pGroupResInfo->index = 0; - pGroupResInfo->pBuf = NULL; -} - -void doBuildSessionResult(SOperatorInfo* pOperator, void* pState, SGroupResInfo* pGroupResInfo, - SSDataBlock* pBlock) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - // set output datablock version - pBlock->info.version = pTaskInfo->version; - - blockDataCleanup(pBlock); - if (!hasRemainResults(pGroupResInfo)) { - cleanupGroupResInfo(pGroupResInfo); - return; - } - - // clear the existed group id - pBlock->info.id.groupId = 0; - buildSessionResultDataBlock(pOperator, pState, pBlock, &pOperator->exprSupp, pGroupResInfo); - if (pBlock->info.rows == 0) { - cleanupGroupResInfo(pGroupResInfo); - } -} -void getMaxTsWins(const SArray* pAllWins, SArray* pMaxWins) { - int32_t size = taosArrayGetSize(pAllWins); - if (size == 0) { - return; - } - - SSessionKey* pSeKey = taosArrayGet(pAllWins, size - 1); - taosArrayPush(pMaxWins, pSeKey); - if (pSeKey->groupId == 0) { - return; - } - uint64_t preGpId = pSeKey->groupId; - for (int32_t i = size - 2; i >= 0; i--) { - pSeKey = taosArrayGet(pAllWins, i); - if (preGpId != pSeKey->groupId) { - taosArrayPush(pMaxWins, pSeKey); - preGpId = pSeKey->groupId; - } - } -} - -static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) { - SExprSupp* pSup = &pOperator->exprSupp; - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SOptrBasicInfo* pBInfo = &pInfo->binfo; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - qDebug("===stream=== stream session agg"); - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } else if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session"); - return pInfo->pDelRes; - } - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session"); - return pBInfo->pRes; - } - - setOperatorCompleted(pOperator); - return NULL; - } - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); - } - if (!pInfo->pStUpdated) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pStUpdated = tSimpleHashInit(64, hashFn); - } - while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - break; - } - printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "final session recv" : "single session recv"); - - if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); - // gap must be 0 - doDeleteTimeWindows(pAggSup, pBlock, pWins); - removeSessionResults(pInfo->pStUpdated, pWins); - if (IS_FINAL_OP(pInfo)) { - int32_t childIndex = getChildIndex(pBlock); - SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex); - SStreamSessionAggOperatorInfo* pChildInfo = pChildOp->info; - // gap must be 0 - doDeleteTimeWindows(&pChildInfo->streamAggSup, pBlock, NULL); - rebuildSessionWindow(pOperator, pWins, pInfo->pStUpdated); - } - copyDeleteWindowInfo(pWins, pInfo->pStDeleted); - taosArrayDestroy(pWins); - continue; - } else if (pBlock->info.type == STREAM_GET_ALL) { - getAllSessionWindow(pAggSup->pResultRows, pInfo->pStUpdated); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, pInfo->pStDeleted, IS_FINAL_OP(pInfo), true); - if (IS_FINAL_OP(pInfo)) { - int32_t chIndex = getChildIndex(pBlock); - int32_t size = taosArrayGetSize(pInfo->pChildren); - // if chIndex + 1 - size > 0, add new child - for (int32_t i = 0; i < chIndex + 1 - size; i++) { - SOperatorInfo* pChildOp = - createStreamFinalSessionAggOperatorInfo(NULL, pInfo->pPhyNode, pOperator->pTaskInfo, 0, NULL); - if (!pChildOp) { - T_LONG_JMP(pOperator->pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - taosArrayPush(pInfo->pChildren, &pChildOp); - } - SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, chIndex); - setInputDataBlock(&pChildOp->exprSupp, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamSessionAggImpl(pChildOp, pBlock, NULL, NULL, true, false); - } - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.watermark); - } - // restore the value - pOperator->status = OP_RES_TO_RETURN; - - closeSessionWindow(pAggSup->pResultRows, &pInfo->twAggSup, pInfo->pStUpdated); - closeChildSessionWindow(pInfo->pChildren, pInfo->twAggSup.maxTs); - copyUpdateResult(pInfo->pStUpdated, pInfo->pUpdated); - removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); - tSimpleHashCleanup(pInfo->pStUpdated); - pInfo->pStUpdated = NULL; - if(pInfo->isHistoryOp) { - getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); - } - initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - -#if 0 - char* pBuf = streamStateSessionDump(pAggSup->pState); - qDebug("===stream===final session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "final session" : "single session"); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo) ? "final session" : "single session"); - return pBInfo->pRes; - } - - setOperatorCompleted(pOperator); - return NULL; -} - -void streamSessionReleaseState(SOperatorInfo* pOperator) { - if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION) { - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); - pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_SESSION_OP_STATE_NAME, strlen(STREAM_SESSION_OP_STATE_NAME), pInfo->historyWins->pData, resSize); - } - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.releaseStreamStateFn) { - downstream->fpSet.releaseStreamStateFn(downstream); - } -} - -void resetWinRange(STimeWindow* winRange) { - winRange->skey = INT64_MIN; - winRange->ekey = INT64_MAX; -} - -void streamSessionReloadState(SOperatorInfo* pOperator) { - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - resetWinRange(&pAggSup->winRange); - - SResultWindowInfo winInfo = {0}; - int32_t size = 0; - void* pBuf = NULL; - int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_SESSION_OP_STATE_NAME, - strlen(STREAM_SESSION_OP_STATE_NAME), &pBuf, &size); - int32_t num = size / sizeof(SSessionKey); - SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; - ASSERT(size == num * sizeof(SSessionKey)); - if (!pInfo->pStUpdated && num > 0) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pStUpdated = tSimpleHashInit(64, hashFn); - } - for (int32_t i = 0; i < num; i++) { - SResultWindowInfo winInfo = {0}; - setSessionOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].win.ekey, pSeKeyBuf[i].groupId, &winInfo); - int32_t winNum = compactSessionWindow(pOperator, &winInfo, pInfo->pStUpdated, pInfo->pStDeleted, true); - if (winNum > 0) { - qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, winInfo.sessionWin.win.skey, winInfo.sessionWin.groupId); - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { - saveResult(winInfo, pInfo->pStUpdated); - } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - if (!isCloseWindow(&winInfo.sessionWin.win, &pInfo->twAggSup)) { - saveDeleteRes(pInfo->pStDeleted, winInfo.sessionWin); - } - SSessionKey key = {0}; - getSessionHashKey(&winInfo.sessionWin, &key); - tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &winInfo, sizeof(SResultWindowInfo)); - } - } - saveSessionOutputBuf(pAggSup, &winInfo); - } - taosMemoryFree(pBuf); - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.reloadStreamStateFn) { - downstream->fpSet.reloadStreamStateFn(downstream); - } -} - -SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { - SSessionWinodwPhysiNode* pSessionNode = (SSessionWinodwPhysiNode*)pPhyNode; - int32_t numOfCols = 0; - int32_t code = TSDB_CODE_OUT_OF_MEMORY; - SStreamSessionAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamSessionAggOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL) { - goto _error; - } - - pOperator->pTaskInfo = pTaskInfo; - - initResultSizeInfo(&pOperator->resultInfo, 4096); - if (pSessionNode->window.pExprs != NULL) { - int32_t numOfScalar = 0; - SExprInfo* pScalarExprInfo = createExprInfo(pSessionNode->window.pExprs, NULL, &numOfScalar); - code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - } - SExprSupp* pSup = &pOperator->exprSupp; - - SExprInfo* pExprInfo = createExprInfo(pSessionNode->window.pFuncs, NULL, &numOfCols); - SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); - code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, pSessionNode->gap, - pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - pInfo->twAggSup = (STimeWindowAggSupp){ - .waterMark = pSessionNode->window.watermark, - .calTrigger = pSessionNode->window.triggerType, - .maxTs = INT64_MIN, - .minTs = INT64_MAX, - }; - - initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - - pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId; - if (pSessionNode->window.pTsEnd) { - pInfo->endTsIndex = ((SColumnNode*)pSessionNode->window.pTsEnd)->slotId; - } - pInfo->binfo.pRes = pResBlock; - pInfo->order = TSDB_ORDER_ASC; - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pStDeleted = tSimpleHashInit(64, hashFn); - pInfo->pDelIterator = NULL; - pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - pInfo->pChildren = NULL; - pInfo->isFinal = false; - pInfo->pPhyNode = pPhyNode; - pInfo->ignoreExpiredData = pSessionNode->window.igExpired; - pInfo->ignoreExpiredDataSaved = false; - pInfo->pUpdated = NULL; - pInfo->pStUpdated = NULL; - pInfo->dataVersion = 0; - pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); - if (!pInfo->historyWins) { - goto _error; - } - if (pHandle) { - pInfo->isHistoryOp = pHandle->fillHistory; - } - - setOperatorInfo(pOperator, "StreamSessionWindowAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_SESSION, true, - OP_NOT_OPENED, pInfo, pTaskInfo); - pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionAgg, NULL, destroyStreamSessionAggOperatorInfo, - optrDefaultBufFn, NULL); - setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); - - if (downstream) { - initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); - code = appendDownstream(pOperator, &downstream, 1); - } - return pOperator; - -_error: - if (pInfo != NULL) { - destroyStreamSessionAggOperatorInfo(pInfo); - } - - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} - -static void clearStreamSessionOperator(SStreamSessionAggOperatorInfo* pInfo) { - tSimpleHashClear(pInfo->streamAggSup.pResultRows); - pInfo->streamAggSup.stateStore.streamStateSessionClear(pInfo->streamAggSup.pState); -} - -static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) { - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - SOptrBasicInfo* pBInfo = &pInfo->binfo; - TSKEY maxTs = INT64_MIN; - SExprSupp* pSup = &pOperator->exprSupp; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - - qDebug("===stream=== stream session semi agg"); - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } - - { - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "semi session"); - return pBInfo->pRes; - } - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "semi session delete"); - return pInfo->pDelRes; - } - - if (pOperator->status == OP_RES_TO_RETURN) { - clearFunctionContext(&pOperator->exprSupp); - // semi interval operator clear disk buffer - clearStreamSessionOperator(pInfo); - setOperatorCompleted(pOperator); - return NULL; - } - } - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); - } - if (!pInfo->pStUpdated) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pStUpdated = tSimpleHashInit(64, hashFn); - } - while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - clearSpecialDataBlock(pInfo->pUpdateRes); - pOperator->status = OP_RES_TO_RETURN; - break; - } - printDataBlock(pBlock, "semi session recv"); - - if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - // gap must be 0 - SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); - doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins); - removeSessionResults(pInfo->pStUpdated, pWins); - copyDeleteWindowInfo(pWins, pInfo->pStDeleted); - taosArrayDestroy(pWins); - break; - } else if (pBlock->info.type == STREAM_GET_ALL) { - getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pStUpdated); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamSessionAggImpl(pOperator, pBlock, pInfo->pStUpdated, NULL, false, false); - maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - } - - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); - pBInfo->pRes->info.watermark = pInfo->twAggSup.maxTs; - - copyUpdateResult(pInfo->pStUpdated, pInfo->pUpdated); - removeSessionResults(pInfo->pStDeleted, pInfo->pUpdated); - tSimpleHashCleanup(pInfo->pStUpdated); - pInfo->pStUpdated = NULL; - initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity); - -#if 0 - char* pBuf = streamStateSessionDump(pAggSup->pState); - qDebug("===stream===semi session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildSessionResult(pOperator, pAggSup->pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "semi session"); - return pBInfo->pRes; - } - - doBuildDeleteDataBlock(pOperator, pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "semi session delete"); - return pInfo->pDelRes; - } - - clearFunctionContext(&pOperator->exprSupp); - // semi interval operator clear disk buffer - clearStreamSessionOperator(pInfo); - setOperatorCompleted(pOperator); - return NULL; -} - -SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, int32_t numOfChild, SReadHandle* pHandle) { - int32_t code = TSDB_CODE_OUT_OF_MEMORY; - SOperatorInfo* pOperator = createStreamSessionAggOperatorInfo(downstream, pPhyNode, pTaskInfo, pHandle); - if (pOperator == NULL) { - goto _error; - } - - SStorageAPI* pAPI = &pTaskInfo->storageAPI; - SStreamSessionAggOperatorInfo* pInfo = pOperator->info; - - pInfo->isFinal = (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION); - char* name = (pInfo->isFinal) ? "StreamSessionFinalAggOperator" : "StreamSessionSemiAggOperator"; - - if (pPhyNode->type != QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION) { - pInfo->pUpdateRes = createSpecialDataBlock(STREAM_CLEAR); - blockDataEnsureCapacity(pInfo->pUpdateRes, 128); - pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamSessionSemiAgg, NULL, - destroyStreamSessionAggOperatorInfo, optrDefaultBufFn, NULL); - } - setOperatorStreamStateFn(pOperator, streamSessionReleaseState, streamSessionReloadState); - setOperatorInfo(pOperator, name, pPhyNode->type, false, OP_NOT_OPENED, pInfo, pTaskInfo); - - pOperator->operatorType = pPhyNode->type; - if (numOfChild > 0) { - pInfo->pChildren = taosArrayInit(numOfChild, sizeof(void*)); - for (int32_t i = 0; i < numOfChild; i++) { - SOperatorInfo* pChildOp = createStreamFinalSessionAggOperatorInfo(NULL, pPhyNode, pTaskInfo, 0, NULL); - if (pChildOp == NULL) { - goto _error; - } - SStreamSessionAggOperatorInfo* pChInfo = pChildOp->info; - pChInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - pAPI->stateStore.streamStateSetNumber(pChInfo->streamAggSup.pState, i); - taosArrayPush(pInfo->pChildren, &pChildOp); - } - } - - if (!IS_FINAL_OP(pInfo) || numOfChild == 0) { - pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE; - } - - return pOperator; - -_error: - if (pInfo != NULL) { - destroyStreamSessionAggOperatorInfo(pInfo); - } - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} - -void destroyStreamStateOperatorInfo(void* param) { - SStreamStateAggOperatorInfo* pInfo = (SStreamStateAggOperatorInfo*)param; - cleanupBasicInfo(&pInfo->binfo); - destroyStreamAggSupporter(&pInfo->streamAggSup); - cleanupGroupResInfo(&pInfo->groupResInfo); - if (pInfo->pChildren != NULL) { - int32_t size = taosArrayGetSize(pInfo->pChildren); - for (int32_t i = 0; i < size; i++) { - SOperatorInfo* pChild = taosArrayGetP(pInfo->pChildren, i); - destroyOperator(pChild); - } - taosArrayDestroy(pInfo->pChildren); - } - colDataDestroy(&pInfo->twAggSup.timeWindowData); - blockDataDestroy(pInfo->pDelRes); - taosArrayDestroy(pInfo->historyWins); - tSimpleHashCleanup(pInfo->pSeUpdated); - tSimpleHashCleanup(pInfo->pSeDeleted); - taosMemoryFreeClear(param); -} - -bool isTsInWindow(SStateWindowInfo* pWin, TSKEY ts) { - if (pWin->winInfo.sessionWin.win.skey <= ts && ts <= pWin->winInfo.sessionWin.win.ekey) { - return true; - } - return false; -} - -bool isEqualStateKey(SStateWindowInfo* pWin, char* pKeyData) { - return pKeyData && compareVal(pKeyData, pWin->pStateKey); -} - -bool compareStateKey(void* data, void* key) { - if (!data || !key) { - return true; - } - SStateKeys* stateKey = (SStateKeys*)key; - stateKey->pData = (char*)key + sizeof(SStateKeys); - return compareVal(data, stateKey); -} - -bool compareWinStateKey(SStateKeys* left, SStateKeys* right) { - if (!left || !right) { - return false; - } - return compareVal(left->pData, right); -} - -void setStateOutputBuf(SStreamAggSupporter* pAggSup, TSKEY ts, uint64_t groupId, char* pKeyData, - SStateWindowInfo* pCurWin, SStateWindowInfo* pNextWin) { - int32_t size = pAggSup->resultRowSize; - pCurWin->winInfo.sessionWin.groupId = groupId; - pCurWin->winInfo.sessionWin.win.skey = ts; - pCurWin->winInfo.sessionWin.win.ekey = ts; - int32_t code = - pAggSup->stateStore.streamStateStateAddIfNotExist(pAggSup->pState, &pCurWin->winInfo.sessionWin, pKeyData, pAggSup->stateKeySize, - compareStateKey, &pCurWin->winInfo.pOutputBuf, &size); - pCurWin->pStateKey = - (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); - pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); - pCurWin->pStateKey->type = pAggSup->stateKeyType; - pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); - pCurWin->pStateKey->isNull = false; - - if (code == TSDB_CODE_SUCCESS && !inWinRange(&pAggSup->winRange, &pCurWin->winInfo.sessionWin.win)) { - code = TSDB_CODE_FAILED; - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)pCurWin->winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); - pCurWin->winInfo.pOutputBuf = taosMemoryCalloc(1, size); - pCurWin->pStateKey = - (SStateKeys*)((char*)pCurWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); - pCurWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); - pCurWin->pStateKey->type = pAggSup->stateKeyType; - pCurWin->pStateKey->pData = (char*)pCurWin->pStateKey + sizeof(SStateKeys); - pCurWin->pStateKey->isNull = false; - pCurWin->winInfo.sessionWin.groupId = groupId; - pCurWin->winInfo.sessionWin.win.skey = ts; - pCurWin->winInfo.sessionWin.win.ekey = ts; - qDebug("===stream===reset state win key. skey:%" PRId64 ", endkey:%" PRId64, pCurWin->winInfo.sessionWin.win.skey, pCurWin->winInfo.sessionWin.win.ekey); - } - - if (code == TSDB_CODE_SUCCESS) { - pCurWin->winInfo.isOutput = true; - pAggSup->stateStore.streamStateSessionDel(pAggSup->pState, &pCurWin->winInfo.sessionWin); - } else if (pKeyData) { - if (IS_VAR_DATA_TYPE(pAggSup->stateKeyType)) { - varDataCopy(pCurWin->pStateKey->pData, pKeyData); - } else { - memcpy(pCurWin->pStateKey->pData, pKeyData, pCurWin->pStateKey->bytes); - } - } - - pNextWin->winInfo.sessionWin = pCurWin->winInfo.sessionWin; - SStreamStateCur* pCur = pAggSup->stateStore.streamStateSessionSeekKeyNext(pAggSup->pState, &pNextWin->winInfo.sessionWin); - int32_t nextSize = pAggSup->resultRowSize; - code = pAggSup->stateStore.streamStateSessionGetKVByCur(pCur, &pNextWin->winInfo.sessionWin, &pNextWin->winInfo.pOutputBuf, &nextSize); - if (code != TSDB_CODE_SUCCESS) { - SET_SESSION_WIN_INVALID(pNextWin->winInfo); - } else { - pNextWin->pStateKey = - (SStateKeys*)((char*)pNextWin->winInfo.pOutputBuf + (pAggSup->resultRowSize - pAggSup->stateKeySize)); - pNextWin->pStateKey->bytes = pAggSup->stateKeySize - sizeof(SStateKeys); - pNextWin->pStateKey->type = pAggSup->stateKeyType; - pNextWin->pStateKey->pData = (char*)pNextWin->pStateKey + sizeof(SStateKeys); - pNextWin->pStateKey->isNull = false; - pNextWin->winInfo.isOutput = true; - } - pAggSup->stateStore.streamStateFreeCur(pCur); -} - -int32_t updateStateWindowInfo(SStateWindowInfo* pWinInfo, SStateWindowInfo* pNextWin, TSKEY* pTs, uint64_t groupId, - SColumnInfoData* pKeyCol, int32_t rows, int32_t start, bool* allEqual, - SSHashObj* pResultRows, SSHashObj* pSeUpdated, SSHashObj* pSeDeleted) { - *allEqual = true; - for (int32_t i = start; i < rows; ++i) { - char* pKeyData = colDataGetData(pKeyCol, i); - if (!isTsInWindow(pWinInfo, pTs[i])) { - if (isEqualStateKey(pWinInfo, pKeyData)) { - if (IS_VALID_SESSION_WIN(pNextWin->winInfo)) { - // ts belongs to the next window - if (pTs[i] >= pNextWin->winInfo.sessionWin.win.skey) { - return i - start; - } - } - } else { - return i - start; - } - } - - if (pWinInfo->winInfo.sessionWin.win.skey > pTs[i]) { - if (pSeDeleted && pWinInfo->winInfo.isOutput) { - saveDeleteRes(pSeDeleted, pWinInfo->winInfo.sessionWin); - } - removeSessionResult(pSeUpdated, pResultRows, pWinInfo->winInfo.sessionWin); - pWinInfo->winInfo.sessionWin.win.skey = pTs[i]; - } - pWinInfo->winInfo.sessionWin.win.ekey = TMAX(pWinInfo->winInfo.sessionWin.win.ekey, pTs[i]); - if (!isEqualStateKey(pWinInfo, pKeyData)) { - *allEqual = false; - } - } - return rows - start; -} - -static void doStreamStateAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SSHashObj* pSeUpdated, - SSHashObj* pStDeleted) { - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - uint64_t groupId = pSDataBlock->info.id.groupId; - int64_t code = TSDB_CODE_SUCCESS; - TSKEY* tsCols = NULL; - SResultRow* pResult = NULL; - int32_t winRows = 0; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - - pInfo->dataVersion = TMAX(pInfo->dataVersion, pSDataBlock->info.version); - pAggSup->winRange = pTaskInfo->streamInfo.fillHistoryWindow; - if (pAggSup->winRange.ekey <= 0) { - pAggSup->winRange.ekey = INT64_MAX; - } - - if (pSDataBlock->pDataBlock != NULL) { - SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex); - tsCols = (int64_t*)pColDataInfo->pData; - } else { - return; - } - - int32_t rows = pSDataBlock->info.rows; - blockDataEnsureCapacity(pAggSup->pScanBlock, rows); - SColumnInfoData* pKeyColInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->stateCol.slotId); - for (int32_t i = 0; i < rows; i += winRows) { - if (pInfo->ignoreExpiredData && isOverdue(tsCols[i], &pInfo->twAggSup) || colDataIsNull_s(pKeyColInfo, i)) { - i++; - continue; - } - char* pKeyData = colDataGetData(pKeyColInfo, i); - int32_t winIndex = 0; - bool allEqual = true; - SStateWindowInfo curWin = {0}; - SStateWindowInfo nextWin = {0}; - setStateOutputBuf(pAggSup, tsCols[i], groupId, pKeyData, &curWin, &nextWin); - if (IS_VALID_SESSION_WIN(nextWin.winInfo)) { - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextWin.winInfo.pOutputBuf, &pAPI->stateStore); - } - setSessionWinOutputInfo(pSeUpdated, &curWin.winInfo); - winRows = updateStateWindowInfo(&curWin, &nextWin, tsCols, groupId, pKeyColInfo, rows, i, &allEqual, - pAggSup->pResultRows, pSeUpdated, pStDeleted); - if (!allEqual) { - uint64_t uid = 0; - appendOneRowToStreamSpecialBlock(pAggSup->pScanBlock, &curWin.winInfo.sessionWin.win.skey, - &curWin.winInfo.sessionWin.win.ekey, &uid, &groupId, NULL); - tSimpleHashRemove(pSeUpdated, &curWin.winInfo.sessionWin, sizeof(SSessionKey)); - doDeleteSessionWindow(pAggSup, &curWin.winInfo.sessionWin); - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)curWin.winInfo.pOutputBuf, &pAPI->stateStore); - continue; - } - code = doOneWindowAggImpl(&pInfo->twAggSup.timeWindowData, &curWin.winInfo, &pResult, i, winRows, rows, numOfOutput, - pOperator, 0); - if (code != TSDB_CODE_SUCCESS || pResult == NULL) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - saveSessionOutputBuf(pAggSup, &curWin.winInfo); - - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { - code = saveResult(curWin.winInfo, pSeUpdated); - if (code != TSDB_CODE_SUCCESS) { - T_LONG_JMP(pTaskInfo->env, TSDB_CODE_OUT_OF_MEMORY); - } - } - - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - SSessionKey key = {0}; - getSessionHashKey(&curWin.winInfo.sessionWin, &key); - tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curWin.winInfo, sizeof(SResultWindowInfo)); - } - } -} - -static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) { - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } - - SExprSupp* pSup = &pOperator->exprSupp; - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - SOptrBasicInfo* pBInfo = &pInfo->binfo; - qDebug("===stream=== stream state agg"); - if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single state delete"); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "single state"); - return pBInfo->pRes; - } - - setOperatorCompleted(pOperator); - return NULL; - } - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(16, sizeof(SSessionKey)); - } - if (!pInfo->pSeUpdated) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pSeUpdated = tSimpleHashInit(64, hashFn); - } - while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - break; - } - printDataBlock(pBlock, "single state recv"); - - if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - SArray* pWins = taosArrayInit(16, sizeof(SSessionKey)); - doDeleteTimeWindows(&pInfo->streamAggSup, pBlock, pWins); - removeSessionResults(pInfo->pSeUpdated, pWins); - copyDeleteWindowInfo(pWins, pInfo->pSeDeleted); - taosArrayDestroy(pWins); - continue; - } else if (pBlock->info.type == STREAM_GET_ALL) { - getAllSessionWindow(pInfo->streamAggSup.pResultRows, pInfo->pSeUpdated); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - doStreamStateAggImpl(pOperator, pBlock, pInfo->pSeUpdated, pInfo->pSeDeleted); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - } - // restore the value - pOperator->status = OP_RES_TO_RETURN; - - closeSessionWindow(pInfo->streamAggSup.pResultRows, &pInfo->twAggSup, pInfo->pSeUpdated); - copyUpdateResult(pInfo->pSeUpdated, pInfo->pUpdated); - removeSessionResults(pInfo->pSeDeleted, pInfo->pUpdated); - tSimpleHashCleanup(pInfo->pSeUpdated); - pInfo->pSeUpdated = NULL; - - if(pInfo->isHistoryOp) { - getMaxTsWins(pInfo->pUpdated, pInfo->historyWins); - } - - initGroupResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - -#if 0 - char* pBuf = streamStateSessionDump(pInfo->streamAggSup.pState); - qDebug("===stream===final session%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildDeleteDataBlock(pOperator, pInfo->pSeDeleted, pInfo->pDelRes, &pInfo->pDelIterator); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single state delete"); - return pInfo->pDelRes; - } - - doBuildSessionResult(pOperator, pInfo->streamAggSup.pState, &pInfo->groupResInfo, pBInfo->pRes); - if (pBInfo->pRes->info.rows > 0) { - printDataBlock(pBInfo->pRes, "single state"); - return pBInfo->pRes; - } - setOperatorCompleted(pOperator); - return NULL; -} - -void streamStateReleaseState(SOperatorInfo* pOperator) { - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - int32_t resSize = taosArrayGetSize(pInfo->historyWins) * sizeof(SSessionKey); - qDebug("===stream=== relase state. save result count:%d", (int32_t)taosArrayGetSize(pInfo->historyWins)); - pInfo->streamAggSup.stateStore.streamStateSaveInfo(pInfo->streamAggSup.pState, STREAM_STATE_OP_STATE_NAME, strlen(STREAM_STATE_OP_STATE_NAME), pInfo->historyWins->pData, resSize); - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.releaseStreamStateFn) { - downstream->fpSet.releaseStreamStateFn(downstream); - } -} - -static void compactStateWindow(SOperatorInfo* pOperator, SResultWindowInfo* pCurWin, SResultWindowInfo* pNextWin, - SSHashObj* pStUpdated, SSHashObj* pStDeleted) { - SExprSupp* pSup = &pOperator->exprSupp; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - SResultRow* pCurResult = NULL; - int32_t numOfOutput = pOperator->exprSupp.numOfExprs; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - initSessionOutputBuf(pCurWin, &pCurResult, pSup->pCtx, numOfOutput, pSup->rowEntryInfoOffset); - SResultRow* pWinResult = NULL; - initSessionOutputBuf(pNextWin, &pWinResult, pAggSup->pDummyCtx, numOfOutput, pSup->rowEntryInfoOffset); - pCurWin->sessionWin.win.ekey = TMAX(pCurWin->sessionWin.win.ekey, pNextWin->sessionWin.win.ekey); - - updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pCurWin->sessionWin.win, 1); - compactFunctions(pSup->pCtx, pAggSup->pDummyCtx, numOfOutput, pTaskInfo, &pInfo->twAggSup.timeWindowData); - tSimpleHashRemove(pStUpdated, &pNextWin->sessionWin, sizeof(SSessionKey)); - if (pNextWin->isOutput && pStDeleted) { - qDebug("===stream=== save delete window info %" PRId64 ", %" PRIu64, pNextWin->sessionWin.win.skey, pNextWin->sessionWin.groupId); - saveDeleteRes(pStDeleted, pNextWin->sessionWin); - } - removeSessionResult(pStUpdated, pAggSup->pResultRows, pNextWin->sessionWin); - doDeleteSessionWindow(pAggSup, &pNextWin->sessionWin); - taosMemoryFree(pNextWin->pOutputBuf); -} - -void streamStateReloadState(SOperatorInfo* pOperator) { - SStreamStateAggOperatorInfo* pInfo = pOperator->info; - SStreamAggSupporter* pAggSup = &pInfo->streamAggSup; - resetWinRange(&pAggSup->winRange); - - SSessionKey seKey = {.win.skey = INT64_MIN, .win.ekey = INT64_MIN, .groupId = 0}; - int32_t size = 0; - void* pBuf = NULL; - int32_t code = pAggSup->stateStore.streamStateGetInfo(pAggSup->pState, STREAM_STATE_OP_STATE_NAME, - strlen(STREAM_STATE_OP_STATE_NAME), &pBuf, &size); - int32_t num = size / sizeof(SSessionKey); - qDebug("===stream=== reload state. get result count:%d", num); - SSessionKey* pSeKeyBuf = (SSessionKey*) pBuf; - ASSERT(size == num * sizeof(SSessionKey)); - if (!pInfo->pSeUpdated && num > 0) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pSeUpdated = tSimpleHashInit(64, hashFn); - } - if (!pInfo->pSeDeleted && num > 0) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pSeDeleted = tSimpleHashInit(64, hashFn); - } - for (int32_t i = 0; i < num; i++) { - SStateWindowInfo curInfo = {0}; - SStateWindowInfo nextInfo = {0}; - SStateWindowInfo dummy = {0}; - qDebug("===stream=== reload state. try process result %" PRId64 ", %" PRIu64 ", index:%d", pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, i); - setStateOutputBuf(pAggSup, pSeKeyBuf[i].win.skey, pSeKeyBuf[i].groupId, NULL, &curInfo, &nextInfo); - bool cpRes = compareWinStateKey(curInfo.pStateKey,nextInfo.pStateKey); - qDebug("===stream=== reload state. next window info %" PRId64 ", %" PRIu64 ", compare:%d", nextInfo.winInfo.sessionWin.win.skey, nextInfo.winInfo.sessionWin.groupId, cpRes); - if (cpRes) { - compactStateWindow(pOperator, &curInfo.winInfo, &nextInfo.winInfo, pInfo->pSeUpdated, pInfo->pSeDeleted); - qDebug("===stream=== reload state. save result %" PRId64 ", %" PRIu64, curInfo.winInfo.sessionWin.win.skey, curInfo.winInfo.sessionWin.groupId); - if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE) { - saveResult(curInfo.winInfo, pInfo->pSeUpdated); - } else if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) { - if (!isCloseWindow(&curInfo.winInfo.sessionWin.win, &pInfo->twAggSup)) { - saveDeleteRes(pInfo->pSeDeleted, curInfo.winInfo.sessionWin); - } - SSessionKey key = {0}; - getSessionHashKey(&curInfo.winInfo.sessionWin, &key); - tSimpleHashPut(pAggSup->pResultRows, &key, sizeof(SSessionKey), &curInfo.winInfo, sizeof(SResultWindowInfo)); - } - } else if (IS_VALID_SESSION_WIN(nextInfo.winInfo)) { - releaseOutputBuf(pAggSup->pState, NULL, (SResultRow*)nextInfo.winInfo.pOutputBuf, &pAggSup->pSessionAPI->stateStore); - } - - if (IS_VALID_SESSION_WIN(curInfo.winInfo)) { - saveSessionOutputBuf(pAggSup, &curInfo.winInfo); - } - } - taosMemoryFree(pBuf); - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - if (downstream->fpSet.reloadStreamStateFn) { - downstream->fpSet.reloadStreamStateFn(downstream); - } -} - -SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo, SReadHandle* pHandle) { - SStreamStateWinodwPhysiNode* pStateNode = (SStreamStateWinodwPhysiNode*)pPhyNode; - int32_t tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId; - SColumnNode* pColNode = (SColumnNode*)(pStateNode->pStateKey); - int32_t code = TSDB_CODE_SUCCESS; - - SStreamStateAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamStateAggOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - goto _error; - } - - pInfo->stateCol = extractColumnFromColumnNode(pColNode); - initResultSizeInfo(&pOperator->resultInfo, 4096); - if (pStateNode->window.pExprs != NULL) { - int32_t numOfScalar = 0; - SExprInfo* pScalarExprInfo = createExprInfo(pStateNode->window.pExprs, NULL, &numOfScalar); - code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - } - - pInfo->twAggSup = (STimeWindowAggSupp){ - .waterMark = pStateNode->window.watermark, - .calTrigger = pStateNode->window.triggerType, - .maxTs = INT64_MIN, - .minTs = INT64_MAX, - }; - - initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - - SExprSupp* pSup = &pOperator->exprSupp; - int32_t numOfCols = 0; - SExprInfo* pExprInfo = createExprInfo(pStateNode->window.pFuncs, NULL, &numOfCols); - SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); - code = initBasicInfoEx(&pInfo->binfo, pSup, pExprInfo, numOfCols, pResBlock, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - int32_t keySize = sizeof(SStateKeys) + pColNode->node.resType.bytes; - int16_t type = pColNode->node.resType.type; - code = initStreamAggSupporter(&pInfo->streamAggSup, pSup->pCtx, numOfCols, 0, pTaskInfo->streamInfo.pState, keySize, - type, &pTaskInfo->storageAPI.stateStore, pHandle, &pTaskInfo->storageAPI); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - pInfo->primaryTsIndex = tsSlotId; - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pSeDeleted = tSimpleHashInit(64, hashFn); - pInfo->pDelIterator = NULL; - pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - pInfo->pChildren = NULL; - pInfo->ignoreExpiredData = pStateNode->window.igExpired; - pInfo->ignoreExpiredDataSaved = false; - pInfo->pUpdated = NULL; - pInfo->pSeUpdated = NULL; - pInfo->dataVersion = 0; - pInfo->historyWins = taosArrayInit(4, sizeof(SSessionKey)); - if (!pInfo->historyWins) { - goto _error; - } - if (pHandle) { - pInfo->isHistoryOp = pHandle->fillHistory; - } - - setOperatorInfo(pOperator, "StreamStateAggOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE, true, OP_NOT_OPENED, - pInfo, pTaskInfo); - pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamStateAgg, NULL, destroyStreamStateOperatorInfo, - optrDefaultBufFn, NULL); - setOperatorStreamStateFn(pOperator, streamStateReleaseState, streamStateReloadState); - initDownStream(downstream, &pInfo->streamAggSup, pOperator->operatorType, pInfo->primaryTsIndex, &pInfo->twAggSup); - code = appendDownstream(pOperator, &downstream, 1); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - return pOperator; - -_error: - destroyStreamStateOperatorInfo(pInfo); - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} - -void destroyMAIOperatorInfo(void* param) { - SMergeAlignedIntervalAggOperatorInfo* miaInfo = (SMergeAlignedIntervalAggOperatorInfo*)param; - destroyIntervalOperatorInfo(miaInfo->intervalAggOperatorInfo); - taosMemoryFreeClear(param); -} - -static SResultRow* doSetSingleOutputTupleBuf(SResultRowInfo* pResultRowInfo, SAggSupporter* pSup) { - SResultRow* pResult = getNewResultRow(pSup->pResultBuf, &pSup->currentPageId, pSup->resultRowSize); - if (NULL == pResult) { - return pResult; - } - pResultRowInfo->cur = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset}; - return pResult; -} - -static int32_t setSingleOutputTupleBuf(SResultRowInfo* pResultRowInfo, STimeWindow* win, SResultRow** pResult, - SExprSupp* pExprSup, SAggSupporter* pAggSup) { - if (*pResult == NULL) { - *pResult = doSetSingleOutputTupleBuf(pResultRowInfo, pAggSup); - if (*pResult == NULL) { - return terrno; - } - } - - // set time window for current result - (*pResult)->win = (*win); - setResultRowInitCtx((*pResult), pExprSup->pCtx, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset); - return TSDB_CODE_SUCCESS; -} - -static void doMergeAlignedIntervalAggImpl(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, - SSDataBlock* pBlock, SSDataBlock* pResultBlock) { - SMergeAlignedIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info; - SIntervalAggOperatorInfo* iaInfo = miaInfo->intervalAggOperatorInfo; - - SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo; - SExprSupp* pSup = &pOperatorInfo->exprSupp; - SInterval* pInterval = &iaInfo->interval; - - int32_t startPos = 0; - int64_t* tsCols = extractTsCol(pBlock, iaInfo); - - TSKEY ts = getStartTsKey(&pBlock->info.window, tsCols); + TSKEY ts = getStartTsKey(&pBlock->info.window, tsCols); // there is an result exists if (miaInfo->curTs != INT64_MIN) { @@ -5196,263 +2189,3 @@ _error: pTaskInfo->code = code; return NULL; } - -static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { - SStreamIntervalOperatorInfo* pInfo = pOperator->info; - SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - SExprSupp* pSup = &pOperator->exprSupp; - - if (pOperator->status == OP_EXEC_DONE) { - return NULL; - } - - if (pOperator->status == OP_RES_TO_RETURN) { - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval delete"); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows > 0) { - printDataBlock(pInfo->binfo.pRes, "single interval"); - return pInfo->binfo.pRes; - } - - if (pInfo->recvGetAll) { - pInfo->recvGetAll = false; - resetUnCloseWinInfo(pInfo->aggSup.pResultRowHashTable); - } - - setOperatorCompleted(pOperator); - if (pInfo->twAggSup.maxTs > 0 && - pInfo->twAggSup.maxTs - pInfo->twAggSup.checkPointInterval > pInfo->twAggSup.checkPointTs) { - pAPI->stateStore.streamStateCommit(pInfo->pState); - pAPI->stateStore.streamStateDeleteCheckPoint(pInfo->pState, pInfo->twAggSup.maxTs - pInfo->twAggSup.deleteMark); - setStreamDataVersion(pTaskInfo, pInfo->dataVersion, pInfo->pState->checkPointId); - pInfo->twAggSup.checkPointTs = pInfo->twAggSup.maxTs; - } - return NULL; - } - - SOperatorInfo* downstream = pOperator->pDownstream[0]; - - if (!pInfo->pUpdated) { - pInfo->pUpdated = taosArrayInit(4096, POINTER_BYTES); - } - - if (!pInfo->pUpdatedMap) { - _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); - pInfo->pUpdatedMap = tSimpleHashInit(4096, hashFn); - } - - while (1) { - SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); - if (pBlock == NULL) { - qDebug("===stream===return data:single interval. recv datablock num:%" PRIu64, pInfo->numOfDatapack); - pInfo->numOfDatapack = 0; - break; - } - - pInfo->numOfDatapack++; - printDataBlock(pBlock, "single interval recv"); - - if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT || - pBlock->info.type == STREAM_CLEAR) { - doDeleteWindows(pOperator, &pInfo->interval, pBlock, pInfo->pDelWins, pInfo->pUpdatedMap); - continue; - } else if (pBlock->info.type == STREAM_GET_ALL) { - qDebug("===stream===single interval recv|block type STREAM_GET_ALL"); - pInfo->recvGetAll = true; - getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap); - continue; - } else if (pBlock->info.type == STREAM_CREATE_CHILD_TABLE) { - printDataBlock(pBlock, "single interval"); - return pBlock; - } else { - ASSERTS(pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_INVALID, "invalid SSDataBlock type"); - } - - if (pBlock->info.type == STREAM_NORMAL && pBlock->info.version != 0) { - // set input version - pTaskInfo->version = pBlock->info.version; - } - - if (pInfo->scalarSupp.pExprInfo != NULL) { - SExprSupp* pExprSup = &pInfo->scalarSupp; - projectApplyFunctions(pExprSup->pExprInfo, pBlock, pBlock, pExprSup->pCtx, pExprSup->numOfExprs, NULL); - } - - // The timewindow that overlaps the timestamps of the input pBlock need to be recalculated and return to the - // caller. Note that all the time window are not close till now. - // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pSup, pBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); - if (pInfo->invertible) { - setInverFunction(pSup->pCtx, pOperator->exprSupp.numOfExprs, pBlock->info.type); - } - - doStreamIntervalAggImpl(pOperator, pBlock, pBlock->info.id.groupId, pInfo->pUpdatedMap); - pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey); - pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, pBlock->info.window.skey); - } - pOperator->status = OP_RES_TO_RETURN; - removeDeleteResults(pInfo->pUpdatedMap, pInfo->pDelWins); - closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, - pInfo->pUpdatedMap, pInfo->pDelWins, pOperator); - - void* pIte = NULL; - int32_t iter = 0; - while ((pIte = tSimpleHashIterate(pInfo->pUpdatedMap, pIte, &iter)) != NULL) { - taosArrayPush(pInfo->pUpdated, pIte); - } - taosArraySort(pInfo->pUpdated, winPosCmprImpl); - - initMultiResInfoFromArrayList(&pInfo->groupResInfo, pInfo->pUpdated); - pInfo->pUpdated = NULL; - blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - tSimpleHashCleanup(pInfo->pUpdatedMap); - pInfo->pUpdatedMap = NULL; - -#if 0 - char* pBuf = streamStateIntervalDump(pInfo->pState); - qDebug("===stream===interval state%s", pBuf); - taosMemoryFree(pBuf); -#endif - - doBuildDeleteResult(pInfo, pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); - if (pInfo->pDelRes->info.rows > 0) { - printDataBlock(pInfo->pDelRes, "single interval delete"); - return pInfo->pDelRes; - } - - doBuildStreamIntervalResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); - if (pInfo->binfo.pRes->info.rows > 0) { - printDataBlock(pInfo->binfo.pRes, "single interval"); - return pInfo->binfo.pRes; - } - - return NULL; -} - -SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, - SExecTaskInfo* pTaskInfo) { - SStreamIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamIntervalOperatorInfo)); - SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); - if (pInfo == NULL || pOperator == NULL) { - goto _error; - } - SStreamIntervalPhysiNode* pIntervalPhyNode = (SStreamIntervalPhysiNode*)pPhyNode; - - int32_t code = TSDB_CODE_SUCCESS; - int32_t numOfCols = 0; - SExprInfo* pExprInfo = createExprInfo(pIntervalPhyNode->window.pFuncs, NULL, &numOfCols); - - SSDataBlock* pResBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc); - pInfo->interval = (SInterval){ - .interval = pIntervalPhyNode->interval, - .sliding = pIntervalPhyNode->sliding, - .intervalUnit = pIntervalPhyNode->intervalUnit, - .slidingUnit = pIntervalPhyNode->slidingUnit, - .offset = pIntervalPhyNode->offset, - .precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision, - }; - - pInfo->twAggSup = (STimeWindowAggSupp){ - .waterMark = pIntervalPhyNode->window.watermark, - .calTrigger = pIntervalPhyNode->window.triggerType, - .maxTs = INT64_MIN, - .minTs = INT64_MAX, - .deleteMark = getDeleteMark(pIntervalPhyNode), - .checkPointTs = 0, - .checkPointInterval = - convertTimePrecision(tsCheckpointInterval, TSDB_TIME_PRECISION_MILLI, pInfo->interval.precision), - }; - - ASSERTS(pInfo->twAggSup.calTrigger != STREAM_TRIGGER_MAX_DELAY, "trigger type should not be max delay"); - - pOperator->pTaskInfo = pTaskInfo; - SStorageAPI* pAPI = &pOperator->pTaskInfo->storageAPI; - - pInfo->ignoreExpiredData = pIntervalPhyNode->window.igExpired; - pInfo->ignoreExpiredDataSaved = false; - pInfo->isFinal = false; - - SExprSupp* pSup = &pOperator->exprSupp; - initBasicInfo(&pInfo->binfo, pResBlock); - initStreamFunciton(pSup->pCtx, pSup->numOfExprs); - initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - - pInfo->primaryTsIndex = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->slotId; - initResultSizeInfo(&pOperator->resultInfo, 4096); - - pInfo->pState = taosMemoryCalloc(1, sizeof(SStreamState)); - *(pInfo->pState) = *(pTaskInfo->streamInfo.pState); - pAPI->stateStore.streamStateSetNumber(pInfo->pState, -1); - - size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; - code = initAggSup(pSup, &pInfo->aggSup, pExprInfo, numOfCols, keyBufSize, pTaskInfo->id.str, - pInfo->pState, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - if (pIntervalPhyNode->window.pExprs != NULL) { - int32_t numOfScalar = 0; - SExprInfo* pScalarExprInfo = createExprInfo(pIntervalPhyNode->window.pExprs, NULL, &numOfScalar); - code = initExprSupp(&pInfo->scalarSupp, pScalarExprInfo, numOfScalar, &pTaskInfo->storageAPI.functionStore); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - } - - pInfo->invertible = allInvertible(pSup->pCtx, numOfCols); - pInfo->invertible = false; - pInfo->pDelWins = taosArrayInit(4, sizeof(SWinKey)); - pInfo->delIndex = 0; - pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - initResultRowInfo(&pInfo->binfo.resultRowInfo); - - pInfo->pPhyNode = NULL; // create new child - pInfo->pPullDataMap = NULL; - pInfo->pFinalPullDataMap = NULL; - pInfo->pPullWins = NULL; // SPullWindowInfo - pInfo->pullIndex = 0; - pInfo->pPullDataRes = NULL; - pInfo->isFinal = false; - pInfo->numOfChild = 0; - pInfo->delKey.ts = INT64_MAX; - pInfo->delKey.groupId = 0; - pInfo->numOfDatapack = 0; - pInfo->pUpdated = NULL; - pInfo->pUpdatedMap = NULL; - int32_t funResSize= getMaxFunResSize(pSup, numOfCols); - - pInfo->pState->pFileState = pTaskInfo->storageAPI.stateStore.streamFileStateInit( - tsStreamBufferSize, sizeof(SWinKey), pInfo->aggSup.resultRowSize, funResSize, compareTs, pInfo->pState, - pInfo->twAggSup.deleteMark, GET_TASKID(pTaskInfo)); - - setOperatorInfo(pOperator, "StreamIntervalOperator", QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL, true, OP_NOT_OPENED, - pInfo, pTaskInfo); - pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doStreamIntervalAgg, NULL, - destroyStreamFinalIntervalOperatorInfo, optrDefaultBufFn, NULL); - setOperatorStreamStateFn(pOperator, streamIntervalReleaseState, streamIntervalReloadState); - - pInfo->statestore = pTaskInfo->storageAPI.stateStore; - pInfo->recvGetAll = false; - - initIntervalDownStream(downstream, pPhyNode->type, pInfo); - code = appendDownstream(pOperator, &downstream, 1); - if (code != TSDB_CODE_SUCCESS) { - goto _error; - } - - return pOperator; - -_error: - destroyStreamFinalIntervalOperatorInfo(pInfo); - taosMemoryFreeClear(pOperator); - pTaskInfo->code = code; - return NULL; -} diff --git a/source/libs/executor/src/tsort.c b/source/libs/executor/src/tsort.c index 1891e93c61d458e500d46e68b43188356ed9a066..6c4a780dfb21bafb0af64b91e3421e0856e73498 100644 --- a/source/libs/executor/src/tsort.c +++ b/source/libs/executor/src/tsort.c @@ -71,12 +71,20 @@ struct SSortHandle { SMultiwayMergeTreeInfo* pMergeTree; bool singleTableMerge; + + bool (*abortCheckFn)(void* param); + void* abortCheckParam; }; -void setSingleTableMerge(SSortHandle* pHandle) { +void tsortSetSingleTableMerge(SSortHandle* pHandle) { pHandle->singleTableMerge = true; } +void tsortSetAbortCheckFn(SSortHandle *pHandle, bool (*checkFn)(void *), void* param) { + pHandle->abortCheckFn = checkFn; + pHandle->abortCheckParam = param; +} + static int32_t msortComparFn(const void* pLeft, const void* pRight, void* param); // | offset[0] | offset[1] |....| nullbitmap | data |...| @@ -726,11 +734,10 @@ static int32_t doInternalMergeSort(SSortHandle* pHandle) { SArray* pPageIdList = taosArrayInit(4, sizeof(int32_t)); while (1) { - if (tsortIsClosed(pHandle)) { + if (tsortIsClosed(pHandle) || (pHandle->abortCheckFn && pHandle->abortCheckFn(pHandle->abortCheckParam))) { code = terrno = TSDB_CODE_TSC_QUERY_CANCELLED; return code; } - SSDataBlock* pDataBlock = getSortedBlockDataInner(pHandle, &pHandle->cmpParam, numOfRows); if (pDataBlock == NULL) { break; diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h index c3afc30a7b203469b0da23244dc281e64f32bd69..d2f19ed2eb8b768a2c57180e4f0433de9234ea89 100644 --- a/source/libs/function/inc/builtinsimpl.h +++ b/source/libs/function/inc/builtinsimpl.h @@ -127,7 +127,10 @@ int32_t derivativeFunction(SqlFunctionCtx* pCtx); bool getIrateFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); bool irateFuncSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo); int32_t irateFunction(SqlFunctionCtx* pCtx); +int32_t irateFunctionMerge(SqlFunctionCtx* pCtx); int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); +int32_t iratePartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); +int32_t getIrateInfoSize(); int32_t cachedLastRowFunction(SqlFunctionCtx* pCtx); diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index cee40001552d68fe62f585666b5c550b346bac13..9a301b7f1c61e09bb4fe36579d6972428798df7c 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1567,6 +1567,45 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) return TSDB_CODE_SUCCESS; } +static int32_t translateIrateImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) { + uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; + if (isPartial) { + if (3 != LIST_LENGTH(pFunc->pParameterList)) { + return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); + } + if (!IS_NUMERIC_TYPE(colType)) { + return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + } + pFunc->node.resType = (SDataType){.bytes = getIrateInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; + } else { + if (1 != LIST_LENGTH(pFunc->pParameterList)) { + return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); + } + if (TSDB_DATA_TYPE_BINARY != colType) { + return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + } + pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE}; + + // add database precision as param + uint8_t dbPrec = pFunc->node.resType.precision; + int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + + + return TSDB_CODE_SUCCESS; +} + +static int32_t translateIratePartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { + return translateIrateImpl(pFunc, pErrBuf, len, true); +} + +static int32_t translateIrateMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { + return translateIrateImpl(pFunc, pErrBuf, len, false); +} + static int32_t translateInterp(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList); uint8_t dbPrec = pFunc->node.resType.precision; @@ -2604,6 +2643,31 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .initFunc = irateFuncSetup, .processFunc = irateFunction, .sprocessFunc = irateScalarFunction, + .finalizeFunc = irateFinalize, + .pPartialFunc = "_irate_partial", + .pMergeFunc = "_irate_merge" + }, + { + .name = "_irate_partial", + .type = FUNCTION_TYPE_IRATE_PARTIAL, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | + FUNC_MGT_FORBID_SYSTABLE_FUNC, + .translateFunc = translateIratePartial, + .getEnvFunc = getIrateFuncEnv, + .initFunc = irateFuncSetup, + .processFunc = irateFunction, + .sprocessFunc = irateScalarFunction, + .finalizeFunc = iratePartialFinalize + }, + { + .name = "_irate_merge", + .type = FUNCTION_TYPE_IRATE_MERGE, + .classification = FUNC_MGT_AGG_FUNC, + .translateFunc = translateIrateMerge, + .getEnvFunc = getIrateFuncEnv, + .initFunc = irateFuncSetup, + .processFunc = irateFunctionMerge, + .sprocessFunc = irateScalarFunction, .finalizeFunc = irateFinalize }, { diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index fad8c9ca5bb4869a9d3d869ba6a36d127c0613fa..bcbb3af95091344c48054f105e0df4e3a44c2035 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -5768,6 +5768,8 @@ int32_t derivativeFunction(SqlFunctionCtx* pCtx) { return TSDB_CODE_SUCCESS; } +int32_t getIrateInfoSize() { return (int32_t)sizeof(SRateInfo); } + bool getIrateFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv) { pEnv->calcMemSize = sizeof(SRateInfo); return true; @@ -5817,6 +5819,7 @@ int32_t irateFunction(SqlFunctionCtx* pCtx) { if (INT64_MIN == pRateInfo->lastKey) { pRateInfo->lastValue = v; pRateInfo->lastKey = tsList[i]; + pRateInfo->hasResult = 1; continue; } @@ -5868,6 +5871,99 @@ static double doCalcRate(const SRateInfo* pRateInfo, double tickPerSec) { return (duration > 0) ? ((double)diff) / (duration / tickPerSec) : 0.0; } +static void irateTransferInfoImpl(TSKEY inputKey, SRateInfo* pInput, SRateInfo* pOutput, bool isFirstKey) { + if (inputKey > pOutput->lastKey) { + pOutput->firstKey = pOutput->lastKey; + pOutput->firstValue = pOutput->lastValue; + + pOutput->lastKey = isFirstKey ? pInput->firstKey : pInput->lastKey; + pOutput->lastValue = isFirstKey ? pInput->firstValue : pInput->lastValue; + } else if ((inputKey < pOutput->lastKey) && (inputKey > pOutput->firstKey)) { + pOutput->firstKey = isFirstKey ? pInput->firstKey : pInput->lastKey; + pOutput->firstValue = isFirstKey ? pInput->firstValue : pInput->lastValue; + } else { + // inputKey < pOutput->firstKey + } +} + +static void irateCopyInfo(SRateInfo* pInput, SRateInfo* pOutput) { + pOutput->firstKey = pInput->firstKey; + pOutput->lastKey = pInput->lastKey; + + pOutput->firstValue = pInput->firstValue; + pOutput->lastValue = pInput->lastValue; +} + +static int32_t irateTransferInfo(SRateInfo* pInput, SRateInfo* pOutput) { + if ((pInput->firstKey != INT64_MIN && (pInput->firstKey == pOutput->firstKey || pInput->firstKey == pOutput->lastKey)) || + (pInput->lastKey != INT64_MIN && (pInput->lastKey == pOutput->firstKey || pInput->lastKey == pOutput->lastKey))) { + return TSDB_CODE_FUNC_DUP_TIMESTAMP; + } + + if (pOutput->hasResult == 0) { + irateCopyInfo(pInput, pOutput); + pOutput->hasResult = pInput->hasResult; + return TSDB_CODE_SUCCESS; + } + + if (pInput->firstKey != INT64_MIN) { + irateTransferInfoImpl(pInput->firstKey, pInput, pOutput, true); + } + + if (pInput->lastKey != INT64_MIN) { + irateTransferInfoImpl(pInput->lastKey, pInput, pOutput, false); + } + + pOutput->hasResult = pInput->hasResult; + return TSDB_CODE_SUCCESS; +} + +int32_t irateFunctionMerge(SqlFunctionCtx* pCtx) { + SInputColumnInfoData* pInput = &pCtx->input; + SColumnInfoData* pCol = pInput->pData[0]; + if (pCol->info.type != TSDB_DATA_TYPE_BINARY) { + return TSDB_CODE_FUNC_FUNTION_PARA_TYPE; + } + + SRateInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + + int32_t start = pInput->startRowIndex; + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); + SRateInfo* pInputInfo = (SRateInfo*)varDataVal(data); + if (pInputInfo->hasResult) { + int32_t code = irateTransferInfo(pInputInfo, pInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + } + + if (pInfo->hasResult) { + GET_RES_INFO(pCtx)->numOfRes = 1; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t iratePartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { + SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); + SRateInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + int32_t resultBytes = getIrateInfoSize(); + char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char)); + + memcpy(varDataVal(res), pInfo, resultBytes); + varDataSetLen(res, resultBytes); + + int32_t slotId = pCtx->pExpr->base.resSchema.slotId; + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); + + colDataSetVal(pCol, pBlock->info.rows, res, false); + + taosMemoryFree(res); + return pResInfo->numOfRes; +} + int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { int32_t slotId = pCtx->pExpr->base.resSchema.slotId; SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); diff --git a/source/libs/function/src/udfd.c b/source/libs/function/src/udfd.c index 7371017111f5662fd765d3c7afb74fedca377b16..575bce09bb8c86fd47635556e50a5bd8e32d9a61 100644 --- a/source/libs/function/src/udfd.c +++ b/source/libs/function/src/udfd.c @@ -378,9 +378,9 @@ int32_t udfdInitializePythonPlugin(SUdfScriptPlugin *plugin) { "pyUdfDestroy", "pyUdfScalarProc", "pyUdfAggStart", "pyUdfAggFinish", "pyUdfAggProc", "pyUdfAggMerge"}; void **funcs[UDFD_MAX_PLUGIN_FUNCS] = { - (void **)&plugin->openFunc, (void **)&plugin->closeFunc, (void **)&plugin->udfInitFunc, - (void **)&plugin->udfDestroyFunc, (void **)&plugin->udfScalarProcFunc, (void **)&plugin->udfAggStartFunc, - (void **)&plugin->udfAggFinishFunc, (void **)&plugin->udfAggProcFunc, (void **)&plugin->udfAggMergeFunc}; + (void **)&plugin->openFunc, (void **)&plugin->closeFunc, (void **)&plugin->udfInitFunc, + (void **)&plugin->udfDestroyFunc, (void **)&plugin->udfScalarProcFunc, (void **)&plugin->udfAggStartFunc, + (void **)&plugin->udfAggFinishFunc, (void **)&plugin->udfAggProcFunc, (void **)&plugin->udfAggMergeFunc}; int32_t err = udfdLoadSharedLib(plugin->libPath, &plugin->lib, funcName, funcs, UDFD_MAX_PLUGIN_FUNCS); if (err != 0) { fnError("can not load python plugin. lib path %s", plugin->libPath); @@ -848,7 +848,7 @@ int32_t udfdSaveFuncBodyToFile(SFuncInfo *pFuncInfo, SUdf *udf) { char path[PATH_MAX] = {0}; udfdGetFuncBodyPath(udf, path); - bool fileExist = !(taosStatFile(path, NULL, NULL) < 0); + bool fileExist = !(taosStatFile(path, NULL, NULL, NULL) < 0); if (fileExist) { strncpy(udf->path, path, PATH_MAX); fnInfo("udfd func body file. reuse existing file %s", path); diff --git a/source/libs/index/src/indexFstFile.c b/source/libs/index/src/indexFstFile.c index e18d0bbad3a99ef089a6c94111f3d148461d954a..43f15f51969d2bb41beead33fa678f243d79e7c0 100644 --- a/source/libs/index/src/indexFstFile.c +++ b/source/libs/index/src/indexFstFile.c @@ -162,7 +162,7 @@ static FORCE_INLINE int idxFileCtxGetSize(IFileCtx* ctx) { return ctx->offset; } else { int64_t file_size = 0; - taosStatFile(ctx->file.buf, &file_size, NULL); + taosStatFile(ctx->file.buf, &file_size, NULL, NULL); return (int)file_size; } } @@ -199,7 +199,7 @@ IFileCtx* idxFileCtxCreate(WriterType type, const char* path, bool readOnly, int code = taosFtruncateFile(ctx->file.pFile, 0); UNUSED(code); - code = taosStatFile(path, &ctx->file.size, NULL); + code = taosStatFile(path, &ctx->file.size, NULL, NULL); UNUSED(code); ctx->file.wBufOffset = 0; diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index f5eacf0bd5d1c15bb7c773ee60caea7abc0dc0b5..d3cbaac5e1bde5437c9c36b61e9032391fd217ca 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -564,7 +564,9 @@ static int32_t physiScanCopy(const SScanPhysiNode* pSrc, SScanPhysiNode* pDst) { } static int32_t physiTagScanCopy(const STagScanPhysiNode* pSrc, STagScanPhysiNode* pDst) { - return physiScanCopy(pSrc, pDst); + COPY_BASE_OBJECT_FIELD(scan, physiScanCopy); + COPY_SCALAR_FIELD(onlyMetaCtbIdx); + return TSDB_CODE_SUCCESS; } static int32_t physiTableScanCopy(const STableScanPhysiNode* pSrc, STableScanPhysiNode* pDst) { diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index f25616065eb064d0160209320ecb744ba6ac23d8..1e4eb510d9c007a2d1bab142465bb204d7fdff3c 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -197,8 +197,10 @@ const char* nodesNodeName(ENodeType type) { return "ShowDnodesStmt"; case QUERY_NODE_SHOW_MNODES_STMT: return "ShowMnodesStmt"; +/* case QUERY_NODE_SHOW_MODULES_STMT: return "ShowModulesStmt"; +*/ case QUERY_NODE_SHOW_QNODES_STMT: return "ShowQnodesStmt"; case QUERY_NODE_SHOW_SNODES_STMT: @@ -660,6 +662,7 @@ static const char* jkScanLogicPlanDynamicScanFuncs = "DynamicScanFuncs"; static const char* jkScanLogicPlanDataRequired = "DataRequired"; static const char* jkScanLogicPlanTagCond = "TagCond"; static const char* jkScanLogicPlanGroupTags = "GroupTags"; +static const char* jkScanLogicPlanOnlyMetaCtbIdx = "OnlyMetaCtbIdx"; static int32_t logicScanNodeToJson(const void* pObj, SJson* pJson) { const SScanLogicNode* pNode = (const SScanLogicNode*)pObj; @@ -701,7 +704,9 @@ static int32_t logicScanNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = nodeListToJson(pJson, jkScanLogicPlanGroupTags, pNode->pGroupTags); } - + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddBoolToObject(pJson, jkScanLogicPlanOnlyMetaCtbIdx, pNode->onlyMetaCtbIdx); + } return code; } @@ -746,7 +751,10 @@ static int32_t jsonToLogicScanNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeList(pJson, jkScanLogicPlanGroupTags, &pNode->pGroupTags); } - + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBoolValue(pJson, jkScanLogicPlanOnlyMetaCtbIdx, &pNode->onlyMetaCtbIdx); + } + return code; } @@ -1562,7 +1570,7 @@ static const char* jkScanPhysiPlanTableName = "TableName"; static const char* jkScanPhysiPlanGroupOrderScan = "GroupOrderScan"; static int32_t physiScanNodeToJson(const void* pObj, SJson* pJson) { - const STagScanPhysiNode* pNode = (const STagScanPhysiNode*)pObj; + const SScanPhysiNode* pNode = (const SScanPhysiNode*)pObj; int32_t code = physicPlanNodeToJson(pObj, pJson); if (TSDB_CODE_SUCCESS == code) { @@ -1591,7 +1599,7 @@ static int32_t physiScanNodeToJson(const void* pObj, SJson* pJson) { } static int32_t jsonToPhysiScanNode(const SJson* pJson, void* pObj) { - STagScanPhysiNode* pNode = (STagScanPhysiNode*)pObj; + SScanPhysiNode* pNode = (SScanPhysiNode*)pObj; int32_t code = jsonToPhysicPlanNode(pJson, pObj); if (TSDB_CODE_SUCCESS == code) { @@ -1619,6 +1627,30 @@ static int32_t jsonToPhysiScanNode(const SJson* pJson, void* pObj) { return code; } +static const char* jkTagScanPhysiOnlyMetaCtbIdx = "OnlyMetaCtbIdx"; + +static int32_t physiTagScanNodeToJson(const void* pObj, SJson* pJson) { + const STagScanPhysiNode* pNode = (const STagScanPhysiNode*)pObj; + + int32_t code = physiScanNodeToJson(pObj, pJson); + + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddBoolToObject(pJson, jkTagScanPhysiOnlyMetaCtbIdx, pNode->onlyMetaCtbIdx); + } + return code; +} + +static int32_t jsonToPhysiTagScanNode(const SJson* pJson, void* pObj) { + STagScanPhysiNode* pNode = (STagScanPhysiNode*)pObj; + + int32_t code = jsonToPhysiScanNode(pJson, pObj); + + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBoolValue(pJson, jkTagScanPhysiOnlyMetaCtbIdx, &pNode->onlyMetaCtbIdx); + } + return code; +} + static const char* jkLastRowScanPhysiPlanGroupTags = "GroupTags"; static const char* jkLastRowScanPhysiPlanGroupSort = "GroupSort"; @@ -2814,6 +2846,8 @@ static const char* jkSubplanDataSink = "DataSink"; static const char* jkSubplanTagCond = "TagCond"; static const char* jkSubplanTagIndexCond = "TagIndexCond"; static const char* jkSubplanShowRewrite = "ShowRewrite"; +static const char* jkSubplanRowsThreshold = "RowThreshold"; +static const char* jkSubplanDynamicRowsThreshold = "DyRowThreshold"; static int32_t subplanToJson(const void* pObj, SJson* pJson) { const SSubplan* pNode = (const SSubplan*)pObj; @@ -2852,6 +2886,12 @@ static int32_t subplanToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddBoolToObject(pJson, jkSubplanShowRewrite, pNode->showRewrite); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkSubplanRowsThreshold, pNode->rowsThreshold); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddBoolToObject(pJson, jkSubplanDynamicRowsThreshold, pNode->dynamicRowThreshold); + } return code; } @@ -2893,6 +2933,12 @@ static int32_t jsonToSubplan(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tjsonGetBoolValue(pJson, jkSubplanShowRewrite, &pNode->showRewrite); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetIntValue(pJson, jkSubplanRowsThreshold, &pNode->rowsThreshold); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBoolValue(pJson, jkSubplanDynamicRowsThreshold, &pNode->dynamicRowThreshold); + } return code; } @@ -6590,6 +6636,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { case QUERY_NODE_LOGIC_PLAN: return logicPlanToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: + return physiTagScanNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: return physiScanNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: @@ -6908,6 +6955,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { case QUERY_NODE_LOGIC_PLAN: return jsonToLogicPlan(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: + return jsonToPhysiTagScanNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: return jsonToPhysiScanNode(pJson, pObj); diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 20e829766dafe75aa2372aa1e4147ac9b856ee71..74d7aad6e80e909161b9d8668abd185860b490a3 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -2003,6 +2003,43 @@ static int32_t msgToPhysiScanNode(STlvDecoder* pDecoder, void* pObj) { return code; } +enum { + PHY_TAG_SCAN_CODE_SCAN = 1, + PHY_TAG_SCAN_CODE_ONLY_META_CTB_IDX +}; + +static int32_t physiTagScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { + const STagScanPhysiNode* pNode = (const STagScanPhysiNode*)pObj; + + int32_t code = tlvEncodeObj(pEncoder, PHY_TAG_SCAN_CODE_SCAN, physiScanNodeToMsg, &pNode->scan); + + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeBool(pEncoder, PHY_TAG_SCAN_CODE_ONLY_META_CTB_IDX, pNode->onlyMetaCtbIdx); + } + return code; +} + +static int32_t msgToPhysiTagScanNode(STlvDecoder* pDecoder, void* pObj) { + STagScanPhysiNode* pNode = (STagScanPhysiNode*)pObj; + + int32_t code = TSDB_CODE_SUCCESS; + STlv* pTlv = NULL; + tlvForEach(pDecoder, pTlv, code) { + switch (pTlv->type) { + case PHY_TAG_SCAN_CODE_SCAN: + code = tlvDecodeObjFromTlv(pTlv, msgToPhysiScanNode, &pNode->scan); + break; + case PHY_TAG_SCAN_CODE_ONLY_META_CTB_IDX: + code = tlvDecodeBool(pTlv, &pNode->onlyMetaCtbIdx); + break; + default: + break; + } + } + + return code; +} + enum { PHY_LAST_ROW_SCAN_CODE_SCAN = 1, PHY_LAST_ROW_SCAN_CODE_GROUP_TAGS, @@ -3538,6 +3575,12 @@ static int32_t subplanInlineToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeValueBool(pEncoder, pNode->showRewrite); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeValueI32(pEncoder, pNode->rowsThreshold); + } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeValueBool(pEncoder, pNode->dynamicRowThreshold); + } return code; } @@ -3587,6 +3630,12 @@ static int32_t msgToSubplanInline(STlvDecoder* pDecoder, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tlvDecodeValueBool(pDecoder, &pNode->showRewrite); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvDecodeValueI32(pDecoder, &pNode->rowsThreshold); + } + if (TSDB_CODE_SUCCESS == code) { + code = tlvDecodeValueBool(pDecoder, &pNode->dynamicRowThreshold); + } return code; } @@ -3726,6 +3775,8 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { code = caseWhenNodeToMsg(pObj, pEncoder); break; case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: + code = physiTagScanNodeToMsg(pObj, pEncoder); + break; case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: code = physiScanNodeToMsg(pObj, pEncoder); break; @@ -3869,6 +3920,8 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) { code = msgToCaseWhenNode(pDecoder, pObj); break; case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: + code = msgToPhysiTagScanNode(pDecoder, pObj); + break; case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: code = msgToPhysiScanNode(pDecoder, pObj); break; diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index c8197721fb2803efa6d4ab40a8ef4dd1f20a46bb..75b63b9d342e16da758a76cb96134cd0faa4af1f 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -406,7 +406,7 @@ SNode* nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SRevokeStmt)); case QUERY_NODE_SHOW_DNODES_STMT: case QUERY_NODE_SHOW_MNODES_STMT: - case QUERY_NODE_SHOW_MODULES_STMT: +// case QUERY_NODE_SHOW_MODULES_STMT: case QUERY_NODE_SHOW_QNODES_STMT: case QUERY_NODE_SHOW_SNODES_STMT: case QUERY_NODE_SHOW_BNODES_STMT: @@ -982,7 +982,7 @@ void nodesDestroyNode(SNode* pNode) { break; case QUERY_NODE_SHOW_DNODES_STMT: case QUERY_NODE_SHOW_MNODES_STMT: - case QUERY_NODE_SHOW_MODULES_STMT: +// case QUERY_NODE_SHOW_MODULES_STMT: case QUERY_NODE_SHOW_QNODES_STMT: case QUERY_NODE_SHOW_SNODES_STMT: case QUERY_NODE_SHOW_BNODES_STMT: diff --git a/source/libs/nodes/test/nodesCloneTest.cpp b/source/libs/nodes/test/nodesCloneTest.cpp index e1e99abab3a8c04541432cdf6c870e24f7cd5a8b..8b8893d3170510fb09ee4598dcea47d54d5b74ea 100644 --- a/source/libs/nodes/test/nodesCloneTest.cpp +++ b/source/libs/nodes/test/nodesCloneTest.cpp @@ -199,9 +199,10 @@ TEST_F(NodesCloneTest, physiScan) { ASSERT_EQ(nodeType(pSrc), nodeType(pDst)); STagScanPhysiNode* pSrcNode = (STagScanPhysiNode*)pSrc; STagScanPhysiNode* pDstNode = (STagScanPhysiNode*)pDst; - ASSERT_EQ(pSrcNode->uid, pDstNode->uid); - ASSERT_EQ(pSrcNode->suid, pDstNode->suid); - ASSERT_EQ(pSrcNode->tableType, pDstNode->tableType); + ASSERT_EQ(pSrcNode->scan.uid, pDstNode->scan.uid); + ASSERT_EQ(pSrcNode->scan.suid, pDstNode->scan.suid); + ASSERT_EQ(pSrcNode->scan.tableType, pDstNode->scan.tableType); + ASSERT_EQ(pSrcNode->onlyMetaCtbIdx, pDstNode->onlyMetaCtbIdx); }); std::unique_ptr srcNode(nullptr, nodesDestroyNode); diff --git a/source/libs/parser/inc/parAst.h b/source/libs/parser/inc/parAst.h index 78422bf746ebcb72c495a2475b8dc26872e7bacc..6d7d4dbc436751f7e63b123ecfc87479f9886c9f 100644 --- a/source/libs/parser/inc/parAst.h +++ b/source/libs/parser/inc/parAst.h @@ -171,8 +171,7 @@ SNode* createDropTableClause(SAstCreateContext* pCxt, bool ignoreNotExists, SNod SNode* createDropTableStmt(SAstCreateContext* pCxt, SNodeList* pTables); SNode* createDropSuperTableStmt(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pRealTable); SNode* createAlterTableModifyOptions(SAstCreateContext* pCxt, SNode* pRealTable, SNode* pOptions); -SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName, - SDataType dataType); +SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SNode* pColDefNode); SNode* createAlterTableDropCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName); SNode* createAlterTableRenameCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pOldColName, SToken* pNewColName); diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 54307fa4609dea8d7f2ed3c217b28e1e09b53512..9becbaa0ca3d0e8146f70e655cc44f2c03a8a412 100755 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -312,17 +312,17 @@ cmd ::= ALTER STABLE alter_table_clause(A). alter_table_clause(A) ::= full_table_name(B) alter_table_options(C). { A = createAlterTableModifyOptions(pCxt, B, C); } alter_table_clause(A) ::= - full_table_name(B) ADD COLUMN column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_ADD_COLUMN, &C, D); } + full_table_name(B) ADD COLUMN column_def(C). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_ADD_COLUMN, C); } alter_table_clause(A) ::= full_table_name(B) DROP COLUMN column_name(C). { A = createAlterTableDropCol(pCxt, B, TSDB_ALTER_TABLE_DROP_COLUMN, &C); } alter_table_clause(A) ::= - full_table_name(B) MODIFY COLUMN column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &C, D); } + full_table_name(B) MODIFY COLUMN column_def(C). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, C); } alter_table_clause(A) ::= full_table_name(B) RENAME COLUMN column_name(C) column_name(D). { A = createAlterTableRenameCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &C, &D); } alter_table_clause(A) ::= - full_table_name(B) ADD TAG column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_ADD_TAG, &C, D); } + full_table_name(B) ADD TAG column_def(C). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_ADD_TAG, C); } alter_table_clause(A) ::= full_table_name(B) DROP TAG column_name(C). { A = createAlterTableDropCol(pCxt, B, TSDB_ALTER_TABLE_DROP_TAG, &C); } alter_table_clause(A) ::= - full_table_name(B) MODIFY TAG column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &C, D); } + full_table_name(B) MODIFY TAG column_def(C). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, C); } alter_table_clause(A) ::= full_table_name(B) RENAME TAG column_name(C) column_name(D). { A = createAlterTableRenameCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &C, &D); } alter_table_clause(A) ::= @@ -358,7 +358,7 @@ column_def_list(A) ::= column_def(B). column_def_list(A) ::= column_def_list(B) NK_COMMA column_def(C). { A = addNodeToList(pCxt, B, C); } column_def(A) ::= column_name(B) type_name(C). { A = createColumnDefNode(pCxt, &B, C, NULL); } -//column_def(A) ::= column_name(B) type_name(C) COMMENT NK_STRING(D). { A = createColumnDefNode(pCxt, &B, C, &D); } +column_def(A) ::= column_name(B) type_name(C) COMMENT NK_STRING(D). { A = createColumnDefNode(pCxt, &B, C, &D); } %type type_name { SDataType } %destructor type_name { } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index f85218c50a767ca41acef02618251b2e0749bceb..c95fb5d348dc75093615981f52ae44e74fb27d90 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -1333,17 +1333,15 @@ SNode* createAlterTableModifyOptions(SAstCreateContext* pCxt, SNode* pRealTable, return createAlterTableStmtFinalize(pRealTable, pStmt); } -SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName, - SDataType dataType) { +SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SNode* pColDefNode) { CHECK_PARSER_STATUS(pCxt); - if (!checkColumnName(pCxt, pColName)) { - return NULL; - } + SColumnDefNode* pCol = (SColumnDefNode*)pColDefNode; SAlterTableStmt* pStmt = (SAlterTableStmt*)nodesMakeNode(QUERY_NODE_ALTER_TABLE_STMT); CHECK_OUT_OF_MEM(pStmt); pStmt->alterType = alterType; - COPY_STRING_FORM_ID_TOKEN(pStmt->colName, pColName); - pStmt->dataType = dataType; + strcpy(pStmt->colName, pCol->colName); + strcpy(pStmt->colComment, pCol->comments); + pStmt->dataType = pCol->dataType; return createAlterTableStmtFinalize(pRealTable, pStmt); } diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index fdec9cba79aa8dd07fdf3706c99ab74023664397..86b4566d37f79abfcad3f1af8316871ca751d513 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -690,8 +690,10 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { return collectMetaKeyFromShowDnodes(pCxt, (SShowStmt*)pStmt); case QUERY_NODE_SHOW_MNODES_STMT: return collectMetaKeyFromShowMnodes(pCxt, (SShowStmt*)pStmt); +/* case QUERY_NODE_SHOW_MODULES_STMT: return collectMetaKeyFromShowModules(pCxt, (SShowStmt*)pStmt); +*/ case QUERY_NODE_SHOW_QNODES_STMT: return collectMetaKeyFromShowQnodes(pCxt, (SShowStmt*)pStmt); case QUERY_NODE_SHOW_SNODES_STMT: diff --git a/source/libs/parser/src/parAuthenticator.c b/source/libs/parser/src/parAuthenticator.c index 9b2ac662c84443c8efa39b308af51d65a941706a..6a26dcfa8bc205bd58c90a194041d74625509b75 100644 --- a/source/libs/parser/src/parAuthenticator.c +++ b/source/libs/parser/src/parAuthenticator.c @@ -263,7 +263,7 @@ static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) { return authAlterTable(pCxt, (SAlterTableStmt*)pStmt); case QUERY_NODE_SHOW_DNODES_STMT: case QUERY_NODE_SHOW_MNODES_STMT: - case QUERY_NODE_SHOW_MODULES_STMT: +// case QUERY_NODE_SHOW_MODULES_STMT: case QUERY_NODE_SHOW_QNODES_STMT: case QUERY_NODE_SHOW_SNODES_STMT: case QUERY_NODE_SHOW_BNODES_STMT: diff --git a/source/libs/parser/src/parInsertSml.c b/source/libs/parser/src/parInsertSml.c index 78b05b6df57d10d5f7d54669353d8906556a72d4..577b8961a72fbf5c6e81bf1c84d493417357f948 100644 --- a/source/libs/parser/src/parInsertSml.c +++ b/source/libs/parser/src/parInsertSml.c @@ -22,7 +22,7 @@ static void clearColValArray(SArray* pCols) { int32_t num = taosArrayGetSize(pCols); for (int32_t i = 0; i < num; ++i) { SColVal* pCol = taosArrayGet(pCols, i); - if (TSDB_DATA_TYPE_NCHAR == pCol->type) { + if (TSDB_DATA_TYPE_NCHAR == pCol->type || TSDB_DATA_TYPE_GEOMETRY == pCol->type) { taosMemoryFreeClear(pCol->value.pData); } pCol->flag = CV_FLAG_NONE; @@ -237,9 +237,13 @@ int32_t smlBuildCol(STableDataCxt* pTableCxt, SSchema* schema, void* data, int32 } pVal->value.pData = pUcs4; pVal->value.nData = len; - } else if (kv->type == TSDB_DATA_TYPE_BINARY || kv->type == TSDB_DATA_TYPE_GEOMETRY) { + } else if (kv->type == TSDB_DATA_TYPE_BINARY) { pVal->value.nData = kv->length; pVal->value.pData = (uint8_t*)kv->value; + } else if (kv->type == TSDB_DATA_TYPE_GEOMETRY) { + pVal->value.nData = kv->length; + pVal->value.pData = taosMemoryMalloc(kv->length); + memcpy(pVal->value.pData, (uint8_t*)kv->value, kv->length); } else { memcpy(&pVal->value.val, &(kv->value), kv->length); } @@ -364,9 +368,13 @@ int32_t smlBindData(SQuery* query, bool dataFormat, SArray* tags, SArray* colsSc } pVal->value.pData = pUcs4; pVal->value.nData = len; - } else if (kv->type == TSDB_DATA_TYPE_BINARY || kv->type == TSDB_DATA_TYPE_GEOMETRY) { + } else if (kv->type == TSDB_DATA_TYPE_BINARY) { pVal->value.nData = kv->length; pVal->value.pData = (uint8_t*)kv->value; + } else if (kv->type == TSDB_DATA_TYPE_GEOMETRY) { + pVal->value.nData = kv->length; + pVal->value.pData = taosMemoryMalloc(kv->length); + memcpy(pVal->value.pData, (uint8_t*)kv->value, kv->length); } else { memcpy(&pVal->value.val, &(kv->value), kv->length); } diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index de7d154db6a8ecf604fa2197ad09e323ae185a43..33699ed8578809ec1361b75fbaec46d9d540c6a3 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -333,7 +333,7 @@ int32_t insGetTableDataCxt(SHashObj* pHash, void* id, int32_t idLen, STableMeta* static void destroyColVal(void* p) { SColVal* pVal = p; - if (TSDB_DATA_TYPE_NCHAR == pVal->type) { + if (TSDB_DATA_TYPE_NCHAR == pVal->type || TSDB_DATA_TYPE_GEOMETRY == pVal->type) { taosMemoryFree(pVal->value.pData); } } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 4ef00d934d3f4ccdb1cc50b42f667b8222efb9cf..ea331037989cfa7ecb4dab9398fccafa343190a0 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -31,8 +31,8 @@ #define SYSTABLE_SHOW_TYPE_OFFSET QUERY_NODE_SHOW_DNODES_STMT typedef struct SRewriteTbNameContext { - int32_t errCode; - char* pTbName; + int32_t errCode; + char* pTbName; } SRewriteTbNameContext; typedef struct STranslateContext { @@ -54,7 +54,7 @@ typedef struct STranslateContext { bool stableQuery; bool showRewrite; SNode* pPrevRoot; - SNode* pPostRoot; + SNode* pPostRoot; } STranslateContext; typedef struct SBuildTopicContext { @@ -92,6 +92,7 @@ static const SSysTableShowAdapter sysTableShowAdapter[] = { .numOfShowCols = 1, .pShowCols = {"*"} }, +/* { .showType = QUERY_NODE_SHOW_MODULES_STMT, .pDbName = TSDB_INFORMATION_SCHEMA_DB, @@ -99,6 +100,7 @@ static const SSysTableShowAdapter sysTableShowAdapter[] = { .numOfShowCols = 1, .pShowCols = {"*"} }, +*/ { .showType = QUERY_NODE_SHOW_QNODES_STMT, .pDbName = TSDB_INFORMATION_SCHEMA_DB, @@ -278,10 +280,11 @@ static const SSysTableShowAdapter sysTableShowAdapter[] = { static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode); static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode); static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal); -static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt); -static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta, SNode** pQuery); -static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery); -static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery); +static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, + SSelectStmt** pStmt); +static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta, SNode** pQuery); +static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery); +static int32_t setRefreshMate(STranslateContext* pCxt, SQuery* pQuery); static bool afterGroupBy(ESqlClause clause) { return clause > SQL_CLAUSE_GROUP_BY; } @@ -772,7 +775,8 @@ static SNodeList* getProjectList(const SNode* pNode) { static bool isTimeLineQuery(SNode* pStmt) { if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) { - return (TIME_LINE_MULTI == ((SSelectStmt*)pStmt)->timeLineResMode) || (TIME_LINE_GLOBAL == ((SSelectStmt*)pStmt)->timeLineResMode); + return (TIME_LINE_MULTI == ((SSelectStmt*)pStmt)->timeLineResMode) || + (TIME_LINE_GLOBAL == ((SSelectStmt*)pStmt)->timeLineResMode); } else if (QUERY_NODE_SET_OPERATOR == nodeType(pStmt)) { return TIME_LINE_GLOBAL == ((SSetOperator*)pStmt)->timeLineResMode; } else { @@ -791,7 +795,7 @@ static bool isGlobalTimeLineQuery(SNode* pStmt) { } static bool isTimeLineAlignedQuery(SNode* pStmt) { - SSelectStmt *pSelect = (SSelectStmt *)pStmt; + SSelectStmt* pSelect = (SSelectStmt*)pStmt; if (isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) { return true; } @@ -801,7 +805,7 @@ static bool isTimeLineAlignedQuery(SNode* pStmt) { if (QUERY_NODE_SELECT_STMT != nodeType(((STempTableNode*)pSelect->pFromTable)->pSubquery)) { return false; } - SSelectStmt *pSub = (SSelectStmt *)((STempTableNode*)pSelect->pFromTable)->pSubquery; + SSelectStmt* pSub = (SSelectStmt*)((STempTableNode*)pSelect->pFromTable)->pSubquery; if (nodesListMatch(pSelect->pPartitionByList, pSub->pPartitionByList)) { return true; } @@ -822,18 +826,18 @@ static bool isPrimaryKeyImpl(SNode* pExpr) { return true; } } else if (QUERY_NODE_OPERATOR == nodeType(pExpr)) { - SOperatorNode* pOper = (SOperatorNode*)pExpr; - if (OP_TYPE_ADD != pOper->opType && OP_TYPE_SUB != pOper->opType) { - return false; - } - if (!isPrimaryKeyImpl(pOper->pLeft)) { - return false; - } - if (QUERY_NODE_VALUE != nodeType(pOper->pRight)) { - return false; - } - return true; + SOperatorNode* pOper = (SOperatorNode*)pExpr; + if (OP_TYPE_ADD != pOper->opType && OP_TYPE_SUB != pOper->opType) { + return false; + } + if (!isPrimaryKeyImpl(pOper->pLeft)) { + return false; + } + if (QUERY_NODE_VALUE != nodeType(pOper->pRight)) { + return false; } + return true; + } return false; } @@ -860,7 +864,7 @@ static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* p pCol->tableType = pTable->pMeta->tableType; pCol->colId = pColSchema->colId; pCol->colType = (tagFlag >= 0 ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN); - pCol->hasIndex = ((0 == tagFlag) || (pColSchema != NULL && IS_IDX_ON(pColSchema))); + pCol->hasIndex = (pColSchema != NULL && IS_IDX_ON(pColSchema)); pCol->node.resType.type = pColSchema->type; pCol->node.resType.bytes = pColSchema->bytes; if (TSDB_DATA_TYPE_TIMESTAMP == pCol->node.resType.type) { @@ -1406,7 +1410,7 @@ static bool isCountStar(SFunctionNode* pFunc) { } static int32_t rewriteCountStarAsCount1(STranslateContext* pCxt, SFunctionNode* pCount) { - int32_t code = TSDB_CODE_SUCCESS; + int32_t code = TSDB_CODE_SUCCESS; SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); if (NULL == pVal) { return TSDB_CODE_OUT_OF_MEMORY; @@ -1608,9 +1612,11 @@ static int32_t translateInterpFunc(STranslateContext* pCxt, SFunctionNode* pFunc return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC); } - if (pSelect->hasInterpFunc && (FUNC_RETURN_ROWS_INDEFINITE == pSelect->returnRows || pSelect->returnRows != fmGetFuncReturnRows(pFunc))) { + if (pSelect->hasInterpFunc && + (FUNC_RETURN_ROWS_INDEFINITE == pSelect->returnRows || pSelect->returnRows != fmGetFuncReturnRows(pFunc))) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC, - "%s ignoring null value options cannot be used when applying to multiple columns", pFunc->functionName); + "%s ignoring null value options cannot be used when applying to multiple columns", + pFunc->functionName); } if (NULL != pSelect->pWindow || NULL != pSelect->pGroupByList) { @@ -1648,7 +1654,8 @@ static int32_t translateTimelineFunc(STranslateContext* pCxt, SFunctionNode* pFu } SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt; if (NULL != pSelect->pFromTable && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) && - !isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery) && !isTimeLineAlignedQuery(pCxt->pCurrStmt)) { + !isGlobalTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery) && + !isTimeLineAlignedQuery(pCxt->pCurrStmt)) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC, "%s function requires valid time series input", pFunc->functionName); } @@ -1718,8 +1725,8 @@ static int32_t translateForbidSysTableFunc(STranslateContext* pCxt, SFunctionNod return TSDB_CODE_SUCCESS; } - SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt; - SNode* pTable = pSelect->pFromTable; + SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt; + SNode* pTable = pSelect->pFromTable; if (NULL != pTable && QUERY_NODE_REAL_TABLE == nodeType(pTable) && TSDB_SYSTEM_TABLE == ((SRealTableNode*)pTable)->pMeta->tableType) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED_FUNC, pFunc->functionName); @@ -2308,7 +2315,8 @@ static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) { } } if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) { - if (pSelect->selectFuncNum > 1 || pSelect->hasOtherVectorFunc || !pSelect->hasSelectFunc || (isDistinctOrderBy(pCxt) && pCxt->currClause == SQL_CLAUSE_ORDER_BY)) { + if (pSelect->selectFuncNum > 1 || pSelect->hasOtherVectorFunc || !pSelect->hasSelectFunc || + (isDistinctOrderBy(pCxt) && pCxt->currClause == SQL_CLAUSE_ORDER_BY)) { return generateDealNodeErrMsg(pCxt, getGroupByErrorCode(pCxt), ((SExprNode*)(*pNode))->userAlias); } else { return rewriteColToSelectValFunc(pCxt, pNode); @@ -2403,14 +2411,14 @@ static int32_t checkHavingGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) if (NULL != pSelect->pHaving) { code = checkExprForGroupBy(pCxt, &pSelect->pHaving); } -/* - if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pProjectionList) { - code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pProjectionList); - } - if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pOrderByList) { - code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pOrderByList); - } -*/ + /* + if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pProjectionList) { + code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pProjectionList); + } + if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pOrderByList) { + code = checkExprListForGroupBy(pCxt, pSelect, pSelect->pOrderByList); + } + */ return code; } @@ -2669,10 +2677,10 @@ static int32_t setTableCacheLastMode(STranslateContext* pCxt, SSelectStmt* pSele static EDealRes doTranslateTbName(SNode** pNode, void* pContext) { switch (nodeType(*pNode)) { case QUERY_NODE_FUNCTION: { - SFunctionNode *pFunc = (SFunctionNode *)*pNode; + SFunctionNode* pFunc = (SFunctionNode*)*pNode; if (FUNCTION_TYPE_TBNAME == pFunc->funcType) { - SRewriteTbNameContext *pCxt = (SRewriteTbNameContext*)pContext; - SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); + SRewriteTbNameContext* pCxt = (SRewriteTbNameContext*)pContext; + SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); if (NULL == pVal) { pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; return DEAL_RES_ERROR; @@ -2711,11 +2719,12 @@ static int32_t replaceTbName(STranslateContext* pCxt, SSelectStmt* pSelect) { } SRealTableNode* pTable = (SRealTableNode*)pSelect->pFromTable; - if (TSDB_CHILD_TABLE != pTable->pMeta->tableType && TSDB_NORMAL_TABLE != pTable->pMeta->tableType && TSDB_SYSTEM_TABLE != pTable->pMeta->tableType) { + if (TSDB_CHILD_TABLE != pTable->pMeta->tableType && TSDB_NORMAL_TABLE != pTable->pMeta->tableType && + TSDB_SYSTEM_TABLE != pTable->pMeta->tableType) { return TSDB_CODE_SUCCESS; } - SNode** pNode = NULL; + SNode** pNode = NULL; SRewriteTbNameContext pRewriteCxt = {0}; pRewriteCxt.pTbName = pTable->table.tableName; @@ -3122,7 +3131,8 @@ static int32_t convertFillValue(STranslateContext* pCxt, SDataType dt, SNodeList code = scalarCalculateConstants(pCastFunc, &pCell->pNode); } if (TSDB_CODE_SUCCESS == code && QUERY_NODE_VALUE != nodeType(pCell->pNode)) { - code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Fill value can only accept constant"); + code = + generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Fill value can only accept constant"); } else if (TSDB_CODE_SUCCESS != code) { code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, "Filled data type mismatch"); } @@ -3588,7 +3598,6 @@ static int32_t createDefaultEveryNode(STranslateContext* pCxt, SNode** pOutput) pEvery->isDuration = true; pEvery->literal = taosStrdup("1s"); - *pOutput = (SNode*)pEvery; return TSDB_CODE_SUCCESS; } @@ -3683,15 +3692,15 @@ static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) { static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->currClause = SQL_CLAUSE_PARTITION_BY; int32_t code = TSDB_CODE_SUCCESS; - + if (pSelect->pPartitionByList) { int8_t typeType = getTableTypeFromTableNode(pSelect->pFromTable); SNode* pPar = nodesListGetNode(pSelect->pPartitionByList, 0); - if (!((TSDB_NORMAL_TABLE == typeType || TSDB_CHILD_TABLE == typeType) && - 1 == pSelect->pPartitionByList->length && (QUERY_NODE_FUNCTION == nodeType(pPar) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPar)->funcType))) { + if (!((TSDB_NORMAL_TABLE == typeType || TSDB_CHILD_TABLE == typeType) && 1 == pSelect->pPartitionByList->length && + (QUERY_NODE_FUNCTION == nodeType(pPar) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPar)->funcType))) { pSelect->timeLineResMode = TIME_LINE_MULTI; } - + code = translateExprList(pCxt, pSelect->pPartitionByList); } if (TSDB_CODE_SUCCESS == code) { @@ -3955,9 +3964,9 @@ static int32_t translateSetOperProject(STranslateContext* pCxt, SSetOperator* pS } snprintf(pRightExpr->aliasName, sizeof(pRightExpr->aliasName), "%s", pLeftExpr->aliasName); SNode* pProj = createSetOperProject(pSetOperator->stmtName, pLeft); - if (QUERY_NODE_COLUMN == nodeType(pLeft) && QUERY_NODE_COLUMN == nodeType(pRight) - && ((SColumnNode*)pLeft)->colId == PRIMARYKEY_TIMESTAMP_COL_ID - && ((SColumnNode*)pRight)->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + if (QUERY_NODE_COLUMN == nodeType(pLeft) && QUERY_NODE_COLUMN == nodeType(pRight) && + ((SColumnNode*)pLeft)->colId == PRIMARYKEY_TIMESTAMP_COL_ID && + ((SColumnNode*)pRight)->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { ((SColumnNode*)pProj)->colId = PRIMARYKEY_TIMESTAMP_COL_ID; } if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pSetOperator->pProjectionList, pProj)) { @@ -4688,6 +4697,7 @@ static int32_t columnDefNodeToField(SNodeList* pList, SArray** pArray) { SColumnDefNode* pCol = (SColumnDefNode*)pNode; SField field = {.type = pCol->dataType.type, .bytes = calcTypeBytes(pCol->dataType)}; strcpy(field.name, pCol->colName); + strcpy(field.comment, pCol->comments); if (pCol->sma) { field.flags |= COL_SMA_ON; } @@ -5035,6 +5045,7 @@ static void toSchema(const SColumnDefNode* pCol, col_id_t colId, SSchema* pSchem pSchema->bytes = calcTypeBytes(pCol->dataType); pSchema->flags = flags; strcpy(pSchema->name, pCol->colName); + strcpy(pSchema->comment, pCol->comments); } typedef struct SSampleAstInfo { @@ -5737,7 +5748,6 @@ static int32_t translateRestoreDnode(STranslateContext* pCxt, SRestoreComponentN return buildCmdMsg(pCxt, TDMT_MND_RESTORE_DNODE, (FSerializeFunc)tSerializeSRestoreDnodeReq, &restoreReq); } - static int32_t getSmaIndexDstVgId(STranslateContext* pCxt, const char* pDbName, const char* pTableName, int32_t* pVgId) { SVgroupInfo vg = {0}; @@ -5865,7 +5875,7 @@ static int32_t checkCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pS } static int32_t translateCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) { - int32_t code = checkCreateSmaIndex(pCxt, pStmt); + int32_t code = checkCreateSmaIndex(pCxt, pStmt); pStmt->pReq = taosMemoryCalloc(1, sizeof(SMCreateSmaReq)); if (pStmt->pReq == NULL) code = TSDB_CODE_OUT_OF_MEMORY; if (TSDB_CODE_SUCCESS == code) { @@ -5879,13 +5889,15 @@ int32_t createIntervalFromCreateSmaIndexStmt(SCreateIndexStmt* pStmt, SInterval* pInterval->interval = ((SValueNode*)pStmt->pOptions->pInterval)->datum.i; pInterval->intervalUnit = ((SValueNode*)pStmt->pOptions->pInterval)->unit; pInterval->offset = NULL != pStmt->pOptions->pOffset ? ((SValueNode*)pStmt->pOptions->pOffset)->datum.i : 0; - pInterval->sliding = NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->datum.i : pInterval->interval; - pInterval->slidingUnit = NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->unit : pInterval->intervalUnit; + pInterval->sliding = + NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->datum.i : pInterval->interval; + pInterval->slidingUnit = + NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->unit : pInterval->intervalUnit; pInterval->precision = pStmt->pOptions->tsPrecision; return TSDB_CODE_SUCCESS; } -int32_t translatePostCreateSmaIndex(SParseContext* pParseCxt, SQuery* pQuery, void ** pResRow) { +int32_t translatePostCreateSmaIndex(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow) { int32_t code = TSDB_CODE_SUCCESS; SCreateIndexStmt* pStmt = (SCreateIndexStmt*)pQuery->pRoot; int64_t lastTs = 0; @@ -6053,7 +6065,7 @@ static int32_t buildCreateTopicReq(STranslateContext* pCxt, SCreateTopicStmt* pS toName(pCxt->pParseCxt->acctId, pStmt->subDbName, pStmt->subSTbName, &name); tNameGetFullDbName(&name, pReq->subDbName); tNameExtractFullName(&name, pReq->subStbName); - if(pStmt->pQuery != NULL) { + if (pStmt->pQuery != NULL) { code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL); } } else if ('\0' != pStmt->subDbName[0]) { @@ -6108,11 +6120,12 @@ static EDealRes checkColumnTagsInCond(SNode* pNode, void* pContext) { addTagList(&pCxt->pTags, nodesCloneNode(pNode)); } } - + return DEAL_RES_CONTINUE; } -static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* pStmt, STableMeta* pMeta, SNodeList** ppProjection) { +static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* pStmt, STableMeta* pMeta, + SNodeList** ppProjection) { SBuildTopicContext colCxt = {.colExists = false, .colNotFound = false, .pMeta = pMeta, .pTags = NULL}; nodesWalkExprPostOrder(pStmt->pWhere, checkColumnTagsInCond, &colCxt); if (colCxt.colNotFound) { @@ -6122,18 +6135,18 @@ static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* nodesDestroyList(colCxt.pTags); return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Columns are forbidden in where clause"); } - if (NULL == colCxt.pTags) { // put one column to select -// for (int32_t i = 0; i < pMeta->tableInfo.numOfColumns; ++i) { - SSchema* column = &pMeta->schema[0]; - SColumnNode* col = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); - if (NULL == col) { - return TSDB_CODE_OUT_OF_MEMORY; - } - strcpy(col->colName, column->name); - strcpy(col->node.aliasName, col->colName); - strcpy(col->node.userAlias, col->colName); - addTagList(&colCxt.pTags, (SNode*)col); -// } + if (NULL == colCxt.pTags) { // put one column to select + // for (int32_t i = 0; i < pMeta->tableInfo.numOfColumns; ++i) { + SSchema* column = &pMeta->schema[0]; + SColumnNode* col = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); + if (NULL == col) { + return TSDB_CODE_OUT_OF_MEMORY; + } + strcpy(col->colName, column->name); + strcpy(col->node.aliasName, col->colName); + strcpy(col->node.userAlias, col->colName); + addTagList(&colCxt.pTags, (SNode*)col); + // } } *ppProjection = colCxt.pTags; @@ -6141,13 +6154,13 @@ static int32_t checkCollectTopicTags(STranslateContext* pCxt, SCreateTopicStmt* } static int32_t buildQueryForTableTopic(STranslateContext* pCxt, SCreateTopicStmt* pStmt, SNode** pSelect) { - SParseContext* pParCxt = pCxt->pParseCxt; - SRequestConnInfo connInfo = {.pTrans = pParCxt->pTransporter, - .requestId = pParCxt->requestId, + SParseContext* pParCxt = pCxt->pParseCxt; + SRequestConnInfo connInfo = {.pTrans = pParCxt->pTransporter, + .requestId = pParCxt->requestId, .requestObjRefId = pParCxt->requestRid, .mgmtEps = pParCxt->mgmtEpSet}; - SName name; - STableMeta* pMeta = NULL; + SName name; + STableMeta* pMeta = NULL; int32_t code = getTableMetaImpl(pCxt, toName(pParCxt->acctId, pStmt->subDbName, pStmt->subSTbName, &name), &pMeta); if (code) { taosMemoryFree(pMeta); @@ -6156,7 +6169,7 @@ static int32_t buildQueryForTableTopic(STranslateContext* pCxt, SCreateTopicStmt if (TSDB_SUPER_TABLE != pMeta->tableType) { taosMemoryFree(pMeta); return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Only supertable table can be used"); - } + } SNodeList* pProjection = NULL; code = checkCollectTopicTags(pCxt, pStmt, pMeta, &pProjection); @@ -6554,7 +6567,8 @@ static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStm return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "SUBTABLE expression must be of VARCHAR type"); } - if (NULL != pSelect->pSubtable && 0 == LIST_LENGTH(pSelect->pPartitionByList) && subtableExprHasColumnOrPseudoColumn(pSelect->pSubtable)) { + if (NULL != pSelect->pSubtable && 0 == LIST_LENGTH(pSelect->pPartitionByList) && + subtableExprHasColumnOrPseudoColumn(pSelect->pSubtable)) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "SUBTABLE expression must not has column when no partition by clause"); } @@ -6910,28 +6924,28 @@ static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta if (NULL == col) { return TSDB_CODE_OUT_OF_MEMORY; } - + strcpy(col->tableAlias, pTable); strcpy(col->colName, pMeta->schema[0].name); SNodeList* pParamterList = nodesMakeList(); if (NULL == pParamterList) { - nodesDestroyNode((SNode *)col); + nodesDestroyNode((SNode*)col); return TSDB_CODE_OUT_OF_MEMORY; } - - int32_t code = nodesListStrictAppend(pParamterList, (SNode *)col); + + int32_t code = nodesListStrictAppend(pParamterList, (SNode*)col); if (code) { - nodesDestroyNode((SNode *)col); + nodesDestroyNode((SNode*)col); nodesDestroyList(pParamterList); return code; } - + SNode* pFunc = (SNode*)createFunction("last", pParamterList); if (NULL == pFunc) { nodesDestroyList(pParamterList); return TSDB_CODE_OUT_OF_MEMORY; } - + SNodeList* pProjectionList = nodesMakeList(); if (NULL == pProjectionList) { nodesDestroyList(pParamterList); @@ -6943,8 +6957,8 @@ static int32_t createLastTsSelectStmt(char* pDb, char* pTable, STableMeta* pMeta nodesDestroyList(pProjectionList); return code; } - - code = createSimpleSelectStmtFromProjList(pDb, pTable, pProjectionList, (SSelectStmt **)pQuery); + + code = createSimpleSelectStmtFromProjList(pDb, pTable, pProjectionList, (SSelectStmt**)pQuery); if (code) { nodesDestroyList(pProjectionList); return code; @@ -6982,14 +6996,14 @@ static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt if (TSDB_CODE_SUCCESS == code && pStmt->pOptions->fillHistory) { SRealTableNode* pTable = (SRealTableNode*)(((SSelectStmt*)pStmt->pQuery)->pFromTable); code = createLastTsSelectStmt(pTable->table.dbName, pTable->table.tableName, pTable->pMeta, &pStmt->pPrevQuery); -/* - if (TSDB_CODE_SUCCESS == code) { - STranslateContext cxt = {0}; - int32_t code = initTranslateContext(pCxt->pParseCxt, pCxt->pMetaCache, &cxt); - code = translateQuery(&cxt, pStmt->pPrevQuery); - destroyTranslateContext(&cxt); - } -*/ + /* + if (TSDB_CODE_SUCCESS == code) { + STranslateContext cxt = {0}; + int32_t code = initTranslateContext(pCxt->pParseCxt, pCxt->pMetaCache, &cxt); + code = translateQuery(&cxt, pStmt->pPrevQuery); + destroyTranslateContext(&cxt); + } + */ } taosMemoryFree(pMeta); return code; @@ -7084,7 +7098,7 @@ static int32_t buildIntervalForCreateStream(SCreateStreamStmt* pStmt, SInterval* if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow)) { return code; } - + SIntervalWindowNode* pWindow = (SIntervalWindowNode*)pSelect->pWindow; pInterval->interval = ((SValueNode*)pWindow->pInterval)->datum.i; pInterval->intervalUnit = ((SValueNode*)pWindow->pInterval)->unit; @@ -7092,16 +7106,16 @@ static int32_t buildIntervalForCreateStream(SCreateStreamStmt* pStmt, SInterval* pInterval->sliding = (NULL != pWindow->pSliding ? ((SValueNode*)pWindow->pSliding)->datum.i : pInterval->interval); pInterval->slidingUnit = (NULL != pWindow->pSliding ? ((SValueNode*)pWindow->pSliding)->unit : pInterval->intervalUnit); - pInterval->precision = ((SColumnNode*)pWindow->pCol)->node.resType.precision; + pInterval->precision = ((SColumnNode*)pWindow->pCol)->node.resType.precision; return code; } int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow) { SCreateStreamStmt* pStmt = (SCreateStreamStmt*)pQuery->pRoot; - STranslateContext cxt = {0}; - SInterval interval = {0}; - int64_t lastTs = 0; + STranslateContext cxt = {0}; + SInterval interval = {0}; + int64_t lastTs = 0; int32_t code = initTranslateContext(pParseCxt, NULL, &cxt); if (TSDB_CODE_SUCCESS == code) { @@ -7136,7 +7150,6 @@ int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void return code; } - static int32_t translateDropStream(STranslateContext* pCxt, SDropStreamStmt* pStmt) { SMDropStreamReq dropReq = {0}; SName name; @@ -7167,7 +7180,7 @@ static int32_t translateResumeStream(STranslateContext* pCxt, SResumeStreamStmt* static int32_t readFromFile(char* pName, int32_t* len, char** buf) { int64_t filesize = 0; - if (taosStatFile(pName, &filesize, NULL) < 0) { + if (taosStatFile(pName, &filesize, NULL, NULL) < 0) { return TAOS_SYSTEM_ERROR(errno); } @@ -7261,7 +7274,7 @@ static int32_t translateGrantTagCond(STranslateContext* pCxt, SGrantStmt* pStmt, } } - int32_t code = createRealTableForGrantTable(pStmt, &pTable); + int32_t code = createRealTableForGrantTable(pStmt, &pTable); if (TSDB_CODE_SUCCESS == code) { SName name; code = getTableMetaImpl(pCxt, toName(pCxt->pParseCxt->acctId, pTable->table.dbName, pTable->table.tableName, &name), @@ -7681,6 +7694,10 @@ static int32_t extractDescribeResultSchema(int32_t* numOfCols, SSchema** pSchema (*pSchema)[3].bytes = DESCRIBE_RESULT_NOTE_LEN; strcpy((*pSchema)[3].name, "note"); + (*pSchema)[4].type = TSDB_DATA_TYPE_BINARY; + (*pSchema)[4].bytes = DESCRIBE_RESULT_COL_COMMENT_LEN; + strcpy((*pSchema)[4].name, "comment"); + return TSDB_CODE_SUCCESS; } @@ -7821,7 +7838,8 @@ static SNodeList* createProjectCols(int32_t ncols, const char* const pCols[]) { return pProjections; } -static int32_t createSimpleSelectStmtImpl(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt) { +static int32_t createSimpleSelectStmtImpl(const char* pDb, const char* pTable, SNodeList* pProjectionList, + SSelectStmt** pStmt) { SSelectStmt* pSelect = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT); if (NULL == pSelect) { return TSDB_CODE_OUT_OF_MEMORY; @@ -7844,9 +7862,8 @@ static int32_t createSimpleSelectStmtImpl(const char* pDb, const char* pTable, S return TSDB_CODE_SUCCESS; } - static int32_t createSimpleSelectStmtFromCols(const char* pDb, const char* pTable, int32_t numOfProjs, - const char* const pProjCol[], SSelectStmt** pStmt) { + const char* const pProjCol[], SSelectStmt** pStmt) { SNodeList* pProjectionList = NULL; if (numOfProjs >= 0) { pProjectionList = createProjectCols(numOfProjs, pProjCol); @@ -7858,13 +7875,15 @@ static int32_t createSimpleSelectStmtFromCols(const char* pDb, const char* pTabl return createSimpleSelectStmtImpl(pDb, pTable, pProjectionList, pStmt); } -static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, SSelectStmt** pStmt) { +static int32_t createSimpleSelectStmtFromProjList(const char* pDb, const char* pTable, SNodeList* pProjectionList, + SSelectStmt** pStmt) { return createSimpleSelectStmtImpl(pDb, pTable, pProjectionList, pStmt); } static int32_t createSelectStmtForShow(ENodeType showType, SSelectStmt** pStmt) { const SSysTableShowAdapter* pShow = &sysTableShowAdapter[showType - SYSTABLE_SHOW_TYPE_OFFSET]; - return createSimpleSelectStmtFromCols(pShow->pDbName, pShow->pTableName, pShow->numOfShowCols, pShow->pShowCols, pStmt); + return createSimpleSelectStmtFromCols(pShow->pDbName, pShow->pTableName, pShow->numOfShowCols, pShow->pShowCols, + pStmt); } static int32_t createSelectStmtForShowTableDist(SShowTableDistributedStmt* pStmt, SSelectStmt** pOutput) { @@ -8002,8 +8021,8 @@ static int32_t createShowTableTagsProjections(SNodeList** pProjections, SNodeLis static int32_t rewriteShowStableTags(STranslateContext* pCxt, SQuery* pQuery) { SShowTableTagsStmt* pShow = (SShowTableTagsStmt*)pQuery->pRoot; SSelectStmt* pSelect = NULL; - int32_t code = createSimpleSelectStmtFromCols(((SValueNode*)pShow->pDbName)->literal, ((SValueNode*)pShow->pTbName)->literal, - -1, NULL, &pSelect); + int32_t code = createSimpleSelectStmtFromCols(((SValueNode*)pShow->pDbName)->literal, + ((SValueNode*)pShow->pTbName)->literal, -1, NULL, &pSelect); if (TSDB_CODE_SUCCESS == code) { code = createShowTableTagsProjections(&pSelect->pProjectionList, &pShow->pTags); } @@ -8859,6 +8878,15 @@ static int32_t buildAddColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, S pReq->type = pStmt->dataType.type; pReq->flags = COL_SMA_ON; pReq->bytes = calcTypeBytes(pStmt->dataType); + if (pStmt->colComment[0]) { + pReq->colComment = taosStrdup(pStmt->colComment); + if (pReq->colComment == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pReq->colCommentLen = strlen(pReq->colComment); + } else { + pReq->colCommentLen = -1; + } return TSDB_CODE_SUCCESS; } @@ -8909,6 +8937,15 @@ static int32_t buildUpdateColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt return TSDB_CODE_OUT_OF_MEMORY; } pReq->colId = pSchema->colId; + if (pStmt->colComment[0]) { + pReq->colComment = taosStrdup(pStmt->colComment); + if (pReq->colComment == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; + } + pReq->colCommentLen = strlen(pReq->colComment); + } else { + pReq->colCommentLen = -1; + } return TSDB_CODE_SUCCESS; } @@ -9162,7 +9199,7 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { case QUERY_NODE_SHOW_USERS_STMT: case QUERY_NODE_SHOW_DNODES_STMT: case QUERY_NODE_SHOW_MNODES_STMT: - case QUERY_NODE_SHOW_MODULES_STMT: +// case QUERY_NODE_SHOW_MODULES_STMT: case QUERY_NODE_SHOW_QNODES_STMT: case QUERY_NODE_SHOW_FUNCTIONS_STMT: case QUERY_NODE_SHOW_INDEXES_STMT: diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index 9fa815491c322a43af8d4d8bf4eeaf0c73da62fc..db6d0932c5c56948cb14b6c50f1ce6ff34722ac2 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -161,25 +161,25 @@ #define TK_NK_EQ 112 #define TK_USING 113 #define TK_TAGS 114 -#define TK_BOOL 115 -#define TK_TINYINT 116 -#define TK_SMALLINT 117 -#define TK_INT 118 -#define TK_INTEGER 119 -#define TK_BIGINT 120 -#define TK_FLOAT 121 -#define TK_DOUBLE 122 -#define TK_BINARY 123 -#define TK_NCHAR 124 -#define TK_UNSIGNED 125 -#define TK_JSON 126 -#define TK_VARCHAR 127 -#define TK_MEDIUMBLOB 128 -#define TK_BLOB 129 -#define TK_VARBINARY 130 -#define TK_GEOMETRY 131 -#define TK_DECIMAL 132 -#define TK_COMMENT 133 +#define TK_COMMENT 115 +#define TK_BOOL 116 +#define TK_TINYINT 117 +#define TK_SMALLINT 118 +#define TK_INT 119 +#define TK_INTEGER 120 +#define TK_BIGINT 121 +#define TK_FLOAT 122 +#define TK_DOUBLE 123 +#define TK_BINARY 124 +#define TK_NCHAR 125 +#define TK_UNSIGNED 126 +#define TK_JSON 127 +#define TK_VARCHAR 128 +#define TK_MEDIUMBLOB 129 +#define TK_BLOB 130 +#define TK_VARBINARY 131 +#define TK_GEOMETRY 132 +#define TK_DECIMAL 133 #define TK_MAX_DELAY 134 #define TK_WATERMARK 135 #define TK_ROLLUP 136 @@ -479,17 +479,17 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 801 -#define YYNRULE 600 -#define YYNRULE_WITH_ACTION 600 +#define YYNSTATE 799 +#define YYNRULE 601 +#define YYNRULE_WITH_ACTION 601 #define YYNTOKEN 338 -#define YY_MAX_SHIFT 800 -#define YY_MIN_SHIFTREDUCE 1181 -#define YY_MAX_SHIFTREDUCE 1780 -#define YY_ERROR_ACTION 1781 -#define YY_ACCEPT_ACTION 1782 -#define YY_NO_ACTION 1783 -#define YY_MIN_REDUCE 1784 +#define YY_MAX_SHIFT 798 +#define YY_MIN_SHIFTREDUCE 1179 +#define YY_MAX_SHIFTREDUCE 1779 +#define YY_ERROR_ACTION 1780 +#define YY_ACCEPT_ACTION 1781 +#define YY_NO_ACTION 1782 +#define YY_MIN_REDUCE 1783 #define YY_MAX_REDUCE 2383 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -557,600 +557,618 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2858) +#define YY_ACTTAB_COUNT (3033) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 2127, 2194, 2172, 2083, 221, 691, 1961, 2155, 538, 1950, - /* 10 */ 1827, 671, 48, 46, 1707, 394, 2180, 1214, 2080, 678, - /* 20 */ 401, 2359, 1556, 41, 40, 135, 2176, 47, 45, 44, - /* 30 */ 43, 42, 575, 1637, 453, 1554, 2172, 540, 1583, 2212, - /* 40 */ 41, 40, 1782, 537, 47, 45, 44, 43, 42, 254, - /* 50 */ 1952, 2162, 1946, 707, 631, 532, 1216, 2354, 1219, 1220, - /* 60 */ 2176, 181, 1632, 530, 2178, 398, 526, 522, 19, 1239, - /* 70 */ 66, 1238, 2360, 188, 701, 1562, 30, 2355, 657, 348, - /* 80 */ 690, 369, 2066, 361, 140, 691, 1961, 2193, 1581, 2229, - /* 90 */ 668, 144, 112, 2195, 711, 2197, 2198, 706, 2178, 701, - /* 100 */ 797, 168, 1240, 15, 185, 135, 2282, 103, 701, 1902, - /* 110 */ 397, 2278, 580, 498, 2083, 416, 48, 46, 691, 1961, - /* 120 */ 415, 690, 1770, 190, 401, 264, 1556, 1666, 1372, 2081, - /* 130 */ 678, 2308, 1954, 1581, 38, 306, 1747, 1637, 193, 1554, - /* 140 */ 1639, 1640, 1807, 1363, 736, 735, 734, 1367, 733, 1369, - /* 150 */ 1370, 732, 729, 1806, 1378, 726, 1380, 1381, 723, 720, - /* 160 */ 717, 184, 631, 51, 656, 2354, 1632, 2354, 94, 62, - /* 170 */ 1612, 1622, 19, 2001, 212, 211, 1638, 1641, 676, 1562, - /* 180 */ 2360, 188, 655, 188, 1667, 2355, 657, 2355, 657, 2297, - /* 190 */ 288, 1557, 2162, 1555, 286, 2290, 667, 497, 136, 666, - /* 200 */ 169, 2354, 1796, 2162, 797, 41, 40, 15, 2194, 47, - /* 210 */ 45, 44, 43, 42, 62, 2294, 655, 188, 708, 1316, - /* 220 */ 435, 2355, 657, 1560, 1561, 1784, 1611, 1614, 1615, 1616, - /* 230 */ 1617, 1618, 1619, 1620, 1621, 703, 699, 1630, 1631, 1633, - /* 240 */ 1634, 1635, 1636, 2, 1639, 1640, 2212, 437, 433, 134, - /* 250 */ 133, 132, 131, 130, 129, 128, 127, 126, 2162, 1318, - /* 260 */ 707, 1785, 37, 399, 1661, 1662, 1663, 1664, 1665, 1669, - /* 270 */ 1670, 1671, 1672, 535, 1612, 1622, 536, 1820, 552, 1581, - /* 280 */ 1638, 1641, 125, 1465, 1466, 124, 123, 122, 121, 120, - /* 290 */ 119, 118, 117, 116, 2193, 1557, 2229, 1555, 646, 112, - /* 300 */ 2195, 711, 2197, 2198, 706, 651, 701, 2045, 395, 147, - /* 310 */ 1581, 151, 2253, 2282, 1582, 2194, 166, 397, 2278, 1239, - /* 320 */ 191, 1238, 668, 144, 1963, 671, 191, 1560, 1561, 1704, - /* 330 */ 1611, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 703, - /* 340 */ 699, 1630, 1631, 1633, 1634, 1635, 1636, 2, 12, 48, - /* 350 */ 46, 746, 1240, 2212, 2014, 410, 409, 401, 2183, 1556, - /* 360 */ 2359, 367, 62, 2354, 181, 2162, 1583, 707, 616, 2012, - /* 370 */ 1637, 191, 1554, 593, 592, 591, 691, 1961, 1563, 2358, - /* 380 */ 583, 141, 587, 2355, 2357, 2067, 586, 650, 652, 647, - /* 390 */ 640, 585, 590, 377, 376, 146, 56, 584, 2253, 1632, - /* 400 */ 252, 2193, 630, 2229, 251, 19, 112, 2195, 711, 2197, - /* 410 */ 2198, 706, 1562, 701, 2185, 2212, 297, 298, 185, 543, - /* 420 */ 2282, 296, 536, 1820, 397, 2278, 187, 2290, 2291, 2194, - /* 430 */ 142, 2295, 1222, 656, 1407, 1408, 2354, 797, 1580, 708, - /* 440 */ 15, 1829, 41, 40, 1273, 2309, 47, 45, 44, 43, - /* 450 */ 42, 655, 188, 48, 46, 1642, 2355, 657, 223, 2194, - /* 460 */ 1613, 401, 538, 1556, 1827, 93, 476, 2212, 356, 708, - /* 470 */ 649, 381, 166, 609, 1637, 475, 1554, 1639, 1640, 2162, - /* 480 */ 1964, 707, 2359, 125, 1274, 2354, 124, 123, 122, 121, - /* 490 */ 120, 119, 118, 117, 116, 2014, 62, 2212, 1805, 668, - /* 500 */ 144, 2358, 382, 1632, 12, 2355, 2356, 1612, 1622, 2162, - /* 510 */ 2012, 707, 109, 1638, 1641, 2193, 1562, 2229, 288, 191, - /* 520 */ 112, 2195, 711, 2197, 2198, 706, 60, 701, 1557, 145, - /* 530 */ 1555, 579, 2374, 628, 2282, 578, 1566, 1953, 397, 2278, - /* 540 */ 1711, 797, 691, 1961, 49, 2193, 1581, 2229, 2162, 2194, - /* 550 */ 170, 2195, 711, 2197, 2198, 706, 12, 701, 10, 708, - /* 560 */ 1560, 1561, 451, 1611, 1614, 1615, 1616, 1617, 1618, 1619, - /* 570 */ 1620, 1621, 703, 699, 1630, 1631, 1633, 1634, 1635, 1636, - /* 580 */ 2, 1639, 1640, 445, 1327, 444, 1703, 2212, 41, 40, - /* 590 */ 632, 2319, 47, 45, 44, 43, 42, 1326, 2297, 2162, - /* 600 */ 1584, 707, 670, 186, 2290, 2291, 165, 142, 2295, 1562, - /* 610 */ 1804, 1612, 1622, 691, 1961, 443, 406, 1638, 1641, 2007, - /* 620 */ 2009, 41, 40, 404, 2293, 47, 45, 44, 43, 42, - /* 630 */ 2297, 163, 1557, 452, 1555, 2193, 677, 2229, 383, 1963, - /* 640 */ 112, 2195, 711, 2197, 2198, 706, 2012, 701, 253, 690, - /* 650 */ 447, 2194, 2257, 191, 2282, 446, 2292, 2156, 397, 2278, - /* 660 */ 2162, 708, 507, 2316, 1560, 1561, 154, 1611, 1614, 1615, - /* 670 */ 1616, 1617, 1618, 1619, 1620, 1621, 703, 699, 1630, 1631, - /* 680 */ 1633, 1634, 1635, 1636, 2, 48, 46, 1938, 550, 2212, - /* 690 */ 2076, 458, 2062, 401, 756, 1556, 1613, 631, 668, 144, - /* 700 */ 2354, 2162, 2014, 707, 631, 1937, 1637, 2354, 1554, 391, - /* 710 */ 47, 45, 44, 43, 42, 2360, 188, 2012, 1527, 1528, - /* 720 */ 2355, 657, 2360, 188, 464, 2062, 55, 2355, 657, 14, - /* 730 */ 13, 1735, 51, 691, 1961, 1632, 1948, 2193, 202, 2229, - /* 740 */ 598, 677, 112, 2195, 711, 2197, 2198, 706, 1562, 701, - /* 750 */ 691, 1961, 266, 466, 2374, 608, 2282, 1863, 41, 40, - /* 760 */ 397, 2278, 47, 45, 44, 43, 42, 2194, 1803, 250, - /* 770 */ 481, 205, 746, 797, 691, 1961, 49, 705, 643, 642, - /* 780 */ 1733, 1734, 1736, 1737, 1738, 601, 491, 2062, 2358, 48, - /* 790 */ 46, 1936, 595, 675, 482, 2076, 1777, 401, 249, 1556, - /* 800 */ 404, 1582, 189, 2290, 2291, 2212, 142, 2295, 166, 693, - /* 810 */ 1637, 2254, 1554, 1639, 1640, 1847, 1963, 2162, 2162, 707, - /* 820 */ 744, 156, 155, 741, 740, 739, 153, 593, 592, 591, - /* 830 */ 2008, 2009, 1680, 210, 583, 141, 587, 594, 70, 1632, - /* 840 */ 586, 69, 52, 1612, 1622, 585, 590, 377, 376, 1638, - /* 850 */ 1641, 584, 1562, 2193, 1746, 2229, 1242, 1243, 342, 2195, - /* 860 */ 711, 2197, 2198, 706, 1557, 701, 1555, 2248, 41, 40, - /* 870 */ 1802, 1944, 47, 45, 44, 43, 42, 797, 571, 570, - /* 880 */ 15, 2194, 744, 156, 155, 741, 740, 739, 153, 1801, - /* 890 */ 614, 708, 207, 2329, 1800, 1965, 1560, 1561, 1776, 1611, - /* 900 */ 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 703, 699, - /* 910 */ 1630, 1631, 1633, 1634, 1635, 1636, 2, 1639, 1640, 2212, - /* 920 */ 2162, 1482, 1483, 607, 744, 156, 155, 741, 740, 739, - /* 930 */ 153, 2162, 86, 707, 2014, 85, 605, 631, 603, 2162, - /* 940 */ 2354, 396, 691, 1961, 2162, 691, 1961, 1612, 1622, 2012, - /* 950 */ 737, 691, 1961, 1638, 1641, 2360, 188, 1481, 1484, 259, - /* 960 */ 2355, 657, 551, 738, 1723, 1958, 2005, 2193, 1557, 2229, - /* 970 */ 1555, 255, 112, 2195, 711, 2197, 2198, 706, 9, 701, - /* 980 */ 589, 588, 34, 2148, 2374, 1331, 2282, 677, 41, 40, - /* 990 */ 397, 2278, 47, 45, 44, 43, 42, 1799, 1330, 191, - /* 1000 */ 1560, 1561, 1860, 1611, 1614, 1615, 1616, 1617, 1618, 1619, - /* 1010 */ 1620, 1621, 703, 699, 1630, 1631, 1633, 1634, 1635, 1636, - /* 1020 */ 2, 1647, 352, 167, 1579, 691, 1961, 1581, 327, 691, - /* 1030 */ 1961, 489, 423, 90, 505, 573, 572, 504, 2172, 686, - /* 1040 */ 407, 2076, 324, 73, 2145, 263, 72, 2162, 166, 674, - /* 1050 */ 371, 2014, 2181, 472, 672, 506, 1963, 349, 405, 1956, - /* 1060 */ 474, 702, 2176, 509, 1798, 659, 2012, 1795, 219, 517, - /* 1070 */ 515, 512, 774, 773, 772, 771, 413, 1939, 770, 769, - /* 1080 */ 148, 764, 763, 762, 761, 760, 759, 758, 158, 754, - /* 1090 */ 753, 752, 412, 411, 749, 748, 747, 176, 175, 1584, - /* 1100 */ 2178, 631, 691, 1961, 2354, 1584, 370, 237, 62, 374, - /* 1110 */ 701, 44, 43, 42, 2162, 691, 1961, 2162, 460, 2360, - /* 1120 */ 188, 149, 301, 173, 2355, 657, 691, 1961, 660, 691, - /* 1130 */ 1961, 569, 565, 561, 557, 688, 236, 1794, 663, 695, - /* 1140 */ 1668, 2254, 768, 766, 1793, 1792, 689, 111, 502, 307, - /* 1150 */ 1791, 496, 495, 494, 493, 488, 487, 486, 485, 484, - /* 1160 */ 480, 479, 478, 477, 351, 469, 468, 467, 698, 462, - /* 1170 */ 461, 368, 691, 1961, 2302, 1700, 91, 1613, 375, 234, - /* 1180 */ 373, 372, 1838, 577, 90, 1790, 1789, 2162, 81, 80, - /* 1190 */ 450, 2194, 408, 200, 2162, 2162, 1788, 2014, 1700, 742, - /* 1200 */ 2162, 708, 2005, 638, 596, 579, 442, 440, 1787, 578, - /* 1210 */ 1957, 743, 2013, 320, 2005, 262, 1991, 350, 35, 54, - /* 1220 */ 431, 3, 2194, 429, 425, 421, 418, 443, 1673, 2212, - /* 1230 */ 757, 2055, 708, 1923, 2347, 2162, 2162, 1219, 1220, 154, - /* 1240 */ 83, 2162, 137, 707, 1903, 74, 2162, 233, 227, 154, - /* 1250 */ 242, 203, 2194, 240, 232, 548, 244, 265, 2162, 243, - /* 1260 */ 2212, 430, 708, 246, 2301, 191, 245, 1797, 248, 581, - /* 1270 */ 456, 247, 2162, 225, 707, 582, 1836, 2193, 611, 2229, - /* 1280 */ 610, 50, 112, 2195, 711, 2197, 2198, 706, 1565, 701, - /* 1290 */ 2212, 1314, 1779, 1780, 2374, 84, 2282, 1312, 599, 1522, - /* 1300 */ 397, 2278, 2162, 644, 707, 1564, 750, 50, 2193, 1525, - /* 1310 */ 2229, 14, 13, 112, 2195, 711, 2197, 2198, 706, 270, - /* 1320 */ 701, 154, 50, 1658, 1556, 2374, 294, 2282, 1292, 71, - /* 1330 */ 152, 397, 2278, 2322, 751, 154, 64, 1554, 2193, 50, - /* 1340 */ 2229, 1732, 2194, 112, 2195, 711, 2197, 2198, 706, 50, - /* 1350 */ 701, 1830, 708, 410, 409, 2374, 1290, 2282, 36, 715, - /* 1360 */ 283, 397, 2278, 1570, 41, 40, 661, 1731, 47, 45, - /* 1370 */ 44, 43, 42, 2194, 1637, 108, 1563, 1562, 664, 272, - /* 1380 */ 2212, 673, 1479, 708, 152, 105, 299, 139, 277, 683, - /* 1390 */ 303, 1901, 2162, 154, 707, 1357, 1674, 138, 152, 1623, - /* 1400 */ 2213, 792, 797, 1632, 1900, 384, 414, 2071, 1821, 319, - /* 1410 */ 2194, 2212, 1826, 2002, 2312, 669, 1562, 282, 285, 1385, - /* 1420 */ 708, 1, 5, 2162, 417, 707, 422, 365, 2193, 1587, - /* 1430 */ 2229, 439, 438, 112, 2195, 711, 2197, 2198, 706, 196, - /* 1440 */ 701, 697, 195, 441, 1389, 2255, 1568, 2282, 2212, 198, - /* 1450 */ 1503, 397, 2278, 1396, 314, 1580, 457, 1394, 157, 2193, - /* 1460 */ 2162, 2229, 707, 1567, 112, 2195, 711, 2197, 2198, 706, - /* 1470 */ 209, 701, 1584, 459, 2072, 463, 694, 500, 2282, 465, - /* 1480 */ 1579, 490, 397, 2278, 470, 483, 2064, 492, 499, 501, - /* 1490 */ 510, 511, 508, 1557, 213, 1555, 2193, 214, 2229, 2194, - /* 1500 */ 513, 113, 2195, 711, 2197, 2198, 706, 514, 701, 708, - /* 1510 */ 1585, 533, 216, 516, 518, 2282, 4, 534, 541, 2281, - /* 1520 */ 2278, 542, 544, 1582, 224, 1560, 1561, 545, 226, 1586, - /* 1530 */ 546, 1588, 1571, 547, 1566, 229, 549, 2212, 231, 88, - /* 1540 */ 89, 553, 235, 574, 355, 576, 1951, 114, 2194, 2162, - /* 1550 */ 239, 707, 1947, 613, 615, 619, 92, 618, 708, 315, - /* 1560 */ 150, 256, 620, 2136, 1574, 1576, 241, 159, 160, 1949, - /* 1570 */ 258, 260, 1945, 161, 2194, 162, 2133, 699, 1630, 1631, - /* 1580 */ 1633, 1634, 1635, 1636, 705, 2193, 2212, 2229, 626, 1510, - /* 1590 */ 113, 2195, 711, 2197, 2198, 706, 623, 701, 2162, 2132, - /* 1600 */ 707, 635, 645, 681, 2282, 8, 2328, 2313, 696, 2278, - /* 1610 */ 2323, 641, 2212, 387, 625, 2327, 648, 624, 268, 271, - /* 1620 */ 2304, 654, 276, 636, 2162, 2194, 707, 633, 634, 662, - /* 1630 */ 281, 388, 1700, 284, 709, 708, 2229, 2353, 2194, 113, - /* 1640 */ 2195, 711, 2197, 2198, 706, 2377, 701, 143, 708, 665, - /* 1650 */ 1583, 178, 278, 2282, 2298, 289, 1589, 360, 2278, 2077, - /* 1660 */ 2193, 98, 2229, 2212, 316, 342, 2195, 711, 2197, 2198, - /* 1670 */ 706, 704, 701, 692, 2247, 2162, 2212, 707, 174, 679, - /* 1680 */ 279, 280, 684, 100, 685, 680, 317, 2194, 2162, 318, - /* 1690 */ 707, 2091, 2090, 102, 2089, 61, 2263, 708, 393, 104, - /* 1700 */ 713, 1924, 2006, 1962, 2194, 321, 793, 2154, 325, 345, - /* 1710 */ 796, 2193, 794, 2229, 708, 330, 171, 2195, 711, 2197, - /* 1720 */ 2198, 706, 310, 701, 2193, 2212, 2229, 53, 323, 113, - /* 1730 */ 2195, 711, 2197, 2198, 706, 344, 701, 2162, 357, 707, - /* 1740 */ 2153, 358, 2212, 2282, 334, 2152, 78, 385, 2279, 2149, - /* 1750 */ 419, 420, 1547, 2194, 2162, 1548, 707, 194, 424, 2147, - /* 1760 */ 426, 427, 428, 708, 2146, 366, 2144, 658, 2375, 432, - /* 1770 */ 2143, 2142, 434, 2193, 436, 2229, 1538, 2194, 170, 2195, - /* 1780 */ 711, 2197, 2198, 706, 2123, 701, 197, 708, 2122, 199, - /* 1790 */ 2193, 2212, 2229, 79, 1506, 343, 2195, 711, 2197, 2198, - /* 1800 */ 706, 1505, 701, 2162, 2194, 707, 2104, 2103, 2102, 448, - /* 1810 */ 449, 2101, 2100, 2054, 708, 2212, 1456, 454, 2051, 2320, - /* 1820 */ 386, 455, 201, 2050, 2194, 82, 2049, 2162, 2048, 707, - /* 1830 */ 2053, 2052, 204, 2047, 708, 2046, 2044, 2043, 2042, 2193, - /* 1840 */ 206, 2229, 2212, 2041, 336, 2195, 711, 2197, 2198, 706, - /* 1850 */ 473, 701, 471, 2057, 2162, 2040, 707, 2039, 2038, 2037, - /* 1860 */ 2036, 2035, 2212, 2193, 2034, 2229, 2033, 392, 343, 2195, - /* 1870 */ 711, 2197, 2198, 706, 2162, 701, 707, 353, 1458, 208, - /* 1880 */ 2025, 87, 2024, 2023, 2022, 2056, 2021, 653, 2032, 2031, - /* 1890 */ 2193, 2194, 2229, 2030, 2029, 171, 2195, 711, 2197, 2198, - /* 1900 */ 706, 708, 701, 2028, 2027, 2026, 2020, 2019, 2018, 2017, - /* 1910 */ 2193, 503, 2229, 2016, 2015, 343, 2195, 711, 2197, 2198, - /* 1920 */ 706, 2194, 701, 1328, 354, 1866, 1324, 215, 1865, 2212, - /* 1930 */ 217, 708, 1332, 1864, 400, 218, 1862, 1859, 521, 520, - /* 1940 */ 1858, 2162, 1851, 707, 524, 528, 519, 2376, 1840, 1816, - /* 1950 */ 523, 525, 527, 531, 1815, 529, 2121, 1221, 2111, 2212, - /* 1960 */ 76, 220, 2099, 77, 402, 228, 182, 2182, 230, 222, - /* 1970 */ 183, 2162, 2098, 707, 539, 2075, 1940, 2193, 1861, 2229, - /* 1980 */ 2194, 1857, 343, 2195, 711, 2197, 2198, 706, 617, 701, - /* 1990 */ 708, 556, 554, 555, 1855, 558, 559, 1853, 560, 1266, - /* 2000 */ 562, 1850, 563, 564, 566, 568, 800, 2193, 1835, 2229, - /* 2010 */ 567, 1833, 343, 2195, 711, 2197, 2198, 706, 2212, 701, - /* 2020 */ 313, 1834, 1832, 1812, 1942, 1401, 1400, 1941, 1315, 765, - /* 2030 */ 2162, 1313, 707, 1311, 1310, 1309, 180, 1308, 1307, 767, - /* 2040 */ 1304, 1303, 238, 63, 790, 786, 782, 778, 1302, 311, - /* 2050 */ 1301, 1848, 378, 2194, 379, 1837, 380, 1811, 1810, 1809, - /* 2060 */ 597, 606, 2120, 708, 1839, 115, 612, 1536, 2229, 57, - /* 2070 */ 600, 338, 2195, 711, 2197, 2198, 706, 602, 701, 604, - /* 2080 */ 29, 1532, 1534, 1531, 2194, 67, 2110, 1512, 1514, 110, - /* 2090 */ 1516, 2212, 304, 621, 708, 2097, 2096, 2359, 17, 58, - /* 2100 */ 20, 6, 65, 2162, 1764, 707, 23, 622, 7, 21, - /* 2110 */ 275, 1491, 261, 1490, 1749, 31, 267, 637, 639, 2194, - /* 2120 */ 2183, 269, 2212, 627, 629, 687, 22, 274, 164, 708, - /* 2130 */ 2095, 33, 1730, 1722, 2162, 1769, 707, 1770, 18, 2193, - /* 2140 */ 172, 2229, 24, 273, 328, 2195, 711, 2197, 2198, 706, - /* 2150 */ 1763, 701, 32, 95, 389, 1768, 2194, 2212, 287, 1767, - /* 2160 */ 291, 390, 59, 177, 2074, 1697, 708, 290, 97, 2162, - /* 2170 */ 2193, 707, 2229, 2073, 1696, 326, 2195, 711, 2197, 2198, - /* 2180 */ 706, 2194, 701, 96, 292, 293, 257, 25, 99, 1728, - /* 2190 */ 105, 708, 295, 300, 2212, 682, 68, 305, 302, 26, - /* 2200 */ 101, 1649, 1648, 13, 179, 2193, 2162, 2229, 707, 1572, - /* 2210 */ 329, 2195, 711, 2197, 2198, 706, 11, 701, 2194, 2212, - /* 2220 */ 2232, 192, 1604, 712, 714, 1627, 1625, 403, 708, 1624, - /* 2230 */ 700, 2162, 1596, 707, 39, 16, 27, 1659, 28, 718, - /* 2240 */ 1386, 716, 2193, 2194, 2229, 1383, 719, 335, 2195, 711, - /* 2250 */ 2197, 2198, 706, 708, 701, 1382, 2212, 721, 1379, 722, - /* 2260 */ 724, 710, 725, 727, 1373, 728, 730, 2193, 2162, 2229, - /* 2270 */ 707, 1371, 339, 2195, 711, 2197, 2198, 706, 731, 701, - /* 2280 */ 106, 2212, 308, 1377, 107, 1395, 1376, 75, 1375, 1391, - /* 2290 */ 1374, 1296, 1264, 2162, 745, 707, 1295, 1294, 1293, 1291, - /* 2300 */ 1289, 1288, 1322, 1287, 2193, 755, 2229, 1285, 1282, 331, - /* 2310 */ 2195, 711, 2197, 2198, 706, 2194, 701, 309, 1284, 1283, - /* 2320 */ 1281, 1319, 1280, 1279, 1317, 708, 1276, 1275, 1272, 2193, - /* 2330 */ 2194, 2229, 1271, 1269, 340, 2195, 711, 2197, 2198, 706, - /* 2340 */ 708, 701, 1270, 1856, 775, 776, 777, 1854, 2194, 779, - /* 2350 */ 780, 781, 1852, 2212, 783, 784, 785, 1849, 708, 787, - /* 2360 */ 789, 1831, 788, 791, 1211, 2162, 1808, 707, 2212, 799, - /* 2370 */ 312, 795, 1783, 1558, 1783, 322, 798, 1783, 1783, 1783, - /* 2380 */ 2162, 1783, 707, 1783, 1783, 1783, 2212, 1783, 1783, 1783, - /* 2390 */ 1783, 1783, 1783, 1783, 1783, 2194, 1783, 1783, 2162, 1783, - /* 2400 */ 707, 2193, 1783, 2229, 1783, 708, 332, 2195, 711, 2197, - /* 2410 */ 2198, 706, 1783, 701, 1783, 1783, 2193, 2194, 2229, 1783, - /* 2420 */ 1783, 341, 2195, 711, 2197, 2198, 706, 708, 701, 1783, - /* 2430 */ 1783, 1783, 1783, 2212, 2193, 1783, 2229, 1783, 1783, 333, - /* 2440 */ 2195, 711, 2197, 2198, 706, 2162, 701, 707, 1783, 1783, - /* 2450 */ 1783, 1783, 1783, 1783, 1783, 2212, 1783, 1783, 1783, 1783, - /* 2460 */ 1783, 1783, 1783, 1783, 2194, 1783, 1783, 2162, 1783, 707, - /* 2470 */ 1783, 1783, 1783, 1783, 708, 1783, 1783, 1783, 1783, 1783, - /* 2480 */ 1783, 2193, 1783, 2229, 1783, 1783, 346, 2195, 711, 2197, - /* 2490 */ 2198, 706, 1783, 701, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2500 */ 1783, 1783, 2212, 2193, 1783, 2229, 1783, 1783, 347, 2195, - /* 2510 */ 711, 2197, 2198, 706, 2162, 701, 707, 1783, 1783, 1783, - /* 2520 */ 1783, 1783, 1783, 2194, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2530 */ 1783, 1783, 1783, 708, 1783, 1783, 2194, 1783, 1783, 1783, - /* 2540 */ 1783, 1783, 1783, 1783, 1783, 1783, 708, 1783, 1783, 1783, - /* 2550 */ 2193, 1783, 2229, 2194, 1783, 2206, 2195, 711, 2197, 2198, - /* 2560 */ 706, 2212, 701, 708, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2570 */ 1783, 1783, 1783, 2162, 2212, 707, 1783, 1783, 1783, 1783, - /* 2580 */ 1783, 1783, 1783, 1783, 1783, 2194, 2162, 1783, 707, 1783, - /* 2590 */ 1783, 2212, 1783, 1783, 1783, 708, 1783, 1783, 1783, 1783, - /* 2600 */ 1783, 1783, 1783, 2162, 1783, 707, 1783, 1783, 1783, 2193, - /* 2610 */ 1783, 2229, 1783, 1783, 2205, 2195, 711, 2197, 2198, 706, - /* 2620 */ 1783, 701, 2193, 2212, 2229, 1783, 1783, 2204, 2195, 711, - /* 2630 */ 2197, 2198, 706, 1783, 701, 2162, 1783, 707, 1783, 2193, - /* 2640 */ 1783, 2229, 1783, 1783, 362, 2195, 711, 2197, 2198, 706, - /* 2650 */ 1783, 701, 2194, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2660 */ 1783, 1783, 708, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2670 */ 1783, 2193, 2194, 2229, 1783, 1783, 363, 2195, 711, 2197, - /* 2680 */ 2198, 706, 708, 701, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2690 */ 2212, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2700 */ 1783, 1783, 2162, 1783, 707, 1783, 1783, 1783, 1783, 1783, - /* 2710 */ 2212, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2720 */ 1783, 1783, 2162, 1783, 707, 1783, 1783, 1783, 1783, 1783, - /* 2730 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2193, 1783, - /* 2740 */ 2229, 1783, 2194, 359, 2195, 711, 2197, 2198, 706, 1783, - /* 2750 */ 701, 1783, 708, 1783, 1783, 1783, 1783, 1783, 2193, 2194, - /* 2760 */ 2229, 1783, 1783, 364, 2195, 711, 2197, 2198, 706, 708, - /* 2770 */ 701, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2780 */ 2212, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2790 */ 1783, 1783, 2162, 1783, 707, 1783, 1783, 2212, 1783, 1783, - /* 2800 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 2162, - /* 2810 */ 1783, 707, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - /* 2820 */ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 709, 1783, - /* 2830 */ 2229, 1783, 1783, 338, 2195, 711, 2197, 2198, 706, 1783, - /* 2840 */ 701, 1783, 1783, 1783, 1783, 2193, 1783, 2229, 1783, 1783, - /* 2850 */ 337, 2195, 711, 2197, 2198, 706, 1783, 701, + /* 0 */ 443, 2194, 221, 2014, 449, 442, 534, 2155, 1826, 378, + /* 10 */ 2083, 667, 48, 46, 1706, 2359, 734, 2012, 2354, 646, + /* 20 */ 397, 181, 1555, 41, 40, 2081, 674, 47, 45, 44, + /* 30 */ 43, 42, 255, 1636, 2358, 1553, 686, 400, 2355, 2357, + /* 40 */ 2212, 2067, 1781, 2083, 1580, 1962, 163, 627, 2212, 344, + /* 50 */ 2354, 2162, 379, 703, 627, 390, 686, 2354, 2080, 674, + /* 60 */ 2012, 652, 1631, 223, 2354, 2360, 188, 534, 19, 1826, + /* 70 */ 2355, 653, 2360, 188, 1237, 1561, 1236, 2355, 653, 651, + /* 80 */ 188, 687, 1960, 357, 2355, 653, 1580, 2193, 90, 2229, + /* 90 */ 664, 144, 112, 2195, 707, 2197, 2198, 702, 2183, 697, + /* 100 */ 795, 135, 645, 15, 185, 367, 2282, 1238, 571, 531, + /* 110 */ 393, 2278, 532, 1819, 1955, 412, 48, 46, 1806, 51, + /* 120 */ 411, 528, 1555, 190, 397, 656, 1555, 1665, 1371, 526, + /* 130 */ 672, 2308, 522, 518, 2055, 1553, 686, 1636, 673, 1553, + /* 140 */ 1638, 1639, 454, 2062, 1362, 732, 731, 730, 1366, 729, + /* 150 */ 1368, 1369, 728, 725, 2185, 1377, 722, 1379, 1380, 719, + /* 160 */ 716, 713, 627, 548, 2359, 2354, 1631, 2354, 2162, 62, + /* 170 */ 1611, 1621, 19, 452, 66, 1561, 1637, 1640, 2145, 1561, + /* 180 */ 2360, 188, 647, 2358, 1666, 2355, 653, 2355, 2356, 202, + /* 190 */ 546, 1556, 2076, 1554, 282, 2290, 663, 2359, 136, 662, + /* 200 */ 795, 2354, 38, 302, 795, 41, 40, 15, 2194, 47, + /* 210 */ 45, 44, 43, 42, 1582, 744, 651, 188, 704, 51, + /* 220 */ 612, 2355, 653, 1559, 1560, 1784, 1610, 1613, 1614, 1615, + /* 230 */ 1616, 1617, 1618, 1619, 1620, 699, 695, 1629, 1630, 1632, + /* 240 */ 1633, 1634, 1635, 2, 1638, 1639, 125, 2212, 12, 124, + /* 250 */ 123, 122, 121, 120, 119, 118, 117, 116, 2162, 169, + /* 260 */ 703, 1795, 37, 395, 1660, 1661, 1662, 1663, 1664, 1668, + /* 270 */ 1669, 1670, 1671, 62, 1611, 1621, 191, 1580, 1561, 125, + /* 280 */ 1637, 1640, 124, 123, 122, 121, 120, 119, 118, 117, + /* 290 */ 116, 1556, 603, 1554, 2193, 1556, 2229, 1554, 1769, 112, + /* 300 */ 2195, 707, 2197, 2198, 702, 601, 697, 599, 2014, 147, + /* 310 */ 735, 155, 2253, 2282, 387, 2194, 539, 393, 2278, 532, + /* 320 */ 1819, 168, 2012, 1559, 1560, 667, 191, 1559, 1560, 1901, + /* 330 */ 1610, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 699, + /* 340 */ 695, 1629, 1630, 1632, 1633, 1634, 1635, 2, 12, 48, + /* 350 */ 46, 687, 1960, 62, 2212, 2014, 754, 397, 536, 1555, + /* 360 */ 494, 363, 1581, 657, 533, 2162, 284, 703, 181, 2012, + /* 370 */ 1636, 135, 1553, 589, 588, 587, 687, 1960, 576, 103, + /* 380 */ 579, 141, 583, 1237, 659, 1236, 582, 365, 2066, 52, + /* 390 */ 184, 581, 586, 373, 372, 426, 193, 580, 140, 1631, + /* 400 */ 2297, 2193, 2001, 2229, 1953, 19, 112, 2195, 707, 2197, + /* 410 */ 2198, 702, 1561, 697, 687, 1960, 1238, 698, 185, 1325, + /* 420 */ 2282, 212, 211, 1212, 393, 2278, 2294, 1464, 1465, 2194, + /* 430 */ 191, 248, 1324, 652, 56, 247, 2354, 795, 1936, 704, + /* 440 */ 15, 1828, 41, 40, 493, 2309, 47, 45, 44, 43, + /* 450 */ 42, 651, 188, 48, 46, 1641, 2355, 653, 258, 2194, + /* 460 */ 1783, 397, 1214, 1555, 1217, 1218, 2014, 402, 2212, 701, + /* 470 */ 2007, 2009, 392, 431, 1636, 1902, 1553, 1638, 1639, 2162, + /* 480 */ 2012, 703, 1481, 1482, 134, 133, 132, 131, 130, 129, + /* 490 */ 128, 127, 126, 460, 2062, 1581, 93, 503, 2212, 352, + /* 500 */ 433, 429, 377, 1631, 605, 744, 1710, 1611, 1621, 2162, + /* 510 */ 191, 703, 1580, 1637, 1640, 2193, 1561, 2229, 1480, 1483, + /* 520 */ 112, 2195, 707, 2197, 2198, 702, 146, 697, 1556, 2253, + /* 530 */ 1554, 1862, 2374, 1796, 2282, 664, 144, 2322, 393, 2278, + /* 540 */ 205, 795, 687, 1960, 49, 2193, 191, 2229, 2008, 2009, + /* 550 */ 338, 2195, 707, 2197, 2198, 702, 700, 697, 688, 2247, + /* 560 */ 1559, 1560, 447, 1610, 1613, 1614, 1615, 1616, 1617, 1618, + /* 570 */ 1619, 1620, 699, 695, 1629, 1630, 1632, 1633, 1634, 1635, + /* 580 */ 2, 1638, 1639, 41, 40, 687, 1960, 47, 45, 44, + /* 590 */ 43, 42, 41, 40, 279, 1583, 47, 45, 44, 43, + /* 600 */ 42, 589, 588, 587, 1734, 448, 165, 640, 579, 141, + /* 610 */ 583, 1611, 1621, 1329, 582, 1406, 1407, 1637, 1640, 581, + /* 620 */ 586, 373, 372, 2014, 660, 580, 1328, 391, 30, 401, + /* 630 */ 687, 1960, 1556, 370, 1554, 1962, 166, 2012, 666, 186, + /* 640 */ 2290, 2291, 139, 142, 2295, 487, 2062, 2156, 2194, 1937, + /* 650 */ 462, 639, 638, 1732, 1733, 1735, 1736, 1737, 704, 1582, + /* 660 */ 2316, 1314, 1612, 9, 1559, 1560, 1935, 1610, 1613, 1614, + /* 670 */ 1615, 1616, 1617, 1618, 1619, 1620, 699, 695, 1629, 1630, + /* 680 */ 1632, 1633, 1634, 1635, 2, 48, 46, 2212, 1746, 687, + /* 690 */ 1960, 505, 210, 397, 627, 1555, 2127, 2354, 2162, 1805, + /* 700 */ 703, 1316, 371, 1900, 369, 368, 1636, 573, 1553, 477, + /* 710 */ 1271, 575, 2360, 188, 2045, 41, 40, 2355, 653, 47, + /* 720 */ 45, 44, 43, 42, 41, 40, 1240, 1241, 47, 45, + /* 730 */ 44, 43, 42, 574, 2193, 1631, 2229, 567, 566, 112, + /* 740 */ 2195, 707, 2197, 2198, 702, 250, 697, 262, 1561, 2162, + /* 750 */ 1272, 2374, 207, 2282, 2297, 41, 40, 393, 2278, 47, + /* 760 */ 45, 44, 43, 42, 742, 14, 13, 2194, 47, 45, + /* 770 */ 44, 43, 42, 795, 687, 1960, 49, 701, 594, 642, + /* 780 */ 2293, 742, 2014, 160, 159, 739, 738, 737, 157, 48, + /* 790 */ 46, 2213, 86, 604, 478, 85, 2013, 397, 2297, 1555, + /* 800 */ 160, 159, 739, 738, 737, 157, 2212, 246, 569, 568, + /* 810 */ 1636, 284, 1553, 1638, 1639, 34, 273, 2162, 249, 703, + /* 820 */ 1745, 41, 40, 597, 2292, 47, 45, 44, 43, 42, + /* 830 */ 591, 1899, 673, 673, 687, 1960, 245, 687, 1960, 1631, + /* 840 */ 293, 294, 1646, 1611, 1621, 292, 1667, 380, 1580, 1637, + /* 850 */ 1640, 1722, 1561, 2193, 547, 2229, 410, 1957, 338, 2195, + /* 860 */ 707, 2197, 2198, 702, 1556, 697, 1554, 2248, 1679, 648, + /* 870 */ 643, 636, 610, 472, 687, 1960, 70, 795, 1804, 69, + /* 880 */ 15, 2194, 471, 1699, 671, 682, 2076, 2076, 1526, 1527, + /* 890 */ 1776, 704, 736, 2329, 251, 2005, 1559, 1560, 2358, 1610, + /* 900 */ 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 699, 695, + /* 910 */ 1629, 1630, 1632, 1633, 1634, 1635, 2, 1638, 1639, 627, + /* 920 */ 2212, 2172, 2354, 740, 35, 2172, 2005, 2172, 2162, 406, + /* 930 */ 405, 2162, 1820, 703, 1672, 1951, 1825, 2360, 188, 2180, + /* 940 */ 1220, 2181, 2355, 653, 1803, 2176, 1579, 1611, 1621, 2176, + /* 950 */ 36, 2176, 1562, 1637, 1640, 1703, 41, 40, 585, 584, + /* 960 */ 47, 45, 44, 43, 42, 687, 1960, 2193, 1556, 2229, + /* 970 */ 1554, 1802, 112, 2195, 707, 2197, 2198, 702, 626, 697, + /* 980 */ 44, 43, 42, 2178, 2374, 259, 2282, 2178, 394, 2178, + /* 990 */ 393, 2278, 1775, 697, 2162, 664, 144, 697, 1612, 697, + /* 1000 */ 1559, 1560, 1859, 1610, 1613, 1614, 1615, 1616, 1617, 1618, + /* 1010 */ 1619, 1620, 699, 695, 1629, 1630, 1632, 1633, 1634, 1635, + /* 1020 */ 2, 2162, 348, 167, 1578, 575, 62, 1801, 323, 687, + /* 1030 */ 1960, 485, 687, 1960, 501, 664, 144, 500, 687, 1960, + /* 1040 */ 766, 764, 320, 73, 687, 1960, 72, 574, 12, 670, + /* 1050 */ 10, 2071, 297, 468, 400, 502, 2312, 345, 684, 689, + /* 1060 */ 470, 2254, 1962, 166, 685, 665, 1800, 1799, 219, 513, + /* 1070 */ 511, 508, 772, 771, 770, 769, 409, 2162, 768, 767, + /* 1080 */ 148, 762, 761, 760, 759, 758, 757, 756, 162, 752, + /* 1090 */ 751, 750, 408, 407, 747, 746, 745, 176, 175, 187, + /* 1100 */ 2290, 2291, 60, 142, 2295, 1583, 366, 237, 62, 624, + /* 1110 */ 1565, 403, 691, 441, 2254, 440, 2162, 2162, 456, 1962, + /* 1120 */ 166, 1949, 166, 173, 1583, 109, 687, 1960, 1798, 687, + /* 1130 */ 1960, 565, 561, 557, 553, 1797, 236, 1794, 1580, 189, + /* 1140 */ 2290, 2291, 145, 142, 2295, 439, 303, 111, 498, 404, + /* 1150 */ 1952, 492, 491, 490, 489, 484, 483, 482, 481, 480, + /* 1160 */ 476, 475, 474, 473, 347, 465, 464, 463, 668, 458, + /* 1170 */ 457, 364, 1793, 2002, 90, 655, 91, 281, 2162, 234, + /* 1180 */ 1945, 166, 1792, 191, 278, 2162, 1791, 2162, 81, 80, + /* 1190 */ 446, 2194, 1790, 200, 1789, 1788, 1787, 1947, 166, 1786, + /* 1200 */ 1956, 704, 1564, 634, 1943, 166, 438, 436, 1963, 166, + /* 1210 */ 741, 316, 1702, 2005, 1991, 627, 1938, 346, 2354, 2194, + /* 1220 */ 427, 2148, 2162, 425, 421, 417, 414, 439, 74, 704, + /* 1230 */ 2212, 2347, 2162, 2360, 188, 158, 2162, 755, 2355, 653, + /* 1240 */ 1922, 2162, 2162, 703, 2162, 2162, 2162, 233, 227, 2162, + /* 1250 */ 1217, 1218, 2194, 242, 232, 544, 240, 203, 2212, 577, + /* 1260 */ 149, 54, 704, 3, 2301, 191, 2302, 1699, 694, 2162, + /* 1270 */ 419, 703, 83, 225, 137, 578, 261, 2193, 84, 2229, + /* 1280 */ 5, 1312, 112, 2195, 707, 2197, 2198, 702, 1612, 697, + /* 1290 */ 151, 2212, 1, 150, 2374, 55, 2282, 1310, 1846, 1837, + /* 1300 */ 393, 2278, 2162, 244, 703, 2193, 243, 2229, 1835, 158, + /* 1310 */ 112, 2195, 707, 2197, 2198, 702, 153, 697, 158, 152, + /* 1320 */ 590, 592, 2374, 607, 2282, 606, 1778, 1779, 393, 2278, + /* 1330 */ 595, 50, 260, 50, 748, 266, 158, 1563, 2193, 50, + /* 1340 */ 2229, 290, 2194, 112, 2195, 707, 2197, 2198, 702, 413, + /* 1350 */ 697, 71, 704, 406, 405, 2374, 1290, 2282, 156, 158, + /* 1360 */ 1567, 393, 2278, 1569, 742, 14, 13, 64, 418, 1521, + /* 1370 */ 2194, 50, 108, 361, 1636, 94, 1562, 1586, 1524, 1829, + /* 1380 */ 704, 2212, 105, 160, 159, 739, 738, 737, 157, 50, + /* 1390 */ 711, 1731, 2162, 1730, 703, 268, 669, 156, 435, 1478, + /* 1400 */ 158, 295, 749, 1631, 434, 195, 196, 138, 437, 2212, + /* 1410 */ 156, 679, 198, 1502, 310, 453, 1561, 1579, 299, 1355, + /* 1420 */ 2162, 455, 703, 1657, 1288, 209, 1583, 1673, 2193, 790, + /* 1430 */ 2229, 1622, 2194, 112, 2195, 707, 2197, 2198, 702, 2072, + /* 1440 */ 697, 693, 704, 459, 461, 2257, 496, 2282, 466, 315, + /* 1450 */ 1384, 393, 2278, 1578, 486, 479, 2193, 1388, 2229, 2064, + /* 1460 */ 1395, 112, 2195, 707, 2197, 2198, 702, 1393, 697, 488, + /* 1470 */ 161, 2212, 495, 2255, 497, 2282, 506, 504, 507, 393, + /* 1480 */ 2278, 213, 2162, 214, 703, 509, 510, 216, 512, 514, + /* 1490 */ 1584, 529, 4, 537, 530, 1566, 538, 1581, 540, 2194, + /* 1500 */ 224, 541, 226, 1585, 542, 545, 1587, 543, 570, 704, + /* 1510 */ 229, 549, 572, 231, 88, 89, 235, 351, 2193, 114, + /* 1520 */ 2229, 2136, 1950, 112, 2195, 707, 2197, 2198, 702, 92, + /* 1530 */ 697, 2133, 1570, 154, 1565, 690, 2132, 2282, 2212, 239, + /* 1540 */ 1946, 393, 2278, 241, 1948, 609, 1944, 611, 311, 2162, + /* 1550 */ 252, 703, 615, 620, 616, 614, 256, 1509, 622, 641, + /* 1560 */ 2328, 2194, 677, 254, 1573, 1575, 619, 631, 637, 2313, + /* 1570 */ 383, 704, 2323, 2327, 621, 644, 264, 695, 1629, 1630, + /* 1580 */ 1632, 1633, 1634, 1635, 267, 2193, 8, 2229, 174, 650, + /* 1590 */ 113, 2195, 707, 2197, 2198, 702, 2304, 697, 272, 632, + /* 1600 */ 2212, 629, 274, 630, 2282, 661, 277, 658, 2281, 2278, + /* 1610 */ 384, 2162, 143, 703, 2377, 1582, 2298, 285, 178, 1699, + /* 1620 */ 98, 1588, 2077, 312, 2194, 675, 676, 2091, 2090, 2089, + /* 1630 */ 389, 313, 680, 100, 704, 681, 102, 275, 61, 276, + /* 1640 */ 104, 2263, 314, 2006, 1961, 306, 317, 2193, 791, 2229, + /* 1650 */ 1923, 709, 113, 2195, 707, 2197, 2198, 702, 53, 697, + /* 1660 */ 2353, 280, 792, 2212, 341, 353, 2282, 321, 319, 2154, + /* 1670 */ 692, 2278, 794, 326, 2162, 2153, 703, 340, 354, 330, + /* 1680 */ 2152, 78, 2149, 415, 416, 2194, 1546, 1547, 194, 420, + /* 1690 */ 2147, 422, 423, 2146, 424, 704, 362, 2144, 428, 2194, + /* 1700 */ 2143, 430, 2142, 432, 1537, 2123, 197, 2122, 199, 704, + /* 1710 */ 705, 79, 2229, 1505, 1504, 113, 2195, 707, 2197, 2198, + /* 1720 */ 702, 2104, 697, 2103, 2212, 2102, 444, 445, 2101, 2282, + /* 1730 */ 2100, 1455, 2054, 356, 2278, 2162, 2194, 703, 2212, 450, + /* 1740 */ 451, 2051, 201, 2050, 2049, 82, 704, 206, 204, 2162, + /* 1750 */ 2048, 703, 2053, 2052, 2047, 2046, 2044, 2043, 2042, 467, + /* 1760 */ 2041, 469, 2194, 2057, 2040, 2039, 2038, 2037, 2036, 2035, + /* 1770 */ 2034, 2193, 704, 2229, 2033, 2212, 170, 2195, 707, 2197, + /* 1780 */ 2198, 702, 2032, 697, 2031, 2193, 2162, 2229, 703, 2030, + /* 1790 */ 171, 2195, 707, 2197, 2198, 702, 2029, 697, 2028, 2027, + /* 1800 */ 2026, 2212, 2025, 87, 2024, 2023, 208, 2022, 2056, 2021, + /* 1810 */ 2020, 2019, 2162, 1457, 703, 2018, 628, 2319, 2017, 499, + /* 1820 */ 2016, 2015, 2193, 1326, 2229, 349, 2194, 170, 2195, 707, + /* 1830 */ 2197, 2198, 702, 350, 697, 1330, 704, 215, 1322, 1864, + /* 1840 */ 217, 654, 2375, 1865, 1863, 218, 1861, 1858, 2193, 515, + /* 1850 */ 2229, 2194, 222, 113, 2195, 707, 2197, 2198, 702, 1857, + /* 1860 */ 697, 704, 517, 519, 521, 2212, 516, 2282, 2320, 381, + /* 1870 */ 523, 520, 2279, 1850, 1839, 524, 2162, 2194, 703, 525, + /* 1880 */ 527, 1815, 182, 220, 1814, 1219, 2121, 704, 76, 2182, + /* 1890 */ 2212, 2111, 77, 2099, 382, 183, 228, 535, 230, 2098, + /* 1900 */ 2075, 2162, 1939, 703, 1860, 1264, 1856, 550, 552, 551, + /* 1910 */ 1854, 554, 2193, 555, 2229, 1852, 2212, 339, 2195, 707, + /* 1920 */ 2197, 2198, 702, 558, 697, 1849, 556, 2162, 559, 703, + /* 1930 */ 562, 560, 563, 564, 1834, 1832, 1833, 2193, 1831, 2229, + /* 1940 */ 1811, 1941, 339, 2195, 707, 2197, 2198, 702, 1400, 697, + /* 1950 */ 2194, 1399, 1940, 1313, 1311, 1309, 1308, 1307, 1306, 1305, + /* 1960 */ 704, 238, 1302, 2193, 1300, 2229, 2194, 613, 332, 2195, + /* 1970 */ 707, 2197, 2198, 702, 63, 697, 704, 763, 1301, 1299, + /* 1980 */ 1847, 765, 374, 1838, 375, 798, 376, 1810, 596, 2212, + /* 1990 */ 593, 1836, 598, 1809, 600, 1808, 602, 115, 1531, 309, + /* 2000 */ 2162, 1535, 703, 1533, 1530, 2212, 29, 2120, 67, 388, + /* 2010 */ 1511, 649, 1513, 2110, 1515, 180, 2162, 2097, 703, 617, + /* 2020 */ 2096, 164, 2359, 788, 784, 780, 776, 2194, 307, 257, + /* 2030 */ 57, 31, 623, 618, 625, 1490, 2193, 704, 2229, 1489, + /* 2040 */ 20, 171, 2195, 707, 2197, 2198, 702, 6, 697, 1748, + /* 2050 */ 17, 263, 2193, 7, 2229, 633, 21, 339, 2195, 707, + /* 2060 */ 2197, 2198, 702, 271, 697, 265, 2212, 22, 110, 635, + /* 2070 */ 396, 300, 270, 2183, 33, 1729, 172, 2162, 65, 703, + /* 2080 */ 1721, 269, 32, 23, 95, 24, 1768, 1763, 2194, 1769, + /* 2090 */ 1762, 385, 1767, 2376, 18, 1766, 386, 283, 704, 298, + /* 2100 */ 177, 2095, 1696, 59, 683, 1695, 2074, 96, 97, 288, + /* 2110 */ 289, 25, 291, 2193, 2194, 2229, 2073, 296, 339, 2195, + /* 2120 */ 707, 2197, 2198, 702, 704, 697, 58, 2212, 1727, 99, + /* 2130 */ 678, 398, 68, 301, 101, 105, 26, 1648, 2162, 287, + /* 2140 */ 703, 11, 13, 1647, 1571, 179, 286, 2232, 1603, 1626, + /* 2150 */ 696, 192, 1624, 2212, 1658, 1623, 710, 39, 399, 714, + /* 2160 */ 708, 16, 717, 720, 2162, 253, 703, 27, 723, 1595, + /* 2170 */ 28, 706, 1385, 712, 2193, 1382, 2229, 715, 2194, 339, + /* 2180 */ 2195, 707, 2197, 2198, 702, 1381, 697, 718, 704, 1378, + /* 2190 */ 721, 726, 1372, 2194, 724, 1361, 304, 1370, 727, 1376, + /* 2200 */ 608, 1394, 2229, 704, 1375, 334, 2195, 707, 2197, 2198, + /* 2210 */ 702, 2194, 697, 106, 107, 1374, 75, 2212, 733, 1390, + /* 2220 */ 1373, 704, 1262, 743, 1294, 1293, 1292, 1291, 2162, 1289, + /* 2230 */ 703, 1287, 2212, 1286, 1285, 1320, 753, 305, 1283, 1282, + /* 2240 */ 1281, 1280, 1279, 2162, 1278, 703, 1277, 1317, 1315, 1274, + /* 2250 */ 2212, 1273, 1270, 1269, 1268, 1267, 1855, 773, 1853, 774, + /* 2260 */ 775, 2162, 777, 703, 2193, 1851, 2229, 779, 781, 324, + /* 2270 */ 2195, 707, 2197, 2198, 702, 778, 697, 783, 782, 2193, + /* 2280 */ 1848, 2229, 785, 786, 322, 2195, 707, 2197, 2198, 702, + /* 2290 */ 787, 697, 1830, 1807, 789, 1209, 308, 2193, 793, 2229, + /* 2300 */ 1557, 318, 325, 2195, 707, 2197, 2198, 702, 2194, 697, + /* 2310 */ 796, 797, 1782, 1782, 1782, 1782, 1782, 1782, 704, 1782, + /* 2320 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 2194, 1782, 1782, + /* 2330 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 704, 1782, 1782, + /* 2340 */ 1782, 2194, 1782, 1782, 1782, 1782, 1782, 2212, 1782, 1782, + /* 2350 */ 1782, 704, 1782, 1782, 1782, 1782, 1782, 1782, 2162, 1782, + /* 2360 */ 703, 1782, 1782, 1782, 1782, 1782, 2212, 1782, 1782, 1782, + /* 2370 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 2162, 2194, 703, + /* 2380 */ 2212, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 704, 1782, + /* 2390 */ 1782, 2162, 1782, 703, 2193, 1782, 2229, 1782, 1782, 331, + /* 2400 */ 2195, 707, 2197, 2198, 702, 1782, 697, 1782, 1782, 1782, + /* 2410 */ 1782, 1782, 1782, 2193, 1782, 2229, 1782, 2212, 335, 2195, + /* 2420 */ 707, 2197, 2198, 702, 1782, 697, 1782, 2193, 2162, 2229, + /* 2430 */ 703, 1782, 327, 2195, 707, 2197, 2198, 702, 1782, 697, + /* 2440 */ 2194, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2450 */ 704, 1782, 1782, 1782, 1782, 2194, 1782, 1782, 1782, 1782, + /* 2460 */ 1782, 1782, 1782, 1782, 2193, 704, 2229, 1782, 1782, 336, + /* 2470 */ 2195, 707, 2197, 2198, 702, 1782, 697, 1782, 1782, 2212, + /* 2480 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2490 */ 2162, 1782, 703, 1782, 2212, 1782, 1782, 1782, 1782, 1782, + /* 2500 */ 1782, 1782, 1782, 1782, 1782, 2162, 2194, 703, 1782, 1782, + /* 2510 */ 1782, 1782, 1782, 1782, 1782, 1782, 704, 1782, 1782, 1782, + /* 2520 */ 2194, 1782, 1782, 1782, 1782, 1782, 2193, 1782, 2229, 1782, + /* 2530 */ 704, 328, 2195, 707, 2197, 2198, 702, 1782, 697, 1782, + /* 2540 */ 1782, 2193, 1782, 2229, 1782, 2212, 337, 2195, 707, 2197, + /* 2550 */ 2198, 702, 1782, 697, 1782, 1782, 2162, 1782, 703, 2212, + /* 2560 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2570 */ 2162, 1782, 703, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2580 */ 1782, 1782, 1782, 1782, 1782, 2194, 1782, 1782, 1782, 1782, + /* 2590 */ 1782, 1782, 2193, 1782, 2229, 704, 1782, 329, 2195, 707, + /* 2600 */ 2197, 2198, 702, 1782, 697, 1782, 2193, 1782, 2229, 1782, + /* 2610 */ 1782, 342, 2195, 707, 2197, 2198, 702, 1782, 697, 1782, + /* 2620 */ 1782, 1782, 1782, 1782, 2212, 1782, 1782, 1782, 1782, 1782, + /* 2630 */ 1782, 1782, 1782, 1782, 1782, 2162, 1782, 703, 1782, 1782, + /* 2640 */ 1782, 1782, 1782, 1782, 1782, 2194, 1782, 1782, 1782, 1782, + /* 2650 */ 1782, 1782, 1782, 1782, 1782, 704, 1782, 1782, 1782, 1782, + /* 2660 */ 2194, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2670 */ 704, 2193, 1782, 2229, 1782, 1782, 343, 2195, 707, 2197, + /* 2680 */ 2198, 702, 1782, 697, 2212, 1782, 1782, 1782, 1782, 1782, + /* 2690 */ 1782, 1782, 1782, 1782, 1782, 2162, 1782, 703, 1782, 2212, + /* 2700 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2710 */ 2162, 1782, 703, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2720 */ 2194, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2730 */ 704, 2193, 1782, 2229, 1782, 2194, 2206, 2195, 707, 2197, + /* 2740 */ 2198, 702, 1782, 697, 1782, 704, 2193, 1782, 2229, 1782, + /* 2750 */ 1782, 2205, 2195, 707, 2197, 2198, 702, 2194, 697, 2212, + /* 2760 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 704, 1782, 1782, + /* 2770 */ 2162, 1782, 703, 1782, 2212, 1782, 1782, 1782, 1782, 1782, + /* 2780 */ 1782, 1782, 1782, 1782, 1782, 2162, 1782, 703, 1782, 1782, + /* 2790 */ 1782, 1782, 1782, 1782, 1782, 1782, 2212, 1782, 1782, 1782, + /* 2800 */ 1782, 1782, 1782, 1782, 1782, 1782, 2193, 2162, 2229, 703, + /* 2810 */ 1782, 2204, 2195, 707, 2197, 2198, 702, 1782, 697, 1782, + /* 2820 */ 1782, 2193, 1782, 2229, 1782, 1782, 358, 2195, 707, 2197, + /* 2830 */ 2198, 702, 2194, 697, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2840 */ 1782, 1782, 704, 2193, 1782, 2229, 1782, 2194, 359, 2195, + /* 2850 */ 707, 2197, 2198, 702, 1782, 697, 1782, 704, 1782, 1782, + /* 2860 */ 1782, 1782, 2194, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2870 */ 1782, 2212, 704, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2880 */ 1782, 1782, 2162, 1782, 703, 1782, 2212, 1782, 1782, 1782, + /* 2890 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 2162, 1782, 703, + /* 2900 */ 1782, 2212, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2910 */ 1782, 1782, 2162, 1782, 703, 1782, 1782, 1782, 2193, 1782, + /* 2920 */ 2229, 1782, 1782, 355, 2195, 707, 2197, 2198, 702, 1782, + /* 2930 */ 697, 1782, 1782, 2193, 2194, 2229, 1782, 1782, 360, 2195, + /* 2940 */ 707, 2197, 2198, 702, 704, 697, 1782, 1782, 705, 1782, + /* 2950 */ 2229, 1782, 1782, 334, 2195, 707, 2197, 2198, 702, 1782, + /* 2960 */ 697, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2970 */ 1782, 1782, 1782, 2212, 1782, 1782, 1782, 1782, 1782, 1782, + /* 2980 */ 1782, 1782, 1782, 1782, 2162, 1782, 703, 1782, 1782, 1782, + /* 2990 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 3000 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 3010 */ 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + /* 3020 */ 2193, 1782, 2229, 1782, 1782, 333, 2195, 707, 2197, 2198, + /* 3030 */ 702, 1782, 697, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 375, 341, 367, 393, 346, 350, 351, 411, 350, 380, - /* 10 */ 352, 351, 12, 13, 14, 405, 381, 4, 408, 409, - /* 20 */ 20, 3, 22, 8, 9, 370, 391, 12, 13, 14, - /* 30 */ 15, 16, 377, 33, 350, 35, 367, 14, 20, 379, - /* 40 */ 8, 9, 338, 20, 12, 13, 14, 15, 16, 424, - /* 50 */ 381, 391, 380, 393, 458, 49, 43, 461, 45, 46, - /* 60 */ 391, 379, 62, 57, 429, 430, 60, 61, 68, 20, - /* 70 */ 4, 22, 476, 477, 439, 75, 44, 481, 482, 395, - /* 80 */ 20, 399, 400, 68, 35, 350, 351, 427, 20, 429, - /* 90 */ 350, 351, 432, 433, 434, 435, 436, 437, 429, 439, - /* 100 */ 100, 360, 53, 103, 444, 370, 446, 357, 439, 368, - /* 110 */ 450, 451, 377, 84, 393, 411, 12, 13, 350, 351, - /* 120 */ 416, 20, 104, 463, 20, 62, 22, 112, 100, 408, - /* 130 */ 409, 471, 382, 20, 447, 448, 104, 33, 370, 35, - /* 140 */ 140, 141, 341, 115, 116, 117, 118, 119, 120, 121, - /* 150 */ 122, 123, 124, 341, 126, 127, 128, 129, 130, 131, - /* 160 */ 132, 378, 458, 103, 458, 461, 62, 461, 105, 103, - /* 170 */ 170, 171, 68, 390, 145, 146, 176, 177, 20, 75, - /* 180 */ 476, 477, 476, 477, 169, 481, 482, 481, 482, 431, - /* 190 */ 172, 191, 391, 193, 454, 455, 456, 168, 458, 459, - /* 200 */ 340, 461, 342, 391, 100, 8, 9, 103, 341, 12, - /* 210 */ 13, 14, 15, 16, 103, 457, 476, 477, 351, 35, - /* 220 */ 186, 481, 482, 223, 224, 0, 226, 227, 228, 229, + /* 0 */ 411, 341, 346, 380, 350, 416, 350, 411, 352, 386, + /* 10 */ 393, 351, 12, 13, 14, 458, 387, 394, 461, 351, + /* 20 */ 20, 380, 22, 8, 9, 408, 409, 12, 13, 14, + /* 30 */ 15, 16, 387, 33, 477, 35, 20, 371, 481, 482, + /* 40 */ 380, 400, 338, 393, 20, 379, 380, 458, 380, 395, + /* 50 */ 461, 391, 386, 393, 458, 405, 20, 461, 408, 409, + /* 60 */ 394, 458, 62, 346, 461, 476, 477, 350, 68, 352, + /* 70 */ 481, 482, 476, 477, 20, 75, 22, 481, 482, 476, + /* 80 */ 477, 350, 351, 68, 481, 482, 20, 427, 359, 429, + /* 90 */ 350, 351, 432, 433, 434, 435, 436, 437, 47, 439, + /* 100 */ 100, 370, 434, 103, 444, 376, 446, 53, 377, 345, + /* 110 */ 450, 451, 348, 349, 385, 411, 12, 13, 341, 103, + /* 120 */ 416, 49, 22, 463, 20, 44, 22, 112, 100, 57, + /* 130 */ 20, 471, 60, 61, 0, 35, 20, 33, 350, 35, + /* 140 */ 140, 141, 350, 351, 116, 117, 118, 119, 120, 121, + /* 150 */ 122, 123, 124, 125, 103, 127, 128, 129, 130, 131, + /* 160 */ 132, 133, 458, 67, 458, 461, 62, 461, 391, 103, + /* 170 */ 170, 171, 68, 39, 4, 75, 176, 177, 0, 75, + /* 180 */ 476, 477, 20, 477, 169, 481, 482, 481, 482, 397, + /* 190 */ 402, 191, 404, 193, 454, 455, 456, 3, 458, 459, + /* 200 */ 100, 461, 447, 448, 100, 8, 9, 103, 341, 12, + /* 210 */ 13, 14, 15, 16, 20, 67, 476, 477, 351, 103, + /* 220 */ 114, 481, 482, 223, 224, 0, 226, 227, 228, 229, /* 230 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - /* 240 */ 240, 241, 242, 243, 140, 141, 379, 213, 214, 24, - /* 250 */ 25, 26, 27, 28, 29, 30, 31, 32, 391, 75, - /* 260 */ 393, 0, 247, 248, 249, 250, 251, 252, 253, 254, - /* 270 */ 255, 256, 257, 345, 170, 171, 348, 349, 67, 20, - /* 280 */ 176, 177, 21, 170, 171, 24, 25, 26, 27, 28, - /* 290 */ 29, 30, 31, 32, 427, 191, 429, 193, 175, 432, - /* 300 */ 433, 434, 435, 436, 437, 20, 439, 0, 371, 442, - /* 310 */ 20, 444, 445, 446, 20, 341, 379, 450, 451, 20, - /* 320 */ 260, 22, 350, 351, 387, 351, 260, 223, 224, 4, + /* 240 */ 240, 241, 242, 243, 140, 141, 21, 380, 244, 24, + /* 250 */ 25, 26, 27, 28, 29, 30, 31, 32, 391, 340, + /* 260 */ 393, 342, 247, 248, 249, 250, 251, 252, 253, 254, + /* 270 */ 255, 256, 257, 103, 170, 171, 260, 20, 75, 21, + /* 280 */ 176, 177, 24, 25, 26, 27, 28, 29, 30, 31, + /* 290 */ 32, 191, 21, 193, 427, 191, 429, 193, 104, 432, + /* 300 */ 433, 434, 435, 436, 437, 34, 439, 36, 380, 442, + /* 310 */ 114, 444, 445, 446, 386, 341, 345, 450, 451, 348, + /* 320 */ 349, 360, 394, 223, 224, 351, 260, 223, 224, 368, /* 330 */ 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* 340 */ 236, 237, 238, 239, 240, 241, 242, 243, 244, 12, - /* 350 */ 13, 67, 53, 379, 379, 12, 13, 20, 47, 22, - /* 360 */ 458, 386, 103, 461, 379, 391, 20, 393, 114, 394, - /* 370 */ 33, 260, 35, 70, 71, 72, 350, 351, 35, 477, - /* 380 */ 77, 78, 79, 481, 482, 400, 83, 351, 265, 266, - /* 390 */ 267, 88, 89, 90, 91, 442, 370, 94, 445, 62, - /* 400 */ 135, 427, 48, 429, 139, 68, 432, 433, 434, 435, - /* 410 */ 436, 437, 75, 439, 103, 379, 134, 135, 444, 345, - /* 420 */ 446, 139, 348, 349, 450, 451, 454, 455, 456, 341, - /* 430 */ 458, 459, 14, 458, 140, 141, 461, 100, 20, 351, - /* 440 */ 103, 353, 8, 9, 35, 471, 12, 13, 14, 15, - /* 450 */ 16, 476, 477, 12, 13, 14, 481, 482, 346, 341, - /* 460 */ 170, 20, 350, 22, 352, 200, 159, 379, 203, 351, - /* 470 */ 434, 206, 379, 208, 33, 168, 35, 140, 141, 391, - /* 480 */ 387, 393, 458, 21, 75, 461, 24, 25, 26, 27, - /* 490 */ 28, 29, 30, 31, 32, 379, 103, 379, 341, 350, - /* 500 */ 351, 477, 386, 62, 244, 481, 482, 170, 171, 391, - /* 510 */ 394, 393, 357, 176, 177, 427, 75, 429, 172, 260, - /* 520 */ 432, 433, 434, 435, 436, 437, 172, 439, 191, 374, - /* 530 */ 193, 133, 444, 179, 446, 137, 193, 382, 450, 451, - /* 540 */ 14, 100, 350, 351, 103, 427, 20, 429, 391, 341, - /* 550 */ 432, 433, 434, 435, 436, 437, 244, 439, 246, 351, + /* 350 */ 13, 350, 351, 103, 380, 380, 75, 20, 14, 22, + /* 360 */ 84, 386, 20, 282, 20, 391, 172, 393, 380, 394, + /* 370 */ 33, 370, 35, 70, 71, 72, 350, 351, 377, 357, + /* 380 */ 77, 78, 79, 20, 44, 22, 83, 399, 400, 103, + /* 390 */ 378, 88, 89, 90, 91, 217, 370, 94, 35, 62, + /* 400 */ 431, 427, 390, 429, 382, 68, 432, 433, 434, 435, + /* 410 */ 436, 437, 75, 439, 350, 351, 53, 387, 444, 22, + /* 420 */ 446, 145, 146, 4, 450, 451, 457, 170, 171, 341, + /* 430 */ 260, 135, 35, 458, 370, 139, 461, 100, 0, 351, + /* 440 */ 103, 353, 8, 9, 168, 471, 12, 13, 14, 15, + /* 450 */ 16, 476, 477, 12, 13, 14, 481, 482, 417, 341, + /* 460 */ 0, 20, 43, 22, 45, 46, 380, 389, 380, 351, + /* 470 */ 392, 393, 386, 186, 33, 368, 35, 140, 141, 391, + /* 480 */ 394, 393, 140, 141, 24, 25, 26, 27, 28, 29, + /* 490 */ 30, 31, 32, 350, 351, 20, 200, 100, 380, 203, + /* 500 */ 213, 214, 206, 62, 208, 67, 14, 170, 171, 391, + /* 510 */ 260, 393, 20, 176, 177, 427, 75, 429, 176, 177, + /* 520 */ 432, 433, 434, 435, 436, 437, 442, 439, 191, 445, + /* 530 */ 193, 0, 444, 342, 446, 350, 351, 401, 450, 451, + /* 540 */ 397, 100, 350, 351, 103, 427, 260, 429, 392, 393, + /* 550 */ 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, /* 560 */ 223, 224, 370, 226, 227, 228, 229, 230, 231, 232, /* 570 */ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - /* 580 */ 243, 140, 141, 190, 22, 192, 261, 379, 8, 9, - /* 590 */ 472, 473, 12, 13, 14, 15, 16, 35, 431, 391, - /* 600 */ 20, 393, 453, 454, 455, 456, 172, 458, 459, 75, - /* 610 */ 341, 170, 171, 350, 351, 222, 389, 176, 177, 392, - /* 620 */ 393, 8, 9, 371, 457, 12, 13, 14, 15, 16, - /* 630 */ 431, 379, 191, 370, 193, 427, 350, 429, 386, 387, - /* 640 */ 432, 433, 434, 435, 436, 437, 394, 439, 134, 20, - /* 650 */ 411, 341, 444, 260, 446, 416, 457, 411, 450, 451, - /* 660 */ 391, 351, 100, 353, 223, 224, 44, 226, 227, 228, + /* 580 */ 243, 140, 141, 8, 9, 350, 351, 12, 13, 14, + /* 590 */ 15, 16, 8, 9, 485, 20, 12, 13, 14, 15, + /* 600 */ 16, 70, 71, 72, 223, 370, 172, 474, 77, 78, + /* 610 */ 79, 170, 171, 22, 83, 140, 141, 176, 177, 88, + /* 620 */ 89, 90, 91, 380, 284, 94, 35, 371, 44, 386, + /* 630 */ 350, 351, 191, 37, 193, 379, 380, 394, 453, 454, + /* 640 */ 455, 456, 354, 458, 459, 350, 351, 411, 341, 0, + /* 650 */ 370, 270, 271, 272, 273, 274, 275, 276, 351, 20, + /* 660 */ 353, 35, 170, 39, 223, 224, 0, 226, 227, 228, /* 670 */ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - /* 680 */ 239, 240, 241, 242, 243, 12, 13, 0, 402, 379, - /* 690 */ 404, 350, 351, 20, 75, 22, 170, 458, 350, 351, - /* 700 */ 461, 391, 379, 393, 458, 0, 33, 461, 35, 386, - /* 710 */ 12, 13, 14, 15, 16, 476, 477, 394, 204, 205, - /* 720 */ 481, 482, 476, 477, 350, 351, 104, 481, 482, 1, - /* 730 */ 2, 223, 103, 350, 351, 62, 380, 427, 397, 429, - /* 740 */ 4, 350, 432, 433, 434, 435, 436, 437, 75, 439, - /* 750 */ 350, 351, 172, 370, 444, 19, 446, 0, 8, 9, - /* 760 */ 450, 451, 12, 13, 14, 15, 16, 341, 341, 33, - /* 770 */ 370, 397, 67, 100, 350, 351, 103, 351, 270, 271, - /* 780 */ 272, 273, 274, 275, 276, 49, 350, 351, 3, 12, - /* 790 */ 13, 0, 56, 402, 370, 404, 183, 20, 62, 22, - /* 800 */ 371, 20, 454, 455, 456, 379, 458, 459, 379, 443, - /* 810 */ 33, 445, 35, 140, 141, 0, 387, 391, 391, 393, - /* 820 */ 133, 134, 135, 136, 137, 138, 139, 70, 71, 72, - /* 830 */ 392, 393, 104, 397, 77, 78, 79, 22, 102, 62, - /* 840 */ 83, 105, 103, 170, 171, 88, 89, 90, 91, 176, - /* 850 */ 177, 94, 75, 427, 104, 429, 54, 55, 432, 433, - /* 860 */ 434, 435, 436, 437, 191, 439, 193, 441, 8, 9, - /* 870 */ 341, 380, 12, 13, 14, 15, 16, 100, 355, 356, - /* 880 */ 103, 341, 133, 134, 135, 136, 137, 138, 139, 341, - /* 890 */ 411, 351, 62, 353, 341, 380, 223, 224, 285, 226, + /* 680 */ 239, 240, 241, 242, 243, 12, 13, 380, 104, 350, + /* 690 */ 351, 100, 397, 20, 458, 22, 375, 461, 391, 341, + /* 700 */ 393, 75, 106, 367, 108, 109, 33, 111, 35, 370, + /* 710 */ 35, 115, 476, 477, 0, 8, 9, 481, 482, 12, + /* 720 */ 13, 14, 15, 16, 8, 9, 54, 55, 12, 13, + /* 730 */ 14, 15, 16, 137, 427, 62, 429, 355, 356, 432, + /* 740 */ 433, 434, 435, 436, 437, 424, 439, 172, 75, 391, + /* 750 */ 75, 444, 62, 446, 431, 8, 9, 450, 451, 12, + /* 760 */ 13, 14, 15, 16, 115, 1, 2, 341, 12, 13, + /* 770 */ 14, 15, 16, 100, 350, 351, 103, 351, 4, 175, + /* 780 */ 457, 115, 380, 134, 135, 136, 137, 138, 139, 12, + /* 790 */ 13, 380, 102, 19, 370, 105, 394, 20, 431, 22, + /* 800 */ 134, 135, 136, 137, 138, 139, 380, 33, 355, 356, + /* 810 */ 33, 172, 35, 140, 141, 2, 468, 391, 134, 393, + /* 820 */ 104, 8, 9, 49, 457, 12, 13, 14, 15, 16, + /* 830 */ 56, 367, 350, 350, 350, 351, 62, 350, 351, 62, + /* 840 */ 134, 135, 14, 170, 171, 139, 169, 410, 20, 176, + /* 850 */ 177, 104, 75, 427, 370, 429, 354, 370, 432, 433, + /* 860 */ 434, 435, 436, 437, 191, 439, 193, 441, 104, 265, + /* 870 */ 266, 267, 411, 159, 350, 351, 102, 100, 341, 105, + /* 880 */ 103, 341, 168, 259, 402, 402, 404, 404, 204, 205, + /* 890 */ 183, 351, 388, 353, 370, 391, 223, 224, 3, 226, /* 900 */ 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - /* 910 */ 237, 238, 239, 240, 241, 242, 243, 140, 141, 379, - /* 920 */ 391, 140, 141, 21, 133, 134, 135, 136, 137, 138, - /* 930 */ 139, 391, 102, 393, 379, 105, 34, 458, 36, 391, - /* 940 */ 461, 386, 350, 351, 391, 350, 351, 170, 171, 394, - /* 950 */ 114, 350, 351, 176, 177, 476, 477, 176, 177, 380, - /* 960 */ 481, 482, 370, 388, 104, 370, 391, 427, 191, 429, - /* 970 */ 193, 370, 432, 433, 434, 435, 436, 437, 39, 439, - /* 980 */ 364, 365, 2, 0, 444, 22, 446, 350, 8, 9, - /* 990 */ 450, 451, 12, 13, 14, 15, 16, 341, 35, 260, + /* 910 */ 237, 238, 239, 240, 241, 242, 243, 140, 141, 458, + /* 920 */ 380, 367, 461, 388, 247, 367, 391, 367, 391, 12, + /* 930 */ 13, 391, 349, 393, 257, 381, 351, 476, 477, 381, + /* 940 */ 14, 381, 481, 482, 341, 391, 20, 170, 171, 391, + /* 950 */ 2, 391, 35, 176, 177, 4, 8, 9, 364, 365, + /* 960 */ 12, 13, 14, 15, 16, 350, 351, 427, 191, 429, + /* 970 */ 193, 341, 432, 433, 434, 435, 436, 437, 48, 439, + /* 980 */ 14, 15, 16, 429, 444, 370, 446, 429, 430, 429, + /* 990 */ 450, 451, 285, 439, 391, 350, 351, 439, 170, 439, /* 1000 */ 223, 224, 0, 226, 227, 228, 229, 230, 231, 232, /* 1010 */ 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - /* 1020 */ 243, 14, 18, 18, 20, 350, 351, 20, 23, 350, - /* 1030 */ 351, 27, 49, 359, 30, 355, 356, 33, 367, 402, - /* 1040 */ 371, 404, 37, 38, 0, 370, 41, 391, 379, 370, - /* 1050 */ 376, 379, 381, 49, 411, 51, 387, 52, 386, 385, - /* 1060 */ 56, 380, 391, 100, 341, 280, 394, 341, 63, 64, - /* 1070 */ 65, 66, 70, 71, 72, 73, 74, 0, 76, 77, + /* 1020 */ 243, 391, 18, 18, 20, 115, 103, 341, 23, 350, + /* 1030 */ 351, 27, 350, 351, 30, 350, 351, 33, 350, 351, + /* 1040 */ 364, 365, 37, 38, 350, 351, 41, 137, 244, 370, + /* 1050 */ 246, 401, 370, 49, 371, 51, 401, 52, 370, 443, + /* 1060 */ 56, 445, 379, 380, 370, 460, 341, 341, 63, 64, + /* 1070 */ 65, 66, 70, 71, 72, 73, 74, 391, 76, 77, /* 1080 */ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - /* 1090 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 20, - /* 1100 */ 429, 458, 350, 351, 461, 20, 102, 33, 103, 37, - /* 1110 */ 439, 14, 15, 16, 391, 350, 351, 391, 114, 476, - /* 1120 */ 477, 44, 370, 49, 481, 482, 350, 351, 44, 350, - /* 1130 */ 351, 57, 58, 59, 60, 370, 62, 341, 44, 443, - /* 1140 */ 169, 445, 364, 365, 341, 341, 370, 142, 144, 370, - /* 1150 */ 341, 147, 148, 149, 150, 151, 152, 153, 154, 155, - /* 1160 */ 156, 157, 158, 159, 160, 161, 162, 163, 68, 165, - /* 1170 */ 166, 167, 350, 351, 258, 259, 102, 170, 106, 105, - /* 1180 */ 108, 109, 0, 111, 359, 341, 341, 391, 183, 184, - /* 1190 */ 185, 341, 370, 188, 391, 391, 341, 379, 259, 388, - /* 1200 */ 391, 351, 391, 353, 22, 133, 201, 202, 341, 137, - /* 1210 */ 385, 388, 394, 372, 391, 417, 375, 212, 247, 42, - /* 1220 */ 215, 44, 341, 218, 219, 220, 221, 222, 257, 379, - /* 1230 */ 366, 0, 351, 369, 353, 391, 391, 45, 46, 44, - /* 1240 */ 42, 391, 44, 393, 368, 114, 391, 173, 174, 44, - /* 1250 */ 107, 172, 341, 110, 180, 181, 107, 172, 391, 110, - /* 1260 */ 379, 217, 351, 107, 353, 260, 110, 342, 107, 13, - /* 1270 */ 39, 110, 391, 199, 393, 13, 0, 427, 207, 429, - /* 1280 */ 209, 44, 432, 433, 434, 435, 436, 437, 35, 439, - /* 1290 */ 379, 35, 140, 141, 444, 164, 446, 35, 22, 104, - /* 1300 */ 450, 451, 391, 474, 393, 35, 13, 44, 427, 104, - /* 1310 */ 429, 1, 2, 432, 433, 434, 435, 436, 437, 44, - /* 1320 */ 439, 44, 44, 223, 22, 444, 44, 446, 35, 44, - /* 1330 */ 44, 450, 451, 401, 13, 44, 44, 35, 427, 44, - /* 1340 */ 429, 104, 341, 432, 433, 434, 435, 436, 437, 44, - /* 1350 */ 439, 0, 351, 12, 13, 444, 35, 446, 2, 44, - /* 1360 */ 485, 450, 451, 22, 8, 9, 282, 104, 12, 13, - /* 1370 */ 14, 15, 16, 341, 33, 103, 35, 75, 284, 104, - /* 1380 */ 379, 104, 104, 351, 44, 113, 104, 354, 468, 104, - /* 1390 */ 104, 367, 391, 44, 393, 104, 104, 44, 44, 104, - /* 1400 */ 379, 50, 100, 62, 367, 410, 354, 401, 349, 104, - /* 1410 */ 341, 379, 351, 390, 401, 460, 75, 452, 478, 104, - /* 1420 */ 351, 462, 262, 391, 412, 393, 49, 428, 427, 20, - /* 1430 */ 429, 421, 206, 432, 433, 434, 435, 436, 437, 359, - /* 1440 */ 439, 100, 426, 421, 104, 444, 193, 446, 379, 359, - /* 1450 */ 189, 450, 451, 104, 414, 20, 351, 104, 104, 427, - /* 1460 */ 391, 429, 393, 193, 432, 433, 434, 435, 436, 437, - /* 1470 */ 42, 439, 20, 398, 401, 351, 444, 169, 446, 398, - /* 1480 */ 20, 351, 450, 451, 396, 350, 350, 398, 396, 396, - /* 1490 */ 101, 363, 99, 191, 362, 193, 427, 350, 429, 341, - /* 1500 */ 98, 432, 433, 434, 435, 436, 437, 361, 439, 351, - /* 1510 */ 20, 343, 350, 350, 350, 446, 48, 347, 343, 450, - /* 1520 */ 451, 347, 421, 20, 359, 223, 224, 393, 359, 20, - /* 1530 */ 352, 20, 191, 413, 193, 359, 352, 379, 359, 359, - /* 1540 */ 359, 350, 359, 343, 343, 379, 379, 350, 341, 391, - /* 1550 */ 379, 393, 379, 210, 425, 197, 103, 196, 351, 421, - /* 1560 */ 423, 357, 420, 391, 223, 224, 379, 379, 379, 379, - /* 1570 */ 419, 357, 379, 379, 341, 379, 391, 236, 237, 238, - /* 1580 */ 239, 240, 241, 242, 351, 427, 379, 429, 350, 195, - /* 1590 */ 432, 433, 434, 435, 436, 437, 393, 439, 391, 391, - /* 1600 */ 393, 391, 269, 268, 446, 277, 467, 401, 450, 451, - /* 1610 */ 401, 391, 379, 391, 412, 467, 391, 418, 406, 406, - /* 1620 */ 470, 182, 469, 279, 391, 341, 393, 263, 278, 281, - /* 1630 */ 412, 286, 259, 479, 427, 351, 429, 480, 341, 432, - /* 1640 */ 433, 434, 435, 436, 437, 486, 439, 351, 351, 283, - /* 1650 */ 20, 352, 466, 446, 431, 357, 20, 450, 451, 404, - /* 1660 */ 427, 357, 429, 379, 406, 432, 433, 434, 435, 436, - /* 1670 */ 437, 438, 439, 440, 441, 391, 379, 393, 467, 391, - /* 1680 */ 465, 464, 174, 357, 403, 391, 406, 341, 391, 375, - /* 1690 */ 393, 391, 391, 357, 391, 103, 449, 351, 391, 103, - /* 1700 */ 383, 369, 391, 351, 341, 350, 36, 0, 339, 422, - /* 1710 */ 343, 427, 344, 429, 351, 373, 432, 433, 434, 435, - /* 1720 */ 436, 437, 357, 439, 427, 379, 429, 415, 358, 432, - /* 1730 */ 433, 434, 435, 436, 437, 373, 439, 391, 407, 393, - /* 1740 */ 0, 407, 379, 446, 373, 0, 42, 384, 451, 0, - /* 1750 */ 35, 216, 35, 341, 391, 35, 393, 35, 216, 0, - /* 1760 */ 35, 35, 216, 351, 0, 216, 0, 483, 484, 35, - /* 1770 */ 0, 0, 22, 427, 35, 429, 211, 341, 432, 433, - /* 1780 */ 434, 435, 436, 437, 0, 439, 199, 351, 0, 199, - /* 1790 */ 427, 379, 429, 200, 193, 432, 433, 434, 435, 436, - /* 1800 */ 437, 191, 439, 391, 341, 393, 0, 0, 0, 187, - /* 1810 */ 186, 0, 0, 0, 351, 379, 47, 35, 0, 473, - /* 1820 */ 384, 49, 47, 0, 341, 42, 0, 391, 0, 393, - /* 1830 */ 0, 0, 47, 0, 351, 0, 0, 0, 0, 427, - /* 1840 */ 159, 429, 379, 0, 432, 433, 434, 435, 436, 437, - /* 1850 */ 159, 439, 35, 0, 391, 0, 393, 0, 0, 0, - /* 1860 */ 0, 0, 379, 427, 0, 429, 0, 384, 432, 433, - /* 1870 */ 434, 435, 436, 437, 391, 439, 393, 48, 22, 47, - /* 1880 */ 0, 42, 0, 0, 0, 0, 0, 475, 0, 0, - /* 1890 */ 427, 341, 429, 0, 0, 432, 433, 434, 435, 436, - /* 1900 */ 437, 351, 439, 0, 0, 0, 0, 0, 0, 0, - /* 1910 */ 427, 143, 429, 0, 0, 432, 433, 434, 435, 436, - /* 1920 */ 437, 341, 439, 22, 48, 0, 35, 62, 0, 379, - /* 1930 */ 62, 351, 22, 0, 384, 62, 0, 0, 39, 49, - /* 1940 */ 0, 391, 0, 393, 49, 49, 35, 484, 0, 0, - /* 1950 */ 35, 39, 35, 35, 0, 39, 0, 14, 0, 379, - /* 1960 */ 39, 42, 0, 39, 384, 39, 44, 47, 182, 40, - /* 1970 */ 47, 391, 0, 393, 47, 0, 0, 427, 0, 429, - /* 1980 */ 341, 0, 432, 433, 434, 435, 436, 437, 1, 439, - /* 1990 */ 351, 39, 35, 49, 0, 35, 49, 0, 39, 69, - /* 2000 */ 35, 0, 49, 39, 35, 39, 19, 427, 0, 429, - /* 2010 */ 49, 0, 432, 433, 434, 435, 436, 437, 379, 439, - /* 2020 */ 33, 0, 0, 0, 0, 35, 22, 0, 35, 44, - /* 2030 */ 391, 35, 393, 35, 35, 35, 49, 35, 35, 44, - /* 2040 */ 35, 35, 110, 112, 57, 58, 59, 60, 22, 62, - /* 2050 */ 35, 0, 22, 341, 22, 0, 22, 0, 0, 0, - /* 2060 */ 51, 22, 0, 351, 0, 20, 427, 104, 429, 172, - /* 2070 */ 35, 432, 433, 434, 435, 436, 437, 35, 439, 35, - /* 2080 */ 103, 35, 35, 35, 341, 103, 0, 35, 22, 102, - /* 2090 */ 198, 379, 105, 22, 351, 0, 0, 3, 264, 258, - /* 2100 */ 44, 48, 3, 391, 35, 393, 264, 172, 48, 44, - /* 2110 */ 47, 172, 174, 172, 104, 103, 103, 101, 99, 341, - /* 2120 */ 47, 104, 379, 178, 178, 138, 44, 44, 194, 351, - /* 2130 */ 0, 44, 104, 104, 391, 104, 393, 104, 264, 427, - /* 2140 */ 103, 429, 44, 103, 432, 433, 434, 435, 436, 437, - /* 2150 */ 35, 439, 103, 103, 35, 35, 341, 379, 47, 35, - /* 2160 */ 173, 35, 44, 47, 0, 104, 351, 180, 39, 391, - /* 2170 */ 427, 393, 429, 0, 104, 432, 433, 434, 435, 436, - /* 2180 */ 437, 341, 439, 103, 47, 104, 199, 103, 39, 104, - /* 2190 */ 113, 351, 103, 103, 379, 175, 103, 47, 173, 44, - /* 2200 */ 103, 101, 101, 2, 47, 427, 391, 429, 393, 22, - /* 2210 */ 432, 433, 434, 435, 436, 437, 245, 439, 341, 379, - /* 2220 */ 103, 47, 22, 114, 35, 104, 104, 35, 351, 104, - /* 2230 */ 103, 391, 104, 393, 103, 103, 103, 223, 103, 35, - /* 2240 */ 104, 103, 427, 341, 429, 104, 103, 432, 433, 434, - /* 2250 */ 435, 436, 437, 351, 439, 104, 379, 35, 104, 103, - /* 2260 */ 35, 225, 103, 35, 104, 103, 35, 427, 391, 429, - /* 2270 */ 393, 104, 432, 433, 434, 435, 436, 437, 103, 439, - /* 2280 */ 103, 379, 44, 125, 103, 35, 125, 103, 125, 22, - /* 2290 */ 125, 35, 69, 391, 68, 393, 35, 35, 35, 35, - /* 2300 */ 35, 35, 75, 35, 427, 97, 429, 35, 22, 432, - /* 2310 */ 433, 434, 435, 436, 437, 341, 439, 44, 35, 35, - /* 2320 */ 35, 75, 35, 35, 35, 351, 35, 35, 35, 427, - /* 2330 */ 341, 429, 35, 35, 432, 433, 434, 435, 436, 437, - /* 2340 */ 351, 439, 22, 0, 35, 49, 39, 0, 341, 35, - /* 2350 */ 49, 39, 0, 379, 35, 49, 39, 0, 351, 35, - /* 2360 */ 39, 0, 49, 35, 35, 391, 0, 393, 379, 20, - /* 2370 */ 22, 21, 487, 22, 487, 22, 21, 487, 487, 487, - /* 2380 */ 391, 487, 393, 487, 487, 487, 379, 487, 487, 487, - /* 2390 */ 487, 487, 487, 487, 487, 341, 487, 487, 391, 487, - /* 2400 */ 393, 427, 487, 429, 487, 351, 432, 433, 434, 435, - /* 2410 */ 436, 437, 487, 439, 487, 487, 427, 341, 429, 487, - /* 2420 */ 487, 432, 433, 434, 435, 436, 437, 351, 439, 487, - /* 2430 */ 487, 487, 487, 379, 427, 487, 429, 487, 487, 432, - /* 2440 */ 433, 434, 435, 436, 437, 391, 439, 393, 487, 487, - /* 2450 */ 487, 487, 487, 487, 487, 379, 487, 487, 487, 487, - /* 2460 */ 487, 487, 487, 487, 341, 487, 487, 391, 487, 393, - /* 2470 */ 487, 487, 487, 487, 351, 487, 487, 487, 487, 487, - /* 2480 */ 487, 427, 487, 429, 487, 487, 432, 433, 434, 435, - /* 2490 */ 436, 437, 487, 439, 487, 487, 487, 487, 487, 487, - /* 2500 */ 487, 487, 379, 427, 487, 429, 487, 487, 432, 433, - /* 2510 */ 434, 435, 436, 437, 391, 439, 393, 487, 487, 487, - /* 2520 */ 487, 487, 487, 341, 487, 487, 487, 487, 487, 487, - /* 2530 */ 487, 487, 487, 351, 487, 487, 341, 487, 487, 487, - /* 2540 */ 487, 487, 487, 487, 487, 487, 351, 487, 487, 487, - /* 2550 */ 427, 487, 429, 341, 487, 432, 433, 434, 435, 436, - /* 2560 */ 437, 379, 439, 351, 487, 487, 487, 487, 487, 487, - /* 2570 */ 487, 487, 487, 391, 379, 393, 487, 487, 487, 487, - /* 2580 */ 487, 487, 487, 487, 487, 341, 391, 487, 393, 487, - /* 2590 */ 487, 379, 487, 487, 487, 351, 487, 487, 487, 487, - /* 2600 */ 487, 487, 487, 391, 487, 393, 487, 487, 487, 427, - /* 2610 */ 487, 429, 487, 487, 432, 433, 434, 435, 436, 437, - /* 2620 */ 487, 439, 427, 379, 429, 487, 487, 432, 433, 434, - /* 2630 */ 435, 436, 437, 487, 439, 391, 487, 393, 487, 427, - /* 2640 */ 487, 429, 487, 487, 432, 433, 434, 435, 436, 437, - /* 2650 */ 487, 439, 341, 487, 487, 487, 487, 487, 487, 487, - /* 2660 */ 487, 487, 351, 487, 487, 487, 487, 487, 487, 487, - /* 2670 */ 487, 427, 341, 429, 487, 487, 432, 433, 434, 435, - /* 2680 */ 436, 437, 351, 439, 487, 487, 487, 487, 487, 487, - /* 2690 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2700 */ 487, 487, 391, 487, 393, 487, 487, 487, 487, 487, - /* 2710 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2720 */ 487, 487, 391, 487, 393, 487, 487, 487, 487, 487, - /* 2730 */ 487, 487, 487, 487, 487, 487, 487, 487, 427, 487, - /* 2740 */ 429, 487, 341, 432, 433, 434, 435, 436, 437, 487, - /* 2750 */ 439, 487, 351, 487, 487, 487, 487, 487, 427, 341, - /* 2760 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 351, - /* 2770 */ 439, 487, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2780 */ 379, 487, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2790 */ 487, 487, 391, 487, 393, 487, 487, 379, 487, 487, - /* 2800 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 391, - /* 2810 */ 487, 393, 487, 487, 487, 487, 487, 487, 487, 487, - /* 2820 */ 487, 487, 487, 487, 487, 487, 487, 487, 427, 487, - /* 2830 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 487, - /* 2840 */ 439, 487, 487, 487, 487, 427, 487, 429, 487, 487, - /* 2850 */ 432, 433, 434, 435, 436, 437, 487, 439, 338, 338, - /* 2860 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2870 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2880 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2890 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2900 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2910 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2920 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2930 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2940 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2950 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2960 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2970 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2980 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 2990 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3000 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3010 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3020 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3030 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 1090 */ 88, 89, 90, 91, 92, 93, 94, 95, 96, 454, + /* 1100 */ 455, 456, 172, 458, 459, 20, 102, 33, 103, 179, + /* 1110 */ 193, 371, 443, 190, 445, 192, 391, 391, 114, 379, + /* 1120 */ 380, 379, 380, 49, 20, 357, 350, 351, 341, 350, + /* 1130 */ 351, 57, 58, 59, 60, 341, 62, 341, 20, 454, + /* 1140 */ 455, 456, 374, 458, 459, 222, 370, 142, 144, 370, + /* 1150 */ 382, 147, 148, 149, 150, 151, 152, 153, 154, 155, + /* 1160 */ 156, 157, 158, 159, 160, 161, 162, 163, 411, 165, + /* 1170 */ 166, 167, 341, 390, 359, 280, 102, 478, 391, 105, + /* 1180 */ 379, 380, 341, 260, 452, 391, 341, 391, 183, 184, + /* 1190 */ 185, 341, 341, 188, 341, 341, 341, 379, 380, 341, + /* 1200 */ 385, 351, 35, 353, 379, 380, 201, 202, 379, 380, + /* 1210 */ 388, 372, 261, 391, 375, 458, 0, 212, 461, 341, + /* 1220 */ 215, 0, 391, 218, 219, 220, 221, 222, 114, 351, + /* 1230 */ 380, 353, 391, 476, 477, 44, 391, 366, 481, 482, + /* 1240 */ 369, 391, 391, 393, 391, 391, 391, 173, 174, 391, + /* 1250 */ 45, 46, 341, 107, 180, 181, 110, 172, 380, 13, + /* 1260 */ 44, 42, 351, 44, 353, 260, 258, 259, 68, 391, + /* 1270 */ 49, 393, 42, 199, 44, 13, 172, 427, 164, 429, + /* 1280 */ 262, 35, 432, 433, 434, 435, 436, 437, 170, 439, + /* 1290 */ 107, 380, 462, 110, 444, 104, 446, 35, 0, 0, + /* 1300 */ 450, 451, 391, 107, 393, 427, 110, 429, 0, 44, + /* 1310 */ 432, 433, 434, 435, 436, 437, 107, 439, 44, 110, + /* 1320 */ 22, 22, 444, 207, 446, 209, 140, 141, 450, 451, + /* 1330 */ 22, 44, 62, 44, 13, 44, 44, 35, 427, 44, + /* 1340 */ 429, 44, 341, 432, 433, 434, 435, 436, 437, 412, + /* 1350 */ 439, 44, 351, 12, 13, 444, 35, 446, 44, 44, + /* 1360 */ 193, 450, 451, 22, 115, 1, 2, 44, 49, 104, + /* 1370 */ 341, 44, 103, 428, 33, 105, 35, 20, 104, 0, + /* 1380 */ 351, 380, 113, 134, 135, 136, 137, 138, 139, 44, + /* 1390 */ 44, 104, 391, 104, 393, 104, 104, 44, 421, 104, + /* 1400 */ 44, 104, 13, 62, 206, 426, 359, 44, 421, 380, + /* 1410 */ 44, 104, 359, 189, 414, 351, 75, 20, 104, 104, + /* 1420 */ 391, 398, 393, 223, 35, 42, 20, 104, 427, 50, + /* 1430 */ 429, 104, 341, 432, 433, 434, 435, 436, 437, 401, + /* 1440 */ 439, 100, 351, 351, 398, 444, 169, 446, 396, 104, + /* 1450 */ 104, 450, 451, 20, 351, 350, 427, 104, 429, 350, + /* 1460 */ 104, 432, 433, 434, 435, 436, 437, 104, 439, 398, + /* 1470 */ 104, 380, 396, 444, 396, 446, 101, 99, 363, 450, + /* 1480 */ 451, 362, 391, 350, 393, 98, 361, 350, 350, 350, + /* 1490 */ 20, 343, 48, 343, 347, 193, 347, 20, 421, 341, + /* 1500 */ 359, 393, 359, 20, 352, 352, 20, 413, 343, 351, + /* 1510 */ 359, 350, 380, 359, 359, 359, 359, 343, 427, 350, + /* 1520 */ 429, 391, 380, 432, 433, 434, 435, 436, 437, 103, + /* 1530 */ 439, 391, 191, 423, 193, 444, 391, 446, 380, 380, + /* 1540 */ 380, 450, 451, 380, 380, 210, 380, 425, 421, 391, + /* 1550 */ 357, 393, 197, 418, 420, 196, 357, 195, 350, 269, + /* 1560 */ 467, 341, 268, 419, 223, 224, 393, 391, 391, 401, + /* 1570 */ 391, 351, 401, 467, 412, 391, 406, 236, 237, 238, + /* 1580 */ 239, 240, 241, 242, 406, 427, 277, 429, 467, 182, + /* 1590 */ 432, 433, 434, 435, 436, 437, 470, 439, 469, 279, + /* 1600 */ 380, 263, 466, 278, 446, 283, 412, 281, 450, 451, + /* 1610 */ 286, 391, 351, 393, 486, 20, 431, 357, 352, 259, + /* 1620 */ 357, 20, 404, 406, 341, 391, 391, 391, 391, 391, + /* 1630 */ 391, 406, 174, 357, 351, 403, 357, 465, 103, 464, + /* 1640 */ 103, 449, 375, 391, 351, 357, 350, 427, 36, 429, + /* 1650 */ 369, 383, 432, 433, 434, 435, 436, 437, 415, 439, + /* 1660 */ 480, 479, 344, 380, 422, 407, 446, 339, 358, 0, + /* 1670 */ 450, 451, 343, 373, 391, 0, 393, 373, 407, 373, + /* 1680 */ 0, 42, 0, 35, 216, 341, 35, 35, 35, 216, + /* 1690 */ 0, 35, 35, 0, 216, 351, 216, 0, 35, 341, + /* 1700 */ 0, 22, 0, 35, 211, 0, 199, 0, 199, 351, + /* 1710 */ 427, 200, 429, 193, 191, 432, 433, 434, 435, 436, + /* 1720 */ 437, 0, 439, 0, 380, 0, 187, 186, 0, 446, + /* 1730 */ 0, 47, 0, 450, 451, 391, 341, 393, 380, 35, + /* 1740 */ 49, 0, 47, 0, 0, 42, 351, 159, 47, 391, + /* 1750 */ 0, 393, 0, 0, 0, 0, 0, 0, 0, 35, + /* 1760 */ 0, 159, 341, 0, 0, 0, 0, 0, 0, 0, + /* 1770 */ 0, 427, 351, 429, 0, 380, 432, 433, 434, 435, + /* 1780 */ 436, 437, 0, 439, 0, 427, 391, 429, 393, 0, + /* 1790 */ 432, 433, 434, 435, 436, 437, 0, 439, 0, 0, + /* 1800 */ 0, 380, 0, 42, 0, 0, 47, 0, 0, 0, + /* 1810 */ 0, 0, 391, 22, 393, 0, 472, 473, 0, 143, + /* 1820 */ 0, 0, 427, 22, 429, 48, 341, 432, 433, 434, + /* 1830 */ 435, 436, 437, 48, 439, 22, 351, 62, 35, 0, + /* 1840 */ 62, 483, 484, 0, 0, 62, 0, 0, 427, 35, + /* 1850 */ 429, 341, 40, 432, 433, 434, 435, 436, 437, 0, + /* 1860 */ 439, 351, 39, 35, 39, 380, 49, 446, 473, 384, + /* 1870 */ 35, 49, 451, 0, 0, 49, 391, 341, 393, 39, + /* 1880 */ 35, 0, 44, 42, 0, 14, 0, 351, 39, 47, + /* 1890 */ 380, 0, 39, 0, 384, 47, 39, 47, 182, 0, + /* 1900 */ 0, 391, 0, 393, 0, 69, 0, 35, 39, 49, + /* 1910 */ 0, 35, 427, 49, 429, 0, 380, 432, 433, 434, + /* 1920 */ 435, 436, 437, 35, 439, 0, 39, 391, 49, 393, + /* 1930 */ 35, 39, 49, 39, 0, 0, 0, 427, 0, 429, + /* 1940 */ 0, 0, 432, 433, 434, 435, 436, 437, 35, 439, + /* 1950 */ 341, 22, 0, 35, 35, 35, 35, 35, 35, 35, + /* 1960 */ 351, 110, 35, 427, 22, 429, 341, 1, 432, 433, + /* 1970 */ 434, 435, 436, 437, 112, 439, 351, 44, 35, 35, + /* 1980 */ 0, 44, 22, 0, 22, 19, 22, 0, 35, 380, + /* 1990 */ 51, 0, 35, 0, 35, 0, 22, 20, 35, 33, + /* 2000 */ 391, 104, 393, 35, 35, 380, 103, 0, 103, 384, + /* 2010 */ 35, 475, 22, 0, 198, 49, 391, 0, 393, 22, + /* 2020 */ 0, 194, 3, 57, 58, 59, 60, 341, 62, 174, + /* 2030 */ 172, 103, 178, 172, 178, 172, 427, 351, 429, 172, + /* 2040 */ 44, 432, 433, 434, 435, 436, 437, 48, 439, 104, + /* 2050 */ 264, 103, 427, 48, 429, 101, 44, 432, 433, 434, + /* 2060 */ 435, 436, 437, 47, 439, 104, 380, 44, 102, 99, + /* 2070 */ 384, 105, 44, 47, 44, 104, 103, 391, 3, 393, + /* 2080 */ 104, 103, 103, 264, 103, 44, 104, 35, 341, 104, + /* 2090 */ 35, 35, 35, 484, 264, 35, 35, 47, 351, 173, + /* 2100 */ 47, 0, 104, 44, 138, 104, 0, 103, 39, 47, + /* 2110 */ 104, 103, 103, 427, 341, 429, 0, 103, 432, 433, + /* 2120 */ 434, 435, 436, 437, 351, 439, 258, 380, 104, 39, + /* 2130 */ 175, 384, 103, 47, 103, 113, 44, 101, 391, 173, + /* 2140 */ 393, 245, 2, 101, 22, 47, 180, 103, 22, 104, + /* 2150 */ 103, 47, 104, 380, 223, 104, 35, 103, 35, 35, + /* 2160 */ 114, 103, 35, 35, 391, 199, 393, 103, 35, 104, + /* 2170 */ 103, 225, 104, 103, 427, 104, 429, 103, 341, 432, + /* 2180 */ 433, 434, 435, 436, 437, 104, 439, 103, 351, 104, + /* 2190 */ 103, 35, 104, 341, 103, 22, 44, 104, 103, 126, + /* 2200 */ 427, 35, 429, 351, 126, 432, 433, 434, 435, 436, + /* 2210 */ 437, 341, 439, 103, 103, 126, 103, 380, 115, 22, + /* 2220 */ 126, 351, 69, 68, 35, 35, 35, 35, 391, 35, + /* 2230 */ 393, 35, 380, 35, 35, 75, 97, 44, 35, 35, + /* 2240 */ 35, 22, 35, 391, 35, 393, 35, 75, 35, 35, + /* 2250 */ 380, 35, 35, 35, 22, 35, 0, 35, 0, 49, + /* 2260 */ 39, 391, 35, 393, 427, 0, 429, 39, 35, 432, + /* 2270 */ 433, 434, 435, 436, 437, 49, 439, 39, 49, 427, + /* 2280 */ 0, 429, 35, 49, 432, 433, 434, 435, 436, 437, + /* 2290 */ 39, 439, 0, 0, 35, 35, 22, 427, 21, 429, + /* 2300 */ 22, 22, 432, 433, 434, 435, 436, 437, 341, 439, + /* 2310 */ 21, 20, 487, 487, 487, 487, 487, 487, 351, 487, + /* 2320 */ 487, 487, 487, 487, 487, 487, 487, 341, 487, 487, + /* 2330 */ 487, 487, 487, 487, 487, 487, 487, 351, 487, 487, + /* 2340 */ 487, 341, 487, 487, 487, 487, 487, 380, 487, 487, + /* 2350 */ 487, 351, 487, 487, 487, 487, 487, 487, 391, 487, + /* 2360 */ 393, 487, 487, 487, 487, 487, 380, 487, 487, 487, + /* 2370 */ 487, 487, 487, 487, 487, 487, 487, 391, 341, 393, + /* 2380 */ 380, 487, 487, 487, 487, 487, 487, 487, 351, 487, + /* 2390 */ 487, 391, 487, 393, 427, 487, 429, 487, 487, 432, + /* 2400 */ 433, 434, 435, 436, 437, 487, 439, 487, 487, 487, + /* 2410 */ 487, 487, 487, 427, 487, 429, 487, 380, 432, 433, + /* 2420 */ 434, 435, 436, 437, 487, 439, 487, 427, 391, 429, + /* 2430 */ 393, 487, 432, 433, 434, 435, 436, 437, 487, 439, + /* 2440 */ 341, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2450 */ 351, 487, 487, 487, 487, 341, 487, 487, 487, 487, + /* 2460 */ 487, 487, 487, 487, 427, 351, 429, 487, 487, 432, + /* 2470 */ 433, 434, 435, 436, 437, 487, 439, 487, 487, 380, + /* 2480 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2490 */ 391, 487, 393, 487, 380, 487, 487, 487, 487, 487, + /* 2500 */ 487, 487, 487, 487, 487, 391, 341, 393, 487, 487, + /* 2510 */ 487, 487, 487, 487, 487, 487, 351, 487, 487, 487, + /* 2520 */ 341, 487, 487, 487, 487, 487, 427, 487, 429, 487, + /* 2530 */ 351, 432, 433, 434, 435, 436, 437, 487, 439, 487, + /* 2540 */ 487, 427, 487, 429, 487, 380, 432, 433, 434, 435, + /* 2550 */ 436, 437, 487, 439, 487, 487, 391, 487, 393, 380, + /* 2560 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2570 */ 391, 487, 393, 487, 487, 487, 487, 487, 487, 487, + /* 2580 */ 487, 487, 487, 487, 487, 341, 487, 487, 487, 487, + /* 2590 */ 487, 487, 427, 487, 429, 351, 487, 432, 433, 434, + /* 2600 */ 435, 436, 437, 487, 439, 487, 427, 487, 429, 487, + /* 2610 */ 487, 432, 433, 434, 435, 436, 437, 487, 439, 487, + /* 2620 */ 487, 487, 487, 487, 380, 487, 487, 487, 487, 487, + /* 2630 */ 487, 487, 487, 487, 487, 391, 487, 393, 487, 487, + /* 2640 */ 487, 487, 487, 487, 487, 341, 487, 487, 487, 487, + /* 2650 */ 487, 487, 487, 487, 487, 351, 487, 487, 487, 487, + /* 2660 */ 341, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2670 */ 351, 427, 487, 429, 487, 487, 432, 433, 434, 435, + /* 2680 */ 436, 437, 487, 439, 380, 487, 487, 487, 487, 487, + /* 2690 */ 487, 487, 487, 487, 487, 391, 487, 393, 487, 380, + /* 2700 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2710 */ 391, 487, 393, 487, 487, 487, 487, 487, 487, 487, + /* 2720 */ 341, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2730 */ 351, 427, 487, 429, 487, 341, 432, 433, 434, 435, + /* 2740 */ 436, 437, 487, 439, 487, 351, 427, 487, 429, 487, + /* 2750 */ 487, 432, 433, 434, 435, 436, 437, 341, 439, 380, + /* 2760 */ 487, 487, 487, 487, 487, 487, 487, 351, 487, 487, + /* 2770 */ 391, 487, 393, 487, 380, 487, 487, 487, 487, 487, + /* 2780 */ 487, 487, 487, 487, 487, 391, 487, 393, 487, 487, + /* 2790 */ 487, 487, 487, 487, 487, 487, 380, 487, 487, 487, + /* 2800 */ 487, 487, 487, 487, 487, 487, 427, 391, 429, 393, + /* 2810 */ 487, 432, 433, 434, 435, 436, 437, 487, 439, 487, + /* 2820 */ 487, 427, 487, 429, 487, 487, 432, 433, 434, 435, + /* 2830 */ 436, 437, 341, 439, 487, 487, 487, 487, 487, 487, + /* 2840 */ 487, 487, 351, 427, 487, 429, 487, 341, 432, 433, + /* 2850 */ 434, 435, 436, 437, 487, 439, 487, 351, 487, 487, + /* 2860 */ 487, 487, 341, 487, 487, 487, 487, 487, 487, 487, + /* 2870 */ 487, 380, 351, 487, 487, 487, 487, 487, 487, 487, + /* 2880 */ 487, 487, 391, 487, 393, 487, 380, 487, 487, 487, + /* 2890 */ 487, 487, 487, 487, 487, 487, 487, 391, 487, 393, + /* 2900 */ 487, 380, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2910 */ 487, 487, 391, 487, 393, 487, 487, 487, 427, 487, + /* 2920 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 487, + /* 2930 */ 439, 487, 487, 427, 341, 429, 487, 487, 432, 433, + /* 2940 */ 434, 435, 436, 437, 351, 439, 487, 487, 427, 487, + /* 2950 */ 429, 487, 487, 432, 433, 434, 435, 436, 437, 487, + /* 2960 */ 439, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 2970 */ 487, 487, 487, 380, 487, 487, 487, 487, 487, 487, + /* 2980 */ 487, 487, 487, 487, 391, 487, 393, 487, 487, 487, + /* 2990 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 3000 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 3010 */ 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + /* 3020 */ 427, 487, 429, 487, 487, 432, 433, 434, 435, 436, + /* 3030 */ 437, 487, 439, 338, 338, 338, 338, 338, 338, 338, /* 3040 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3050 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3060 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, @@ -1166,214 +1184,229 @@ static const YYCODETYPE yy_lookahead[] = { /* 3160 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3170 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, /* 3180 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - /* 3190 */ 338, 338, 338, 338, 338, 338, + /* 3190 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3200 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3210 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3220 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3230 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3240 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3250 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3260 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3270 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3280 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3290 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3300 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3310 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3320 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3330 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3340 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3350 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3360 */ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + /* 3370 */ 338, }; -#define YY_SHIFT_COUNT (800) +#define YY_SHIFT_COUNT (798) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2366) +#define YY_SHIFT_MAX (2293) static const unsigned short int yy_shift_ofst[] = { /* 0 */ 1005, 0, 104, 0, 337, 337, 337, 337, 337, 337, /* 10 */ 337, 337, 337, 337, 337, 337, 441, 673, 673, 777, /* 20 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, /* 30 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, /* 40 */ 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, - /* 50 */ 673, 60, 259, 393, 629, 111, 739, 111, 629, 629, - /* 60 */ 111, 1341, 111, 1341, 1341, 66, 111, 68, 781, 101, - /* 70 */ 101, 781, 13, 13, 113, 294, 23, 23, 101, 101, - /* 80 */ 101, 101, 101, 101, 101, 101, 101, 101, 158, 101, - /* 90 */ 101, 211, 68, 101, 101, 285, 68, 101, 158, 101, - /* 100 */ 158, 68, 101, 101, 68, 101, 68, 68, 68, 101, - /* 110 */ 284, 1004, 15, 15, 303, 462, 1302, 1302, 1302, 1302, - /* 120 */ 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, - /* 130 */ 1302, 1302, 1302, 1302, 1302, 1072, 18, 113, 294, 802, - /* 140 */ 802, 184, 346, 346, 346, 705, 312, 312, 184, 211, - /* 150 */ 254, 260, 68, 534, 68, 534, 534, 836, 619, 28, - /* 160 */ 28, 28, 28, 28, 28, 28, 28, 1987, 757, 261, - /* 170 */ 580, 613, 508, 49, 123, 343, 343, 526, 354, 1007, - /* 180 */ 299, 1079, 1192, 418, 398, 1085, 916, 939, 785, 916, - /* 190 */ 1177, 325, 290, 1160, 1377, 1409, 1226, 211, 1409, 211, - /* 200 */ 1261, 1435, 1428, 1452, 1435, 1428, 1308, 1460, 1435, 1460, - /* 210 */ 1428, 1308, 1308, 1389, 1393, 1460, 1402, 1460, 1460, 1460, - /* 220 */ 1490, 1468, 1490, 1468, 1409, 211, 1503, 211, 1509, 1511, - /* 230 */ 211, 1509, 211, 211, 211, 1460, 211, 1490, 68, 68, - /* 240 */ 68, 68, 68, 68, 68, 68, 68, 68, 68, 1460, - /* 250 */ 1490, 534, 534, 534, 1343, 1453, 1409, 284, 1358, 1361, - /* 260 */ 1503, 284, 1394, 1160, 1460, 1452, 1452, 534, 1333, 1335, - /* 270 */ 534, 1333, 1335, 534, 534, 68, 1328, 1439, 1333, 1344, - /* 280 */ 1350, 1364, 1160, 1345, 1366, 1348, 1373, 1435, 1630, 1509, - /* 290 */ 284, 284, 1636, 1335, 534, 534, 534, 534, 534, 1335, - /* 300 */ 534, 1508, 284, 836, 284, 1435, 1592, 1596, 534, 619, - /* 310 */ 1460, 284, 1670, 1490, 2858, 2858, 2858, 2858, 2858, 2858, - /* 320 */ 2858, 2858, 2858, 1002, 1074, 225, 32, 736, 750, 860, - /* 330 */ 687, 980, 1356, 434, 791, 197, 197, 197, 197, 197, - /* 340 */ 197, 197, 197, 197, 749, 265, 698, 698, 29, 6, - /* 350 */ 34, 307, 830, 562, 963, 902, 514, 282, 282, 1097, - /* 360 */ 728, 971, 1097, 1097, 1097, 983, 1044, 622, 1231, 1198, - /* 370 */ 1131, 1077, 1143, 1149, 1156, 1161, 1256, 1262, 815, 1182, - /* 380 */ 1276, 1071, 1195, 1205, 63, 1237, 1263, 1275, 1152, 1084, - /* 390 */ 1094, 1277, 1278, 1282, 1285, 1286, 1291, 1310, 1292, 1100, - /* 400 */ 1295, 311, 1305, 1315, 1340, 1349, 1353, 1354, 1272, 1253, - /* 410 */ 1270, 1293, 1321, 409, 1351, 1707, 1740, 1745, 1704, 1749, - /* 420 */ 1715, 1535, 1717, 1720, 1722, 1542, 1759, 1725, 1726, 1546, - /* 430 */ 1764, 1549, 1766, 1734, 1770, 1750, 1771, 1739, 1565, 1784, - /* 440 */ 1587, 1788, 1590, 1593, 1601, 1610, 1806, 1807, 1808, 1622, - /* 450 */ 1624, 1811, 1812, 1769, 1813, 1782, 1772, 1818, 1775, 1823, - /* 460 */ 1783, 1826, 1828, 1830, 1785, 1831, 1833, 1835, 1836, 1837, - /* 470 */ 1838, 1681, 1817, 1843, 1691, 1853, 1855, 1857, 1858, 1859, - /* 480 */ 1860, 1861, 1864, 1866, 1888, 1889, 1893, 1894, 1903, 1904, - /* 490 */ 1905, 1832, 1880, 1839, 1882, 1883, 1884, 1885, 1886, 1906, - /* 500 */ 1856, 1907, 1908, 1909, 1768, 1913, 1914, 1901, 1829, 1910, - /* 510 */ 1876, 1925, 1865, 1891, 1928, 1868, 1933, 1873, 1936, 1937, - /* 520 */ 1911, 1890, 1899, 1940, 1915, 1895, 1912, 1942, 1917, 1896, - /* 530 */ 1916, 1948, 1918, 1949, 1919, 1921, 1922, 1920, 1923, 1943, - /* 540 */ 1927, 1954, 1929, 1924, 1956, 1958, 1962, 1926, 1786, 1972, - /* 550 */ 1975, 1976, 1930, 1978, 1981, 1957, 1944, 1952, 1994, 1960, - /* 560 */ 1947, 1959, 1997, 1965, 1953, 1964, 2001, 1969, 1961, 1966, - /* 570 */ 2008, 2011, 2021, 2022, 2023, 2024, 1931, 1932, 1990, 2004, - /* 580 */ 2027, 1993, 1996, 1998, 1999, 2000, 2002, 2003, 1985, 1995, - /* 590 */ 2005, 2006, 2026, 2015, 2051, 2030, 2064, 2032, 2009, 2055, - /* 600 */ 2034, 2035, 2057, 2042, 2058, 2044, 2059, 2039, 2045, 2046, - /* 610 */ 2047, 2048, 1963, 1977, 2062, 1897, 1982, 1892, 2052, 2066, - /* 620 */ 2086, 1934, 2071, 1935, 1938, 2095, 2096, 1939, 1945, 1941, - /* 630 */ 1946, 2094, 2056, 1834, 2012, 2010, 2013, 2053, 2016, 2060, - /* 640 */ 2019, 2017, 2065, 2082, 2028, 2037, 2040, 2049, 2029, 2083, - /* 650 */ 2063, 2073, 2050, 2087, 1842, 2031, 2033, 2099, 2098, 1874, - /* 660 */ 2069, 2115, 2119, 2120, 2124, 2126, 2061, 2070, 2111, 1841, - /* 670 */ 2118, 2116, 2130, 2164, 2080, 2129, 1920, 2137, 2084, 2081, - /* 680 */ 2085, 2089, 2090, 2020, 2093, 2173, 2149, 2025, 2097, 2077, - /* 690 */ 1920, 2150, 2155, 2100, 1971, 2101, 2201, 2187, 2014, 2117, - /* 700 */ 2121, 2127, 2122, 2131, 2125, 2157, 2132, 2133, 2174, 2128, - /* 710 */ 2200, 2036, 2135, 2109, 2136, 2189, 2192, 2138, 2141, 2204, - /* 720 */ 2143, 2151, 2222, 2156, 2154, 2225, 2159, 2160, 2228, 2162, - /* 730 */ 2167, 2231, 2175, 2158, 2161, 2163, 2165, 2177, 2238, 2181, - /* 740 */ 2250, 2184, 2238, 2238, 2267, 2223, 2226, 2256, 2261, 2262, - /* 750 */ 2263, 2264, 2265, 2266, 2268, 2227, 2208, 2273, 2272, 2283, - /* 760 */ 2284, 2286, 2285, 2287, 2288, 2246, 1985, 2289, 1995, 2291, - /* 770 */ 2292, 2293, 2297, 2320, 2298, 2343, 2309, 2296, 2307, 2347, - /* 780 */ 2314, 2301, 2312, 2352, 2319, 2306, 2317, 2357, 2324, 2313, - /* 790 */ 2321, 2361, 2328, 2329, 2366, 2348, 2350, 2351, 2353, 2355, - /* 800 */ 2349, + /* 50 */ 673, 16, 66, 923, 116, 250, 286, 250, 116, 116, + /* 60 */ 250, 1341, 250, 1341, 1341, 170, 250, 24, 342, 36, + /* 70 */ 36, 342, 419, 419, 257, 475, 344, 344, 36, 36, + /* 80 */ 36, 36, 36, 36, 36, 36, 36, 36, 110, 36, + /* 90 */ 36, 96, 24, 36, 36, 162, 24, 36, 110, 36, + /* 100 */ 110, 24, 36, 36, 24, 36, 24, 24, 24, 36, + /* 110 */ 148, 1004, 15, 15, 303, 258, 100, 100, 100, 100, + /* 120 */ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + /* 130 */ 100, 100, 100, 100, 100, 596, 194, 257, 475, 672, + /* 140 */ 672, 626, 639, 639, 639, 438, 804, 804, 626, 96, + /* 150 */ 24, 24, 24, 24, 106, 4, 24, 203, 24, 203, + /* 160 */ 203, 196, 281, 28, 28, 28, 28, 1966, 531, 225, + /* 170 */ 575, 707, 381, 363, 604, 917, 917, 492, 930, 828, + /* 180 */ 54, 1085, 1205, 926, 910, 1104, 1008, 624, 895, 1008, + /* 190 */ 1219, 951, 1118, 1018, 1319, 1357, 1198, 96, 1357, 96, + /* 200 */ 1224, 1397, 1383, 1406, 1397, 1383, 1277, 1433, 1397, 1433, + /* 210 */ 1383, 1277, 1277, 1375, 1378, 1433, 1387, 1433, 1433, 1433, + /* 220 */ 1470, 1444, 1470, 1444, 1357, 96, 1477, 96, 1483, 1486, + /* 230 */ 96, 1483, 96, 96, 96, 1433, 96, 1470, 24, 24, + /* 240 */ 24, 24, 24, 24, 24, 1433, 1470, 203, 203, 203, + /* 250 */ 1335, 1426, 1357, 148, 1355, 1359, 1477, 148, 1362, 1018, + /* 260 */ 1433, 1406, 1406, 203, 1290, 1294, 203, 1290, 1294, 203, + /* 270 */ 203, 24, 1309, 1407, 1290, 1320, 1325, 1338, 1018, 1324, + /* 280 */ 1322, 1326, 1360, 1397, 1595, 1483, 148, 148, 1601, 1294, + /* 290 */ 203, 203, 203, 203, 203, 1294, 203, 1458, 148, 196, + /* 300 */ 148, 1397, 1535, 1537, 203, 281, 1433, 148, 1612, 1470, + /* 310 */ 3033, 3033, 3033, 3033, 3033, 3033, 3033, 3033, 3033, 1002, + /* 320 */ 1074, 460, 584, 774, 716, 747, 649, 813, 948, 434, + /* 330 */ 666, 197, 197, 197, 197, 197, 197, 197, 197, 197, + /* 340 */ 1249, 296, 756, 756, 276, 72, 287, 714, 690, 397, + /* 350 */ 591, 271, 684, 706, 706, 966, 764, 677, 966, 966, + /* 360 */ 966, 1221, 178, 1191, 134, 1230, 1114, 1216, 1146, 1183, + /* 370 */ 1196, 1209, 1246, 1262, 1298, 1299, 1308, 1116, 1265, 1274, + /* 380 */ 1270, 1287, 1289, 1291, 1186, 81, 340, 1292, 1295, 1297, + /* 390 */ 1307, 1314, 1315, 1364, 1323, 1200, 1327, 51, 1345, 1346, + /* 400 */ 1353, 1356, 1363, 1366, 1269, 1167, 1302, 1321, 1389, 675, + /* 410 */ 1379, 1669, 1675, 1680, 1639, 1682, 1648, 1468, 1651, 1652, + /* 420 */ 1653, 1473, 1690, 1656, 1657, 1478, 1693, 1480, 1697, 1663, + /* 430 */ 1700, 1679, 1702, 1668, 1493, 1705, 1507, 1707, 1509, 1511, + /* 440 */ 1520, 1523, 1721, 1723, 1725, 1539, 1541, 1728, 1730, 1684, + /* 450 */ 1732, 1704, 1691, 1741, 1695, 1743, 1703, 1744, 1750, 1752, + /* 460 */ 1701, 1753, 1754, 1755, 1756, 1757, 1758, 1588, 1724, 1760, + /* 470 */ 1602, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1774, + /* 480 */ 1782, 1784, 1789, 1796, 1798, 1799, 1800, 1759, 1802, 1761, + /* 490 */ 1804, 1805, 1807, 1808, 1809, 1810, 1791, 1811, 1815, 1818, + /* 500 */ 1676, 1820, 1821, 1801, 1777, 1813, 1785, 1843, 1775, 1803, + /* 510 */ 1839, 1778, 1844, 1783, 1846, 1847, 1814, 1817, 1823, 1859, + /* 520 */ 1828, 1822, 1825, 1873, 1835, 1826, 1840, 1874, 1845, 1881, + /* 530 */ 1841, 1849, 1838, 1842, 1848, 1871, 1850, 1884, 1812, 1853, + /* 540 */ 1886, 1891, 1893, 1857, 1716, 1899, 1900, 1902, 1836, 1904, + /* 550 */ 1906, 1872, 1860, 1869, 1910, 1876, 1864, 1887, 1915, 1888, + /* 560 */ 1879, 1892, 1925, 1895, 1883, 1894, 1934, 1935, 1936, 1938, + /* 570 */ 1940, 1941, 1862, 1851, 1913, 1929, 1952, 1918, 1919, 1920, + /* 580 */ 1921, 1922, 1923, 1924, 1933, 1937, 1927, 1943, 1942, 1944, + /* 590 */ 1980, 1960, 1983, 1962, 1939, 1991, 1964, 1953, 1987, 1957, + /* 600 */ 1993, 1959, 1995, 1974, 1977, 1963, 1968, 1969, 1897, 1903, + /* 610 */ 2007, 1858, 1905, 1816, 1975, 1990, 2013, 1827, 1997, 1861, + /* 620 */ 1855, 2017, 2020, 1863, 1854, 1867, 1856, 2019, 1996, 1786, + /* 630 */ 1928, 1945, 1948, 1999, 1954, 2005, 1970, 1961, 2012, 2023, + /* 640 */ 1971, 1973, 1978, 1979, 1976, 2028, 2016, 2026, 1981, 2030, + /* 650 */ 1819, 1982, 1985, 2075, 2041, 1830, 2052, 2055, 2056, 2057, + /* 660 */ 2060, 2061, 1998, 2001, 2050, 1868, 2059, 2053, 2101, 2106, + /* 670 */ 2004, 2069, 1842, 2062, 2008, 2006, 2024, 2009, 2014, 1955, + /* 680 */ 2029, 2116, 2090, 1926, 2031, 2022, 1842, 2086, 2092, 2036, + /* 690 */ 1896, 2042, 2140, 2122, 1931, 2044, 2045, 2047, 2048, 2054, + /* 700 */ 2051, 2098, 2058, 2064, 2104, 2065, 2126, 1946, 2067, 2046, + /* 710 */ 2068, 2121, 2123, 2070, 2071, 2124, 2074, 2081, 2127, 2084, + /* 720 */ 2085, 2128, 2087, 2088, 2133, 2091, 2093, 2156, 2095, 2073, + /* 730 */ 2078, 2089, 2094, 2173, 2103, 2110, 2152, 2111, 2166, 2113, + /* 740 */ 2152, 2152, 2197, 2153, 2155, 2189, 2190, 2191, 2192, 2194, + /* 750 */ 2196, 2198, 2199, 2160, 2139, 2193, 2203, 2204, 2205, 2219, + /* 760 */ 2207, 2209, 2211, 2172, 1933, 2213, 1937, 2214, 2216, 2217, + /* 770 */ 2218, 2232, 2220, 2256, 2222, 2210, 2221, 2258, 2227, 2226, + /* 780 */ 2228, 2265, 2233, 2229, 2238, 2280, 2247, 2234, 2251, 2292, + /* 790 */ 2259, 2260, 2293, 2274, 2277, 2278, 2279, 2289, 2291, }; -#define YY_REDUCE_COUNT (322) -#define YY_REDUCE_MIN (-404) -#define YY_REDUCE_MAX (2418) +#define YY_REDUCE_COUNT (318) +#define YY_REDUCE_MIN (-443) +#define YY_REDUCE_MAX (2593) static const short yy_reduce_ofst[] = { - /* 0 */ -296, -340, -133, -26, 88, 310, 540, 850, 881, 911, - /* 10 */ 208, 1001, 1032, 1069, 1158, 1207, 1233, 118, 1284, 1297, - /* 20 */ 1346, 1363, 1436, 1412, 1463, 1483, 426, 1550, 1580, 1639, - /* 30 */ 1712, 1743, 1778, 1815, 1840, 1877, 1902, 1974, 1989, 2007, - /* 40 */ 2054, 2076, 2123, 2182, 2195, 2212, 2244, 2311, 2331, 2401, - /* 50 */ 2418, -260, -25, 239, 149, -404, 246, 479, -28, 348, - /* 60 */ 643, -365, -294, -331, 671, -98, 24, 252, -390, -345, - /* 70 */ -265, -279, -72, 74, -318, 227, -342, 112, -232, 26, - /* 80 */ 192, 263, 341, 374, 383, 400, 424, 436, 286, 592, - /* 90 */ 595, 674, 116, 601, 675, 36, 323, 679, 391, 752, - /* 100 */ 637, -63, 765, 776, 555, 779, 429, 672, 669, 822, - /* 110 */ 155, -316, -313, -313, -259, -140, -199, -188, 157, 269, - /* 120 */ 427, 529, 548, 553, 656, 723, 726, 796, 803, 804, - /* 130 */ 809, 844, 845, 855, 867, -217, -242, -15, 438, 523, - /* 140 */ 680, 616, -242, 167, 199, -250, 366, 696, 778, 825, - /* 150 */ -375, -47, 93, 575, 818, 811, 823, 841, 864, -371, - /* 160 */ -328, 356, 491, 515, 579, 681, 515, 798, 876, 925, - /* 170 */ 932, 875, 829, 1033, 920, 1024, 1037, 1021, 995, 1021, - /* 180 */ 1052, 1006, 1059, 1061, 1023, 1013, 955, 955, 940, 955, - /* 190 */ 965, 959, 1021, 1012, 999, 1010, 1016, 1080, 1022, 1090, - /* 200 */ 1040, 1105, 1075, 1073, 1124, 1081, 1088, 1135, 1130, 1136, - /* 210 */ 1089, 1092, 1093, 1128, 1132, 1147, 1146, 1162, 1163, 1164, - /* 220 */ 1168, 1170, 1175, 1174, 1101, 1165, 1134, 1169, 1178, 1120, - /* 230 */ 1176, 1184, 1179, 1180, 1181, 1191, 1183, 1200, 1166, 1167, - /* 240 */ 1171, 1173, 1187, 1188, 1189, 1190, 1193, 1194, 1196, 1197, - /* 250 */ 1201, 1172, 1185, 1208, 1129, 1137, 1138, 1204, 1142, 1151, - /* 260 */ 1203, 1214, 1199, 1202, 1238, 1206, 1209, 1210, 1139, 1212, - /* 270 */ 1220, 1148, 1213, 1222, 1225, 1021, 1150, 1153, 1211, 1186, - /* 280 */ 1215, 1217, 1218, 1159, 1157, 1154, 955, 1296, 1223, 1299, - /* 290 */ 1298, 1304, 1255, 1258, 1288, 1294, 1300, 1301, 1303, 1280, - /* 300 */ 1307, 1281, 1326, 1314, 1336, 1352, 1247, 1317, 1311, 1332, - /* 310 */ 1355, 1365, 1368, 1367, 1312, 1287, 1331, 1334, 1342, 1362, - /* 320 */ 1371, 1370, 1369, + /* 0 */ -296, -340, -133, -26, 88, 307, 540, 850, 878, 911, + /* 10 */ 1001, 1029, 1091, 1158, 1220, 1283, 118, 1344, 1358, 1421, + /* 20 */ 1395, 1485, 1510, 1536, 1609, 1625, 426, 1686, 1747, 1773, + /* 30 */ 1837, 1852, 1870, 1967, 1986, 2000, 2037, 2099, 2114, 2165, + /* 40 */ 2179, 2244, 2304, 2319, 2379, 2394, 2416, 2491, 2506, 2521, + /* 50 */ 2593, -260, -25, -411, 185, -404, 236, 461, 645, 685, + /* 60 */ 757, 558, -397, 554, 560, -443, -294, -334, -350, -269, + /* 70 */ 1, -383, -236, -29, -12, 78, -344, -283, 26, 64, + /* 80 */ 192, 235, -208, 143, 280, 339, 424, 295, -212, 484, + /* 90 */ 487, -271, -377, 524, 615, -332, -72, 679, 482, 682, + /* 100 */ 483, 256, 688, 694, 86, 776, 683, 243, 740, 779, + /* 110 */ 768, -346, -245, -245, -39, -81, -223, 358, 537, 603, + /* 120 */ 630, 686, 725, 726, 787, 794, 796, 831, 841, 845, + /* 130 */ 851, 853, 854, 855, 858, 12, -31, -359, 156, 382, + /* 140 */ 453, 594, -31, 323, 367, 22, 616, 669, 676, 815, + /* 150 */ 742, 801, 818, 825, 321, 84, 829, 504, 402, 535, + /* 160 */ 822, 839, 871, -371, -355, 30, -371, 41, 107, 191, + /* 170 */ 136, 109, 133, 288, 348, 336, 464, 411, 437, 411, + /* 180 */ 502, 650, 583, 585, 783, 655, 605, 605, 699, 605, + /* 190 */ 732, 830, 411, 937, 945, 977, 979, 1047, 987, 1053, + /* 200 */ 1000, 1064, 1023, 1038, 1092, 1046, 1052, 1105, 1103, 1109, + /* 210 */ 1071, 1076, 1078, 1115, 1119, 1133, 1125, 1137, 1138, 1139, + /* 220 */ 1148, 1147, 1150, 1149, 1077, 1141, 1108, 1143, 1152, 1094, + /* 230 */ 1151, 1153, 1154, 1155, 1156, 1161, 1157, 1165, 1132, 1142, + /* 240 */ 1159, 1160, 1163, 1164, 1166, 1169, 1174, 1130, 1140, 1145, + /* 250 */ 1122, 1110, 1127, 1193, 1134, 1144, 1173, 1199, 1135, 1162, + /* 260 */ 1208, 1168, 1171, 1176, 1093, 1170, 1177, 1106, 1178, 1179, + /* 270 */ 1184, 411, 1126, 1129, 1121, 1136, 1172, 1175, 1194, 1128, + /* 280 */ 1180, 1182, 605, 1261, 1185, 1266, 1260, 1263, 1218, 1217, + /* 290 */ 1234, 1235, 1236, 1237, 1238, 1225, 1239, 1232, 1276, 1267, + /* 300 */ 1279, 1293, 1192, 1268, 1252, 1281, 1296, 1288, 1318, 1329, + /* 310 */ 1243, 1242, 1258, 1271, 1300, 1304, 1306, 1310, 1328, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 10 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 20 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 30 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 40 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 50 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 60 */ 2092, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 70 */ 1781, 1781, 1781, 1781, 2065, 1781, 1781, 1781, 1781, 1781, - /* 80 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 90 */ 1781, 1870, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 100 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 110 */ 1868, 2058, 2284, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 120 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 130 */ 1781, 1781, 1781, 1781, 1781, 1781, 2296, 1781, 1781, 1844, - /* 140 */ 1844, 1781, 2296, 2296, 2296, 1868, 2256, 2256, 1781, 1870, - /* 150 */ 2126, 1781, 1781, 1781, 1781, 1781, 1781, 1990, 1781, 1781, - /* 160 */ 1781, 1781, 1781, 2014, 1781, 1781, 1781, 2118, 1781, 1781, - /* 170 */ 2321, 2378, 1781, 1781, 2324, 1781, 1781, 1781, 1781, 1781, - /* 180 */ 1781, 2070, 1781, 1781, 1943, 2311, 2288, 2302, 2362, 2289, - /* 190 */ 2286, 2305, 1781, 2315, 1781, 1781, 2140, 1870, 1781, 1870, - /* 200 */ 2105, 1781, 2063, 1781, 1781, 2063, 2060, 1781, 1781, 1781, - /* 210 */ 2063, 2060, 2060, 1932, 1928, 1781, 1926, 1781, 1781, 1781, - /* 220 */ 1781, 1828, 1781, 1828, 1781, 1870, 1781, 1870, 1781, 1781, - /* 230 */ 1870, 1781, 1870, 1870, 1870, 1781, 1870, 1781, 1781, 1781, - /* 240 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 250 */ 1781, 1781, 1781, 1781, 2138, 2124, 1781, 1868, 2116, 2114, - /* 260 */ 1781, 1868, 2112, 2315, 1781, 1781, 1781, 1781, 2332, 2330, - /* 270 */ 1781, 2332, 2330, 1781, 1781, 1781, 2346, 2342, 2332, 2351, - /* 280 */ 2348, 2317, 2315, 2381, 2368, 2364, 2302, 1781, 1781, 1781, - /* 290 */ 1868, 1868, 1781, 2330, 1781, 1781, 1781, 1781, 1781, 2330, - /* 300 */ 1781, 1781, 1868, 1781, 1868, 1781, 1781, 1959, 1781, 1781, - /* 310 */ 1781, 1868, 1813, 1781, 2107, 2129, 2088, 2088, 1993, 1993, - /* 320 */ 1993, 1871, 1786, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 330 */ 1781, 1781, 1781, 1781, 1781, 2345, 2344, 2211, 1781, 2260, - /* 340 */ 2259, 2258, 2249, 2210, 1955, 1781, 2209, 2208, 1781, 1781, - /* 350 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 2079, 2078, 2202, - /* 360 */ 1781, 1781, 2203, 2201, 2200, 1781, 1781, 1781, 1781, 1781, - /* 370 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 380 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 2365, - /* 390 */ 2369, 1781, 1781, 1781, 1781, 1781, 1781, 2285, 1781, 1781, - /* 400 */ 1781, 2184, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 410 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 420 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 430 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 440 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 450 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 460 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 470 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 480 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 490 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 500 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 510 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 520 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 530 */ 1781, 1781, 1781, 1781, 1781, 1781, 1818, 2189, 1781, 1781, - /* 540 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 550 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 560 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 570 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 580 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1909, 1908, - /* 590 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 600 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 610 */ 1781, 1781, 2193, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 620 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 630 */ 1781, 2361, 2318, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 640 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 650 */ 1781, 2184, 1781, 2343, 1781, 1781, 2359, 1781, 2363, 1781, - /* 660 */ 1781, 1781, 1781, 1781, 1781, 1781, 2295, 2291, 1781, 1781, - /* 670 */ 2287, 1781, 1781, 1781, 1781, 1781, 2192, 1781, 1781, 1781, - /* 680 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 690 */ 2183, 1781, 2246, 1781, 1781, 1781, 2280, 1781, 1781, 2231, - /* 700 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 2193, - /* 710 */ 1781, 2196, 1781, 1781, 1781, 1781, 1781, 1987, 1781, 1781, - /* 720 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 730 */ 1781, 1781, 1781, 1971, 1969, 1968, 1967, 1781, 2000, 1781, - /* 740 */ 1781, 1781, 1996, 1995, 1781, 1781, 1781, 1781, 1781, 1781, - /* 750 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1889, 1781, 1781, - /* 760 */ 1781, 1781, 1781, 1781, 1781, 1781, 1881, 1781, 1880, 1781, - /* 770 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 780 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 790 */ 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, 1781, - /* 800 */ 1781, + /* 0 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 10 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 20 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 30 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 40 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 50 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 60 */ 2092, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 70 */ 1780, 1780, 1780, 1780, 2065, 1780, 1780, 1780, 1780, 1780, + /* 80 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 90 */ 1780, 1869, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 100 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 110 */ 1867, 2058, 2284, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 120 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 130 */ 1780, 1780, 1780, 1780, 1780, 1780, 2296, 1780, 1780, 1843, + /* 140 */ 1843, 1780, 2296, 2296, 2296, 1867, 2256, 2256, 1780, 1869, + /* 150 */ 1780, 1780, 1780, 1780, 2126, 1780, 1780, 1780, 1780, 1780, + /* 160 */ 1780, 1990, 1780, 2014, 1780, 1780, 1780, 2118, 1780, 1780, + /* 170 */ 2321, 2378, 1780, 1780, 2324, 1780, 1780, 1780, 1780, 1780, + /* 180 */ 1780, 2070, 1780, 1780, 1942, 2311, 2288, 2302, 2362, 2289, + /* 190 */ 2286, 2305, 1780, 2315, 1780, 1780, 2140, 1869, 1780, 1869, + /* 200 */ 2105, 1780, 2063, 1780, 1780, 2063, 2060, 1780, 1780, 1780, + /* 210 */ 2063, 2060, 2060, 1931, 1927, 1780, 1925, 1780, 1780, 1780, + /* 220 */ 1780, 1827, 1780, 1827, 1780, 1869, 1780, 1869, 1780, 1780, + /* 230 */ 1869, 1780, 1869, 1869, 1869, 1780, 1869, 1780, 1780, 1780, + /* 240 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 250 */ 2138, 2124, 1780, 1867, 2116, 2114, 1780, 1867, 2112, 2315, + /* 260 */ 1780, 1780, 1780, 1780, 2332, 2330, 1780, 2332, 2330, 1780, + /* 270 */ 1780, 1780, 2346, 2342, 2332, 2351, 2348, 2317, 2315, 2381, + /* 280 */ 2368, 2364, 2302, 1780, 1780, 1780, 1867, 1867, 1780, 2330, + /* 290 */ 1780, 1780, 1780, 1780, 1780, 2330, 1780, 1780, 1867, 1780, + /* 300 */ 1867, 1780, 1780, 1958, 1780, 1780, 1780, 1867, 1812, 1780, + /* 310 */ 2107, 2129, 2088, 2088, 1993, 1993, 1993, 1870, 1785, 1780, + /* 320 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 330 */ 1780, 2345, 2344, 2211, 1780, 2260, 2259, 2258, 2249, 2210, + /* 340 */ 1954, 1780, 2209, 2208, 1780, 1780, 1780, 1780, 1780, 1780, + /* 350 */ 1780, 1780, 1780, 2079, 2078, 2202, 1780, 1780, 2203, 2201, + /* 360 */ 2200, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 370 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 380 */ 1780, 1780, 1780, 1780, 1780, 2365, 2369, 1780, 1780, 1780, + /* 390 */ 1780, 1780, 1780, 2285, 1780, 1780, 1780, 2184, 1780, 1780, + /* 400 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 410 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 420 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 430 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 440 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 450 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 460 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 470 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 480 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 490 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 500 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 510 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 520 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 530 */ 1780, 1780, 1817, 2189, 1780, 1780, 1780, 1780, 1780, 1780, + /* 540 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 550 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 560 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 570 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 580 */ 1780, 1780, 1780, 1780, 1908, 1907, 1780, 1780, 1780, 1780, + /* 590 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 600 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 2193, 1780, + /* 610 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 620 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 2361, 2318, 1780, + /* 630 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 640 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 2184, 1780, 2343, + /* 650 */ 1780, 1780, 2359, 1780, 2363, 1780, 1780, 1780, 1780, 1780, + /* 660 */ 1780, 1780, 2295, 2291, 1780, 1780, 2287, 1780, 1780, 1780, + /* 670 */ 1780, 1780, 2192, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 680 */ 1780, 1780, 1780, 1780, 1780, 1780, 2183, 1780, 2246, 1780, + /* 690 */ 1780, 1780, 2280, 1780, 1780, 2231, 1780, 1780, 1780, 1780, + /* 700 */ 1780, 1780, 1780, 1780, 1780, 2193, 1780, 2196, 1780, 1780, + /* 710 */ 1780, 1780, 1780, 1987, 1780, 1780, 1780, 1780, 1780, 1780, + /* 720 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1971, + /* 730 */ 1969, 1968, 1967, 1780, 1964, 1780, 2000, 1780, 1780, 1780, + /* 740 */ 1996, 1995, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 750 */ 1780, 1780, 1780, 1780, 1780, 1888, 1780, 1780, 1780, 1780, + /* 760 */ 1780, 1780, 1780, 1780, 1880, 1780, 1879, 1780, 1780, 1780, + /* 770 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 780 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + /* 790 */ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, }; /********** End of lemon-generated parsing tables *****************************/ @@ -1508,6 +1541,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* NK_EQ => nothing */ 0, /* USING => nothing */ 0, /* TAGS => nothing */ + 0, /* COMMENT => nothing */ 0, /* BOOL => nothing */ 0, /* TINYINT => nothing */ 0, /* SMALLINT => nothing */ @@ -1526,7 +1560,6 @@ static const YYCODETYPE yyFallback[] = { 0, /* VARBINARY => nothing */ 0, /* GEOMETRY => nothing */ 0, /* DECIMAL => nothing */ - 0, /* COMMENT => nothing */ 0, /* MAX_DELAY => nothing */ 0, /* WATERMARK => nothing */ 0, /* ROLLUP => nothing */ @@ -1934,25 +1967,25 @@ static const char *const yyTokenName[] = { /* 112 */ "NK_EQ", /* 113 */ "USING", /* 114 */ "TAGS", - /* 115 */ "BOOL", - /* 116 */ "TINYINT", - /* 117 */ "SMALLINT", - /* 118 */ "INT", - /* 119 */ "INTEGER", - /* 120 */ "BIGINT", - /* 121 */ "FLOAT", - /* 122 */ "DOUBLE", - /* 123 */ "BINARY", - /* 124 */ "NCHAR", - /* 125 */ "UNSIGNED", - /* 126 */ "JSON", - /* 127 */ "VARCHAR", - /* 128 */ "MEDIUMBLOB", - /* 129 */ "BLOB", - /* 130 */ "VARBINARY", - /* 131 */ "GEOMETRY", - /* 132 */ "DECIMAL", - /* 133 */ "COMMENT", + /* 115 */ "COMMENT", + /* 116 */ "BOOL", + /* 117 */ "TINYINT", + /* 118 */ "SMALLINT", + /* 119 */ "INT", + /* 120 */ "INTEGER", + /* 121 */ "BIGINT", + /* 122 */ "FLOAT", + /* 123 */ "DOUBLE", + /* 124 */ "BINARY", + /* 125 */ "NCHAR", + /* 126 */ "UNSIGNED", + /* 127 */ "JSON", + /* 128 */ "VARCHAR", + /* 129 */ "MEDIUMBLOB", + /* 130 */ "BLOB", + /* 131 */ "VARBINARY", + /* 132 */ "GEOMETRY", + /* 133 */ "DECIMAL", /* 134 */ "MAX_DELAY", /* 135 */ "WATERMARK", /* 136 */ "ROLLUP", @@ -2198,15 +2231,15 @@ static const char *const yyTokenName[] = { /* 376 */ "multi_drop_clause", /* 377 */ "alter_table_clause", /* 378 */ "alter_table_options", - /* 379 */ "column_name", - /* 380 */ "type_name", + /* 379 */ "column_def", + /* 380 */ "column_name", /* 381 */ "signed_literal", /* 382 */ "create_subtable_clause", /* 383 */ "specific_cols_opt", /* 384 */ "expression_list", /* 385 */ "drop_table_clause", /* 386 */ "col_name_list", - /* 387 */ "column_def", + /* 387 */ "type_name", /* 388 */ "duration_list", /* 389 */ "rollup_func_list", /* 390 */ "alter_table_option", @@ -2473,13 +2506,13 @@ static const char *const yyRuleName[] = { /* 157 */ "cmd ::= ALTER TABLE alter_table_clause", /* 158 */ "cmd ::= ALTER STABLE alter_table_clause", /* 159 */ "alter_table_clause ::= full_table_name alter_table_options", - /* 160 */ "alter_table_clause ::= full_table_name ADD COLUMN column_name type_name", + /* 160 */ "alter_table_clause ::= full_table_name ADD COLUMN column_def", /* 161 */ "alter_table_clause ::= full_table_name DROP COLUMN column_name", - /* 162 */ "alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name", + /* 162 */ "alter_table_clause ::= full_table_name MODIFY COLUMN column_def", /* 163 */ "alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name", - /* 164 */ "alter_table_clause ::= full_table_name ADD TAG column_name type_name", + /* 164 */ "alter_table_clause ::= full_table_name ADD TAG column_def", /* 165 */ "alter_table_clause ::= full_table_name DROP TAG column_name", - /* 166 */ "alter_table_clause ::= full_table_name MODIFY TAG column_name type_name", + /* 166 */ "alter_table_clause ::= full_table_name MODIFY TAG column_def", /* 167 */ "alter_table_clause ::= full_table_name RENAME TAG column_name column_name", /* 168 */ "alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal", /* 169 */ "multi_create_clause ::= create_subtable_clause", @@ -2495,424 +2528,425 @@ static const char *const yyRuleName[] = { /* 179 */ "column_def_list ::= column_def", /* 180 */ "column_def_list ::= column_def_list NK_COMMA column_def", /* 181 */ "column_def ::= column_name type_name", - /* 182 */ "type_name ::= BOOL", - /* 183 */ "type_name ::= TINYINT", - /* 184 */ "type_name ::= SMALLINT", - /* 185 */ "type_name ::= INT", - /* 186 */ "type_name ::= INTEGER", - /* 187 */ "type_name ::= BIGINT", - /* 188 */ "type_name ::= FLOAT", - /* 189 */ "type_name ::= DOUBLE", - /* 190 */ "type_name ::= BINARY NK_LP NK_INTEGER NK_RP", - /* 191 */ "type_name ::= TIMESTAMP", - /* 192 */ "type_name ::= NCHAR NK_LP NK_INTEGER NK_RP", - /* 193 */ "type_name ::= TINYINT UNSIGNED", - /* 194 */ "type_name ::= SMALLINT UNSIGNED", - /* 195 */ "type_name ::= INT UNSIGNED", - /* 196 */ "type_name ::= BIGINT UNSIGNED", - /* 197 */ "type_name ::= JSON", - /* 198 */ "type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP", - /* 199 */ "type_name ::= MEDIUMBLOB", - /* 200 */ "type_name ::= BLOB", - /* 201 */ "type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP", - /* 202 */ "type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP", - /* 203 */ "type_name ::= DECIMAL", - /* 204 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP", - /* 205 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP", - /* 206 */ "tags_def_opt ::=", - /* 207 */ "tags_def_opt ::= tags_def", - /* 208 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP", - /* 209 */ "table_options ::=", - /* 210 */ "table_options ::= table_options COMMENT NK_STRING", - /* 211 */ "table_options ::= table_options MAX_DELAY duration_list", - /* 212 */ "table_options ::= table_options WATERMARK duration_list", - /* 213 */ "table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP", - /* 214 */ "table_options ::= table_options TTL NK_INTEGER", - /* 215 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP", - /* 216 */ "table_options ::= table_options DELETE_MARK duration_list", - /* 217 */ "alter_table_options ::= alter_table_option", - /* 218 */ "alter_table_options ::= alter_table_options alter_table_option", - /* 219 */ "alter_table_option ::= COMMENT NK_STRING", - /* 220 */ "alter_table_option ::= TTL NK_INTEGER", - /* 221 */ "duration_list ::= duration_literal", - /* 222 */ "duration_list ::= duration_list NK_COMMA duration_literal", - /* 223 */ "rollup_func_list ::= rollup_func_name", - /* 224 */ "rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name", - /* 225 */ "rollup_func_name ::= function_name", - /* 226 */ "rollup_func_name ::= FIRST", - /* 227 */ "rollup_func_name ::= LAST", - /* 228 */ "col_name_list ::= col_name", - /* 229 */ "col_name_list ::= col_name_list NK_COMMA col_name", - /* 230 */ "col_name ::= column_name", - /* 231 */ "cmd ::= SHOW DNODES", - /* 232 */ "cmd ::= SHOW USERS", - /* 233 */ "cmd ::= SHOW USER PRIVILEGES", - /* 234 */ "cmd ::= SHOW DATABASES", - /* 235 */ "cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt", - /* 236 */ "cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt", - /* 237 */ "cmd ::= SHOW db_name_cond_opt VGROUPS", - /* 238 */ "cmd ::= SHOW MNODES", - /* 239 */ "cmd ::= SHOW QNODES", - /* 240 */ "cmd ::= SHOW FUNCTIONS", - /* 241 */ "cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt", - /* 242 */ "cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name", - /* 243 */ "cmd ::= SHOW STREAMS", - /* 244 */ "cmd ::= SHOW ACCOUNTS", - /* 245 */ "cmd ::= SHOW APPS", - /* 246 */ "cmd ::= SHOW CONNECTIONS", - /* 247 */ "cmd ::= SHOW LICENCES", - /* 248 */ "cmd ::= SHOW GRANTS", - /* 249 */ "cmd ::= SHOW CREATE DATABASE db_name", - /* 250 */ "cmd ::= SHOW CREATE TABLE full_table_name", - /* 251 */ "cmd ::= SHOW CREATE STABLE full_table_name", - /* 252 */ "cmd ::= SHOW QUERIES", - /* 253 */ "cmd ::= SHOW SCORES", - /* 254 */ "cmd ::= SHOW TOPICS", - /* 255 */ "cmd ::= SHOW VARIABLES", - /* 256 */ "cmd ::= SHOW CLUSTER VARIABLES", - /* 257 */ "cmd ::= SHOW LOCAL VARIABLES", - /* 258 */ "cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt", - /* 259 */ "cmd ::= SHOW BNODES", - /* 260 */ "cmd ::= SHOW SNODES", - /* 261 */ "cmd ::= SHOW CLUSTER", - /* 262 */ "cmd ::= SHOW TRANSACTIONS", - /* 263 */ "cmd ::= SHOW TABLE DISTRIBUTED full_table_name", - /* 264 */ "cmd ::= SHOW CONSUMERS", - /* 265 */ "cmd ::= SHOW SUBSCRIPTIONS", - /* 266 */ "cmd ::= SHOW TAGS FROM table_name_cond from_db_opt", - /* 267 */ "cmd ::= SHOW TAGS FROM db_name NK_DOT table_name", - /* 268 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt", - /* 269 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name", - /* 270 */ "cmd ::= SHOW VNODES ON DNODE NK_INTEGER", - /* 271 */ "cmd ::= SHOW VNODES", - /* 272 */ "cmd ::= SHOW db_name_cond_opt ALIVE", - /* 273 */ "cmd ::= SHOW CLUSTER ALIVE", - /* 274 */ "db_name_cond_opt ::=", - /* 275 */ "db_name_cond_opt ::= db_name NK_DOT", - /* 276 */ "like_pattern_opt ::=", - /* 277 */ "like_pattern_opt ::= LIKE NK_STRING", - /* 278 */ "table_name_cond ::= table_name", - /* 279 */ "from_db_opt ::=", - /* 280 */ "from_db_opt ::= FROM db_name", - /* 281 */ "tag_list_opt ::=", - /* 282 */ "tag_list_opt ::= tag_item", - /* 283 */ "tag_list_opt ::= tag_list_opt NK_COMMA tag_item", - /* 284 */ "tag_item ::= TBNAME", - /* 285 */ "tag_item ::= QTAGS", - /* 286 */ "tag_item ::= column_name", - /* 287 */ "tag_item ::= column_name column_alias", - /* 288 */ "tag_item ::= column_name AS column_alias", - /* 289 */ "cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options", - /* 290 */ "cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP", - /* 291 */ "cmd ::= DROP INDEX exists_opt full_index_name", - /* 292 */ "full_index_name ::= index_name", - /* 293 */ "full_index_name ::= db_name NK_DOT index_name", - /* 294 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt", - /* 295 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt", - /* 296 */ "func_list ::= func", - /* 297 */ "func_list ::= func_list NK_COMMA func", - /* 298 */ "func ::= sma_func_name NK_LP expression_list NK_RP", - /* 299 */ "sma_func_name ::= function_name", - /* 300 */ "sma_func_name ::= COUNT", - /* 301 */ "sma_func_name ::= FIRST", - /* 302 */ "sma_func_name ::= LAST", - /* 303 */ "sma_func_name ::= LAST_ROW", - /* 304 */ "sma_stream_opt ::=", - /* 305 */ "sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal", - /* 306 */ "sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal", - /* 307 */ "sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal", - /* 308 */ "with_meta ::= AS", - /* 309 */ "with_meta ::= WITH META AS", - /* 310 */ "with_meta ::= ONLY META AS", - /* 311 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery", - /* 312 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name", - /* 313 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt", - /* 314 */ "cmd ::= DROP TOPIC exists_opt topic_name", - /* 315 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", - /* 316 */ "cmd ::= DESC full_table_name", - /* 317 */ "cmd ::= DESCRIBE full_table_name", - /* 318 */ "cmd ::= RESET QUERY CACHE", - /* 319 */ "cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery", - /* 320 */ "cmd ::= EXPLAIN analyze_opt explain_options insert_query", - /* 321 */ "analyze_opt ::=", - /* 322 */ "analyze_opt ::= ANALYZE", - /* 323 */ "explain_options ::=", - /* 324 */ "explain_options ::= explain_options VERBOSE NK_BOOL", - /* 325 */ "explain_options ::= explain_options RATIO NK_FLOAT", - /* 326 */ "cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt", - /* 327 */ "cmd ::= DROP FUNCTION exists_opt function_name", - /* 328 */ "agg_func_opt ::=", - /* 329 */ "agg_func_opt ::= AGGREGATE", - /* 330 */ "bufsize_opt ::=", - /* 331 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", - /* 332 */ "language_opt ::=", - /* 333 */ "language_opt ::= LANGUAGE NK_STRING", - /* 334 */ "or_replace_opt ::=", - /* 335 */ "or_replace_opt ::= OR REPLACE", - /* 336 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery", - /* 337 */ "cmd ::= DROP STREAM exists_opt stream_name", - /* 338 */ "cmd ::= PAUSE STREAM exists_opt stream_name", - /* 339 */ "cmd ::= RESUME STREAM exists_opt ignore_opt stream_name", - /* 340 */ "col_list_opt ::=", - /* 341 */ "col_list_opt ::= NK_LP col_name_list NK_RP", - /* 342 */ "tag_def_or_ref_opt ::=", - /* 343 */ "tag_def_or_ref_opt ::= tags_def", - /* 344 */ "tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP", - /* 345 */ "stream_options ::=", - /* 346 */ "stream_options ::= stream_options TRIGGER AT_ONCE", - /* 347 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", - /* 348 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", - /* 349 */ "stream_options ::= stream_options WATERMARK duration_literal", - /* 350 */ "stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER", - /* 351 */ "stream_options ::= stream_options FILL_HISTORY NK_INTEGER", - /* 352 */ "stream_options ::= stream_options DELETE_MARK duration_literal", - /* 353 */ "stream_options ::= stream_options IGNORE UPDATE NK_INTEGER", - /* 354 */ "subtable_opt ::=", - /* 355 */ "subtable_opt ::= SUBTABLE NK_LP expression NK_RP", - /* 356 */ "ignore_opt ::=", - /* 357 */ "ignore_opt ::= IGNORE UNTREATED", - /* 358 */ "cmd ::= KILL CONNECTION NK_INTEGER", - /* 359 */ "cmd ::= KILL QUERY NK_STRING", - /* 360 */ "cmd ::= KILL TRANSACTION NK_INTEGER", - /* 361 */ "cmd ::= BALANCE VGROUP", - /* 362 */ "cmd ::= BALANCE VGROUP LEADER", - /* 363 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", - /* 364 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", - /* 365 */ "cmd ::= SPLIT VGROUP NK_INTEGER", - /* 366 */ "dnode_list ::= DNODE NK_INTEGER", - /* 367 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", - /* 368 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", - /* 369 */ "cmd ::= query_or_subquery", - /* 370 */ "cmd ::= insert_query", - /* 371 */ "insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery", - /* 372 */ "insert_query ::= INSERT INTO full_table_name query_or_subquery", - /* 373 */ "literal ::= NK_INTEGER", - /* 374 */ "literal ::= NK_FLOAT", - /* 375 */ "literal ::= NK_STRING", - /* 376 */ "literal ::= NK_BOOL", - /* 377 */ "literal ::= TIMESTAMP NK_STRING", - /* 378 */ "literal ::= duration_literal", - /* 379 */ "literal ::= NULL", - /* 380 */ "literal ::= NK_QUESTION", - /* 381 */ "duration_literal ::= NK_VARIABLE", - /* 382 */ "signed ::= NK_INTEGER", - /* 383 */ "signed ::= NK_PLUS NK_INTEGER", - /* 384 */ "signed ::= NK_MINUS NK_INTEGER", - /* 385 */ "signed ::= NK_FLOAT", - /* 386 */ "signed ::= NK_PLUS NK_FLOAT", - /* 387 */ "signed ::= NK_MINUS NK_FLOAT", - /* 388 */ "signed_literal ::= signed", - /* 389 */ "signed_literal ::= NK_STRING", - /* 390 */ "signed_literal ::= NK_BOOL", - /* 391 */ "signed_literal ::= TIMESTAMP NK_STRING", - /* 392 */ "signed_literal ::= duration_literal", - /* 393 */ "signed_literal ::= NULL", - /* 394 */ "signed_literal ::= literal_func", - /* 395 */ "signed_literal ::= NK_QUESTION", - /* 396 */ "literal_list ::= signed_literal", - /* 397 */ "literal_list ::= literal_list NK_COMMA signed_literal", - /* 398 */ "db_name ::= NK_ID", - /* 399 */ "table_name ::= NK_ID", - /* 400 */ "column_name ::= NK_ID", - /* 401 */ "function_name ::= NK_ID", - /* 402 */ "table_alias ::= NK_ID", - /* 403 */ "column_alias ::= NK_ID", - /* 404 */ "user_name ::= NK_ID", - /* 405 */ "topic_name ::= NK_ID", - /* 406 */ "stream_name ::= NK_ID", - /* 407 */ "cgroup_name ::= NK_ID", - /* 408 */ "index_name ::= NK_ID", - /* 409 */ "expr_or_subquery ::= expression", - /* 410 */ "expression ::= literal", - /* 411 */ "expression ::= pseudo_column", - /* 412 */ "expression ::= column_reference", - /* 413 */ "expression ::= function_expression", - /* 414 */ "expression ::= case_when_expression", - /* 415 */ "expression ::= NK_LP expression NK_RP", - /* 416 */ "expression ::= NK_PLUS expr_or_subquery", - /* 417 */ "expression ::= NK_MINUS expr_or_subquery", - /* 418 */ "expression ::= expr_or_subquery NK_PLUS expr_or_subquery", - /* 419 */ "expression ::= expr_or_subquery NK_MINUS expr_or_subquery", - /* 420 */ "expression ::= expr_or_subquery NK_STAR expr_or_subquery", - /* 421 */ "expression ::= expr_or_subquery NK_SLASH expr_or_subquery", - /* 422 */ "expression ::= expr_or_subquery NK_REM expr_or_subquery", - /* 423 */ "expression ::= column_reference NK_ARROW NK_STRING", - /* 424 */ "expression ::= expr_or_subquery NK_BITAND expr_or_subquery", - /* 425 */ "expression ::= expr_or_subquery NK_BITOR expr_or_subquery", - /* 426 */ "expression_list ::= expr_or_subquery", - /* 427 */ "expression_list ::= expression_list NK_COMMA expr_or_subquery", - /* 428 */ "column_reference ::= column_name", - /* 429 */ "column_reference ::= table_name NK_DOT column_name", - /* 430 */ "pseudo_column ::= ROWTS", - /* 431 */ "pseudo_column ::= TBNAME", - /* 432 */ "pseudo_column ::= table_name NK_DOT TBNAME", - /* 433 */ "pseudo_column ::= QSTART", - /* 434 */ "pseudo_column ::= QEND", - /* 435 */ "pseudo_column ::= QDURATION", - /* 436 */ "pseudo_column ::= WSTART", - /* 437 */ "pseudo_column ::= WEND", - /* 438 */ "pseudo_column ::= WDURATION", - /* 439 */ "pseudo_column ::= IROWTS", - /* 440 */ "pseudo_column ::= ISFILLED", - /* 441 */ "pseudo_column ::= QTAGS", - /* 442 */ "function_expression ::= function_name NK_LP expression_list NK_RP", - /* 443 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", - /* 444 */ "function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP", - /* 445 */ "function_expression ::= literal_func", - /* 446 */ "literal_func ::= noarg_func NK_LP NK_RP", - /* 447 */ "literal_func ::= NOW", - /* 448 */ "noarg_func ::= NOW", - /* 449 */ "noarg_func ::= TODAY", - /* 450 */ "noarg_func ::= TIMEZONE", - /* 451 */ "noarg_func ::= DATABASE", - /* 452 */ "noarg_func ::= CLIENT_VERSION", - /* 453 */ "noarg_func ::= SERVER_VERSION", - /* 454 */ "noarg_func ::= SERVER_STATUS", - /* 455 */ "noarg_func ::= CURRENT_USER", - /* 456 */ "noarg_func ::= USER", - /* 457 */ "star_func ::= COUNT", - /* 458 */ "star_func ::= FIRST", - /* 459 */ "star_func ::= LAST", - /* 460 */ "star_func ::= LAST_ROW", - /* 461 */ "star_func_para_list ::= NK_STAR", - /* 462 */ "star_func_para_list ::= other_para_list", - /* 463 */ "other_para_list ::= star_func_para", - /* 464 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", - /* 465 */ "star_func_para ::= expr_or_subquery", - /* 466 */ "star_func_para ::= table_name NK_DOT NK_STAR", - /* 467 */ "case_when_expression ::= CASE when_then_list case_when_else_opt END", - /* 468 */ "case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END", - /* 469 */ "when_then_list ::= when_then_expr", - /* 470 */ "when_then_list ::= when_then_list when_then_expr", - /* 471 */ "when_then_expr ::= WHEN common_expression THEN common_expression", - /* 472 */ "case_when_else_opt ::=", - /* 473 */ "case_when_else_opt ::= ELSE common_expression", - /* 474 */ "predicate ::= expr_or_subquery compare_op expr_or_subquery", - /* 475 */ "predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery", - /* 476 */ "predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery", - /* 477 */ "predicate ::= expr_or_subquery IS NULL", - /* 478 */ "predicate ::= expr_or_subquery IS NOT NULL", - /* 479 */ "predicate ::= expr_or_subquery in_op in_predicate_value", - /* 480 */ "compare_op ::= NK_LT", - /* 481 */ "compare_op ::= NK_GT", - /* 482 */ "compare_op ::= NK_LE", - /* 483 */ "compare_op ::= NK_GE", - /* 484 */ "compare_op ::= NK_NE", - /* 485 */ "compare_op ::= NK_EQ", - /* 486 */ "compare_op ::= LIKE", - /* 487 */ "compare_op ::= NOT LIKE", - /* 488 */ "compare_op ::= MATCH", - /* 489 */ "compare_op ::= NMATCH", - /* 490 */ "compare_op ::= CONTAINS", - /* 491 */ "in_op ::= IN", - /* 492 */ "in_op ::= NOT IN", - /* 493 */ "in_predicate_value ::= NK_LP literal_list NK_RP", - /* 494 */ "boolean_value_expression ::= boolean_primary", - /* 495 */ "boolean_value_expression ::= NOT boolean_primary", - /* 496 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", - /* 497 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", - /* 498 */ "boolean_primary ::= predicate", - /* 499 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", - /* 500 */ "common_expression ::= expr_or_subquery", - /* 501 */ "common_expression ::= boolean_value_expression", - /* 502 */ "from_clause_opt ::=", - /* 503 */ "from_clause_opt ::= FROM table_reference_list", - /* 504 */ "table_reference_list ::= table_reference", - /* 505 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", - /* 506 */ "table_reference ::= table_primary", - /* 507 */ "table_reference ::= joined_table", - /* 508 */ "table_primary ::= table_name alias_opt", - /* 509 */ "table_primary ::= db_name NK_DOT table_name alias_opt", - /* 510 */ "table_primary ::= subquery alias_opt", - /* 511 */ "table_primary ::= parenthesized_joined_table", - /* 512 */ "alias_opt ::=", - /* 513 */ "alias_opt ::= table_alias", - /* 514 */ "alias_opt ::= AS table_alias", - /* 515 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", - /* 516 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", - /* 517 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", - /* 518 */ "join_type ::=", - /* 519 */ "join_type ::= INNER", - /* 520 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", - /* 521 */ "set_quantifier_opt ::=", - /* 522 */ "set_quantifier_opt ::= DISTINCT", - /* 523 */ "set_quantifier_opt ::= ALL", - /* 524 */ "select_list ::= select_item", - /* 525 */ "select_list ::= select_list NK_COMMA select_item", - /* 526 */ "select_item ::= NK_STAR", - /* 527 */ "select_item ::= common_expression", - /* 528 */ "select_item ::= common_expression column_alias", - /* 529 */ "select_item ::= common_expression AS column_alias", - /* 530 */ "select_item ::= table_name NK_DOT NK_STAR", - /* 531 */ "where_clause_opt ::=", - /* 532 */ "where_clause_opt ::= WHERE search_condition", - /* 533 */ "partition_by_clause_opt ::=", - /* 534 */ "partition_by_clause_opt ::= PARTITION BY partition_list", - /* 535 */ "partition_list ::= partition_item", - /* 536 */ "partition_list ::= partition_list NK_COMMA partition_item", - /* 537 */ "partition_item ::= expr_or_subquery", - /* 538 */ "partition_item ::= expr_or_subquery column_alias", - /* 539 */ "partition_item ::= expr_or_subquery AS column_alias", - /* 540 */ "twindow_clause_opt ::=", - /* 541 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", - /* 542 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP", - /* 543 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", - /* 544 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", - /* 545 */ "twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition", - /* 546 */ "sliding_opt ::=", - /* 547 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", - /* 548 */ "fill_opt ::=", - /* 549 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", - /* 550 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP", - /* 551 */ "fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP", - /* 552 */ "fill_mode ::= NONE", - /* 553 */ "fill_mode ::= PREV", - /* 554 */ "fill_mode ::= NULL", - /* 555 */ "fill_mode ::= NULL_F", - /* 556 */ "fill_mode ::= LINEAR", - /* 557 */ "fill_mode ::= NEXT", - /* 558 */ "group_by_clause_opt ::=", - /* 559 */ "group_by_clause_opt ::= GROUP BY group_by_list", - /* 560 */ "group_by_list ::= expr_or_subquery", - /* 561 */ "group_by_list ::= group_by_list NK_COMMA expr_or_subquery", - /* 562 */ "having_clause_opt ::=", - /* 563 */ "having_clause_opt ::= HAVING search_condition", - /* 564 */ "range_opt ::=", - /* 565 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP", - /* 566 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_RP", - /* 567 */ "every_opt ::=", - /* 568 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", - /* 569 */ "query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt", - /* 570 */ "query_simple ::= query_specification", - /* 571 */ "query_simple ::= union_query_expression", - /* 572 */ "union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery", - /* 573 */ "union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery", - /* 574 */ "query_simple_or_subquery ::= query_simple", - /* 575 */ "query_simple_or_subquery ::= subquery", - /* 576 */ "query_or_subquery ::= query_expression", - /* 577 */ "query_or_subquery ::= subquery", - /* 578 */ "order_by_clause_opt ::=", - /* 579 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", - /* 580 */ "slimit_clause_opt ::=", - /* 581 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", - /* 582 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", - /* 583 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 584 */ "limit_clause_opt ::=", - /* 585 */ "limit_clause_opt ::= LIMIT NK_INTEGER", - /* 586 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", - /* 587 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 588 */ "subquery ::= NK_LP query_expression NK_RP", - /* 589 */ "subquery ::= NK_LP subquery NK_RP", - /* 590 */ "search_condition ::= common_expression", - /* 591 */ "sort_specification_list ::= sort_specification", - /* 592 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", - /* 593 */ "sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt", - /* 594 */ "ordering_specification_opt ::=", - /* 595 */ "ordering_specification_opt ::= ASC", - /* 596 */ "ordering_specification_opt ::= DESC", - /* 597 */ "null_ordering_opt ::=", - /* 598 */ "null_ordering_opt ::= NULLS FIRST", - /* 599 */ "null_ordering_opt ::= NULLS LAST", + /* 182 */ "column_def ::= column_name type_name COMMENT NK_STRING", + /* 183 */ "type_name ::= BOOL", + /* 184 */ "type_name ::= TINYINT", + /* 185 */ "type_name ::= SMALLINT", + /* 186 */ "type_name ::= INT", + /* 187 */ "type_name ::= INTEGER", + /* 188 */ "type_name ::= BIGINT", + /* 189 */ "type_name ::= FLOAT", + /* 190 */ "type_name ::= DOUBLE", + /* 191 */ "type_name ::= BINARY NK_LP NK_INTEGER NK_RP", + /* 192 */ "type_name ::= TIMESTAMP", + /* 193 */ "type_name ::= NCHAR NK_LP NK_INTEGER NK_RP", + /* 194 */ "type_name ::= TINYINT UNSIGNED", + /* 195 */ "type_name ::= SMALLINT UNSIGNED", + /* 196 */ "type_name ::= INT UNSIGNED", + /* 197 */ "type_name ::= BIGINT UNSIGNED", + /* 198 */ "type_name ::= JSON", + /* 199 */ "type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP", + /* 200 */ "type_name ::= MEDIUMBLOB", + /* 201 */ "type_name ::= BLOB", + /* 202 */ "type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP", + /* 203 */ "type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP", + /* 204 */ "type_name ::= DECIMAL", + /* 205 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP", + /* 206 */ "type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP", + /* 207 */ "tags_def_opt ::=", + /* 208 */ "tags_def_opt ::= tags_def", + /* 209 */ "tags_def ::= TAGS NK_LP column_def_list NK_RP", + /* 210 */ "table_options ::=", + /* 211 */ "table_options ::= table_options COMMENT NK_STRING", + /* 212 */ "table_options ::= table_options MAX_DELAY duration_list", + /* 213 */ "table_options ::= table_options WATERMARK duration_list", + /* 214 */ "table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP", + /* 215 */ "table_options ::= table_options TTL NK_INTEGER", + /* 216 */ "table_options ::= table_options SMA NK_LP col_name_list NK_RP", + /* 217 */ "table_options ::= table_options DELETE_MARK duration_list", + /* 218 */ "alter_table_options ::= alter_table_option", + /* 219 */ "alter_table_options ::= alter_table_options alter_table_option", + /* 220 */ "alter_table_option ::= COMMENT NK_STRING", + /* 221 */ "alter_table_option ::= TTL NK_INTEGER", + /* 222 */ "duration_list ::= duration_literal", + /* 223 */ "duration_list ::= duration_list NK_COMMA duration_literal", + /* 224 */ "rollup_func_list ::= rollup_func_name", + /* 225 */ "rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name", + /* 226 */ "rollup_func_name ::= function_name", + /* 227 */ "rollup_func_name ::= FIRST", + /* 228 */ "rollup_func_name ::= LAST", + /* 229 */ "col_name_list ::= col_name", + /* 230 */ "col_name_list ::= col_name_list NK_COMMA col_name", + /* 231 */ "col_name ::= column_name", + /* 232 */ "cmd ::= SHOW DNODES", + /* 233 */ "cmd ::= SHOW USERS", + /* 234 */ "cmd ::= SHOW USER PRIVILEGES", + /* 235 */ "cmd ::= SHOW DATABASES", + /* 236 */ "cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt", + /* 237 */ "cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt", + /* 238 */ "cmd ::= SHOW db_name_cond_opt VGROUPS", + /* 239 */ "cmd ::= SHOW MNODES", + /* 240 */ "cmd ::= SHOW QNODES", + /* 241 */ "cmd ::= SHOW FUNCTIONS", + /* 242 */ "cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt", + /* 243 */ "cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name", + /* 244 */ "cmd ::= SHOW STREAMS", + /* 245 */ "cmd ::= SHOW ACCOUNTS", + /* 246 */ "cmd ::= SHOW APPS", + /* 247 */ "cmd ::= SHOW CONNECTIONS", + /* 248 */ "cmd ::= SHOW LICENCES", + /* 249 */ "cmd ::= SHOW GRANTS", + /* 250 */ "cmd ::= SHOW CREATE DATABASE db_name", + /* 251 */ "cmd ::= SHOW CREATE TABLE full_table_name", + /* 252 */ "cmd ::= SHOW CREATE STABLE full_table_name", + /* 253 */ "cmd ::= SHOW QUERIES", + /* 254 */ "cmd ::= SHOW SCORES", + /* 255 */ "cmd ::= SHOW TOPICS", + /* 256 */ "cmd ::= SHOW VARIABLES", + /* 257 */ "cmd ::= SHOW CLUSTER VARIABLES", + /* 258 */ "cmd ::= SHOW LOCAL VARIABLES", + /* 259 */ "cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt", + /* 260 */ "cmd ::= SHOW BNODES", + /* 261 */ "cmd ::= SHOW SNODES", + /* 262 */ "cmd ::= SHOW CLUSTER", + /* 263 */ "cmd ::= SHOW TRANSACTIONS", + /* 264 */ "cmd ::= SHOW TABLE DISTRIBUTED full_table_name", + /* 265 */ "cmd ::= SHOW CONSUMERS", + /* 266 */ "cmd ::= SHOW SUBSCRIPTIONS", + /* 267 */ "cmd ::= SHOW TAGS FROM table_name_cond from_db_opt", + /* 268 */ "cmd ::= SHOW TAGS FROM db_name NK_DOT table_name", + /* 269 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt", + /* 270 */ "cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name", + /* 271 */ "cmd ::= SHOW VNODES ON DNODE NK_INTEGER", + /* 272 */ "cmd ::= SHOW VNODES", + /* 273 */ "cmd ::= SHOW db_name_cond_opt ALIVE", + /* 274 */ "cmd ::= SHOW CLUSTER ALIVE", + /* 275 */ "db_name_cond_opt ::=", + /* 276 */ "db_name_cond_opt ::= db_name NK_DOT", + /* 277 */ "like_pattern_opt ::=", + /* 278 */ "like_pattern_opt ::= LIKE NK_STRING", + /* 279 */ "table_name_cond ::= table_name", + /* 280 */ "from_db_opt ::=", + /* 281 */ "from_db_opt ::= FROM db_name", + /* 282 */ "tag_list_opt ::=", + /* 283 */ "tag_list_opt ::= tag_item", + /* 284 */ "tag_list_opt ::= tag_list_opt NK_COMMA tag_item", + /* 285 */ "tag_item ::= TBNAME", + /* 286 */ "tag_item ::= QTAGS", + /* 287 */ "tag_item ::= column_name", + /* 288 */ "tag_item ::= column_name column_alias", + /* 289 */ "tag_item ::= column_name AS column_alias", + /* 290 */ "cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options", + /* 291 */ "cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP", + /* 292 */ "cmd ::= DROP INDEX exists_opt full_index_name", + /* 293 */ "full_index_name ::= index_name", + /* 294 */ "full_index_name ::= db_name NK_DOT index_name", + /* 295 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt", + /* 296 */ "index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt", + /* 297 */ "func_list ::= func", + /* 298 */ "func_list ::= func_list NK_COMMA func", + /* 299 */ "func ::= sma_func_name NK_LP expression_list NK_RP", + /* 300 */ "sma_func_name ::= function_name", + /* 301 */ "sma_func_name ::= COUNT", + /* 302 */ "sma_func_name ::= FIRST", + /* 303 */ "sma_func_name ::= LAST", + /* 304 */ "sma_func_name ::= LAST_ROW", + /* 305 */ "sma_stream_opt ::=", + /* 306 */ "sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal", + /* 307 */ "sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal", + /* 308 */ "sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal", + /* 309 */ "with_meta ::= AS", + /* 310 */ "with_meta ::= WITH META AS", + /* 311 */ "with_meta ::= ONLY META AS", + /* 312 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery", + /* 313 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name", + /* 314 */ "cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt", + /* 315 */ "cmd ::= DROP TOPIC exists_opt topic_name", + /* 316 */ "cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name", + /* 317 */ "cmd ::= DESC full_table_name", + /* 318 */ "cmd ::= DESCRIBE full_table_name", + /* 319 */ "cmd ::= RESET QUERY CACHE", + /* 320 */ "cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery", + /* 321 */ "cmd ::= EXPLAIN analyze_opt explain_options insert_query", + /* 322 */ "analyze_opt ::=", + /* 323 */ "analyze_opt ::= ANALYZE", + /* 324 */ "explain_options ::=", + /* 325 */ "explain_options ::= explain_options VERBOSE NK_BOOL", + /* 326 */ "explain_options ::= explain_options RATIO NK_FLOAT", + /* 327 */ "cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt", + /* 328 */ "cmd ::= DROP FUNCTION exists_opt function_name", + /* 329 */ "agg_func_opt ::=", + /* 330 */ "agg_func_opt ::= AGGREGATE", + /* 331 */ "bufsize_opt ::=", + /* 332 */ "bufsize_opt ::= BUFSIZE NK_INTEGER", + /* 333 */ "language_opt ::=", + /* 334 */ "language_opt ::= LANGUAGE NK_STRING", + /* 335 */ "or_replace_opt ::=", + /* 336 */ "or_replace_opt ::= OR REPLACE", + /* 337 */ "cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery", + /* 338 */ "cmd ::= DROP STREAM exists_opt stream_name", + /* 339 */ "cmd ::= PAUSE STREAM exists_opt stream_name", + /* 340 */ "cmd ::= RESUME STREAM exists_opt ignore_opt stream_name", + /* 341 */ "col_list_opt ::=", + /* 342 */ "col_list_opt ::= NK_LP col_name_list NK_RP", + /* 343 */ "tag_def_or_ref_opt ::=", + /* 344 */ "tag_def_or_ref_opt ::= tags_def", + /* 345 */ "tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP", + /* 346 */ "stream_options ::=", + /* 347 */ "stream_options ::= stream_options TRIGGER AT_ONCE", + /* 348 */ "stream_options ::= stream_options TRIGGER WINDOW_CLOSE", + /* 349 */ "stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal", + /* 350 */ "stream_options ::= stream_options WATERMARK duration_literal", + /* 351 */ "stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER", + /* 352 */ "stream_options ::= stream_options FILL_HISTORY NK_INTEGER", + /* 353 */ "stream_options ::= stream_options DELETE_MARK duration_literal", + /* 354 */ "stream_options ::= stream_options IGNORE UPDATE NK_INTEGER", + /* 355 */ "subtable_opt ::=", + /* 356 */ "subtable_opt ::= SUBTABLE NK_LP expression NK_RP", + /* 357 */ "ignore_opt ::=", + /* 358 */ "ignore_opt ::= IGNORE UNTREATED", + /* 359 */ "cmd ::= KILL CONNECTION NK_INTEGER", + /* 360 */ "cmd ::= KILL QUERY NK_STRING", + /* 361 */ "cmd ::= KILL TRANSACTION NK_INTEGER", + /* 362 */ "cmd ::= BALANCE VGROUP", + /* 363 */ "cmd ::= BALANCE VGROUP LEADER", + /* 364 */ "cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER", + /* 365 */ "cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list", + /* 366 */ "cmd ::= SPLIT VGROUP NK_INTEGER", + /* 367 */ "dnode_list ::= DNODE NK_INTEGER", + /* 368 */ "dnode_list ::= dnode_list DNODE NK_INTEGER", + /* 369 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", + /* 370 */ "cmd ::= query_or_subquery", + /* 371 */ "cmd ::= insert_query", + /* 372 */ "insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery", + /* 373 */ "insert_query ::= INSERT INTO full_table_name query_or_subquery", + /* 374 */ "literal ::= NK_INTEGER", + /* 375 */ "literal ::= NK_FLOAT", + /* 376 */ "literal ::= NK_STRING", + /* 377 */ "literal ::= NK_BOOL", + /* 378 */ "literal ::= TIMESTAMP NK_STRING", + /* 379 */ "literal ::= duration_literal", + /* 380 */ "literal ::= NULL", + /* 381 */ "literal ::= NK_QUESTION", + /* 382 */ "duration_literal ::= NK_VARIABLE", + /* 383 */ "signed ::= NK_INTEGER", + /* 384 */ "signed ::= NK_PLUS NK_INTEGER", + /* 385 */ "signed ::= NK_MINUS NK_INTEGER", + /* 386 */ "signed ::= NK_FLOAT", + /* 387 */ "signed ::= NK_PLUS NK_FLOAT", + /* 388 */ "signed ::= NK_MINUS NK_FLOAT", + /* 389 */ "signed_literal ::= signed", + /* 390 */ "signed_literal ::= NK_STRING", + /* 391 */ "signed_literal ::= NK_BOOL", + /* 392 */ "signed_literal ::= TIMESTAMP NK_STRING", + /* 393 */ "signed_literal ::= duration_literal", + /* 394 */ "signed_literal ::= NULL", + /* 395 */ "signed_literal ::= literal_func", + /* 396 */ "signed_literal ::= NK_QUESTION", + /* 397 */ "literal_list ::= signed_literal", + /* 398 */ "literal_list ::= literal_list NK_COMMA signed_literal", + /* 399 */ "db_name ::= NK_ID", + /* 400 */ "table_name ::= NK_ID", + /* 401 */ "column_name ::= NK_ID", + /* 402 */ "function_name ::= NK_ID", + /* 403 */ "table_alias ::= NK_ID", + /* 404 */ "column_alias ::= NK_ID", + /* 405 */ "user_name ::= NK_ID", + /* 406 */ "topic_name ::= NK_ID", + /* 407 */ "stream_name ::= NK_ID", + /* 408 */ "cgroup_name ::= NK_ID", + /* 409 */ "index_name ::= NK_ID", + /* 410 */ "expr_or_subquery ::= expression", + /* 411 */ "expression ::= literal", + /* 412 */ "expression ::= pseudo_column", + /* 413 */ "expression ::= column_reference", + /* 414 */ "expression ::= function_expression", + /* 415 */ "expression ::= case_when_expression", + /* 416 */ "expression ::= NK_LP expression NK_RP", + /* 417 */ "expression ::= NK_PLUS expr_or_subquery", + /* 418 */ "expression ::= NK_MINUS expr_or_subquery", + /* 419 */ "expression ::= expr_or_subquery NK_PLUS expr_or_subquery", + /* 420 */ "expression ::= expr_or_subquery NK_MINUS expr_or_subquery", + /* 421 */ "expression ::= expr_or_subquery NK_STAR expr_or_subquery", + /* 422 */ "expression ::= expr_or_subquery NK_SLASH expr_or_subquery", + /* 423 */ "expression ::= expr_or_subquery NK_REM expr_or_subquery", + /* 424 */ "expression ::= column_reference NK_ARROW NK_STRING", + /* 425 */ "expression ::= expr_or_subquery NK_BITAND expr_or_subquery", + /* 426 */ "expression ::= expr_or_subquery NK_BITOR expr_or_subquery", + /* 427 */ "expression_list ::= expr_or_subquery", + /* 428 */ "expression_list ::= expression_list NK_COMMA expr_or_subquery", + /* 429 */ "column_reference ::= column_name", + /* 430 */ "column_reference ::= table_name NK_DOT column_name", + /* 431 */ "pseudo_column ::= ROWTS", + /* 432 */ "pseudo_column ::= TBNAME", + /* 433 */ "pseudo_column ::= table_name NK_DOT TBNAME", + /* 434 */ "pseudo_column ::= QSTART", + /* 435 */ "pseudo_column ::= QEND", + /* 436 */ "pseudo_column ::= QDURATION", + /* 437 */ "pseudo_column ::= WSTART", + /* 438 */ "pseudo_column ::= WEND", + /* 439 */ "pseudo_column ::= WDURATION", + /* 440 */ "pseudo_column ::= IROWTS", + /* 441 */ "pseudo_column ::= ISFILLED", + /* 442 */ "pseudo_column ::= QTAGS", + /* 443 */ "function_expression ::= function_name NK_LP expression_list NK_RP", + /* 444 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", + /* 445 */ "function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP", + /* 446 */ "function_expression ::= literal_func", + /* 447 */ "literal_func ::= noarg_func NK_LP NK_RP", + /* 448 */ "literal_func ::= NOW", + /* 449 */ "noarg_func ::= NOW", + /* 450 */ "noarg_func ::= TODAY", + /* 451 */ "noarg_func ::= TIMEZONE", + /* 452 */ "noarg_func ::= DATABASE", + /* 453 */ "noarg_func ::= CLIENT_VERSION", + /* 454 */ "noarg_func ::= SERVER_VERSION", + /* 455 */ "noarg_func ::= SERVER_STATUS", + /* 456 */ "noarg_func ::= CURRENT_USER", + /* 457 */ "noarg_func ::= USER", + /* 458 */ "star_func ::= COUNT", + /* 459 */ "star_func ::= FIRST", + /* 460 */ "star_func ::= LAST", + /* 461 */ "star_func ::= LAST_ROW", + /* 462 */ "star_func_para_list ::= NK_STAR", + /* 463 */ "star_func_para_list ::= other_para_list", + /* 464 */ "other_para_list ::= star_func_para", + /* 465 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", + /* 466 */ "star_func_para ::= expr_or_subquery", + /* 467 */ "star_func_para ::= table_name NK_DOT NK_STAR", + /* 468 */ "case_when_expression ::= CASE when_then_list case_when_else_opt END", + /* 469 */ "case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END", + /* 470 */ "when_then_list ::= when_then_expr", + /* 471 */ "when_then_list ::= when_then_list when_then_expr", + /* 472 */ "when_then_expr ::= WHEN common_expression THEN common_expression", + /* 473 */ "case_when_else_opt ::=", + /* 474 */ "case_when_else_opt ::= ELSE common_expression", + /* 475 */ "predicate ::= expr_or_subquery compare_op expr_or_subquery", + /* 476 */ "predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery", + /* 477 */ "predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery", + /* 478 */ "predicate ::= expr_or_subquery IS NULL", + /* 479 */ "predicate ::= expr_or_subquery IS NOT NULL", + /* 480 */ "predicate ::= expr_or_subquery in_op in_predicate_value", + /* 481 */ "compare_op ::= NK_LT", + /* 482 */ "compare_op ::= NK_GT", + /* 483 */ "compare_op ::= NK_LE", + /* 484 */ "compare_op ::= NK_GE", + /* 485 */ "compare_op ::= NK_NE", + /* 486 */ "compare_op ::= NK_EQ", + /* 487 */ "compare_op ::= LIKE", + /* 488 */ "compare_op ::= NOT LIKE", + /* 489 */ "compare_op ::= MATCH", + /* 490 */ "compare_op ::= NMATCH", + /* 491 */ "compare_op ::= CONTAINS", + /* 492 */ "in_op ::= IN", + /* 493 */ "in_op ::= NOT IN", + /* 494 */ "in_predicate_value ::= NK_LP literal_list NK_RP", + /* 495 */ "boolean_value_expression ::= boolean_primary", + /* 496 */ "boolean_value_expression ::= NOT boolean_primary", + /* 497 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", + /* 498 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", + /* 499 */ "boolean_primary ::= predicate", + /* 500 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", + /* 501 */ "common_expression ::= expr_or_subquery", + /* 502 */ "common_expression ::= boolean_value_expression", + /* 503 */ "from_clause_opt ::=", + /* 504 */ "from_clause_opt ::= FROM table_reference_list", + /* 505 */ "table_reference_list ::= table_reference", + /* 506 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", + /* 507 */ "table_reference ::= table_primary", + /* 508 */ "table_reference ::= joined_table", + /* 509 */ "table_primary ::= table_name alias_opt", + /* 510 */ "table_primary ::= db_name NK_DOT table_name alias_opt", + /* 511 */ "table_primary ::= subquery alias_opt", + /* 512 */ "table_primary ::= parenthesized_joined_table", + /* 513 */ "alias_opt ::=", + /* 514 */ "alias_opt ::= table_alias", + /* 515 */ "alias_opt ::= AS table_alias", + /* 516 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", + /* 517 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", + /* 518 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", + /* 519 */ "join_type ::=", + /* 520 */ "join_type ::= INNER", + /* 521 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", + /* 522 */ "set_quantifier_opt ::=", + /* 523 */ "set_quantifier_opt ::= DISTINCT", + /* 524 */ "set_quantifier_opt ::= ALL", + /* 525 */ "select_list ::= select_item", + /* 526 */ "select_list ::= select_list NK_COMMA select_item", + /* 527 */ "select_item ::= NK_STAR", + /* 528 */ "select_item ::= common_expression", + /* 529 */ "select_item ::= common_expression column_alias", + /* 530 */ "select_item ::= common_expression AS column_alias", + /* 531 */ "select_item ::= table_name NK_DOT NK_STAR", + /* 532 */ "where_clause_opt ::=", + /* 533 */ "where_clause_opt ::= WHERE search_condition", + /* 534 */ "partition_by_clause_opt ::=", + /* 535 */ "partition_by_clause_opt ::= PARTITION BY partition_list", + /* 536 */ "partition_list ::= partition_item", + /* 537 */ "partition_list ::= partition_list NK_COMMA partition_item", + /* 538 */ "partition_item ::= expr_or_subquery", + /* 539 */ "partition_item ::= expr_or_subquery column_alias", + /* 540 */ "partition_item ::= expr_or_subquery AS column_alias", + /* 541 */ "twindow_clause_opt ::=", + /* 542 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", + /* 543 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP", + /* 544 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", + /* 545 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", + /* 546 */ "twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition", + /* 547 */ "sliding_opt ::=", + /* 548 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", + /* 549 */ "fill_opt ::=", + /* 550 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", + /* 551 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP", + /* 552 */ "fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP", + /* 553 */ "fill_mode ::= NONE", + /* 554 */ "fill_mode ::= PREV", + /* 555 */ "fill_mode ::= NULL", + /* 556 */ "fill_mode ::= NULL_F", + /* 557 */ "fill_mode ::= LINEAR", + /* 558 */ "fill_mode ::= NEXT", + /* 559 */ "group_by_clause_opt ::=", + /* 560 */ "group_by_clause_opt ::= GROUP BY group_by_list", + /* 561 */ "group_by_list ::= expr_or_subquery", + /* 562 */ "group_by_list ::= group_by_list NK_COMMA expr_or_subquery", + /* 563 */ "having_clause_opt ::=", + /* 564 */ "having_clause_opt ::= HAVING search_condition", + /* 565 */ "range_opt ::=", + /* 566 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP", + /* 567 */ "range_opt ::= RANGE NK_LP expr_or_subquery NK_RP", + /* 568 */ "every_opt ::=", + /* 569 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", + /* 570 */ "query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt", + /* 571 */ "query_simple ::= query_specification", + /* 572 */ "query_simple ::= union_query_expression", + /* 573 */ "union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery", + /* 574 */ "union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery", + /* 575 */ "query_simple_or_subquery ::= query_simple", + /* 576 */ "query_simple_or_subquery ::= subquery", + /* 577 */ "query_or_subquery ::= query_expression", + /* 578 */ "query_or_subquery ::= subquery", + /* 579 */ "order_by_clause_opt ::=", + /* 580 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", + /* 581 */ "slimit_clause_opt ::=", + /* 582 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", + /* 583 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", + /* 584 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 585 */ "limit_clause_opt ::=", + /* 586 */ "limit_clause_opt ::= LIMIT NK_INTEGER", + /* 587 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", + /* 588 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 589 */ "subquery ::= NK_LP query_expression NK_RP", + /* 590 */ "subquery ::= NK_LP subquery NK_RP", + /* 591 */ "search_condition ::= common_expression", + /* 592 */ "sort_specification_list ::= sort_specification", + /* 593 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", + /* 594 */ "sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt", + /* 595 */ "ordering_specification_opt ::=", + /* 596 */ "ordering_specification_opt ::= ASC", + /* 597 */ "ordering_specification_opt ::= DESC", + /* 598 */ "null_ordering_opt ::=", + /* 599 */ "null_ordering_opt ::= NULLS FIRST", + /* 600 */ "null_ordering_opt ::= NULLS LAST", }; #endif /* NDEBUG */ @@ -3053,10 +3087,10 @@ static void yy_destructor( case 373: /* table_options */ case 377: /* alter_table_clause */ case 378: /* alter_table_options */ + case 379: /* column_def */ case 381: /* signed_literal */ case 382: /* create_subtable_clause */ case 385: /* drop_table_clause */ - case 387: /* column_def */ case 391: /* duration_literal */ case 392: /* rollup_func_name */ case 394: /* col_name */ @@ -3116,7 +3150,7 @@ static void yy_destructor( { #line 7 "sql.y" nodesDestroyNode((yypminor->yy452)); -#line 3119 "sql.c" +#line 3153 "sql.c" } break; case 339: /* account_options */ @@ -3128,7 +3162,7 @@ static void yy_destructor( { #line 54 "sql.y" -#line 3131 "sql.c" +#line 3165 "sql.c" } break; case 343: /* user_name */ @@ -3136,7 +3170,7 @@ static void yy_destructor( case 351: /* table_name */ case 352: /* topic_name */ case 354: /* dnode_endpoint */ - case 379: /* column_name */ + case 380: /* column_name */ case 393: /* function_name */ case 401: /* column_alias */ case 404: /* index_name */ @@ -3151,14 +3185,14 @@ static void yy_destructor( { #line 742 "sql.y" -#line 3154 "sql.c" +#line 3188 "sql.c" } break; case 344: /* sysinfo_opt */ { #line 92 "sql.y" -#line 3161 "sql.c" +#line 3195 "sql.c" } break; case 345: /* privileges */ @@ -3167,14 +3201,14 @@ static void yy_destructor( { #line 101 "sql.y" -#line 3170 "sql.c" +#line 3204 "sql.c" } break; case 346: /* priv_level */ { #line 117 "sql.y" -#line 3177 "sql.c" +#line 3211 "sql.c" } break; case 355: /* force_opt */ @@ -3189,7 +3223,7 @@ static void yy_destructor( { #line 146 "sql.y" -#line 3192 "sql.c" +#line 3226 "sql.c" } break; case 364: /* integer_list */ @@ -3224,7 +3258,7 @@ static void yy_destructor( { #line 270 "sql.y" nodesDestroyList((yypminor->yy812)); -#line 3227 "sql.c" +#line 3261 "sql.c" } break; case 368: /* alter_db_option */ @@ -3232,14 +3266,14 @@ static void yy_destructor( { #line 243 "sql.y" -#line 3235 "sql.c" +#line 3269 "sql.c" } break; - case 380: /* type_name */ + case 387: /* type_name */ { #line 364 "sql.y" -#line 3242 "sql.c" +#line 3276 "sql.c" } break; case 447: /* compare_op */ @@ -3247,35 +3281,35 @@ static void yy_destructor( { #line 930 "sql.y" -#line 3250 "sql.c" +#line 3284 "sql.c" } break; case 460: /* join_type */ { #line 1006 "sql.y" -#line 3257 "sql.c" +#line 3291 "sql.c" } break; case 474: /* fill_mode */ { #line 1081 "sql.y" -#line 3264 "sql.c" +#line 3298 "sql.c" } break; case 485: /* ordering_specification_opt */ { #line 1166 "sql.y" -#line 3271 "sql.c" +#line 3305 "sql.c" } break; case 486: /* null_ordering_opt */ { #line 1172 "sql.y" -#line 3278 "sql.c" +#line 3312 "sql.c" } break; /********* End destructor definitions *****************************************/ @@ -3724,13 +3758,13 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 338, /* (157) cmd ::= ALTER TABLE alter_table_clause */ 338, /* (158) cmd ::= ALTER STABLE alter_table_clause */ 377, /* (159) alter_table_clause ::= full_table_name alter_table_options */ - 377, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ + 377, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_def */ 377, /* (161) alter_table_clause ::= full_table_name DROP COLUMN column_name */ - 377, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ + 377, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_def */ 377, /* (163) alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ - 377, /* (164) alter_table_clause ::= full_table_name ADD TAG column_name type_name */ + 377, /* (164) alter_table_clause ::= full_table_name ADD TAG column_def */ 377, /* (165) alter_table_clause ::= full_table_name DROP TAG column_name */ - 377, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ + 377, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_def */ 377, /* (167) alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ 377, /* (168) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ 374, /* (169) multi_create_clause ::= create_subtable_clause */ @@ -3745,425 +3779,426 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 370, /* (178) full_table_name ::= db_name NK_DOT table_name */ 371, /* (179) column_def_list ::= column_def */ 371, /* (180) column_def_list ::= column_def_list NK_COMMA column_def */ - 387, /* (181) column_def ::= column_name type_name */ - 380, /* (182) type_name ::= BOOL */ - 380, /* (183) type_name ::= TINYINT */ - 380, /* (184) type_name ::= SMALLINT */ - 380, /* (185) type_name ::= INT */ - 380, /* (186) type_name ::= INTEGER */ - 380, /* (187) type_name ::= BIGINT */ - 380, /* (188) type_name ::= FLOAT */ - 380, /* (189) type_name ::= DOUBLE */ - 380, /* (190) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ - 380, /* (191) type_name ::= TIMESTAMP */ - 380, /* (192) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ - 380, /* (193) type_name ::= TINYINT UNSIGNED */ - 380, /* (194) type_name ::= SMALLINT UNSIGNED */ - 380, /* (195) type_name ::= INT UNSIGNED */ - 380, /* (196) type_name ::= BIGINT UNSIGNED */ - 380, /* (197) type_name ::= JSON */ - 380, /* (198) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ - 380, /* (199) type_name ::= MEDIUMBLOB */ - 380, /* (200) type_name ::= BLOB */ - 380, /* (201) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ - 380, /* (202) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ - 380, /* (203) type_name ::= DECIMAL */ - 380, /* (204) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ - 380, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ - 372, /* (206) tags_def_opt ::= */ - 372, /* (207) tags_def_opt ::= tags_def */ - 375, /* (208) tags_def ::= TAGS NK_LP column_def_list NK_RP */ - 373, /* (209) table_options ::= */ - 373, /* (210) table_options ::= table_options COMMENT NK_STRING */ - 373, /* (211) table_options ::= table_options MAX_DELAY duration_list */ - 373, /* (212) table_options ::= table_options WATERMARK duration_list */ - 373, /* (213) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ - 373, /* (214) table_options ::= table_options TTL NK_INTEGER */ - 373, /* (215) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ - 373, /* (216) table_options ::= table_options DELETE_MARK duration_list */ - 378, /* (217) alter_table_options ::= alter_table_option */ - 378, /* (218) alter_table_options ::= alter_table_options alter_table_option */ - 390, /* (219) alter_table_option ::= COMMENT NK_STRING */ - 390, /* (220) alter_table_option ::= TTL NK_INTEGER */ - 388, /* (221) duration_list ::= duration_literal */ - 388, /* (222) duration_list ::= duration_list NK_COMMA duration_literal */ - 389, /* (223) rollup_func_list ::= rollup_func_name */ - 389, /* (224) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ - 392, /* (225) rollup_func_name ::= function_name */ - 392, /* (226) rollup_func_name ::= FIRST */ - 392, /* (227) rollup_func_name ::= LAST */ - 386, /* (228) col_name_list ::= col_name */ - 386, /* (229) col_name_list ::= col_name_list NK_COMMA col_name */ - 394, /* (230) col_name ::= column_name */ - 338, /* (231) cmd ::= SHOW DNODES */ - 338, /* (232) cmd ::= SHOW USERS */ - 338, /* (233) cmd ::= SHOW USER PRIVILEGES */ - 338, /* (234) cmd ::= SHOW DATABASES */ - 338, /* (235) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ - 338, /* (236) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ - 338, /* (237) cmd ::= SHOW db_name_cond_opt VGROUPS */ - 338, /* (238) cmd ::= SHOW MNODES */ - 338, /* (239) cmd ::= SHOW QNODES */ - 338, /* (240) cmd ::= SHOW FUNCTIONS */ - 338, /* (241) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ - 338, /* (242) cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ - 338, /* (243) cmd ::= SHOW STREAMS */ - 338, /* (244) cmd ::= SHOW ACCOUNTS */ - 338, /* (245) cmd ::= SHOW APPS */ - 338, /* (246) cmd ::= SHOW CONNECTIONS */ - 338, /* (247) cmd ::= SHOW LICENCES */ - 338, /* (248) cmd ::= SHOW GRANTS */ - 338, /* (249) cmd ::= SHOW CREATE DATABASE db_name */ - 338, /* (250) cmd ::= SHOW CREATE TABLE full_table_name */ - 338, /* (251) cmd ::= SHOW CREATE STABLE full_table_name */ - 338, /* (252) cmd ::= SHOW QUERIES */ - 338, /* (253) cmd ::= SHOW SCORES */ - 338, /* (254) cmd ::= SHOW TOPICS */ - 338, /* (255) cmd ::= SHOW VARIABLES */ - 338, /* (256) cmd ::= SHOW CLUSTER VARIABLES */ - 338, /* (257) cmd ::= SHOW LOCAL VARIABLES */ - 338, /* (258) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ - 338, /* (259) cmd ::= SHOW BNODES */ - 338, /* (260) cmd ::= SHOW SNODES */ - 338, /* (261) cmd ::= SHOW CLUSTER */ - 338, /* (262) cmd ::= SHOW TRANSACTIONS */ - 338, /* (263) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ - 338, /* (264) cmd ::= SHOW CONSUMERS */ - 338, /* (265) cmd ::= SHOW SUBSCRIPTIONS */ - 338, /* (266) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ - 338, /* (267) cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ - 338, /* (268) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ - 338, /* (269) cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ - 338, /* (270) cmd ::= SHOW VNODES ON DNODE NK_INTEGER */ - 338, /* (271) cmd ::= SHOW VNODES */ - 338, /* (272) cmd ::= SHOW db_name_cond_opt ALIVE */ - 338, /* (273) cmd ::= SHOW CLUSTER ALIVE */ - 395, /* (274) db_name_cond_opt ::= */ - 395, /* (275) db_name_cond_opt ::= db_name NK_DOT */ - 396, /* (276) like_pattern_opt ::= */ - 396, /* (277) like_pattern_opt ::= LIKE NK_STRING */ - 397, /* (278) table_name_cond ::= table_name */ - 398, /* (279) from_db_opt ::= */ - 398, /* (280) from_db_opt ::= FROM db_name */ - 399, /* (281) tag_list_opt ::= */ - 399, /* (282) tag_list_opt ::= tag_item */ - 399, /* (283) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ - 400, /* (284) tag_item ::= TBNAME */ - 400, /* (285) tag_item ::= QTAGS */ - 400, /* (286) tag_item ::= column_name */ - 400, /* (287) tag_item ::= column_name column_alias */ - 400, /* (288) tag_item ::= column_name AS column_alias */ - 338, /* (289) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ - 338, /* (290) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ - 338, /* (291) cmd ::= DROP INDEX exists_opt full_index_name */ - 402, /* (292) full_index_name ::= index_name */ - 402, /* (293) full_index_name ::= db_name NK_DOT index_name */ - 403, /* (294) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ - 403, /* (295) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ - 405, /* (296) func_list ::= func */ - 405, /* (297) func_list ::= func_list NK_COMMA func */ - 408, /* (298) func ::= sma_func_name NK_LP expression_list NK_RP */ - 409, /* (299) sma_func_name ::= function_name */ - 409, /* (300) sma_func_name ::= COUNT */ - 409, /* (301) sma_func_name ::= FIRST */ - 409, /* (302) sma_func_name ::= LAST */ - 409, /* (303) sma_func_name ::= LAST_ROW */ - 407, /* (304) sma_stream_opt ::= */ - 407, /* (305) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ - 407, /* (306) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ - 407, /* (307) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ - 410, /* (308) with_meta ::= AS */ - 410, /* (309) with_meta ::= WITH META AS */ - 410, /* (310) with_meta ::= ONLY META AS */ - 338, /* (311) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ - 338, /* (312) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ - 338, /* (313) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ - 338, /* (314) cmd ::= DROP TOPIC exists_opt topic_name */ - 338, /* (315) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ - 338, /* (316) cmd ::= DESC full_table_name */ - 338, /* (317) cmd ::= DESCRIBE full_table_name */ - 338, /* (318) cmd ::= RESET QUERY CACHE */ - 338, /* (319) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - 338, /* (320) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ - 414, /* (321) analyze_opt ::= */ - 414, /* (322) analyze_opt ::= ANALYZE */ - 415, /* (323) explain_options ::= */ - 415, /* (324) explain_options ::= explain_options VERBOSE NK_BOOL */ - 415, /* (325) explain_options ::= explain_options RATIO NK_FLOAT */ - 338, /* (326) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ - 338, /* (327) cmd ::= DROP FUNCTION exists_opt function_name */ - 418, /* (328) agg_func_opt ::= */ - 418, /* (329) agg_func_opt ::= AGGREGATE */ - 419, /* (330) bufsize_opt ::= */ - 419, /* (331) bufsize_opt ::= BUFSIZE NK_INTEGER */ - 420, /* (332) language_opt ::= */ - 420, /* (333) language_opt ::= LANGUAGE NK_STRING */ - 417, /* (334) or_replace_opt ::= */ - 417, /* (335) or_replace_opt ::= OR REPLACE */ - 338, /* (336) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ - 338, /* (337) cmd ::= DROP STREAM exists_opt stream_name */ - 338, /* (338) cmd ::= PAUSE STREAM exists_opt stream_name */ - 338, /* (339) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ - 423, /* (340) col_list_opt ::= */ - 423, /* (341) col_list_opt ::= NK_LP col_name_list NK_RP */ - 424, /* (342) tag_def_or_ref_opt ::= */ - 424, /* (343) tag_def_or_ref_opt ::= tags_def */ - 424, /* (344) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ - 422, /* (345) stream_options ::= */ - 422, /* (346) stream_options ::= stream_options TRIGGER AT_ONCE */ - 422, /* (347) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - 422, /* (348) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - 422, /* (349) stream_options ::= stream_options WATERMARK duration_literal */ - 422, /* (350) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ - 422, /* (351) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ - 422, /* (352) stream_options ::= stream_options DELETE_MARK duration_literal */ - 422, /* (353) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ - 425, /* (354) subtable_opt ::= */ - 425, /* (355) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - 426, /* (356) ignore_opt ::= */ - 426, /* (357) ignore_opt ::= IGNORE UNTREATED */ - 338, /* (358) cmd ::= KILL CONNECTION NK_INTEGER */ - 338, /* (359) cmd ::= KILL QUERY NK_STRING */ - 338, /* (360) cmd ::= KILL TRANSACTION NK_INTEGER */ - 338, /* (361) cmd ::= BALANCE VGROUP */ - 338, /* (362) cmd ::= BALANCE VGROUP LEADER */ - 338, /* (363) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ - 338, /* (364) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ - 338, /* (365) cmd ::= SPLIT VGROUP NK_INTEGER */ - 428, /* (366) dnode_list ::= DNODE NK_INTEGER */ - 428, /* (367) dnode_list ::= dnode_list DNODE NK_INTEGER */ - 338, /* (368) cmd ::= DELETE FROM full_table_name where_clause_opt */ - 338, /* (369) cmd ::= query_or_subquery */ - 338, /* (370) cmd ::= insert_query */ - 416, /* (371) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ - 416, /* (372) insert_query ::= INSERT INTO full_table_name query_or_subquery */ - 341, /* (373) literal ::= NK_INTEGER */ - 341, /* (374) literal ::= NK_FLOAT */ - 341, /* (375) literal ::= NK_STRING */ - 341, /* (376) literal ::= NK_BOOL */ - 341, /* (377) literal ::= TIMESTAMP NK_STRING */ - 341, /* (378) literal ::= duration_literal */ - 341, /* (379) literal ::= NULL */ - 341, /* (380) literal ::= NK_QUESTION */ - 391, /* (381) duration_literal ::= NK_VARIABLE */ - 367, /* (382) signed ::= NK_INTEGER */ - 367, /* (383) signed ::= NK_PLUS NK_INTEGER */ - 367, /* (384) signed ::= NK_MINUS NK_INTEGER */ - 367, /* (385) signed ::= NK_FLOAT */ - 367, /* (386) signed ::= NK_PLUS NK_FLOAT */ - 367, /* (387) signed ::= NK_MINUS NK_FLOAT */ - 381, /* (388) signed_literal ::= signed */ - 381, /* (389) signed_literal ::= NK_STRING */ - 381, /* (390) signed_literal ::= NK_BOOL */ - 381, /* (391) signed_literal ::= TIMESTAMP NK_STRING */ - 381, /* (392) signed_literal ::= duration_literal */ - 381, /* (393) signed_literal ::= NULL */ - 381, /* (394) signed_literal ::= literal_func */ - 381, /* (395) signed_literal ::= NK_QUESTION */ - 430, /* (396) literal_list ::= signed_literal */ - 430, /* (397) literal_list ::= literal_list NK_COMMA signed_literal */ - 350, /* (398) db_name ::= NK_ID */ - 351, /* (399) table_name ::= NK_ID */ - 379, /* (400) column_name ::= NK_ID */ - 393, /* (401) function_name ::= NK_ID */ - 431, /* (402) table_alias ::= NK_ID */ - 401, /* (403) column_alias ::= NK_ID */ - 343, /* (404) user_name ::= NK_ID */ - 352, /* (405) topic_name ::= NK_ID */ - 421, /* (406) stream_name ::= NK_ID */ - 413, /* (407) cgroup_name ::= NK_ID */ - 404, /* (408) index_name ::= NK_ID */ - 432, /* (409) expr_or_subquery ::= expression */ - 427, /* (410) expression ::= literal */ - 427, /* (411) expression ::= pseudo_column */ - 427, /* (412) expression ::= column_reference */ - 427, /* (413) expression ::= function_expression */ - 427, /* (414) expression ::= case_when_expression */ - 427, /* (415) expression ::= NK_LP expression NK_RP */ - 427, /* (416) expression ::= NK_PLUS expr_or_subquery */ - 427, /* (417) expression ::= NK_MINUS expr_or_subquery */ - 427, /* (418) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ - 427, /* (419) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ - 427, /* (420) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ - 427, /* (421) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ - 427, /* (422) expression ::= expr_or_subquery NK_REM expr_or_subquery */ - 427, /* (423) expression ::= column_reference NK_ARROW NK_STRING */ - 427, /* (424) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ - 427, /* (425) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ - 384, /* (426) expression_list ::= expr_or_subquery */ - 384, /* (427) expression_list ::= expression_list NK_COMMA expr_or_subquery */ - 434, /* (428) column_reference ::= column_name */ - 434, /* (429) column_reference ::= table_name NK_DOT column_name */ - 433, /* (430) pseudo_column ::= ROWTS */ - 433, /* (431) pseudo_column ::= TBNAME */ - 433, /* (432) pseudo_column ::= table_name NK_DOT TBNAME */ - 433, /* (433) pseudo_column ::= QSTART */ - 433, /* (434) pseudo_column ::= QEND */ - 433, /* (435) pseudo_column ::= QDURATION */ - 433, /* (436) pseudo_column ::= WSTART */ - 433, /* (437) pseudo_column ::= WEND */ - 433, /* (438) pseudo_column ::= WDURATION */ - 433, /* (439) pseudo_column ::= IROWTS */ - 433, /* (440) pseudo_column ::= ISFILLED */ - 433, /* (441) pseudo_column ::= QTAGS */ - 435, /* (442) function_expression ::= function_name NK_LP expression_list NK_RP */ - 435, /* (443) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ - 435, /* (444) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ - 435, /* (445) function_expression ::= literal_func */ - 429, /* (446) literal_func ::= noarg_func NK_LP NK_RP */ - 429, /* (447) literal_func ::= NOW */ - 439, /* (448) noarg_func ::= NOW */ - 439, /* (449) noarg_func ::= TODAY */ - 439, /* (450) noarg_func ::= TIMEZONE */ - 439, /* (451) noarg_func ::= DATABASE */ - 439, /* (452) noarg_func ::= CLIENT_VERSION */ - 439, /* (453) noarg_func ::= SERVER_VERSION */ - 439, /* (454) noarg_func ::= SERVER_STATUS */ - 439, /* (455) noarg_func ::= CURRENT_USER */ - 439, /* (456) noarg_func ::= USER */ - 437, /* (457) star_func ::= COUNT */ - 437, /* (458) star_func ::= FIRST */ - 437, /* (459) star_func ::= LAST */ - 437, /* (460) star_func ::= LAST_ROW */ - 438, /* (461) star_func_para_list ::= NK_STAR */ - 438, /* (462) star_func_para_list ::= other_para_list */ - 440, /* (463) other_para_list ::= star_func_para */ - 440, /* (464) other_para_list ::= other_para_list NK_COMMA star_func_para */ - 441, /* (465) star_func_para ::= expr_or_subquery */ - 441, /* (466) star_func_para ::= table_name NK_DOT NK_STAR */ - 436, /* (467) case_when_expression ::= CASE when_then_list case_when_else_opt END */ - 436, /* (468) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ - 442, /* (469) when_then_list ::= when_then_expr */ - 442, /* (470) when_then_list ::= when_then_list when_then_expr */ - 445, /* (471) when_then_expr ::= WHEN common_expression THEN common_expression */ - 443, /* (472) case_when_else_opt ::= */ - 443, /* (473) case_when_else_opt ::= ELSE common_expression */ - 446, /* (474) predicate ::= expr_or_subquery compare_op expr_or_subquery */ - 446, /* (475) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ - 446, /* (476) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ - 446, /* (477) predicate ::= expr_or_subquery IS NULL */ - 446, /* (478) predicate ::= expr_or_subquery IS NOT NULL */ - 446, /* (479) predicate ::= expr_or_subquery in_op in_predicate_value */ - 447, /* (480) compare_op ::= NK_LT */ - 447, /* (481) compare_op ::= NK_GT */ - 447, /* (482) compare_op ::= NK_LE */ - 447, /* (483) compare_op ::= NK_GE */ - 447, /* (484) compare_op ::= NK_NE */ - 447, /* (485) compare_op ::= NK_EQ */ - 447, /* (486) compare_op ::= LIKE */ - 447, /* (487) compare_op ::= NOT LIKE */ - 447, /* (488) compare_op ::= MATCH */ - 447, /* (489) compare_op ::= NMATCH */ - 447, /* (490) compare_op ::= CONTAINS */ - 448, /* (491) in_op ::= IN */ - 448, /* (492) in_op ::= NOT IN */ - 449, /* (493) in_predicate_value ::= NK_LP literal_list NK_RP */ - 450, /* (494) boolean_value_expression ::= boolean_primary */ - 450, /* (495) boolean_value_expression ::= NOT boolean_primary */ - 450, /* (496) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - 450, /* (497) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - 451, /* (498) boolean_primary ::= predicate */ - 451, /* (499) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - 444, /* (500) common_expression ::= expr_or_subquery */ - 444, /* (501) common_expression ::= boolean_value_expression */ - 452, /* (502) from_clause_opt ::= */ - 452, /* (503) from_clause_opt ::= FROM table_reference_list */ - 453, /* (504) table_reference_list ::= table_reference */ - 453, /* (505) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - 454, /* (506) table_reference ::= table_primary */ - 454, /* (507) table_reference ::= joined_table */ - 455, /* (508) table_primary ::= table_name alias_opt */ - 455, /* (509) table_primary ::= db_name NK_DOT table_name alias_opt */ - 455, /* (510) table_primary ::= subquery alias_opt */ - 455, /* (511) table_primary ::= parenthesized_joined_table */ - 457, /* (512) alias_opt ::= */ - 457, /* (513) alias_opt ::= table_alias */ - 457, /* (514) alias_opt ::= AS table_alias */ - 459, /* (515) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - 459, /* (516) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - 456, /* (517) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - 460, /* (518) join_type ::= */ - 460, /* (519) join_type ::= INNER */ - 461, /* (520) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ - 462, /* (521) set_quantifier_opt ::= */ - 462, /* (522) set_quantifier_opt ::= DISTINCT */ - 462, /* (523) set_quantifier_opt ::= ALL */ - 463, /* (524) select_list ::= select_item */ - 463, /* (525) select_list ::= select_list NK_COMMA select_item */ - 471, /* (526) select_item ::= NK_STAR */ - 471, /* (527) select_item ::= common_expression */ - 471, /* (528) select_item ::= common_expression column_alias */ - 471, /* (529) select_item ::= common_expression AS column_alias */ - 471, /* (530) select_item ::= table_name NK_DOT NK_STAR */ - 412, /* (531) where_clause_opt ::= */ - 412, /* (532) where_clause_opt ::= WHERE search_condition */ - 464, /* (533) partition_by_clause_opt ::= */ - 464, /* (534) partition_by_clause_opt ::= PARTITION BY partition_list */ - 472, /* (535) partition_list ::= partition_item */ - 472, /* (536) partition_list ::= partition_list NK_COMMA partition_item */ - 473, /* (537) partition_item ::= expr_or_subquery */ - 473, /* (538) partition_item ::= expr_or_subquery column_alias */ - 473, /* (539) partition_item ::= expr_or_subquery AS column_alias */ - 468, /* (540) twindow_clause_opt ::= */ - 468, /* (541) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ - 468, /* (542) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ - 468, /* (543) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - 468, /* (544) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - 468, /* (545) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ - 406, /* (546) sliding_opt ::= */ - 406, /* (547) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - 467, /* (548) fill_opt ::= */ - 467, /* (549) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - 467, /* (550) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ - 467, /* (551) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ - 474, /* (552) fill_mode ::= NONE */ - 474, /* (553) fill_mode ::= PREV */ - 474, /* (554) fill_mode ::= NULL */ - 474, /* (555) fill_mode ::= NULL_F */ - 474, /* (556) fill_mode ::= LINEAR */ - 474, /* (557) fill_mode ::= NEXT */ - 469, /* (558) group_by_clause_opt ::= */ - 469, /* (559) group_by_clause_opt ::= GROUP BY group_by_list */ - 475, /* (560) group_by_list ::= expr_or_subquery */ - 475, /* (561) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ - 470, /* (562) having_clause_opt ::= */ - 470, /* (563) having_clause_opt ::= HAVING search_condition */ - 465, /* (564) range_opt ::= */ - 465, /* (565) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ - 465, /* (566) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ - 466, /* (567) every_opt ::= */ - 466, /* (568) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - 476, /* (569) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ - 477, /* (570) query_simple ::= query_specification */ - 477, /* (571) query_simple ::= union_query_expression */ - 481, /* (572) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ - 481, /* (573) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ - 482, /* (574) query_simple_or_subquery ::= query_simple */ - 482, /* (575) query_simple_or_subquery ::= subquery */ - 411, /* (576) query_or_subquery ::= query_expression */ - 411, /* (577) query_or_subquery ::= subquery */ - 478, /* (578) order_by_clause_opt ::= */ - 478, /* (579) order_by_clause_opt ::= ORDER BY sort_specification_list */ - 479, /* (580) slimit_clause_opt ::= */ - 479, /* (581) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - 479, /* (582) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - 479, /* (583) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 480, /* (584) limit_clause_opt ::= */ - 480, /* (585) limit_clause_opt ::= LIMIT NK_INTEGER */ - 480, /* (586) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - 480, /* (587) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 458, /* (588) subquery ::= NK_LP query_expression NK_RP */ - 458, /* (589) subquery ::= NK_LP subquery NK_RP */ - 353, /* (590) search_condition ::= common_expression */ - 483, /* (591) sort_specification_list ::= sort_specification */ - 483, /* (592) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - 484, /* (593) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ - 485, /* (594) ordering_specification_opt ::= */ - 485, /* (595) ordering_specification_opt ::= ASC */ - 485, /* (596) ordering_specification_opt ::= DESC */ - 486, /* (597) null_ordering_opt ::= */ - 486, /* (598) null_ordering_opt ::= NULLS FIRST */ - 486, /* (599) null_ordering_opt ::= NULLS LAST */ + 379, /* (181) column_def ::= column_name type_name */ + 379, /* (182) column_def ::= column_name type_name COMMENT NK_STRING */ + 387, /* (183) type_name ::= BOOL */ + 387, /* (184) type_name ::= TINYINT */ + 387, /* (185) type_name ::= SMALLINT */ + 387, /* (186) type_name ::= INT */ + 387, /* (187) type_name ::= INTEGER */ + 387, /* (188) type_name ::= BIGINT */ + 387, /* (189) type_name ::= FLOAT */ + 387, /* (190) type_name ::= DOUBLE */ + 387, /* (191) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + 387, /* (192) type_name ::= TIMESTAMP */ + 387, /* (193) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + 387, /* (194) type_name ::= TINYINT UNSIGNED */ + 387, /* (195) type_name ::= SMALLINT UNSIGNED */ + 387, /* (196) type_name ::= INT UNSIGNED */ + 387, /* (197) type_name ::= BIGINT UNSIGNED */ + 387, /* (198) type_name ::= JSON */ + 387, /* (199) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + 387, /* (200) type_name ::= MEDIUMBLOB */ + 387, /* (201) type_name ::= BLOB */ + 387, /* (202) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + 387, /* (203) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ + 387, /* (204) type_name ::= DECIMAL */ + 387, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + 387, /* (206) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + 372, /* (207) tags_def_opt ::= */ + 372, /* (208) tags_def_opt ::= tags_def */ + 375, /* (209) tags_def ::= TAGS NK_LP column_def_list NK_RP */ + 373, /* (210) table_options ::= */ + 373, /* (211) table_options ::= table_options COMMENT NK_STRING */ + 373, /* (212) table_options ::= table_options MAX_DELAY duration_list */ + 373, /* (213) table_options ::= table_options WATERMARK duration_list */ + 373, /* (214) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ + 373, /* (215) table_options ::= table_options TTL NK_INTEGER */ + 373, /* (216) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + 373, /* (217) table_options ::= table_options DELETE_MARK duration_list */ + 378, /* (218) alter_table_options ::= alter_table_option */ + 378, /* (219) alter_table_options ::= alter_table_options alter_table_option */ + 390, /* (220) alter_table_option ::= COMMENT NK_STRING */ + 390, /* (221) alter_table_option ::= TTL NK_INTEGER */ + 388, /* (222) duration_list ::= duration_literal */ + 388, /* (223) duration_list ::= duration_list NK_COMMA duration_literal */ + 389, /* (224) rollup_func_list ::= rollup_func_name */ + 389, /* (225) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ + 392, /* (226) rollup_func_name ::= function_name */ + 392, /* (227) rollup_func_name ::= FIRST */ + 392, /* (228) rollup_func_name ::= LAST */ + 386, /* (229) col_name_list ::= col_name */ + 386, /* (230) col_name_list ::= col_name_list NK_COMMA col_name */ + 394, /* (231) col_name ::= column_name */ + 338, /* (232) cmd ::= SHOW DNODES */ + 338, /* (233) cmd ::= SHOW USERS */ + 338, /* (234) cmd ::= SHOW USER PRIVILEGES */ + 338, /* (235) cmd ::= SHOW DATABASES */ + 338, /* (236) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ + 338, /* (237) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ + 338, /* (238) cmd ::= SHOW db_name_cond_opt VGROUPS */ + 338, /* (239) cmd ::= SHOW MNODES */ + 338, /* (240) cmd ::= SHOW QNODES */ + 338, /* (241) cmd ::= SHOW FUNCTIONS */ + 338, /* (242) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ + 338, /* (243) cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ + 338, /* (244) cmd ::= SHOW STREAMS */ + 338, /* (245) cmd ::= SHOW ACCOUNTS */ + 338, /* (246) cmd ::= SHOW APPS */ + 338, /* (247) cmd ::= SHOW CONNECTIONS */ + 338, /* (248) cmd ::= SHOW LICENCES */ + 338, /* (249) cmd ::= SHOW GRANTS */ + 338, /* (250) cmd ::= SHOW CREATE DATABASE db_name */ + 338, /* (251) cmd ::= SHOW CREATE TABLE full_table_name */ + 338, /* (252) cmd ::= SHOW CREATE STABLE full_table_name */ + 338, /* (253) cmd ::= SHOW QUERIES */ + 338, /* (254) cmd ::= SHOW SCORES */ + 338, /* (255) cmd ::= SHOW TOPICS */ + 338, /* (256) cmd ::= SHOW VARIABLES */ + 338, /* (257) cmd ::= SHOW CLUSTER VARIABLES */ + 338, /* (258) cmd ::= SHOW LOCAL VARIABLES */ + 338, /* (259) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ + 338, /* (260) cmd ::= SHOW BNODES */ + 338, /* (261) cmd ::= SHOW SNODES */ + 338, /* (262) cmd ::= SHOW CLUSTER */ + 338, /* (263) cmd ::= SHOW TRANSACTIONS */ + 338, /* (264) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + 338, /* (265) cmd ::= SHOW CONSUMERS */ + 338, /* (266) cmd ::= SHOW SUBSCRIPTIONS */ + 338, /* (267) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ + 338, /* (268) cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ + 338, /* (269) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ + 338, /* (270) cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ + 338, /* (271) cmd ::= SHOW VNODES ON DNODE NK_INTEGER */ + 338, /* (272) cmd ::= SHOW VNODES */ + 338, /* (273) cmd ::= SHOW db_name_cond_opt ALIVE */ + 338, /* (274) cmd ::= SHOW CLUSTER ALIVE */ + 395, /* (275) db_name_cond_opt ::= */ + 395, /* (276) db_name_cond_opt ::= db_name NK_DOT */ + 396, /* (277) like_pattern_opt ::= */ + 396, /* (278) like_pattern_opt ::= LIKE NK_STRING */ + 397, /* (279) table_name_cond ::= table_name */ + 398, /* (280) from_db_opt ::= */ + 398, /* (281) from_db_opt ::= FROM db_name */ + 399, /* (282) tag_list_opt ::= */ + 399, /* (283) tag_list_opt ::= tag_item */ + 399, /* (284) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ + 400, /* (285) tag_item ::= TBNAME */ + 400, /* (286) tag_item ::= QTAGS */ + 400, /* (287) tag_item ::= column_name */ + 400, /* (288) tag_item ::= column_name column_alias */ + 400, /* (289) tag_item ::= column_name AS column_alias */ + 338, /* (290) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ + 338, /* (291) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ + 338, /* (292) cmd ::= DROP INDEX exists_opt full_index_name */ + 402, /* (293) full_index_name ::= index_name */ + 402, /* (294) full_index_name ::= db_name NK_DOT index_name */ + 403, /* (295) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ + 403, /* (296) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ + 405, /* (297) func_list ::= func */ + 405, /* (298) func_list ::= func_list NK_COMMA func */ + 408, /* (299) func ::= sma_func_name NK_LP expression_list NK_RP */ + 409, /* (300) sma_func_name ::= function_name */ + 409, /* (301) sma_func_name ::= COUNT */ + 409, /* (302) sma_func_name ::= FIRST */ + 409, /* (303) sma_func_name ::= LAST */ + 409, /* (304) sma_func_name ::= LAST_ROW */ + 407, /* (305) sma_stream_opt ::= */ + 407, /* (306) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ + 407, /* (307) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ + 407, /* (308) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ + 410, /* (309) with_meta ::= AS */ + 410, /* (310) with_meta ::= WITH META AS */ + 410, /* (311) with_meta ::= ONLY META AS */ + 338, /* (312) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ + 338, /* (313) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ + 338, /* (314) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ + 338, /* (315) cmd ::= DROP TOPIC exists_opt topic_name */ + 338, /* (316) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + 338, /* (317) cmd ::= DESC full_table_name */ + 338, /* (318) cmd ::= DESCRIBE full_table_name */ + 338, /* (319) cmd ::= RESET QUERY CACHE */ + 338, /* (320) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + 338, /* (321) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ + 414, /* (322) analyze_opt ::= */ + 414, /* (323) analyze_opt ::= ANALYZE */ + 415, /* (324) explain_options ::= */ + 415, /* (325) explain_options ::= explain_options VERBOSE NK_BOOL */ + 415, /* (326) explain_options ::= explain_options RATIO NK_FLOAT */ + 338, /* (327) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ + 338, /* (328) cmd ::= DROP FUNCTION exists_opt function_name */ + 418, /* (329) agg_func_opt ::= */ + 418, /* (330) agg_func_opt ::= AGGREGATE */ + 419, /* (331) bufsize_opt ::= */ + 419, /* (332) bufsize_opt ::= BUFSIZE NK_INTEGER */ + 420, /* (333) language_opt ::= */ + 420, /* (334) language_opt ::= LANGUAGE NK_STRING */ + 417, /* (335) or_replace_opt ::= */ + 417, /* (336) or_replace_opt ::= OR REPLACE */ + 338, /* (337) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ + 338, /* (338) cmd ::= DROP STREAM exists_opt stream_name */ + 338, /* (339) cmd ::= PAUSE STREAM exists_opt stream_name */ + 338, /* (340) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ + 423, /* (341) col_list_opt ::= */ + 423, /* (342) col_list_opt ::= NK_LP col_name_list NK_RP */ + 424, /* (343) tag_def_or_ref_opt ::= */ + 424, /* (344) tag_def_or_ref_opt ::= tags_def */ + 424, /* (345) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ + 422, /* (346) stream_options ::= */ + 422, /* (347) stream_options ::= stream_options TRIGGER AT_ONCE */ + 422, /* (348) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + 422, /* (349) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + 422, /* (350) stream_options ::= stream_options WATERMARK duration_literal */ + 422, /* (351) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ + 422, /* (352) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ + 422, /* (353) stream_options ::= stream_options DELETE_MARK duration_literal */ + 422, /* (354) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ + 425, /* (355) subtable_opt ::= */ + 425, /* (356) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + 426, /* (357) ignore_opt ::= */ + 426, /* (358) ignore_opt ::= IGNORE UNTREATED */ + 338, /* (359) cmd ::= KILL CONNECTION NK_INTEGER */ + 338, /* (360) cmd ::= KILL QUERY NK_STRING */ + 338, /* (361) cmd ::= KILL TRANSACTION NK_INTEGER */ + 338, /* (362) cmd ::= BALANCE VGROUP */ + 338, /* (363) cmd ::= BALANCE VGROUP LEADER */ + 338, /* (364) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + 338, /* (365) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + 338, /* (366) cmd ::= SPLIT VGROUP NK_INTEGER */ + 428, /* (367) dnode_list ::= DNODE NK_INTEGER */ + 428, /* (368) dnode_list ::= dnode_list DNODE NK_INTEGER */ + 338, /* (369) cmd ::= DELETE FROM full_table_name where_clause_opt */ + 338, /* (370) cmd ::= query_or_subquery */ + 338, /* (371) cmd ::= insert_query */ + 416, /* (372) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ + 416, /* (373) insert_query ::= INSERT INTO full_table_name query_or_subquery */ + 341, /* (374) literal ::= NK_INTEGER */ + 341, /* (375) literal ::= NK_FLOAT */ + 341, /* (376) literal ::= NK_STRING */ + 341, /* (377) literal ::= NK_BOOL */ + 341, /* (378) literal ::= TIMESTAMP NK_STRING */ + 341, /* (379) literal ::= duration_literal */ + 341, /* (380) literal ::= NULL */ + 341, /* (381) literal ::= NK_QUESTION */ + 391, /* (382) duration_literal ::= NK_VARIABLE */ + 367, /* (383) signed ::= NK_INTEGER */ + 367, /* (384) signed ::= NK_PLUS NK_INTEGER */ + 367, /* (385) signed ::= NK_MINUS NK_INTEGER */ + 367, /* (386) signed ::= NK_FLOAT */ + 367, /* (387) signed ::= NK_PLUS NK_FLOAT */ + 367, /* (388) signed ::= NK_MINUS NK_FLOAT */ + 381, /* (389) signed_literal ::= signed */ + 381, /* (390) signed_literal ::= NK_STRING */ + 381, /* (391) signed_literal ::= NK_BOOL */ + 381, /* (392) signed_literal ::= TIMESTAMP NK_STRING */ + 381, /* (393) signed_literal ::= duration_literal */ + 381, /* (394) signed_literal ::= NULL */ + 381, /* (395) signed_literal ::= literal_func */ + 381, /* (396) signed_literal ::= NK_QUESTION */ + 430, /* (397) literal_list ::= signed_literal */ + 430, /* (398) literal_list ::= literal_list NK_COMMA signed_literal */ + 350, /* (399) db_name ::= NK_ID */ + 351, /* (400) table_name ::= NK_ID */ + 380, /* (401) column_name ::= NK_ID */ + 393, /* (402) function_name ::= NK_ID */ + 431, /* (403) table_alias ::= NK_ID */ + 401, /* (404) column_alias ::= NK_ID */ + 343, /* (405) user_name ::= NK_ID */ + 352, /* (406) topic_name ::= NK_ID */ + 421, /* (407) stream_name ::= NK_ID */ + 413, /* (408) cgroup_name ::= NK_ID */ + 404, /* (409) index_name ::= NK_ID */ + 432, /* (410) expr_or_subquery ::= expression */ + 427, /* (411) expression ::= literal */ + 427, /* (412) expression ::= pseudo_column */ + 427, /* (413) expression ::= column_reference */ + 427, /* (414) expression ::= function_expression */ + 427, /* (415) expression ::= case_when_expression */ + 427, /* (416) expression ::= NK_LP expression NK_RP */ + 427, /* (417) expression ::= NK_PLUS expr_or_subquery */ + 427, /* (418) expression ::= NK_MINUS expr_or_subquery */ + 427, /* (419) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + 427, /* (420) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + 427, /* (421) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + 427, /* (422) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + 427, /* (423) expression ::= expr_or_subquery NK_REM expr_or_subquery */ + 427, /* (424) expression ::= column_reference NK_ARROW NK_STRING */ + 427, /* (425) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + 427, /* (426) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + 384, /* (427) expression_list ::= expr_or_subquery */ + 384, /* (428) expression_list ::= expression_list NK_COMMA expr_or_subquery */ + 434, /* (429) column_reference ::= column_name */ + 434, /* (430) column_reference ::= table_name NK_DOT column_name */ + 433, /* (431) pseudo_column ::= ROWTS */ + 433, /* (432) pseudo_column ::= TBNAME */ + 433, /* (433) pseudo_column ::= table_name NK_DOT TBNAME */ + 433, /* (434) pseudo_column ::= QSTART */ + 433, /* (435) pseudo_column ::= QEND */ + 433, /* (436) pseudo_column ::= QDURATION */ + 433, /* (437) pseudo_column ::= WSTART */ + 433, /* (438) pseudo_column ::= WEND */ + 433, /* (439) pseudo_column ::= WDURATION */ + 433, /* (440) pseudo_column ::= IROWTS */ + 433, /* (441) pseudo_column ::= ISFILLED */ + 433, /* (442) pseudo_column ::= QTAGS */ + 435, /* (443) function_expression ::= function_name NK_LP expression_list NK_RP */ + 435, /* (444) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ + 435, /* (445) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ + 435, /* (446) function_expression ::= literal_func */ + 429, /* (447) literal_func ::= noarg_func NK_LP NK_RP */ + 429, /* (448) literal_func ::= NOW */ + 439, /* (449) noarg_func ::= NOW */ + 439, /* (450) noarg_func ::= TODAY */ + 439, /* (451) noarg_func ::= TIMEZONE */ + 439, /* (452) noarg_func ::= DATABASE */ + 439, /* (453) noarg_func ::= CLIENT_VERSION */ + 439, /* (454) noarg_func ::= SERVER_VERSION */ + 439, /* (455) noarg_func ::= SERVER_STATUS */ + 439, /* (456) noarg_func ::= CURRENT_USER */ + 439, /* (457) noarg_func ::= USER */ + 437, /* (458) star_func ::= COUNT */ + 437, /* (459) star_func ::= FIRST */ + 437, /* (460) star_func ::= LAST */ + 437, /* (461) star_func ::= LAST_ROW */ + 438, /* (462) star_func_para_list ::= NK_STAR */ + 438, /* (463) star_func_para_list ::= other_para_list */ + 440, /* (464) other_para_list ::= star_func_para */ + 440, /* (465) other_para_list ::= other_para_list NK_COMMA star_func_para */ + 441, /* (466) star_func_para ::= expr_or_subquery */ + 441, /* (467) star_func_para ::= table_name NK_DOT NK_STAR */ + 436, /* (468) case_when_expression ::= CASE when_then_list case_when_else_opt END */ + 436, /* (469) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ + 442, /* (470) when_then_list ::= when_then_expr */ + 442, /* (471) when_then_list ::= when_then_list when_then_expr */ + 445, /* (472) when_then_expr ::= WHEN common_expression THEN common_expression */ + 443, /* (473) case_when_else_opt ::= */ + 443, /* (474) case_when_else_opt ::= ELSE common_expression */ + 446, /* (475) predicate ::= expr_or_subquery compare_op expr_or_subquery */ + 446, /* (476) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + 446, /* (477) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + 446, /* (478) predicate ::= expr_or_subquery IS NULL */ + 446, /* (479) predicate ::= expr_or_subquery IS NOT NULL */ + 446, /* (480) predicate ::= expr_or_subquery in_op in_predicate_value */ + 447, /* (481) compare_op ::= NK_LT */ + 447, /* (482) compare_op ::= NK_GT */ + 447, /* (483) compare_op ::= NK_LE */ + 447, /* (484) compare_op ::= NK_GE */ + 447, /* (485) compare_op ::= NK_NE */ + 447, /* (486) compare_op ::= NK_EQ */ + 447, /* (487) compare_op ::= LIKE */ + 447, /* (488) compare_op ::= NOT LIKE */ + 447, /* (489) compare_op ::= MATCH */ + 447, /* (490) compare_op ::= NMATCH */ + 447, /* (491) compare_op ::= CONTAINS */ + 448, /* (492) in_op ::= IN */ + 448, /* (493) in_op ::= NOT IN */ + 449, /* (494) in_predicate_value ::= NK_LP literal_list NK_RP */ + 450, /* (495) boolean_value_expression ::= boolean_primary */ + 450, /* (496) boolean_value_expression ::= NOT boolean_primary */ + 450, /* (497) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + 450, /* (498) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + 451, /* (499) boolean_primary ::= predicate */ + 451, /* (500) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + 444, /* (501) common_expression ::= expr_or_subquery */ + 444, /* (502) common_expression ::= boolean_value_expression */ + 452, /* (503) from_clause_opt ::= */ + 452, /* (504) from_clause_opt ::= FROM table_reference_list */ + 453, /* (505) table_reference_list ::= table_reference */ + 453, /* (506) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + 454, /* (507) table_reference ::= table_primary */ + 454, /* (508) table_reference ::= joined_table */ + 455, /* (509) table_primary ::= table_name alias_opt */ + 455, /* (510) table_primary ::= db_name NK_DOT table_name alias_opt */ + 455, /* (511) table_primary ::= subquery alias_opt */ + 455, /* (512) table_primary ::= parenthesized_joined_table */ + 457, /* (513) alias_opt ::= */ + 457, /* (514) alias_opt ::= table_alias */ + 457, /* (515) alias_opt ::= AS table_alias */ + 459, /* (516) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + 459, /* (517) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + 456, /* (518) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + 460, /* (519) join_type ::= */ + 460, /* (520) join_type ::= INNER */ + 461, /* (521) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + 462, /* (522) set_quantifier_opt ::= */ + 462, /* (523) set_quantifier_opt ::= DISTINCT */ + 462, /* (524) set_quantifier_opt ::= ALL */ + 463, /* (525) select_list ::= select_item */ + 463, /* (526) select_list ::= select_list NK_COMMA select_item */ + 471, /* (527) select_item ::= NK_STAR */ + 471, /* (528) select_item ::= common_expression */ + 471, /* (529) select_item ::= common_expression column_alias */ + 471, /* (530) select_item ::= common_expression AS column_alias */ + 471, /* (531) select_item ::= table_name NK_DOT NK_STAR */ + 412, /* (532) where_clause_opt ::= */ + 412, /* (533) where_clause_opt ::= WHERE search_condition */ + 464, /* (534) partition_by_clause_opt ::= */ + 464, /* (535) partition_by_clause_opt ::= PARTITION BY partition_list */ + 472, /* (536) partition_list ::= partition_item */ + 472, /* (537) partition_list ::= partition_list NK_COMMA partition_item */ + 473, /* (538) partition_item ::= expr_or_subquery */ + 473, /* (539) partition_item ::= expr_or_subquery column_alias */ + 473, /* (540) partition_item ::= expr_or_subquery AS column_alias */ + 468, /* (541) twindow_clause_opt ::= */ + 468, /* (542) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + 468, /* (543) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ + 468, /* (544) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + 468, /* (545) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + 468, /* (546) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ + 406, /* (547) sliding_opt ::= */ + 406, /* (548) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + 467, /* (549) fill_opt ::= */ + 467, /* (550) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + 467, /* (551) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ + 467, /* (552) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ + 474, /* (553) fill_mode ::= NONE */ + 474, /* (554) fill_mode ::= PREV */ + 474, /* (555) fill_mode ::= NULL */ + 474, /* (556) fill_mode ::= NULL_F */ + 474, /* (557) fill_mode ::= LINEAR */ + 474, /* (558) fill_mode ::= NEXT */ + 469, /* (559) group_by_clause_opt ::= */ + 469, /* (560) group_by_clause_opt ::= GROUP BY group_by_list */ + 475, /* (561) group_by_list ::= expr_or_subquery */ + 475, /* (562) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ + 470, /* (563) having_clause_opt ::= */ + 470, /* (564) having_clause_opt ::= HAVING search_condition */ + 465, /* (565) range_opt ::= */ + 465, /* (566) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ + 465, /* (567) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ + 466, /* (568) every_opt ::= */ + 466, /* (569) every_opt ::= EVERY NK_LP duration_literal NK_RP */ + 476, /* (570) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + 477, /* (571) query_simple ::= query_specification */ + 477, /* (572) query_simple ::= union_query_expression */ + 481, /* (573) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ + 481, /* (574) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ + 482, /* (575) query_simple_or_subquery ::= query_simple */ + 482, /* (576) query_simple_or_subquery ::= subquery */ + 411, /* (577) query_or_subquery ::= query_expression */ + 411, /* (578) query_or_subquery ::= subquery */ + 478, /* (579) order_by_clause_opt ::= */ + 478, /* (580) order_by_clause_opt ::= ORDER BY sort_specification_list */ + 479, /* (581) slimit_clause_opt ::= */ + 479, /* (582) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + 479, /* (583) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + 479, /* (584) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 480, /* (585) limit_clause_opt ::= */ + 480, /* (586) limit_clause_opt ::= LIMIT NK_INTEGER */ + 480, /* (587) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + 480, /* (588) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 458, /* (589) subquery ::= NK_LP query_expression NK_RP */ + 458, /* (590) subquery ::= NK_LP subquery NK_RP */ + 353, /* (591) search_condition ::= common_expression */ + 483, /* (592) sort_specification_list ::= sort_specification */ + 483, /* (593) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + 484, /* (594) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ + 485, /* (595) ordering_specification_opt ::= */ + 485, /* (596) ordering_specification_opt ::= ASC */ + 485, /* (597) ordering_specification_opt ::= DESC */ + 486, /* (598) null_ordering_opt ::= */ + 486, /* (599) null_ordering_opt ::= NULLS FIRST */ + 486, /* (600) null_ordering_opt ::= NULLS LAST */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -4329,13 +4364,13 @@ static const signed char yyRuleInfoNRhs[] = { -3, /* (157) cmd ::= ALTER TABLE alter_table_clause */ -3, /* (158) cmd ::= ALTER STABLE alter_table_clause */ -2, /* (159) alter_table_clause ::= full_table_name alter_table_options */ - -5, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ + -4, /* (160) alter_table_clause ::= full_table_name ADD COLUMN column_def */ -4, /* (161) alter_table_clause ::= full_table_name DROP COLUMN column_name */ - -5, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ + -4, /* (162) alter_table_clause ::= full_table_name MODIFY COLUMN column_def */ -5, /* (163) alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ - -5, /* (164) alter_table_clause ::= full_table_name ADD TAG column_name type_name */ + -4, /* (164) alter_table_clause ::= full_table_name ADD TAG column_def */ -4, /* (165) alter_table_clause ::= full_table_name DROP TAG column_name */ - -5, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ + -4, /* (166) alter_table_clause ::= full_table_name MODIFY TAG column_def */ -5, /* (167) alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ -6, /* (168) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ -1, /* (169) multi_create_clause ::= create_subtable_clause */ @@ -4351,424 +4386,425 @@ static const signed char yyRuleInfoNRhs[] = { -1, /* (179) column_def_list ::= column_def */ -3, /* (180) column_def_list ::= column_def_list NK_COMMA column_def */ -2, /* (181) column_def ::= column_name type_name */ - -1, /* (182) type_name ::= BOOL */ - -1, /* (183) type_name ::= TINYINT */ - -1, /* (184) type_name ::= SMALLINT */ - -1, /* (185) type_name ::= INT */ - -1, /* (186) type_name ::= INTEGER */ - -1, /* (187) type_name ::= BIGINT */ - -1, /* (188) type_name ::= FLOAT */ - -1, /* (189) type_name ::= DOUBLE */ - -4, /* (190) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ - -1, /* (191) type_name ::= TIMESTAMP */ - -4, /* (192) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ - -2, /* (193) type_name ::= TINYINT UNSIGNED */ - -2, /* (194) type_name ::= SMALLINT UNSIGNED */ - -2, /* (195) type_name ::= INT UNSIGNED */ - -2, /* (196) type_name ::= BIGINT UNSIGNED */ - -1, /* (197) type_name ::= JSON */ - -4, /* (198) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ - -1, /* (199) type_name ::= MEDIUMBLOB */ - -1, /* (200) type_name ::= BLOB */ - -4, /* (201) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ - -4, /* (202) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ - -1, /* (203) type_name ::= DECIMAL */ - -4, /* (204) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ - -6, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ - 0, /* (206) tags_def_opt ::= */ - -1, /* (207) tags_def_opt ::= tags_def */ - -4, /* (208) tags_def ::= TAGS NK_LP column_def_list NK_RP */ - 0, /* (209) table_options ::= */ - -3, /* (210) table_options ::= table_options COMMENT NK_STRING */ - -3, /* (211) table_options ::= table_options MAX_DELAY duration_list */ - -3, /* (212) table_options ::= table_options WATERMARK duration_list */ - -5, /* (213) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ - -3, /* (214) table_options ::= table_options TTL NK_INTEGER */ - -5, /* (215) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ - -3, /* (216) table_options ::= table_options DELETE_MARK duration_list */ - -1, /* (217) alter_table_options ::= alter_table_option */ - -2, /* (218) alter_table_options ::= alter_table_options alter_table_option */ - -2, /* (219) alter_table_option ::= COMMENT NK_STRING */ - -2, /* (220) alter_table_option ::= TTL NK_INTEGER */ - -1, /* (221) duration_list ::= duration_literal */ - -3, /* (222) duration_list ::= duration_list NK_COMMA duration_literal */ - -1, /* (223) rollup_func_list ::= rollup_func_name */ - -3, /* (224) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ - -1, /* (225) rollup_func_name ::= function_name */ - -1, /* (226) rollup_func_name ::= FIRST */ - -1, /* (227) rollup_func_name ::= LAST */ - -1, /* (228) col_name_list ::= col_name */ - -3, /* (229) col_name_list ::= col_name_list NK_COMMA col_name */ - -1, /* (230) col_name ::= column_name */ - -2, /* (231) cmd ::= SHOW DNODES */ - -2, /* (232) cmd ::= SHOW USERS */ - -3, /* (233) cmd ::= SHOW USER PRIVILEGES */ - -2, /* (234) cmd ::= SHOW DATABASES */ - -4, /* (235) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ - -4, /* (236) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ - -3, /* (237) cmd ::= SHOW db_name_cond_opt VGROUPS */ - -2, /* (238) cmd ::= SHOW MNODES */ - -2, /* (239) cmd ::= SHOW QNODES */ - -2, /* (240) cmd ::= SHOW FUNCTIONS */ - -5, /* (241) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ - -6, /* (242) cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ - -2, /* (243) cmd ::= SHOW STREAMS */ - -2, /* (244) cmd ::= SHOW ACCOUNTS */ - -2, /* (245) cmd ::= SHOW APPS */ - -2, /* (246) cmd ::= SHOW CONNECTIONS */ - -2, /* (247) cmd ::= SHOW LICENCES */ - -2, /* (248) cmd ::= SHOW GRANTS */ - -4, /* (249) cmd ::= SHOW CREATE DATABASE db_name */ - -4, /* (250) cmd ::= SHOW CREATE TABLE full_table_name */ - -4, /* (251) cmd ::= SHOW CREATE STABLE full_table_name */ - -2, /* (252) cmd ::= SHOW QUERIES */ - -2, /* (253) cmd ::= SHOW SCORES */ - -2, /* (254) cmd ::= SHOW TOPICS */ - -2, /* (255) cmd ::= SHOW VARIABLES */ - -3, /* (256) cmd ::= SHOW CLUSTER VARIABLES */ - -3, /* (257) cmd ::= SHOW LOCAL VARIABLES */ - -5, /* (258) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ - -2, /* (259) cmd ::= SHOW BNODES */ - -2, /* (260) cmd ::= SHOW SNODES */ - -2, /* (261) cmd ::= SHOW CLUSTER */ - -2, /* (262) cmd ::= SHOW TRANSACTIONS */ - -4, /* (263) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ - -2, /* (264) cmd ::= SHOW CONSUMERS */ - -2, /* (265) cmd ::= SHOW SUBSCRIPTIONS */ - -5, /* (266) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ - -6, /* (267) cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ - -7, /* (268) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ - -8, /* (269) cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ - -5, /* (270) cmd ::= SHOW VNODES ON DNODE NK_INTEGER */ - -2, /* (271) cmd ::= SHOW VNODES */ - -3, /* (272) cmd ::= SHOW db_name_cond_opt ALIVE */ - -3, /* (273) cmd ::= SHOW CLUSTER ALIVE */ - 0, /* (274) db_name_cond_opt ::= */ - -2, /* (275) db_name_cond_opt ::= db_name NK_DOT */ - 0, /* (276) like_pattern_opt ::= */ - -2, /* (277) like_pattern_opt ::= LIKE NK_STRING */ - -1, /* (278) table_name_cond ::= table_name */ - 0, /* (279) from_db_opt ::= */ - -2, /* (280) from_db_opt ::= FROM db_name */ - 0, /* (281) tag_list_opt ::= */ - -1, /* (282) tag_list_opt ::= tag_item */ - -3, /* (283) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ - -1, /* (284) tag_item ::= TBNAME */ - -1, /* (285) tag_item ::= QTAGS */ - -1, /* (286) tag_item ::= column_name */ - -2, /* (287) tag_item ::= column_name column_alias */ - -3, /* (288) tag_item ::= column_name AS column_alias */ - -8, /* (289) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ - -9, /* (290) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ - -4, /* (291) cmd ::= DROP INDEX exists_opt full_index_name */ - -1, /* (292) full_index_name ::= index_name */ - -3, /* (293) full_index_name ::= db_name NK_DOT index_name */ - -10, /* (294) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ - -12, /* (295) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ - -1, /* (296) func_list ::= func */ - -3, /* (297) func_list ::= func_list NK_COMMA func */ - -4, /* (298) func ::= sma_func_name NK_LP expression_list NK_RP */ - -1, /* (299) sma_func_name ::= function_name */ - -1, /* (300) sma_func_name ::= COUNT */ - -1, /* (301) sma_func_name ::= FIRST */ - -1, /* (302) sma_func_name ::= LAST */ - -1, /* (303) sma_func_name ::= LAST_ROW */ - 0, /* (304) sma_stream_opt ::= */ - -3, /* (305) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ - -3, /* (306) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ - -3, /* (307) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ - -1, /* (308) with_meta ::= AS */ - -3, /* (309) with_meta ::= WITH META AS */ - -3, /* (310) with_meta ::= ONLY META AS */ - -6, /* (311) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ - -7, /* (312) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ - -8, /* (313) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ - -4, /* (314) cmd ::= DROP TOPIC exists_opt topic_name */ - -7, /* (315) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ - -2, /* (316) cmd ::= DESC full_table_name */ - -2, /* (317) cmd ::= DESCRIBE full_table_name */ - -3, /* (318) cmd ::= RESET QUERY CACHE */ - -4, /* (319) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - -4, /* (320) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ - 0, /* (321) analyze_opt ::= */ - -1, /* (322) analyze_opt ::= ANALYZE */ - 0, /* (323) explain_options ::= */ - -3, /* (324) explain_options ::= explain_options VERBOSE NK_BOOL */ - -3, /* (325) explain_options ::= explain_options RATIO NK_FLOAT */ - -12, /* (326) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ - -4, /* (327) cmd ::= DROP FUNCTION exists_opt function_name */ - 0, /* (328) agg_func_opt ::= */ - -1, /* (329) agg_func_opt ::= AGGREGATE */ - 0, /* (330) bufsize_opt ::= */ - -2, /* (331) bufsize_opt ::= BUFSIZE NK_INTEGER */ - 0, /* (332) language_opt ::= */ - -2, /* (333) language_opt ::= LANGUAGE NK_STRING */ - 0, /* (334) or_replace_opt ::= */ - -2, /* (335) or_replace_opt ::= OR REPLACE */ - -12, /* (336) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ - -4, /* (337) cmd ::= DROP STREAM exists_opt stream_name */ - -4, /* (338) cmd ::= PAUSE STREAM exists_opt stream_name */ - -5, /* (339) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ - 0, /* (340) col_list_opt ::= */ - -3, /* (341) col_list_opt ::= NK_LP col_name_list NK_RP */ - 0, /* (342) tag_def_or_ref_opt ::= */ - -1, /* (343) tag_def_or_ref_opt ::= tags_def */ - -4, /* (344) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ - 0, /* (345) stream_options ::= */ - -3, /* (346) stream_options ::= stream_options TRIGGER AT_ONCE */ - -3, /* (347) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - -4, /* (348) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - -3, /* (349) stream_options ::= stream_options WATERMARK duration_literal */ - -4, /* (350) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ - -3, /* (351) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ - -3, /* (352) stream_options ::= stream_options DELETE_MARK duration_literal */ - -4, /* (353) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ - 0, /* (354) subtable_opt ::= */ - -4, /* (355) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - 0, /* (356) ignore_opt ::= */ - -2, /* (357) ignore_opt ::= IGNORE UNTREATED */ - -3, /* (358) cmd ::= KILL CONNECTION NK_INTEGER */ - -3, /* (359) cmd ::= KILL QUERY NK_STRING */ - -3, /* (360) cmd ::= KILL TRANSACTION NK_INTEGER */ - -2, /* (361) cmd ::= BALANCE VGROUP */ - -3, /* (362) cmd ::= BALANCE VGROUP LEADER */ - -4, /* (363) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ - -4, /* (364) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ - -3, /* (365) cmd ::= SPLIT VGROUP NK_INTEGER */ - -2, /* (366) dnode_list ::= DNODE NK_INTEGER */ - -3, /* (367) dnode_list ::= dnode_list DNODE NK_INTEGER */ - -4, /* (368) cmd ::= DELETE FROM full_table_name where_clause_opt */ - -1, /* (369) cmd ::= query_or_subquery */ - -1, /* (370) cmd ::= insert_query */ - -7, /* (371) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ - -4, /* (372) insert_query ::= INSERT INTO full_table_name query_or_subquery */ - -1, /* (373) literal ::= NK_INTEGER */ - -1, /* (374) literal ::= NK_FLOAT */ - -1, /* (375) literal ::= NK_STRING */ - -1, /* (376) literal ::= NK_BOOL */ - -2, /* (377) literal ::= TIMESTAMP NK_STRING */ - -1, /* (378) literal ::= duration_literal */ - -1, /* (379) literal ::= NULL */ - -1, /* (380) literal ::= NK_QUESTION */ - -1, /* (381) duration_literal ::= NK_VARIABLE */ - -1, /* (382) signed ::= NK_INTEGER */ - -2, /* (383) signed ::= NK_PLUS NK_INTEGER */ - -2, /* (384) signed ::= NK_MINUS NK_INTEGER */ - -1, /* (385) signed ::= NK_FLOAT */ - -2, /* (386) signed ::= NK_PLUS NK_FLOAT */ - -2, /* (387) signed ::= NK_MINUS NK_FLOAT */ - -1, /* (388) signed_literal ::= signed */ - -1, /* (389) signed_literal ::= NK_STRING */ - -1, /* (390) signed_literal ::= NK_BOOL */ - -2, /* (391) signed_literal ::= TIMESTAMP NK_STRING */ - -1, /* (392) signed_literal ::= duration_literal */ - -1, /* (393) signed_literal ::= NULL */ - -1, /* (394) signed_literal ::= literal_func */ - -1, /* (395) signed_literal ::= NK_QUESTION */ - -1, /* (396) literal_list ::= signed_literal */ - -3, /* (397) literal_list ::= literal_list NK_COMMA signed_literal */ - -1, /* (398) db_name ::= NK_ID */ - -1, /* (399) table_name ::= NK_ID */ - -1, /* (400) column_name ::= NK_ID */ - -1, /* (401) function_name ::= NK_ID */ - -1, /* (402) table_alias ::= NK_ID */ - -1, /* (403) column_alias ::= NK_ID */ - -1, /* (404) user_name ::= NK_ID */ - -1, /* (405) topic_name ::= NK_ID */ - -1, /* (406) stream_name ::= NK_ID */ - -1, /* (407) cgroup_name ::= NK_ID */ - -1, /* (408) index_name ::= NK_ID */ - -1, /* (409) expr_or_subquery ::= expression */ - -1, /* (410) expression ::= literal */ - -1, /* (411) expression ::= pseudo_column */ - -1, /* (412) expression ::= column_reference */ - -1, /* (413) expression ::= function_expression */ - -1, /* (414) expression ::= case_when_expression */ - -3, /* (415) expression ::= NK_LP expression NK_RP */ - -2, /* (416) expression ::= NK_PLUS expr_or_subquery */ - -2, /* (417) expression ::= NK_MINUS expr_or_subquery */ - -3, /* (418) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ - -3, /* (419) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ - -3, /* (420) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ - -3, /* (421) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ - -3, /* (422) expression ::= expr_or_subquery NK_REM expr_or_subquery */ - -3, /* (423) expression ::= column_reference NK_ARROW NK_STRING */ - -3, /* (424) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ - -3, /* (425) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ - -1, /* (426) expression_list ::= expr_or_subquery */ - -3, /* (427) expression_list ::= expression_list NK_COMMA expr_or_subquery */ - -1, /* (428) column_reference ::= column_name */ - -3, /* (429) column_reference ::= table_name NK_DOT column_name */ - -1, /* (430) pseudo_column ::= ROWTS */ - -1, /* (431) pseudo_column ::= TBNAME */ - -3, /* (432) pseudo_column ::= table_name NK_DOT TBNAME */ - -1, /* (433) pseudo_column ::= QSTART */ - -1, /* (434) pseudo_column ::= QEND */ - -1, /* (435) pseudo_column ::= QDURATION */ - -1, /* (436) pseudo_column ::= WSTART */ - -1, /* (437) pseudo_column ::= WEND */ - -1, /* (438) pseudo_column ::= WDURATION */ - -1, /* (439) pseudo_column ::= IROWTS */ - -1, /* (440) pseudo_column ::= ISFILLED */ - -1, /* (441) pseudo_column ::= QTAGS */ - -4, /* (442) function_expression ::= function_name NK_LP expression_list NK_RP */ - -4, /* (443) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ - -6, /* (444) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ - -1, /* (445) function_expression ::= literal_func */ - -3, /* (446) literal_func ::= noarg_func NK_LP NK_RP */ - -1, /* (447) literal_func ::= NOW */ - -1, /* (448) noarg_func ::= NOW */ - -1, /* (449) noarg_func ::= TODAY */ - -1, /* (450) noarg_func ::= TIMEZONE */ - -1, /* (451) noarg_func ::= DATABASE */ - -1, /* (452) noarg_func ::= CLIENT_VERSION */ - -1, /* (453) noarg_func ::= SERVER_VERSION */ - -1, /* (454) noarg_func ::= SERVER_STATUS */ - -1, /* (455) noarg_func ::= CURRENT_USER */ - -1, /* (456) noarg_func ::= USER */ - -1, /* (457) star_func ::= COUNT */ - -1, /* (458) star_func ::= FIRST */ - -1, /* (459) star_func ::= LAST */ - -1, /* (460) star_func ::= LAST_ROW */ - -1, /* (461) star_func_para_list ::= NK_STAR */ - -1, /* (462) star_func_para_list ::= other_para_list */ - -1, /* (463) other_para_list ::= star_func_para */ - -3, /* (464) other_para_list ::= other_para_list NK_COMMA star_func_para */ - -1, /* (465) star_func_para ::= expr_or_subquery */ - -3, /* (466) star_func_para ::= table_name NK_DOT NK_STAR */ - -4, /* (467) case_when_expression ::= CASE when_then_list case_when_else_opt END */ - -5, /* (468) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ - -1, /* (469) when_then_list ::= when_then_expr */ - -2, /* (470) when_then_list ::= when_then_list when_then_expr */ - -4, /* (471) when_then_expr ::= WHEN common_expression THEN common_expression */ - 0, /* (472) case_when_else_opt ::= */ - -2, /* (473) case_when_else_opt ::= ELSE common_expression */ - -3, /* (474) predicate ::= expr_or_subquery compare_op expr_or_subquery */ - -5, /* (475) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ - -6, /* (476) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ - -3, /* (477) predicate ::= expr_or_subquery IS NULL */ - -4, /* (478) predicate ::= expr_or_subquery IS NOT NULL */ - -3, /* (479) predicate ::= expr_or_subquery in_op in_predicate_value */ - -1, /* (480) compare_op ::= NK_LT */ - -1, /* (481) compare_op ::= NK_GT */ - -1, /* (482) compare_op ::= NK_LE */ - -1, /* (483) compare_op ::= NK_GE */ - -1, /* (484) compare_op ::= NK_NE */ - -1, /* (485) compare_op ::= NK_EQ */ - -1, /* (486) compare_op ::= LIKE */ - -2, /* (487) compare_op ::= NOT LIKE */ - -1, /* (488) compare_op ::= MATCH */ - -1, /* (489) compare_op ::= NMATCH */ - -1, /* (490) compare_op ::= CONTAINS */ - -1, /* (491) in_op ::= IN */ - -2, /* (492) in_op ::= NOT IN */ - -3, /* (493) in_predicate_value ::= NK_LP literal_list NK_RP */ - -1, /* (494) boolean_value_expression ::= boolean_primary */ - -2, /* (495) boolean_value_expression ::= NOT boolean_primary */ - -3, /* (496) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - -3, /* (497) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - -1, /* (498) boolean_primary ::= predicate */ - -3, /* (499) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - -1, /* (500) common_expression ::= expr_or_subquery */ - -1, /* (501) common_expression ::= boolean_value_expression */ - 0, /* (502) from_clause_opt ::= */ - -2, /* (503) from_clause_opt ::= FROM table_reference_list */ - -1, /* (504) table_reference_list ::= table_reference */ - -3, /* (505) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - -1, /* (506) table_reference ::= table_primary */ - -1, /* (507) table_reference ::= joined_table */ - -2, /* (508) table_primary ::= table_name alias_opt */ - -4, /* (509) table_primary ::= db_name NK_DOT table_name alias_opt */ - -2, /* (510) table_primary ::= subquery alias_opt */ - -1, /* (511) table_primary ::= parenthesized_joined_table */ - 0, /* (512) alias_opt ::= */ - -1, /* (513) alias_opt ::= table_alias */ - -2, /* (514) alias_opt ::= AS table_alias */ - -3, /* (515) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - -3, /* (516) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - -6, /* (517) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - 0, /* (518) join_type ::= */ - -1, /* (519) join_type ::= INNER */ - -12, /* (520) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ - 0, /* (521) set_quantifier_opt ::= */ - -1, /* (522) set_quantifier_opt ::= DISTINCT */ - -1, /* (523) set_quantifier_opt ::= ALL */ - -1, /* (524) select_list ::= select_item */ - -3, /* (525) select_list ::= select_list NK_COMMA select_item */ - -1, /* (526) select_item ::= NK_STAR */ - -1, /* (527) select_item ::= common_expression */ - -2, /* (528) select_item ::= common_expression column_alias */ - -3, /* (529) select_item ::= common_expression AS column_alias */ - -3, /* (530) select_item ::= table_name NK_DOT NK_STAR */ - 0, /* (531) where_clause_opt ::= */ - -2, /* (532) where_clause_opt ::= WHERE search_condition */ - 0, /* (533) partition_by_clause_opt ::= */ - -3, /* (534) partition_by_clause_opt ::= PARTITION BY partition_list */ - -1, /* (535) partition_list ::= partition_item */ - -3, /* (536) partition_list ::= partition_list NK_COMMA partition_item */ - -1, /* (537) partition_item ::= expr_or_subquery */ - -2, /* (538) partition_item ::= expr_or_subquery column_alias */ - -3, /* (539) partition_item ::= expr_or_subquery AS column_alias */ - 0, /* (540) twindow_clause_opt ::= */ - -6, /* (541) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ - -4, /* (542) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ - -6, /* (543) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - -8, /* (544) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - -7, /* (545) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ - 0, /* (546) sliding_opt ::= */ - -4, /* (547) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - 0, /* (548) fill_opt ::= */ - -4, /* (549) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - -6, /* (550) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ - -6, /* (551) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ - -1, /* (552) fill_mode ::= NONE */ - -1, /* (553) fill_mode ::= PREV */ - -1, /* (554) fill_mode ::= NULL */ - -1, /* (555) fill_mode ::= NULL_F */ - -1, /* (556) fill_mode ::= LINEAR */ - -1, /* (557) fill_mode ::= NEXT */ - 0, /* (558) group_by_clause_opt ::= */ - -3, /* (559) group_by_clause_opt ::= GROUP BY group_by_list */ - -1, /* (560) group_by_list ::= expr_or_subquery */ - -3, /* (561) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ - 0, /* (562) having_clause_opt ::= */ - -2, /* (563) having_clause_opt ::= HAVING search_condition */ - 0, /* (564) range_opt ::= */ - -6, /* (565) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ - -4, /* (566) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ - 0, /* (567) every_opt ::= */ - -4, /* (568) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - -4, /* (569) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ - -1, /* (570) query_simple ::= query_specification */ - -1, /* (571) query_simple ::= union_query_expression */ - -4, /* (572) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ - -3, /* (573) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ - -1, /* (574) query_simple_or_subquery ::= query_simple */ - -1, /* (575) query_simple_or_subquery ::= subquery */ - -1, /* (576) query_or_subquery ::= query_expression */ - -1, /* (577) query_or_subquery ::= subquery */ - 0, /* (578) order_by_clause_opt ::= */ - -3, /* (579) order_by_clause_opt ::= ORDER BY sort_specification_list */ - 0, /* (580) slimit_clause_opt ::= */ - -2, /* (581) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - -4, /* (582) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - -4, /* (583) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - 0, /* (584) limit_clause_opt ::= */ - -2, /* (585) limit_clause_opt ::= LIMIT NK_INTEGER */ - -4, /* (586) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - -4, /* (587) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - -3, /* (588) subquery ::= NK_LP query_expression NK_RP */ - -3, /* (589) subquery ::= NK_LP subquery NK_RP */ - -1, /* (590) search_condition ::= common_expression */ - -1, /* (591) sort_specification_list ::= sort_specification */ - -3, /* (592) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - -3, /* (593) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ - 0, /* (594) ordering_specification_opt ::= */ - -1, /* (595) ordering_specification_opt ::= ASC */ - -1, /* (596) ordering_specification_opt ::= DESC */ - 0, /* (597) null_ordering_opt ::= */ - -2, /* (598) null_ordering_opt ::= NULLS FIRST */ - -2, /* (599) null_ordering_opt ::= NULLS LAST */ + -4, /* (182) column_def ::= column_name type_name COMMENT NK_STRING */ + -1, /* (183) type_name ::= BOOL */ + -1, /* (184) type_name ::= TINYINT */ + -1, /* (185) type_name ::= SMALLINT */ + -1, /* (186) type_name ::= INT */ + -1, /* (187) type_name ::= INTEGER */ + -1, /* (188) type_name ::= BIGINT */ + -1, /* (189) type_name ::= FLOAT */ + -1, /* (190) type_name ::= DOUBLE */ + -4, /* (191) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + -1, /* (192) type_name ::= TIMESTAMP */ + -4, /* (193) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + -2, /* (194) type_name ::= TINYINT UNSIGNED */ + -2, /* (195) type_name ::= SMALLINT UNSIGNED */ + -2, /* (196) type_name ::= INT UNSIGNED */ + -2, /* (197) type_name ::= BIGINT UNSIGNED */ + -1, /* (198) type_name ::= JSON */ + -4, /* (199) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + -1, /* (200) type_name ::= MEDIUMBLOB */ + -1, /* (201) type_name ::= BLOB */ + -4, /* (202) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + -4, /* (203) type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ + -1, /* (204) type_name ::= DECIMAL */ + -4, /* (205) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + -6, /* (206) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + 0, /* (207) tags_def_opt ::= */ + -1, /* (208) tags_def_opt ::= tags_def */ + -4, /* (209) tags_def ::= TAGS NK_LP column_def_list NK_RP */ + 0, /* (210) table_options ::= */ + -3, /* (211) table_options ::= table_options COMMENT NK_STRING */ + -3, /* (212) table_options ::= table_options MAX_DELAY duration_list */ + -3, /* (213) table_options ::= table_options WATERMARK duration_list */ + -5, /* (214) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ + -3, /* (215) table_options ::= table_options TTL NK_INTEGER */ + -5, /* (216) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + -3, /* (217) table_options ::= table_options DELETE_MARK duration_list */ + -1, /* (218) alter_table_options ::= alter_table_option */ + -2, /* (219) alter_table_options ::= alter_table_options alter_table_option */ + -2, /* (220) alter_table_option ::= COMMENT NK_STRING */ + -2, /* (221) alter_table_option ::= TTL NK_INTEGER */ + -1, /* (222) duration_list ::= duration_literal */ + -3, /* (223) duration_list ::= duration_list NK_COMMA duration_literal */ + -1, /* (224) rollup_func_list ::= rollup_func_name */ + -3, /* (225) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ + -1, /* (226) rollup_func_name ::= function_name */ + -1, /* (227) rollup_func_name ::= FIRST */ + -1, /* (228) rollup_func_name ::= LAST */ + -1, /* (229) col_name_list ::= col_name */ + -3, /* (230) col_name_list ::= col_name_list NK_COMMA col_name */ + -1, /* (231) col_name ::= column_name */ + -2, /* (232) cmd ::= SHOW DNODES */ + -2, /* (233) cmd ::= SHOW USERS */ + -3, /* (234) cmd ::= SHOW USER PRIVILEGES */ + -2, /* (235) cmd ::= SHOW DATABASES */ + -4, /* (236) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ + -4, /* (237) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ + -3, /* (238) cmd ::= SHOW db_name_cond_opt VGROUPS */ + -2, /* (239) cmd ::= SHOW MNODES */ + -2, /* (240) cmd ::= SHOW QNODES */ + -2, /* (241) cmd ::= SHOW FUNCTIONS */ + -5, /* (242) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ + -6, /* (243) cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ + -2, /* (244) cmd ::= SHOW STREAMS */ + -2, /* (245) cmd ::= SHOW ACCOUNTS */ + -2, /* (246) cmd ::= SHOW APPS */ + -2, /* (247) cmd ::= SHOW CONNECTIONS */ + -2, /* (248) cmd ::= SHOW LICENCES */ + -2, /* (249) cmd ::= SHOW GRANTS */ + -4, /* (250) cmd ::= SHOW CREATE DATABASE db_name */ + -4, /* (251) cmd ::= SHOW CREATE TABLE full_table_name */ + -4, /* (252) cmd ::= SHOW CREATE STABLE full_table_name */ + -2, /* (253) cmd ::= SHOW QUERIES */ + -2, /* (254) cmd ::= SHOW SCORES */ + -2, /* (255) cmd ::= SHOW TOPICS */ + -2, /* (256) cmd ::= SHOW VARIABLES */ + -3, /* (257) cmd ::= SHOW CLUSTER VARIABLES */ + -3, /* (258) cmd ::= SHOW LOCAL VARIABLES */ + -5, /* (259) cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ + -2, /* (260) cmd ::= SHOW BNODES */ + -2, /* (261) cmd ::= SHOW SNODES */ + -2, /* (262) cmd ::= SHOW CLUSTER */ + -2, /* (263) cmd ::= SHOW TRANSACTIONS */ + -4, /* (264) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + -2, /* (265) cmd ::= SHOW CONSUMERS */ + -2, /* (266) cmd ::= SHOW SUBSCRIPTIONS */ + -5, /* (267) cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ + -6, /* (268) cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ + -7, /* (269) cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ + -8, /* (270) cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ + -5, /* (271) cmd ::= SHOW VNODES ON DNODE NK_INTEGER */ + -2, /* (272) cmd ::= SHOW VNODES */ + -3, /* (273) cmd ::= SHOW db_name_cond_opt ALIVE */ + -3, /* (274) cmd ::= SHOW CLUSTER ALIVE */ + 0, /* (275) db_name_cond_opt ::= */ + -2, /* (276) db_name_cond_opt ::= db_name NK_DOT */ + 0, /* (277) like_pattern_opt ::= */ + -2, /* (278) like_pattern_opt ::= LIKE NK_STRING */ + -1, /* (279) table_name_cond ::= table_name */ + 0, /* (280) from_db_opt ::= */ + -2, /* (281) from_db_opt ::= FROM db_name */ + 0, /* (282) tag_list_opt ::= */ + -1, /* (283) tag_list_opt ::= tag_item */ + -3, /* (284) tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ + -1, /* (285) tag_item ::= TBNAME */ + -1, /* (286) tag_item ::= QTAGS */ + -1, /* (287) tag_item ::= column_name */ + -2, /* (288) tag_item ::= column_name column_alias */ + -3, /* (289) tag_item ::= column_name AS column_alias */ + -8, /* (290) cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ + -9, /* (291) cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ + -4, /* (292) cmd ::= DROP INDEX exists_opt full_index_name */ + -1, /* (293) full_index_name ::= index_name */ + -3, /* (294) full_index_name ::= db_name NK_DOT index_name */ + -10, /* (295) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ + -12, /* (296) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ + -1, /* (297) func_list ::= func */ + -3, /* (298) func_list ::= func_list NK_COMMA func */ + -4, /* (299) func ::= sma_func_name NK_LP expression_list NK_RP */ + -1, /* (300) sma_func_name ::= function_name */ + -1, /* (301) sma_func_name ::= COUNT */ + -1, /* (302) sma_func_name ::= FIRST */ + -1, /* (303) sma_func_name ::= LAST */ + -1, /* (304) sma_func_name ::= LAST_ROW */ + 0, /* (305) sma_stream_opt ::= */ + -3, /* (306) sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ + -3, /* (307) sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ + -3, /* (308) sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ + -1, /* (309) with_meta ::= AS */ + -3, /* (310) with_meta ::= WITH META AS */ + -3, /* (311) with_meta ::= ONLY META AS */ + -6, /* (312) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ + -7, /* (313) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ + -8, /* (314) cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ + -4, /* (315) cmd ::= DROP TOPIC exists_opt topic_name */ + -7, /* (316) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + -2, /* (317) cmd ::= DESC full_table_name */ + -2, /* (318) cmd ::= DESCRIBE full_table_name */ + -3, /* (319) cmd ::= RESET QUERY CACHE */ + -4, /* (320) cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + -4, /* (321) cmd ::= EXPLAIN analyze_opt explain_options insert_query */ + 0, /* (322) analyze_opt ::= */ + -1, /* (323) analyze_opt ::= ANALYZE */ + 0, /* (324) explain_options ::= */ + -3, /* (325) explain_options ::= explain_options VERBOSE NK_BOOL */ + -3, /* (326) explain_options ::= explain_options RATIO NK_FLOAT */ + -12, /* (327) cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ + -4, /* (328) cmd ::= DROP FUNCTION exists_opt function_name */ + 0, /* (329) agg_func_opt ::= */ + -1, /* (330) agg_func_opt ::= AGGREGATE */ + 0, /* (331) bufsize_opt ::= */ + -2, /* (332) bufsize_opt ::= BUFSIZE NK_INTEGER */ + 0, /* (333) language_opt ::= */ + -2, /* (334) language_opt ::= LANGUAGE NK_STRING */ + 0, /* (335) or_replace_opt ::= */ + -2, /* (336) or_replace_opt ::= OR REPLACE */ + -12, /* (337) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ + -4, /* (338) cmd ::= DROP STREAM exists_opt stream_name */ + -4, /* (339) cmd ::= PAUSE STREAM exists_opt stream_name */ + -5, /* (340) cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ + 0, /* (341) col_list_opt ::= */ + -3, /* (342) col_list_opt ::= NK_LP col_name_list NK_RP */ + 0, /* (343) tag_def_or_ref_opt ::= */ + -1, /* (344) tag_def_or_ref_opt ::= tags_def */ + -4, /* (345) tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ + 0, /* (346) stream_options ::= */ + -3, /* (347) stream_options ::= stream_options TRIGGER AT_ONCE */ + -3, /* (348) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + -4, /* (349) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + -3, /* (350) stream_options ::= stream_options WATERMARK duration_literal */ + -4, /* (351) stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ + -3, /* (352) stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ + -3, /* (353) stream_options ::= stream_options DELETE_MARK duration_literal */ + -4, /* (354) stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ + 0, /* (355) subtable_opt ::= */ + -4, /* (356) subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + 0, /* (357) ignore_opt ::= */ + -2, /* (358) ignore_opt ::= IGNORE UNTREATED */ + -3, /* (359) cmd ::= KILL CONNECTION NK_INTEGER */ + -3, /* (360) cmd ::= KILL QUERY NK_STRING */ + -3, /* (361) cmd ::= KILL TRANSACTION NK_INTEGER */ + -2, /* (362) cmd ::= BALANCE VGROUP */ + -3, /* (363) cmd ::= BALANCE VGROUP LEADER */ + -4, /* (364) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + -4, /* (365) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + -3, /* (366) cmd ::= SPLIT VGROUP NK_INTEGER */ + -2, /* (367) dnode_list ::= DNODE NK_INTEGER */ + -3, /* (368) dnode_list ::= dnode_list DNODE NK_INTEGER */ + -4, /* (369) cmd ::= DELETE FROM full_table_name where_clause_opt */ + -1, /* (370) cmd ::= query_or_subquery */ + -1, /* (371) cmd ::= insert_query */ + -7, /* (372) insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ + -4, /* (373) insert_query ::= INSERT INTO full_table_name query_or_subquery */ + -1, /* (374) literal ::= NK_INTEGER */ + -1, /* (375) literal ::= NK_FLOAT */ + -1, /* (376) literal ::= NK_STRING */ + -1, /* (377) literal ::= NK_BOOL */ + -2, /* (378) literal ::= TIMESTAMP NK_STRING */ + -1, /* (379) literal ::= duration_literal */ + -1, /* (380) literal ::= NULL */ + -1, /* (381) literal ::= NK_QUESTION */ + -1, /* (382) duration_literal ::= NK_VARIABLE */ + -1, /* (383) signed ::= NK_INTEGER */ + -2, /* (384) signed ::= NK_PLUS NK_INTEGER */ + -2, /* (385) signed ::= NK_MINUS NK_INTEGER */ + -1, /* (386) signed ::= NK_FLOAT */ + -2, /* (387) signed ::= NK_PLUS NK_FLOAT */ + -2, /* (388) signed ::= NK_MINUS NK_FLOAT */ + -1, /* (389) signed_literal ::= signed */ + -1, /* (390) signed_literal ::= NK_STRING */ + -1, /* (391) signed_literal ::= NK_BOOL */ + -2, /* (392) signed_literal ::= TIMESTAMP NK_STRING */ + -1, /* (393) signed_literal ::= duration_literal */ + -1, /* (394) signed_literal ::= NULL */ + -1, /* (395) signed_literal ::= literal_func */ + -1, /* (396) signed_literal ::= NK_QUESTION */ + -1, /* (397) literal_list ::= signed_literal */ + -3, /* (398) literal_list ::= literal_list NK_COMMA signed_literal */ + -1, /* (399) db_name ::= NK_ID */ + -1, /* (400) table_name ::= NK_ID */ + -1, /* (401) column_name ::= NK_ID */ + -1, /* (402) function_name ::= NK_ID */ + -1, /* (403) table_alias ::= NK_ID */ + -1, /* (404) column_alias ::= NK_ID */ + -1, /* (405) user_name ::= NK_ID */ + -1, /* (406) topic_name ::= NK_ID */ + -1, /* (407) stream_name ::= NK_ID */ + -1, /* (408) cgroup_name ::= NK_ID */ + -1, /* (409) index_name ::= NK_ID */ + -1, /* (410) expr_or_subquery ::= expression */ + -1, /* (411) expression ::= literal */ + -1, /* (412) expression ::= pseudo_column */ + -1, /* (413) expression ::= column_reference */ + -1, /* (414) expression ::= function_expression */ + -1, /* (415) expression ::= case_when_expression */ + -3, /* (416) expression ::= NK_LP expression NK_RP */ + -2, /* (417) expression ::= NK_PLUS expr_or_subquery */ + -2, /* (418) expression ::= NK_MINUS expr_or_subquery */ + -3, /* (419) expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + -3, /* (420) expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + -3, /* (421) expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + -3, /* (422) expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + -3, /* (423) expression ::= expr_or_subquery NK_REM expr_or_subquery */ + -3, /* (424) expression ::= column_reference NK_ARROW NK_STRING */ + -3, /* (425) expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + -3, /* (426) expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + -1, /* (427) expression_list ::= expr_or_subquery */ + -3, /* (428) expression_list ::= expression_list NK_COMMA expr_or_subquery */ + -1, /* (429) column_reference ::= column_name */ + -3, /* (430) column_reference ::= table_name NK_DOT column_name */ + -1, /* (431) pseudo_column ::= ROWTS */ + -1, /* (432) pseudo_column ::= TBNAME */ + -3, /* (433) pseudo_column ::= table_name NK_DOT TBNAME */ + -1, /* (434) pseudo_column ::= QSTART */ + -1, /* (435) pseudo_column ::= QEND */ + -1, /* (436) pseudo_column ::= QDURATION */ + -1, /* (437) pseudo_column ::= WSTART */ + -1, /* (438) pseudo_column ::= WEND */ + -1, /* (439) pseudo_column ::= WDURATION */ + -1, /* (440) pseudo_column ::= IROWTS */ + -1, /* (441) pseudo_column ::= ISFILLED */ + -1, /* (442) pseudo_column ::= QTAGS */ + -4, /* (443) function_expression ::= function_name NK_LP expression_list NK_RP */ + -4, /* (444) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ + -6, /* (445) function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ + -1, /* (446) function_expression ::= literal_func */ + -3, /* (447) literal_func ::= noarg_func NK_LP NK_RP */ + -1, /* (448) literal_func ::= NOW */ + -1, /* (449) noarg_func ::= NOW */ + -1, /* (450) noarg_func ::= TODAY */ + -1, /* (451) noarg_func ::= TIMEZONE */ + -1, /* (452) noarg_func ::= DATABASE */ + -1, /* (453) noarg_func ::= CLIENT_VERSION */ + -1, /* (454) noarg_func ::= SERVER_VERSION */ + -1, /* (455) noarg_func ::= SERVER_STATUS */ + -1, /* (456) noarg_func ::= CURRENT_USER */ + -1, /* (457) noarg_func ::= USER */ + -1, /* (458) star_func ::= COUNT */ + -1, /* (459) star_func ::= FIRST */ + -1, /* (460) star_func ::= LAST */ + -1, /* (461) star_func ::= LAST_ROW */ + -1, /* (462) star_func_para_list ::= NK_STAR */ + -1, /* (463) star_func_para_list ::= other_para_list */ + -1, /* (464) other_para_list ::= star_func_para */ + -3, /* (465) other_para_list ::= other_para_list NK_COMMA star_func_para */ + -1, /* (466) star_func_para ::= expr_or_subquery */ + -3, /* (467) star_func_para ::= table_name NK_DOT NK_STAR */ + -4, /* (468) case_when_expression ::= CASE when_then_list case_when_else_opt END */ + -5, /* (469) case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ + -1, /* (470) when_then_list ::= when_then_expr */ + -2, /* (471) when_then_list ::= when_then_list when_then_expr */ + -4, /* (472) when_then_expr ::= WHEN common_expression THEN common_expression */ + 0, /* (473) case_when_else_opt ::= */ + -2, /* (474) case_when_else_opt ::= ELSE common_expression */ + -3, /* (475) predicate ::= expr_or_subquery compare_op expr_or_subquery */ + -5, /* (476) predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + -6, /* (477) predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + -3, /* (478) predicate ::= expr_or_subquery IS NULL */ + -4, /* (479) predicate ::= expr_or_subquery IS NOT NULL */ + -3, /* (480) predicate ::= expr_or_subquery in_op in_predicate_value */ + -1, /* (481) compare_op ::= NK_LT */ + -1, /* (482) compare_op ::= NK_GT */ + -1, /* (483) compare_op ::= NK_LE */ + -1, /* (484) compare_op ::= NK_GE */ + -1, /* (485) compare_op ::= NK_NE */ + -1, /* (486) compare_op ::= NK_EQ */ + -1, /* (487) compare_op ::= LIKE */ + -2, /* (488) compare_op ::= NOT LIKE */ + -1, /* (489) compare_op ::= MATCH */ + -1, /* (490) compare_op ::= NMATCH */ + -1, /* (491) compare_op ::= CONTAINS */ + -1, /* (492) in_op ::= IN */ + -2, /* (493) in_op ::= NOT IN */ + -3, /* (494) in_predicate_value ::= NK_LP literal_list NK_RP */ + -1, /* (495) boolean_value_expression ::= boolean_primary */ + -2, /* (496) boolean_value_expression ::= NOT boolean_primary */ + -3, /* (497) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + -3, /* (498) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + -1, /* (499) boolean_primary ::= predicate */ + -3, /* (500) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + -1, /* (501) common_expression ::= expr_or_subquery */ + -1, /* (502) common_expression ::= boolean_value_expression */ + 0, /* (503) from_clause_opt ::= */ + -2, /* (504) from_clause_opt ::= FROM table_reference_list */ + -1, /* (505) table_reference_list ::= table_reference */ + -3, /* (506) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + -1, /* (507) table_reference ::= table_primary */ + -1, /* (508) table_reference ::= joined_table */ + -2, /* (509) table_primary ::= table_name alias_opt */ + -4, /* (510) table_primary ::= db_name NK_DOT table_name alias_opt */ + -2, /* (511) table_primary ::= subquery alias_opt */ + -1, /* (512) table_primary ::= parenthesized_joined_table */ + 0, /* (513) alias_opt ::= */ + -1, /* (514) alias_opt ::= table_alias */ + -2, /* (515) alias_opt ::= AS table_alias */ + -3, /* (516) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + -3, /* (517) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + -6, /* (518) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + 0, /* (519) join_type ::= */ + -1, /* (520) join_type ::= INNER */ + -12, /* (521) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + 0, /* (522) set_quantifier_opt ::= */ + -1, /* (523) set_quantifier_opt ::= DISTINCT */ + -1, /* (524) set_quantifier_opt ::= ALL */ + -1, /* (525) select_list ::= select_item */ + -3, /* (526) select_list ::= select_list NK_COMMA select_item */ + -1, /* (527) select_item ::= NK_STAR */ + -1, /* (528) select_item ::= common_expression */ + -2, /* (529) select_item ::= common_expression column_alias */ + -3, /* (530) select_item ::= common_expression AS column_alias */ + -3, /* (531) select_item ::= table_name NK_DOT NK_STAR */ + 0, /* (532) where_clause_opt ::= */ + -2, /* (533) where_clause_opt ::= WHERE search_condition */ + 0, /* (534) partition_by_clause_opt ::= */ + -3, /* (535) partition_by_clause_opt ::= PARTITION BY partition_list */ + -1, /* (536) partition_list ::= partition_item */ + -3, /* (537) partition_list ::= partition_list NK_COMMA partition_item */ + -1, /* (538) partition_item ::= expr_or_subquery */ + -2, /* (539) partition_item ::= expr_or_subquery column_alias */ + -3, /* (540) partition_item ::= expr_or_subquery AS column_alias */ + 0, /* (541) twindow_clause_opt ::= */ + -6, /* (542) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + -4, /* (543) twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ + -6, /* (544) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + -8, /* (545) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + -7, /* (546) twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ + 0, /* (547) sliding_opt ::= */ + -4, /* (548) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + 0, /* (549) fill_opt ::= */ + -4, /* (550) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + -6, /* (551) fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ + -6, /* (552) fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ + -1, /* (553) fill_mode ::= NONE */ + -1, /* (554) fill_mode ::= PREV */ + -1, /* (555) fill_mode ::= NULL */ + -1, /* (556) fill_mode ::= NULL_F */ + -1, /* (557) fill_mode ::= LINEAR */ + -1, /* (558) fill_mode ::= NEXT */ + 0, /* (559) group_by_clause_opt ::= */ + -3, /* (560) group_by_clause_opt ::= GROUP BY group_by_list */ + -1, /* (561) group_by_list ::= expr_or_subquery */ + -3, /* (562) group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ + 0, /* (563) having_clause_opt ::= */ + -2, /* (564) having_clause_opt ::= HAVING search_condition */ + 0, /* (565) range_opt ::= */ + -6, /* (566) range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ + -4, /* (567) range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ + 0, /* (568) every_opt ::= */ + -4, /* (569) every_opt ::= EVERY NK_LP duration_literal NK_RP */ + -4, /* (570) query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + -1, /* (571) query_simple ::= query_specification */ + -1, /* (572) query_simple ::= union_query_expression */ + -4, /* (573) union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ + -3, /* (574) union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ + -1, /* (575) query_simple_or_subquery ::= query_simple */ + -1, /* (576) query_simple_or_subquery ::= subquery */ + -1, /* (577) query_or_subquery ::= query_expression */ + -1, /* (578) query_or_subquery ::= subquery */ + 0, /* (579) order_by_clause_opt ::= */ + -3, /* (580) order_by_clause_opt ::= ORDER BY sort_specification_list */ + 0, /* (581) slimit_clause_opt ::= */ + -2, /* (582) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + -4, /* (583) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + -4, /* (584) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + 0, /* (585) limit_clause_opt ::= */ + -2, /* (586) limit_clause_opt ::= LIMIT NK_INTEGER */ + -4, /* (587) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + -4, /* (588) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + -3, /* (589) subquery ::= NK_LP query_expression NK_RP */ + -3, /* (590) subquery ::= NK_LP subquery NK_RP */ + -1, /* (591) search_condition ::= common_expression */ + -1, /* (592) sort_specification_list ::= sort_specification */ + -3, /* (593) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + -3, /* (594) sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ + 0, /* (595) ordering_specification_opt ::= */ + -1, /* (596) ordering_specification_opt ::= ASC */ + -1, /* (597) ordering_specification_opt ::= DESC */ + 0, /* (598) null_ordering_opt ::= */ + -2, /* (599) null_ordering_opt ::= NULLS FIRST */ + -2, /* (600) null_ordering_opt ::= NULLS LAST */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -4813,19 +4849,19 @@ static YYACTIONTYPE yy_reduce( case 0: /* cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ #line 50 "sql.y" { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } -#line 4816 "sql.c" +#line 4852 "sql.c" yy_destructor(yypParser,339,&yymsp[0].minor); break; case 1: /* cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ #line 51 "sql.y" { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } -#line 4822 "sql.c" +#line 4858 "sql.c" yy_destructor(yypParser,340,&yymsp[0].minor); break; case 2: /* account_options ::= */ #line 55 "sql.y" { } -#line 4828 "sql.c" +#line 4864 "sql.c" break; case 3: /* account_options ::= account_options PPS literal */ case 4: /* account_options ::= account_options TSERIES literal */ yytestcase(yyruleno==4); @@ -4839,7 +4875,7 @@ static YYACTIONTYPE yy_reduce( { yy_destructor(yypParser,339,&yymsp[-2].minor); #line 56 "sql.y" { } -#line 4842 "sql.c" +#line 4878 "sql.c" yy_destructor(yypParser,341,&yymsp[0].minor); } break; @@ -4847,14 +4883,14 @@ static YYACTIONTYPE yy_reduce( { yy_destructor(yypParser,342,&yymsp[0].minor); #line 68 "sql.y" { } -#line 4850 "sql.c" +#line 4886 "sql.c" } break; case 13: /* alter_account_options ::= alter_account_options alter_account_option */ { yy_destructor(yypParser,340,&yymsp[-1].minor); #line 69 "sql.y" { } -#line 4857 "sql.c" +#line 4893 "sql.c" yy_destructor(yypParser,342,&yymsp[0].minor); } break; @@ -4870,488 +4906,488 @@ static YYACTIONTYPE yy_reduce( case 23: /* alter_account_option ::= STATE literal */ yytestcase(yyruleno==23); #line 73 "sql.y" { } -#line 4873 "sql.c" +#line 4909 "sql.c" yy_destructor(yypParser,341,&yymsp[0].minor); break; case 24: /* cmd ::= CREATE USER user_name PASS NK_STRING sysinfo_opt */ #line 85 "sql.y" { pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-3].minor.yy371, &yymsp[-1].minor.yy0, yymsp[0].minor.yy475); } -#line 4879 "sql.c" +#line 4915 "sql.c" break; case 25: /* cmd ::= ALTER USER user_name PASS NK_STRING */ #line 86 "sql.y" { pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy371, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); } -#line 4884 "sql.c" +#line 4920 "sql.c" break; case 26: /* cmd ::= ALTER USER user_name ENABLE NK_INTEGER */ #line 87 "sql.y" { pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy371, TSDB_ALTER_USER_ENABLE, &yymsp[0].minor.yy0); } -#line 4889 "sql.c" +#line 4925 "sql.c" break; case 27: /* cmd ::= ALTER USER user_name SYSINFO NK_INTEGER */ #line 88 "sql.y" { pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy371, TSDB_ALTER_USER_SYSINFO, &yymsp[0].minor.yy0); } -#line 4894 "sql.c" +#line 4930 "sql.c" break; case 28: /* cmd ::= DROP USER user_name */ #line 89 "sql.y" { pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy371); } -#line 4899 "sql.c" +#line 4935 "sql.c" break; case 29: /* sysinfo_opt ::= */ #line 93 "sql.y" { yymsp[1].minor.yy475 = 1; } -#line 4904 "sql.c" +#line 4940 "sql.c" break; case 30: /* sysinfo_opt ::= SYSINFO NK_INTEGER */ #line 94 "sql.y" { yymsp[-1].minor.yy475 = taosStr2Int8(yymsp[0].minor.yy0.z, NULL, 10); } -#line 4909 "sql.c" +#line 4945 "sql.c" break; case 31: /* cmd ::= GRANT privileges ON priv_level with_opt TO user_name */ #line 97 "sql.y" { pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-5].minor.yy729, &yymsp[-3].minor.yy347, &yymsp[0].minor.yy371, yymsp[-2].minor.yy452); } -#line 4914 "sql.c" +#line 4950 "sql.c" break; case 32: /* cmd ::= REVOKE privileges ON priv_level with_opt FROM user_name */ #line 98 "sql.y" { pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-5].minor.yy729, &yymsp[-3].minor.yy347, &yymsp[0].minor.yy371, yymsp[-2].minor.yy452); } -#line 4919 "sql.c" +#line 4955 "sql.c" break; case 33: /* privileges ::= ALL */ #line 102 "sql.y" { yymsp[0].minor.yy729 = PRIVILEGE_TYPE_ALL; } -#line 4924 "sql.c" +#line 4960 "sql.c" break; case 34: /* privileges ::= priv_type_list */ case 36: /* priv_type_list ::= priv_type */ yytestcase(yyruleno==36); #line 103 "sql.y" { yylhsminor.yy729 = yymsp[0].minor.yy729; } -#line 4930 "sql.c" +#line 4966 "sql.c" yymsp[0].minor.yy729 = yylhsminor.yy729; break; case 35: /* privileges ::= SUBSCRIBE */ #line 104 "sql.y" { yymsp[0].minor.yy729 = PRIVILEGE_TYPE_SUBSCRIBE; } -#line 4936 "sql.c" +#line 4972 "sql.c" break; case 37: /* priv_type_list ::= priv_type_list NK_COMMA priv_type */ #line 109 "sql.y" { yylhsminor.yy729 = yymsp[-2].minor.yy729 | yymsp[0].minor.yy729; } -#line 4941 "sql.c" +#line 4977 "sql.c" yymsp[-2].minor.yy729 = yylhsminor.yy729; break; case 38: /* priv_type ::= READ */ #line 113 "sql.y" { yymsp[0].minor.yy729 = PRIVILEGE_TYPE_READ; } -#line 4947 "sql.c" +#line 4983 "sql.c" break; case 39: /* priv_type ::= WRITE */ #line 114 "sql.y" { yymsp[0].minor.yy729 = PRIVILEGE_TYPE_WRITE; } -#line 4952 "sql.c" +#line 4988 "sql.c" break; case 40: /* priv_level ::= NK_STAR NK_DOT NK_STAR */ #line 118 "sql.y" { yylhsminor.yy347.first = yymsp[-2].minor.yy0; yylhsminor.yy347.second = yymsp[0].minor.yy0; } -#line 4957 "sql.c" +#line 4993 "sql.c" yymsp[-2].minor.yy347 = yylhsminor.yy347; break; case 41: /* priv_level ::= db_name NK_DOT NK_STAR */ #line 119 "sql.y" { yylhsminor.yy347.first = yymsp[-2].minor.yy371; yylhsminor.yy347.second = yymsp[0].minor.yy0; } -#line 4963 "sql.c" +#line 4999 "sql.c" yymsp[-2].minor.yy347 = yylhsminor.yy347; break; case 42: /* priv_level ::= db_name NK_DOT table_name */ #line 120 "sql.y" { yylhsminor.yy347.first = yymsp[-2].minor.yy371; yylhsminor.yy347.second = yymsp[0].minor.yy371; } -#line 4969 "sql.c" +#line 5005 "sql.c" yymsp[-2].minor.yy347 = yylhsminor.yy347; break; case 43: /* priv_level ::= topic_name */ #line 121 "sql.y" { yylhsminor.yy347.first = yymsp[0].minor.yy371; yylhsminor.yy347.second = nil_token; } -#line 4975 "sql.c" +#line 5011 "sql.c" yymsp[0].minor.yy347 = yylhsminor.yy347; break; case 44: /* with_opt ::= */ case 144: /* start_opt ::= */ yytestcase(yyruleno==144); case 148: /* end_opt ::= */ yytestcase(yyruleno==148); - case 276: /* like_pattern_opt ::= */ yytestcase(yyruleno==276); - case 354: /* subtable_opt ::= */ yytestcase(yyruleno==354); - case 472: /* case_when_else_opt ::= */ yytestcase(yyruleno==472); - case 502: /* from_clause_opt ::= */ yytestcase(yyruleno==502); - case 531: /* where_clause_opt ::= */ yytestcase(yyruleno==531); - case 540: /* twindow_clause_opt ::= */ yytestcase(yyruleno==540); - case 546: /* sliding_opt ::= */ yytestcase(yyruleno==546); - case 548: /* fill_opt ::= */ yytestcase(yyruleno==548); - case 562: /* having_clause_opt ::= */ yytestcase(yyruleno==562); - case 564: /* range_opt ::= */ yytestcase(yyruleno==564); - case 567: /* every_opt ::= */ yytestcase(yyruleno==567); - case 580: /* slimit_clause_opt ::= */ yytestcase(yyruleno==580); - case 584: /* limit_clause_opt ::= */ yytestcase(yyruleno==584); + case 277: /* like_pattern_opt ::= */ yytestcase(yyruleno==277); + case 355: /* subtable_opt ::= */ yytestcase(yyruleno==355); + case 473: /* case_when_else_opt ::= */ yytestcase(yyruleno==473); + case 503: /* from_clause_opt ::= */ yytestcase(yyruleno==503); + case 532: /* where_clause_opt ::= */ yytestcase(yyruleno==532); + case 541: /* twindow_clause_opt ::= */ yytestcase(yyruleno==541); + case 547: /* sliding_opt ::= */ yytestcase(yyruleno==547); + case 549: /* fill_opt ::= */ yytestcase(yyruleno==549); + case 563: /* having_clause_opt ::= */ yytestcase(yyruleno==563); + case 565: /* range_opt ::= */ yytestcase(yyruleno==565); + case 568: /* every_opt ::= */ yytestcase(yyruleno==568); + case 581: /* slimit_clause_opt ::= */ yytestcase(yyruleno==581); + case 585: /* limit_clause_opt ::= */ yytestcase(yyruleno==585); #line 123 "sql.y" { yymsp[1].minor.yy452 = NULL; } -#line 4996 "sql.c" +#line 5032 "sql.c" break; case 45: /* with_opt ::= WITH search_condition */ - case 503: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==503); - case 532: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==532); - case 563: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==563); + case 504: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==504); + case 533: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==533); + case 564: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==564); #line 124 "sql.y" { yymsp[-1].minor.yy452 = yymsp[0].minor.yy452; } -#line 5004 "sql.c" +#line 5040 "sql.c" break; case 46: /* cmd ::= CREATE DNODE dnode_endpoint */ #line 127 "sql.y" { pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy371, NULL); } -#line 5009 "sql.c" +#line 5045 "sql.c" break; case 47: /* cmd ::= CREATE DNODE dnode_endpoint PORT NK_INTEGER */ #line 128 "sql.y" { pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0); } -#line 5014 "sql.c" +#line 5050 "sql.c" break; case 48: /* cmd ::= DROP DNODE NK_INTEGER force_opt */ #line 129 "sql.y" { pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy667, false); } -#line 5019 "sql.c" +#line 5055 "sql.c" break; case 49: /* cmd ::= DROP DNODE dnode_endpoint force_opt */ #line 130 "sql.y" { pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy667, false); } -#line 5024 "sql.c" +#line 5060 "sql.c" break; case 50: /* cmd ::= DROP DNODE NK_INTEGER unsafe_opt */ #line 131 "sql.y" { pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy0, false, yymsp[0].minor.yy667); } -#line 5029 "sql.c" +#line 5065 "sql.c" break; case 51: /* cmd ::= DROP DNODE dnode_endpoint unsafe_opt */ #line 132 "sql.y" { pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[-1].minor.yy371, false, yymsp[0].minor.yy667); } -#line 5034 "sql.c" +#line 5070 "sql.c" break; case 52: /* cmd ::= ALTER DNODE NK_INTEGER NK_STRING */ #line 133 "sql.y" { pCxt->pRootNode = createAlterDnodeStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, NULL); } -#line 5039 "sql.c" +#line 5075 "sql.c" break; case 53: /* cmd ::= ALTER DNODE NK_INTEGER NK_STRING NK_STRING */ #line 134 "sql.y" { pCxt->pRootNode = createAlterDnodeStmt(pCxt, &yymsp[-2].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } -#line 5044 "sql.c" +#line 5080 "sql.c" break; case 54: /* cmd ::= ALTER ALL DNODES NK_STRING */ #line 135 "sql.y" { pCxt->pRootNode = createAlterDnodeStmt(pCxt, NULL, &yymsp[0].minor.yy0, NULL); } -#line 5049 "sql.c" +#line 5085 "sql.c" break; case 55: /* cmd ::= ALTER ALL DNODES NK_STRING NK_STRING */ #line 136 "sql.y" { pCxt->pRootNode = createAlterDnodeStmt(pCxt, NULL, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } -#line 5054 "sql.c" +#line 5090 "sql.c" break; case 56: /* cmd ::= RESTORE DNODE NK_INTEGER */ #line 137 "sql.y" { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_DNODE_STMT, &yymsp[0].minor.yy0); } -#line 5059 "sql.c" +#line 5095 "sql.c" break; case 57: /* dnode_endpoint ::= NK_STRING */ case 58: /* dnode_endpoint ::= NK_ID */ yytestcase(yyruleno==58); case 59: /* dnode_endpoint ::= NK_IPTOKEN */ yytestcase(yyruleno==59); - case 300: /* sma_func_name ::= COUNT */ yytestcase(yyruleno==300); - case 301: /* sma_func_name ::= FIRST */ yytestcase(yyruleno==301); - case 302: /* sma_func_name ::= LAST */ yytestcase(yyruleno==302); - case 303: /* sma_func_name ::= LAST_ROW */ yytestcase(yyruleno==303); - case 398: /* db_name ::= NK_ID */ yytestcase(yyruleno==398); - case 399: /* table_name ::= NK_ID */ yytestcase(yyruleno==399); - case 400: /* column_name ::= NK_ID */ yytestcase(yyruleno==400); - case 401: /* function_name ::= NK_ID */ yytestcase(yyruleno==401); - case 402: /* table_alias ::= NK_ID */ yytestcase(yyruleno==402); - case 403: /* column_alias ::= NK_ID */ yytestcase(yyruleno==403); - case 404: /* user_name ::= NK_ID */ yytestcase(yyruleno==404); - case 405: /* topic_name ::= NK_ID */ yytestcase(yyruleno==405); - case 406: /* stream_name ::= NK_ID */ yytestcase(yyruleno==406); - case 407: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==407); - case 408: /* index_name ::= NK_ID */ yytestcase(yyruleno==408); - case 448: /* noarg_func ::= NOW */ yytestcase(yyruleno==448); - case 449: /* noarg_func ::= TODAY */ yytestcase(yyruleno==449); - case 450: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==450); - case 451: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==451); - case 452: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==452); - case 453: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==453); - case 454: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==454); - case 455: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==455); - case 456: /* noarg_func ::= USER */ yytestcase(yyruleno==456); - case 457: /* star_func ::= COUNT */ yytestcase(yyruleno==457); - case 458: /* star_func ::= FIRST */ yytestcase(yyruleno==458); - case 459: /* star_func ::= LAST */ yytestcase(yyruleno==459); - case 460: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==460); + case 301: /* sma_func_name ::= COUNT */ yytestcase(yyruleno==301); + case 302: /* sma_func_name ::= FIRST */ yytestcase(yyruleno==302); + case 303: /* sma_func_name ::= LAST */ yytestcase(yyruleno==303); + case 304: /* sma_func_name ::= LAST_ROW */ yytestcase(yyruleno==304); + case 399: /* db_name ::= NK_ID */ yytestcase(yyruleno==399); + case 400: /* table_name ::= NK_ID */ yytestcase(yyruleno==400); + case 401: /* column_name ::= NK_ID */ yytestcase(yyruleno==401); + case 402: /* function_name ::= NK_ID */ yytestcase(yyruleno==402); + case 403: /* table_alias ::= NK_ID */ yytestcase(yyruleno==403); + case 404: /* column_alias ::= NK_ID */ yytestcase(yyruleno==404); + case 405: /* user_name ::= NK_ID */ yytestcase(yyruleno==405); + case 406: /* topic_name ::= NK_ID */ yytestcase(yyruleno==406); + case 407: /* stream_name ::= NK_ID */ yytestcase(yyruleno==407); + case 408: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==408); + case 409: /* index_name ::= NK_ID */ yytestcase(yyruleno==409); + case 449: /* noarg_func ::= NOW */ yytestcase(yyruleno==449); + case 450: /* noarg_func ::= TODAY */ yytestcase(yyruleno==450); + case 451: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==451); + case 452: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==452); + case 453: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==453); + case 454: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==454); + case 455: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==455); + case 456: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==456); + case 457: /* noarg_func ::= USER */ yytestcase(yyruleno==457); + case 458: /* star_func ::= COUNT */ yytestcase(yyruleno==458); + case 459: /* star_func ::= FIRST */ yytestcase(yyruleno==459); + case 460: /* star_func ::= LAST */ yytestcase(yyruleno==460); + case 461: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==461); #line 141 "sql.y" { yylhsminor.yy371 = yymsp[0].minor.yy0; } -#line 5094 "sql.c" +#line 5130 "sql.c" yymsp[0].minor.yy371 = yylhsminor.yy371; break; case 60: /* force_opt ::= */ case 84: /* not_exists_opt ::= */ yytestcase(yyruleno==84); case 86: /* exists_opt ::= */ yytestcase(yyruleno==86); - case 321: /* analyze_opt ::= */ yytestcase(yyruleno==321); - case 328: /* agg_func_opt ::= */ yytestcase(yyruleno==328); - case 334: /* or_replace_opt ::= */ yytestcase(yyruleno==334); - case 356: /* ignore_opt ::= */ yytestcase(yyruleno==356); - case 521: /* set_quantifier_opt ::= */ yytestcase(yyruleno==521); + case 322: /* analyze_opt ::= */ yytestcase(yyruleno==322); + case 329: /* agg_func_opt ::= */ yytestcase(yyruleno==329); + case 335: /* or_replace_opt ::= */ yytestcase(yyruleno==335); + case 357: /* ignore_opt ::= */ yytestcase(yyruleno==357); + case 522: /* set_quantifier_opt ::= */ yytestcase(yyruleno==522); #line 147 "sql.y" { yymsp[1].minor.yy667 = false; } -#line 5107 "sql.c" +#line 5143 "sql.c" break; case 61: /* force_opt ::= FORCE */ case 62: /* unsafe_opt ::= UNSAFE */ yytestcase(yyruleno==62); - case 322: /* analyze_opt ::= ANALYZE */ yytestcase(yyruleno==322); - case 329: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==329); - case 522: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==522); + case 323: /* analyze_opt ::= ANALYZE */ yytestcase(yyruleno==323); + case 330: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==330); + case 523: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==523); #line 148 "sql.y" { yymsp[0].minor.yy667 = true; } -#line 5116 "sql.c" +#line 5152 "sql.c" break; case 63: /* cmd ::= ALTER LOCAL NK_STRING */ #line 155 "sql.y" { pCxt->pRootNode = createAlterLocalStmt(pCxt, &yymsp[0].minor.yy0, NULL); } -#line 5121 "sql.c" +#line 5157 "sql.c" break; case 64: /* cmd ::= ALTER LOCAL NK_STRING NK_STRING */ #line 156 "sql.y" { pCxt->pRootNode = createAlterLocalStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } -#line 5126 "sql.c" +#line 5162 "sql.c" break; case 65: /* cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ #line 159 "sql.y" { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_QNODE_STMT, &yymsp[0].minor.yy0); } -#line 5131 "sql.c" +#line 5167 "sql.c" break; case 66: /* cmd ::= DROP QNODE ON DNODE NK_INTEGER */ #line 160 "sql.y" { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_QNODE_STMT, &yymsp[0].minor.yy0); } -#line 5136 "sql.c" +#line 5172 "sql.c" break; case 67: /* cmd ::= RESTORE QNODE ON DNODE NK_INTEGER */ #line 161 "sql.y" { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_QNODE_STMT, &yymsp[0].minor.yy0); } -#line 5141 "sql.c" +#line 5177 "sql.c" break; case 68: /* cmd ::= CREATE BNODE ON DNODE NK_INTEGER */ #line 164 "sql.y" { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_BNODE_STMT, &yymsp[0].minor.yy0); } -#line 5146 "sql.c" +#line 5182 "sql.c" break; case 69: /* cmd ::= DROP BNODE ON DNODE NK_INTEGER */ #line 165 "sql.y" { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_BNODE_STMT, &yymsp[0].minor.yy0); } -#line 5151 "sql.c" +#line 5187 "sql.c" break; case 70: /* cmd ::= CREATE SNODE ON DNODE NK_INTEGER */ #line 168 "sql.y" { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_SNODE_STMT, &yymsp[0].minor.yy0); } -#line 5156 "sql.c" +#line 5192 "sql.c" break; case 71: /* cmd ::= DROP SNODE ON DNODE NK_INTEGER */ #line 169 "sql.y" { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_SNODE_STMT, &yymsp[0].minor.yy0); } -#line 5161 "sql.c" +#line 5197 "sql.c" break; case 72: /* cmd ::= CREATE MNODE ON DNODE NK_INTEGER */ #line 172 "sql.y" { pCxt->pRootNode = createCreateComponentNodeStmt(pCxt, QUERY_NODE_CREATE_MNODE_STMT, &yymsp[0].minor.yy0); } -#line 5166 "sql.c" +#line 5202 "sql.c" break; case 73: /* cmd ::= DROP MNODE ON DNODE NK_INTEGER */ #line 173 "sql.y" { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_MNODE_STMT, &yymsp[0].minor.yy0); } -#line 5171 "sql.c" +#line 5207 "sql.c" break; case 74: /* cmd ::= RESTORE MNODE ON DNODE NK_INTEGER */ #line 174 "sql.y" { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_MNODE_STMT, &yymsp[0].minor.yy0); } -#line 5176 "sql.c" +#line 5212 "sql.c" break; case 75: /* cmd ::= RESTORE VNODE ON DNODE NK_INTEGER */ #line 177 "sql.y" { pCxt->pRootNode = createRestoreComponentNodeStmt(pCxt, QUERY_NODE_RESTORE_VNODE_STMT, &yymsp[0].minor.yy0); } -#line 5181 "sql.c" +#line 5217 "sql.c" break; case 76: /* cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ #line 180 "sql.y" { pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy667, &yymsp[-1].minor.yy371, yymsp[0].minor.yy452); } -#line 5186 "sql.c" +#line 5222 "sql.c" break; case 77: /* cmd ::= DROP DATABASE exists_opt db_name */ #line 181 "sql.y" { pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } -#line 5191 "sql.c" +#line 5227 "sql.c" break; case 78: /* cmd ::= USE db_name */ #line 182 "sql.y" { pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy371); } -#line 5196 "sql.c" +#line 5232 "sql.c" break; case 79: /* cmd ::= ALTER DATABASE db_name alter_db_options */ #line 183 "sql.y" { pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy452); } -#line 5201 "sql.c" +#line 5237 "sql.c" break; case 80: /* cmd ::= FLUSH DATABASE db_name */ #line 184 "sql.y" { pCxt->pRootNode = createFlushDatabaseStmt(pCxt, &yymsp[0].minor.yy371); } -#line 5206 "sql.c" +#line 5242 "sql.c" break; case 81: /* cmd ::= TRIM DATABASE db_name speed_opt */ #line 185 "sql.y" { pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy416); } -#line 5211 "sql.c" +#line 5247 "sql.c" break; case 82: /* cmd ::= COMPACT DATABASE db_name start_opt end_opt */ #line 186 "sql.y" { pCxt->pRootNode = createCompactStmt(pCxt, &yymsp[-2].minor.yy371, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } -#line 5216 "sql.c" +#line 5252 "sql.c" break; case 83: /* not_exists_opt ::= IF NOT EXISTS */ #line 190 "sql.y" { yymsp[-2].minor.yy667 = true; } -#line 5221 "sql.c" +#line 5257 "sql.c" break; case 85: /* exists_opt ::= IF EXISTS */ - case 335: /* or_replace_opt ::= OR REPLACE */ yytestcase(yyruleno==335); - case 357: /* ignore_opt ::= IGNORE UNTREATED */ yytestcase(yyruleno==357); + case 336: /* or_replace_opt ::= OR REPLACE */ yytestcase(yyruleno==336); + case 358: /* ignore_opt ::= IGNORE UNTREATED */ yytestcase(yyruleno==358); #line 195 "sql.y" { yymsp[-1].minor.yy667 = true; } -#line 5228 "sql.c" +#line 5264 "sql.c" break; case 87: /* db_options ::= */ #line 198 "sql.y" { yymsp[1].minor.yy452 = createDefaultDatabaseOptions(pCxt); } -#line 5233 "sql.c" +#line 5269 "sql.c" break; case 88: /* db_options ::= db_options BUFFER NK_INTEGER */ #line 199 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); } -#line 5238 "sql.c" +#line 5274 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 89: /* db_options ::= db_options CACHEMODEL NK_STRING */ #line 200 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_CACHEMODEL, &yymsp[0].minor.yy0); } -#line 5244 "sql.c" +#line 5280 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 90: /* db_options ::= db_options CACHESIZE NK_INTEGER */ #line 201 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_CACHESIZE, &yymsp[0].minor.yy0); } -#line 5250 "sql.c" +#line 5286 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 91: /* db_options ::= db_options COMP NK_INTEGER */ #line 202 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_COMP, &yymsp[0].minor.yy0); } -#line 5256 "sql.c" +#line 5292 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 92: /* db_options ::= db_options DURATION NK_INTEGER */ case 93: /* db_options ::= db_options DURATION NK_VARIABLE */ yytestcase(yyruleno==93); #line 203 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } -#line 5263 "sql.c" +#line 5299 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 94: /* db_options ::= db_options MAXROWS NK_INTEGER */ #line 205 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } -#line 5269 "sql.c" +#line 5305 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 95: /* db_options ::= db_options MINROWS NK_INTEGER */ #line 206 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } -#line 5275 "sql.c" +#line 5311 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 96: /* db_options ::= db_options KEEP integer_list */ case 97: /* db_options ::= db_options KEEP variable_list */ yytestcase(yyruleno==97); #line 207 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_KEEP, yymsp[0].minor.yy812); } -#line 5282 "sql.c" +#line 5318 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 98: /* db_options ::= db_options PAGES NK_INTEGER */ #line 209 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_PAGES, &yymsp[0].minor.yy0); } -#line 5288 "sql.c" +#line 5324 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 99: /* db_options ::= db_options PAGESIZE NK_INTEGER */ #line 210 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); } -#line 5294 "sql.c" +#line 5330 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 100: /* db_options ::= db_options TSDB_PAGESIZE NK_INTEGER */ #line 211 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_TSDB_PAGESIZE, &yymsp[0].minor.yy0); } -#line 5300 "sql.c" +#line 5336 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 101: /* db_options ::= db_options PRECISION NK_STRING */ #line 212 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } -#line 5306 "sql.c" +#line 5342 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 102: /* db_options ::= db_options REPLICA NK_INTEGER */ #line 213 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } -#line 5312 "sql.c" +#line 5348 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 103: /* db_options ::= db_options VGROUPS NK_INTEGER */ #line 215 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } -#line 5318 "sql.c" +#line 5354 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 104: /* db_options ::= db_options SINGLE_STABLE NK_INTEGER */ #line 216 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); } -#line 5324 "sql.c" +#line 5360 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 105: /* db_options ::= db_options RETENTIONS retention_list */ #line 217 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_RETENTIONS, yymsp[0].minor.yy812); } -#line 5330 "sql.c" +#line 5366 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 106: /* db_options ::= db_options SCHEMALESS NK_INTEGER */ #line 218 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); } -#line 5336 "sql.c" +#line 5372 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 107: /* db_options ::= db_options WAL_LEVEL NK_INTEGER */ #line 219 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL, &yymsp[0].minor.yy0); } -#line 5342 "sql.c" +#line 5378 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 108: /* db_options ::= db_options WAL_FSYNC_PERIOD NK_INTEGER */ #line 220 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } -#line 5348 "sql.c" +#line 5384 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 109: /* db_options ::= db_options WAL_RETENTION_PERIOD NK_INTEGER */ #line 221 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL_RETENTION_PERIOD, &yymsp[0].minor.yy0); } -#line 5354 "sql.c" +#line 5390 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 110: /* db_options ::= db_options WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ @@ -5361,13 +5397,13 @@ static YYACTIONTYPE yy_reduce( t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-3].minor.yy452, DB_OPTION_WAL_RETENTION_PERIOD, &t); } -#line 5364 "sql.c" +#line 5400 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 111: /* db_options ::= db_options WAL_RETENTION_SIZE NK_INTEGER */ #line 227 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL_RETENTION_SIZE, &yymsp[0].minor.yy0); } -#line 5370 "sql.c" +#line 5406 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 112: /* db_options ::= db_options WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ @@ -5377,106 +5413,106 @@ static YYACTIONTYPE yy_reduce( t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-3].minor.yy452, DB_OPTION_WAL_RETENTION_SIZE, &t); } -#line 5380 "sql.c" +#line 5416 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 113: /* db_options ::= db_options WAL_ROLL_PERIOD NK_INTEGER */ #line 233 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL_ROLL_PERIOD, &yymsp[0].minor.yy0); } -#line 5386 "sql.c" +#line 5422 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 114: /* db_options ::= db_options WAL_SEGMENT_SIZE NK_INTEGER */ #line 234 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_WAL_SEGMENT_SIZE, &yymsp[0].minor.yy0); } -#line 5392 "sql.c" +#line 5428 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 115: /* db_options ::= db_options STT_TRIGGER NK_INTEGER */ #line 235 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_STT_TRIGGER, &yymsp[0].minor.yy0); } -#line 5398 "sql.c" +#line 5434 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 116: /* db_options ::= db_options TABLE_PREFIX signed */ #line 236 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_TABLE_PREFIX, yymsp[0].minor.yy452); } -#line 5404 "sql.c" +#line 5440 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 117: /* db_options ::= db_options TABLE_SUFFIX signed */ #line 237 "sql.y" { yylhsminor.yy452 = setDatabaseOption(pCxt, yymsp[-2].minor.yy452, DB_OPTION_TABLE_SUFFIX, yymsp[0].minor.yy452); } -#line 5410 "sql.c" +#line 5446 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 118: /* alter_db_options ::= alter_db_option */ #line 239 "sql.y" { yylhsminor.yy452 = createAlterDatabaseOptions(pCxt); yylhsminor.yy452 = setAlterDatabaseOption(pCxt, yylhsminor.yy452, &yymsp[0].minor.yy365); } -#line 5416 "sql.c" +#line 5452 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 119: /* alter_db_options ::= alter_db_options alter_db_option */ #line 240 "sql.y" { yylhsminor.yy452 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy452, &yymsp[0].minor.yy365); } -#line 5422 "sql.c" +#line 5458 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 120: /* alter_db_option ::= BUFFER NK_INTEGER */ #line 244 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5428 "sql.c" +#line 5464 "sql.c" break; case 121: /* alter_db_option ::= CACHEMODEL NK_STRING */ #line 245 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_CACHEMODEL; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5433 "sql.c" +#line 5469 "sql.c" break; case 122: /* alter_db_option ::= CACHESIZE NK_INTEGER */ #line 246 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_CACHESIZE; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5438 "sql.c" +#line 5474 "sql.c" break; case 123: /* alter_db_option ::= WAL_FSYNC_PERIOD NK_INTEGER */ #line 247 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5443 "sql.c" +#line 5479 "sql.c" break; case 124: /* alter_db_option ::= KEEP integer_list */ case 125: /* alter_db_option ::= KEEP variable_list */ yytestcase(yyruleno==125); #line 248 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_KEEP; yymsp[-1].minor.yy365.pList = yymsp[0].minor.yy812; } -#line 5449 "sql.c" +#line 5485 "sql.c" break; case 126: /* alter_db_option ::= PAGES NK_INTEGER */ #line 250 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_PAGES; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5454 "sql.c" +#line 5490 "sql.c" break; case 127: /* alter_db_option ::= REPLICA NK_INTEGER */ #line 251 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5459 "sql.c" +#line 5495 "sql.c" break; case 128: /* alter_db_option ::= WAL_LEVEL NK_INTEGER */ #line 253 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_WAL; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5464 "sql.c" +#line 5500 "sql.c" break; case 129: /* alter_db_option ::= STT_TRIGGER NK_INTEGER */ #line 254 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_STT_TRIGGER; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5469 "sql.c" +#line 5505 "sql.c" break; case 130: /* alter_db_option ::= MINROWS NK_INTEGER */ #line 255 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_MINROWS; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5474 "sql.c" +#line 5510 "sql.c" break; case 131: /* alter_db_option ::= WAL_RETENTION_PERIOD NK_INTEGER */ #line 256 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5479 "sql.c" +#line 5515 "sql.c" break; case 132: /* alter_db_option ::= WAL_RETENTION_PERIOD NK_MINUS NK_INTEGER */ #line 257 "sql.y" @@ -5485,12 +5521,12 @@ static YYACTIONTYPE yy_reduce( t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; yymsp[-2].minor.yy365.type = DB_OPTION_WAL_RETENTION_PERIOD; yymsp[-2].minor.yy365.val = t; } -#line 5488 "sql.c" +#line 5524 "sql.c" break; case 133: /* alter_db_option ::= WAL_RETENTION_SIZE NK_INTEGER */ #line 262 "sql.y" { yymsp[-1].minor.yy365.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5493 "sql.c" +#line 5529 "sql.c" break; case 134: /* alter_db_option ::= WAL_RETENTION_SIZE NK_MINUS NK_INTEGER */ #line 263 "sql.y" @@ -5499,1596 +5535,1602 @@ static YYACTIONTYPE yy_reduce( t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; yymsp[-2].minor.yy365.type = DB_OPTION_WAL_RETENTION_SIZE; yymsp[-2].minor.yy365.val = t; } -#line 5502 "sql.c" +#line 5538 "sql.c" break; case 135: /* integer_list ::= NK_INTEGER */ #line 271 "sql.y" { yylhsminor.yy812 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } -#line 5507 "sql.c" +#line 5543 "sql.c" yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 136: /* integer_list ::= integer_list NK_COMMA NK_INTEGER */ - case 367: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==367); + case 368: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==368); #line 272 "sql.y" { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } -#line 5514 "sql.c" +#line 5550 "sql.c" yymsp[-2].minor.yy812 = yylhsminor.yy812; break; case 137: /* variable_list ::= NK_VARIABLE */ #line 276 "sql.y" { yylhsminor.yy812 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } -#line 5520 "sql.c" +#line 5556 "sql.c" yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 138: /* variable_list ::= variable_list NK_COMMA NK_VARIABLE */ #line 277 "sql.y" { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } -#line 5526 "sql.c" +#line 5562 "sql.c" yymsp[-2].minor.yy812 = yylhsminor.yy812; break; case 139: /* retention_list ::= retention */ case 169: /* multi_create_clause ::= create_subtable_clause */ yytestcase(yyruleno==169); case 172: /* multi_drop_clause ::= drop_table_clause */ yytestcase(yyruleno==172); case 179: /* column_def_list ::= column_def */ yytestcase(yyruleno==179); - case 223: /* rollup_func_list ::= rollup_func_name */ yytestcase(yyruleno==223); - case 228: /* col_name_list ::= col_name */ yytestcase(yyruleno==228); - case 282: /* tag_list_opt ::= tag_item */ yytestcase(yyruleno==282); - case 296: /* func_list ::= func */ yytestcase(yyruleno==296); - case 396: /* literal_list ::= signed_literal */ yytestcase(yyruleno==396); - case 463: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==463); - case 469: /* when_then_list ::= when_then_expr */ yytestcase(yyruleno==469); - case 524: /* select_list ::= select_item */ yytestcase(yyruleno==524); - case 535: /* partition_list ::= partition_item */ yytestcase(yyruleno==535); - case 591: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==591); + case 224: /* rollup_func_list ::= rollup_func_name */ yytestcase(yyruleno==224); + case 229: /* col_name_list ::= col_name */ yytestcase(yyruleno==229); + case 283: /* tag_list_opt ::= tag_item */ yytestcase(yyruleno==283); + case 297: /* func_list ::= func */ yytestcase(yyruleno==297); + case 397: /* literal_list ::= signed_literal */ yytestcase(yyruleno==397); + case 464: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==464); + case 470: /* when_then_list ::= when_then_expr */ yytestcase(yyruleno==470); + case 525: /* select_list ::= select_item */ yytestcase(yyruleno==525); + case 536: /* partition_list ::= partition_item */ yytestcase(yyruleno==536); + case 592: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==592); #line 281 "sql.y" { yylhsminor.yy812 = createNodeList(pCxt, yymsp[0].minor.yy452); } -#line 5545 "sql.c" +#line 5581 "sql.c" yymsp[0].minor.yy812 = yylhsminor.yy812; break; case 140: /* retention_list ::= retention_list NK_COMMA retention */ case 173: /* multi_drop_clause ::= multi_drop_clause NK_COMMA drop_table_clause */ yytestcase(yyruleno==173); case 180: /* column_def_list ::= column_def_list NK_COMMA column_def */ yytestcase(yyruleno==180); - case 224: /* rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ yytestcase(yyruleno==224); - case 229: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==229); - case 283: /* tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ yytestcase(yyruleno==283); - case 297: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==297); - case 397: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==397); - case 464: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==464); - case 525: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==525); - case 536: /* partition_list ::= partition_list NK_COMMA partition_item */ yytestcase(yyruleno==536); - case 592: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==592); + case 225: /* rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ yytestcase(yyruleno==225); + case 230: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==230); + case 284: /* tag_list_opt ::= tag_list_opt NK_COMMA tag_item */ yytestcase(yyruleno==284); + case 298: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==298); + case 398: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==398); + case 465: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==465); + case 526: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==526); + case 537: /* partition_list ::= partition_list NK_COMMA partition_item */ yytestcase(yyruleno==537); + case 593: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==593); #line 282 "sql.y" { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, yymsp[0].minor.yy452); } -#line 5562 "sql.c" +#line 5598 "sql.c" yymsp[-2].minor.yy812 = yylhsminor.yy812; break; case 141: /* retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ #line 284 "sql.y" { yylhsminor.yy452 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } -#line 5568 "sql.c" +#line 5604 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 142: /* speed_opt ::= */ - case 330: /* bufsize_opt ::= */ yytestcase(yyruleno==330); + case 331: /* bufsize_opt ::= */ yytestcase(yyruleno==331); #line 288 "sql.y" { yymsp[1].minor.yy416 = 0; } -#line 5575 "sql.c" +#line 5611 "sql.c" break; case 143: /* speed_opt ::= MAX_SPEED NK_INTEGER */ - case 331: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ yytestcase(yyruleno==331); + case 332: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ yytestcase(yyruleno==332); #line 289 "sql.y" { yymsp[-1].minor.yy416 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } -#line 5581 "sql.c" +#line 5617 "sql.c" break; case 145: /* start_opt ::= START WITH NK_INTEGER */ case 149: /* end_opt ::= END WITH NK_INTEGER */ yytestcase(yyruleno==149); #line 292 "sql.y" { yymsp[-2].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } -#line 5587 "sql.c" +#line 5623 "sql.c" break; case 146: /* start_opt ::= START WITH NK_STRING */ case 150: /* end_opt ::= END WITH NK_STRING */ yytestcase(yyruleno==150); #line 293 "sql.y" { yymsp[-2].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } -#line 5593 "sql.c" +#line 5629 "sql.c" break; case 147: /* start_opt ::= START WITH TIMESTAMP NK_STRING */ case 151: /* end_opt ::= END WITH TIMESTAMP NK_STRING */ yytestcase(yyruleno==151); #line 294 "sql.y" { yymsp[-3].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } -#line 5599 "sql.c" +#line 5635 "sql.c" break; case 152: /* cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ case 154: /* cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ yytestcase(yyruleno==154); #line 303 "sql.y" { pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy667, yymsp[-5].minor.yy452, yymsp[-3].minor.yy812, yymsp[-1].minor.yy812, yymsp[0].minor.yy452); } -#line 5605 "sql.c" +#line 5641 "sql.c" break; case 153: /* cmd ::= CREATE TABLE multi_create_clause */ #line 304 "sql.y" { pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy812); } -#line 5610 "sql.c" +#line 5646 "sql.c" break; case 155: /* cmd ::= DROP TABLE multi_drop_clause */ #line 307 "sql.y" { pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy812); } -#line 5615 "sql.c" +#line 5651 "sql.c" break; case 156: /* cmd ::= DROP STABLE exists_opt full_table_name */ #line 308 "sql.y" { pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy667, yymsp[0].minor.yy452); } -#line 5620 "sql.c" +#line 5656 "sql.c" break; case 157: /* cmd ::= ALTER TABLE alter_table_clause */ - case 369: /* cmd ::= query_or_subquery */ yytestcase(yyruleno==369); - case 370: /* cmd ::= insert_query */ yytestcase(yyruleno==370); + case 370: /* cmd ::= query_or_subquery */ yytestcase(yyruleno==370); + case 371: /* cmd ::= insert_query */ yytestcase(yyruleno==371); #line 310 "sql.y" { pCxt->pRootNode = yymsp[0].minor.yy452; } -#line 5627 "sql.c" +#line 5663 "sql.c" break; case 158: /* cmd ::= ALTER STABLE alter_table_clause */ #line 311 "sql.y" { pCxt->pRootNode = setAlterSuperTableType(yymsp[0].minor.yy452); } -#line 5632 "sql.c" +#line 5668 "sql.c" break; case 159: /* alter_table_clause ::= full_table_name alter_table_options */ #line 313 "sql.y" { yylhsminor.yy452 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } -#line 5637 "sql.c" +#line 5673 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 160: /* alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ + case 160: /* alter_table_clause ::= full_table_name ADD COLUMN column_def */ #line 315 "sql.y" -{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } -#line 5643 "sql.c" - yymsp[-4].minor.yy452 = yylhsminor.yy452; +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_ADD_COLUMN, yymsp[0].minor.yy452); } +#line 5679 "sql.c" + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 161: /* alter_table_clause ::= full_table_name DROP COLUMN column_name */ #line 316 "sql.y" { yylhsminor.yy452 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy371); } -#line 5649 "sql.c" +#line 5685 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 162: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ + case 162: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_def */ #line 318 "sql.y" -{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } -#line 5655 "sql.c" - yymsp[-4].minor.yy452 = yylhsminor.yy452; +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, yymsp[0].minor.yy452); } +#line 5691 "sql.c" + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 163: /* alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ #line 320 "sql.y" { yylhsminor.yy452 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } -#line 5661 "sql.c" +#line 5697 "sql.c" yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 164: /* alter_table_clause ::= full_table_name ADD TAG column_name type_name */ + case 164: /* alter_table_clause ::= full_table_name ADD TAG column_def */ #line 322 "sql.y" -{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } -#line 5667 "sql.c" - yymsp[-4].minor.yy452 = yylhsminor.yy452; +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_ADD_TAG, yymsp[0].minor.yy452); } +#line 5703 "sql.c" + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 165: /* alter_table_clause ::= full_table_name DROP TAG column_name */ #line 323 "sql.y" { yylhsminor.yy452 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy371); } -#line 5673 "sql.c" +#line 5709 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 166: /* alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ + case 166: /* alter_table_clause ::= full_table_name MODIFY TAG column_def */ #line 325 "sql.y" -{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310); } -#line 5679 "sql.c" - yymsp[-4].minor.yy452 = yylhsminor.yy452; +{ yylhsminor.yy452 = createAlterTableAddModifyCol(pCxt, yymsp[-3].minor.yy452, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, yymsp[0].minor.yy452); } +#line 5715 "sql.c" + yymsp[-3].minor.yy452 = yylhsminor.yy452; break; case 167: /* alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ #line 327 "sql.y" { yylhsminor.yy452 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy452, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } -#line 5685 "sql.c" +#line 5721 "sql.c" yymsp[-4].minor.yy452 = yylhsminor.yy452; break; case 168: /* alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ #line 329 "sql.y" { yylhsminor.yy452 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy452, &yymsp[-2].minor.yy371, yymsp[0].minor.yy452); } -#line 5691 "sql.c" +#line 5727 "sql.c" yymsp[-5].minor.yy452 = yylhsminor.yy452; break; case 170: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ - case 470: /* when_then_list ::= when_then_list when_then_expr */ yytestcase(yyruleno==470); + case 471: /* when_then_list ::= when_then_list when_then_expr */ yytestcase(yyruleno==471); #line 334 "sql.y" { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-1].minor.yy812, yymsp[0].minor.yy452); } -#line 5698 "sql.c" +#line 5734 "sql.c" yymsp[-1].minor.yy812 = yylhsminor.yy812; break; case 171: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_cols_opt TAGS NK_LP expression_list NK_RP table_options */ #line 338 "sql.y" { yylhsminor.yy452 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy667, yymsp[-8].minor.yy452, yymsp[-6].minor.yy452, yymsp[-5].minor.yy812, yymsp[-2].minor.yy812, yymsp[0].minor.yy452); } -#line 5704 "sql.c" +#line 5740 "sql.c" yymsp[-9].minor.yy452 = yylhsminor.yy452; break; case 174: /* drop_table_clause ::= exists_opt full_table_name */ #line 345 "sql.y" { yylhsminor.yy452 = createDropTableClause(pCxt, yymsp[-1].minor.yy667, yymsp[0].minor.yy452); } -#line 5710 "sql.c" +#line 5746 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; case 175: /* specific_cols_opt ::= */ - case 206: /* tags_def_opt ::= */ yytestcase(yyruleno==206); - case 281: /* tag_list_opt ::= */ yytestcase(yyruleno==281); - case 340: /* col_list_opt ::= */ yytestcase(yyruleno==340); - case 342: /* tag_def_or_ref_opt ::= */ yytestcase(yyruleno==342); - case 533: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==533); - case 558: /* group_by_clause_opt ::= */ yytestcase(yyruleno==558); - case 578: /* order_by_clause_opt ::= */ yytestcase(yyruleno==578); + case 207: /* tags_def_opt ::= */ yytestcase(yyruleno==207); + case 282: /* tag_list_opt ::= */ yytestcase(yyruleno==282); + case 341: /* col_list_opt ::= */ yytestcase(yyruleno==341); + case 343: /* tag_def_or_ref_opt ::= */ yytestcase(yyruleno==343); + case 534: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==534); + case 559: /* group_by_clause_opt ::= */ yytestcase(yyruleno==559); + case 579: /* order_by_clause_opt ::= */ yytestcase(yyruleno==579); #line 349 "sql.y" { yymsp[1].minor.yy812 = NULL; } -#line 5723 "sql.c" +#line 5759 "sql.c" break; case 176: /* specific_cols_opt ::= NK_LP col_name_list NK_RP */ - case 341: /* col_list_opt ::= NK_LP col_name_list NK_RP */ yytestcase(yyruleno==341); + case 342: /* col_list_opt ::= NK_LP col_name_list NK_RP */ yytestcase(yyruleno==342); #line 350 "sql.y" { yymsp[-2].minor.yy812 = yymsp[-1].minor.yy812; } -#line 5729 "sql.c" +#line 5765 "sql.c" break; case 177: /* full_table_name ::= table_name */ #line 352 "sql.y" { yylhsminor.yy452 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy371, NULL); } -#line 5734 "sql.c" +#line 5770 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; case 178: /* full_table_name ::= db_name NK_DOT table_name */ #line 353 "sql.y" { yylhsminor.yy452 = createRealTableNode(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371, NULL); } -#line 5740 "sql.c" +#line 5776 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; case 181: /* column_def ::= column_name type_name */ #line 360 "sql.y" { yylhsminor.yy452 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy371, yymsp[0].minor.yy310, NULL); } -#line 5746 "sql.c" +#line 5782 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 182: /* type_name ::= BOOL */ + case 182: /* column_def ::= column_name type_name COMMENT NK_STRING */ +#line 361 "sql.y" +{ yylhsminor.yy452 = createColumnDefNode(pCxt, &yymsp[-3].minor.yy371, yymsp[-2].minor.yy310, &yymsp[0].minor.yy0); } +#line 5788 "sql.c" + yymsp[-3].minor.yy452 = yylhsminor.yy452; + break; + case 183: /* type_name ::= BOOL */ #line 365 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BOOL); } -#line 5752 "sql.c" +#line 5794 "sql.c" break; - case 183: /* type_name ::= TINYINT */ + case 184: /* type_name ::= TINYINT */ #line 366 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_TINYINT); } -#line 5757 "sql.c" +#line 5799 "sql.c" break; - case 184: /* type_name ::= SMALLINT */ + case 185: /* type_name ::= SMALLINT */ #line 367 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_SMALLINT); } -#line 5762 "sql.c" +#line 5804 "sql.c" break; - case 185: /* type_name ::= INT */ - case 186: /* type_name ::= INTEGER */ yytestcase(yyruleno==186); + case 186: /* type_name ::= INT */ + case 187: /* type_name ::= INTEGER */ yytestcase(yyruleno==187); #line 368 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_INT); } -#line 5768 "sql.c" +#line 5810 "sql.c" break; - case 187: /* type_name ::= BIGINT */ + case 188: /* type_name ::= BIGINT */ #line 370 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BIGINT); } -#line 5773 "sql.c" +#line 5815 "sql.c" break; - case 188: /* type_name ::= FLOAT */ + case 189: /* type_name ::= FLOAT */ #line 371 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_FLOAT); } -#line 5778 "sql.c" +#line 5820 "sql.c" break; - case 189: /* type_name ::= DOUBLE */ + case 190: /* type_name ::= DOUBLE */ #line 372 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_DOUBLE); } -#line 5783 "sql.c" +#line 5825 "sql.c" break; - case 190: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + case 191: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ #line 373 "sql.y" { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } -#line 5788 "sql.c" +#line 5830 "sql.c" break; - case 191: /* type_name ::= TIMESTAMP */ + case 192: /* type_name ::= TIMESTAMP */ #line 374 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } -#line 5793 "sql.c" +#line 5835 "sql.c" break; - case 192: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + case 193: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ #line 375 "sql.y" { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } -#line 5798 "sql.c" +#line 5840 "sql.c" break; - case 193: /* type_name ::= TINYINT UNSIGNED */ + case 194: /* type_name ::= TINYINT UNSIGNED */ #line 376 "sql.y" { yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UTINYINT); } -#line 5803 "sql.c" +#line 5845 "sql.c" break; - case 194: /* type_name ::= SMALLINT UNSIGNED */ + case 195: /* type_name ::= SMALLINT UNSIGNED */ #line 377 "sql.y" { yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_USMALLINT); } -#line 5808 "sql.c" +#line 5850 "sql.c" break; - case 195: /* type_name ::= INT UNSIGNED */ + case 196: /* type_name ::= INT UNSIGNED */ #line 378 "sql.y" { yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UINT); } -#line 5813 "sql.c" +#line 5855 "sql.c" break; - case 196: /* type_name ::= BIGINT UNSIGNED */ + case 197: /* type_name ::= BIGINT UNSIGNED */ #line 379 "sql.y" { yymsp[-1].minor.yy310 = createDataType(TSDB_DATA_TYPE_UBIGINT); } -#line 5818 "sql.c" +#line 5860 "sql.c" break; - case 197: /* type_name ::= JSON */ + case 198: /* type_name ::= JSON */ #line 380 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_JSON); } -#line 5823 "sql.c" +#line 5865 "sql.c" break; - case 198: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + case 199: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ #line 381 "sql.y" { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } -#line 5828 "sql.c" +#line 5870 "sql.c" break; - case 199: /* type_name ::= MEDIUMBLOB */ + case 200: /* type_name ::= MEDIUMBLOB */ #line 382 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } -#line 5833 "sql.c" +#line 5875 "sql.c" break; - case 200: /* type_name ::= BLOB */ + case 201: /* type_name ::= BLOB */ #line 383 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_BLOB); } -#line 5838 "sql.c" +#line 5880 "sql.c" break; - case 201: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + case 202: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ #line 384 "sql.y" { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } -#line 5843 "sql.c" +#line 5885 "sql.c" break; - case 202: /* type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ + case 203: /* type_name ::= GEOMETRY NK_LP NK_INTEGER NK_RP */ #line 385 "sql.y" { yymsp[-3].minor.yy310 = createVarLenDataType(TSDB_DATA_TYPE_GEOMETRY, &yymsp[-1].minor.yy0); } -#line 5848 "sql.c" +#line 5890 "sql.c" break; - case 203: /* type_name ::= DECIMAL */ + case 204: /* type_name ::= DECIMAL */ #line 386 "sql.y" { yymsp[0].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } -#line 5853 "sql.c" +#line 5895 "sql.c" break; - case 204: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + case 205: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ #line 387 "sql.y" { yymsp[-3].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } -#line 5858 "sql.c" +#line 5900 "sql.c" break; - case 205: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + case 206: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ #line 388 "sql.y" { yymsp[-5].minor.yy310 = createDataType(TSDB_DATA_TYPE_DECIMAL); } -#line 5863 "sql.c" +#line 5905 "sql.c" break; - case 207: /* tags_def_opt ::= tags_def */ - case 343: /* tag_def_or_ref_opt ::= tags_def */ yytestcase(yyruleno==343); - case 462: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==462); + case 208: /* tags_def_opt ::= tags_def */ + case 344: /* tag_def_or_ref_opt ::= tags_def */ yytestcase(yyruleno==344); + case 463: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==463); #line 393 "sql.y" { yylhsminor.yy812 = yymsp[0].minor.yy812; } -#line 5870 "sql.c" +#line 5912 "sql.c" yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 208: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ - case 344: /* tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ yytestcase(yyruleno==344); + case 209: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ + case 345: /* tag_def_or_ref_opt ::= TAGS NK_LP col_name_list NK_RP */ yytestcase(yyruleno==345); #line 397 "sql.y" { yymsp[-3].minor.yy812 = yymsp[-1].minor.yy812; } -#line 5877 "sql.c" +#line 5919 "sql.c" break; - case 209: /* table_options ::= */ + case 210: /* table_options ::= */ #line 399 "sql.y" { yymsp[1].minor.yy452 = createDefaultTableOptions(pCxt); } -#line 5882 "sql.c" +#line 5924 "sql.c" break; - case 210: /* table_options ::= table_options COMMENT NK_STRING */ + case 211: /* table_options ::= table_options COMMENT NK_STRING */ #line 400 "sql.y" { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } -#line 5887 "sql.c" +#line 5929 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 211: /* table_options ::= table_options MAX_DELAY duration_list */ + case 212: /* table_options ::= table_options MAX_DELAY duration_list */ #line 401 "sql.y" { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_MAXDELAY, yymsp[0].minor.yy812); } -#line 5893 "sql.c" +#line 5935 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 212: /* table_options ::= table_options WATERMARK duration_list */ + case 213: /* table_options ::= table_options WATERMARK duration_list */ #line 402 "sql.y" { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_WATERMARK, yymsp[0].minor.yy812); } -#line 5899 "sql.c" +#line 5941 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 213: /* table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ + case 214: /* table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ #line 403 "sql.y" { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-4].minor.yy452, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy812); } -#line 5905 "sql.c" +#line 5947 "sql.c" yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 214: /* table_options ::= table_options TTL NK_INTEGER */ + case 215: /* table_options ::= table_options TTL NK_INTEGER */ #line 404 "sql.y" { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } -#line 5911 "sql.c" +#line 5953 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 215: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + case 216: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ #line 405 "sql.y" { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-4].minor.yy452, TABLE_OPTION_SMA, yymsp[-1].minor.yy812); } -#line 5917 "sql.c" +#line 5959 "sql.c" yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 216: /* table_options ::= table_options DELETE_MARK duration_list */ + case 217: /* table_options ::= table_options DELETE_MARK duration_list */ #line 406 "sql.y" { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-2].minor.yy452, TABLE_OPTION_DELETE_MARK, yymsp[0].minor.yy812); } -#line 5923 "sql.c" +#line 5965 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 217: /* alter_table_options ::= alter_table_option */ + case 218: /* alter_table_options ::= alter_table_option */ #line 408 "sql.y" { yylhsminor.yy452 = createAlterTableOptions(pCxt); yylhsminor.yy452 = setTableOption(pCxt, yylhsminor.yy452, yymsp[0].minor.yy365.type, &yymsp[0].minor.yy365.val); } -#line 5929 "sql.c" +#line 5971 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 218: /* alter_table_options ::= alter_table_options alter_table_option */ + case 219: /* alter_table_options ::= alter_table_options alter_table_option */ #line 409 "sql.y" { yylhsminor.yy452 = setTableOption(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy365.type, &yymsp[0].minor.yy365.val); } -#line 5935 "sql.c" +#line 5977 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 219: /* alter_table_option ::= COMMENT NK_STRING */ + case 220: /* alter_table_option ::= COMMENT NK_STRING */ #line 413 "sql.y" { yymsp[-1].minor.yy365.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5941 "sql.c" +#line 5983 "sql.c" break; - case 220: /* alter_table_option ::= TTL NK_INTEGER */ + case 221: /* alter_table_option ::= TTL NK_INTEGER */ #line 414 "sql.y" { yymsp[-1].minor.yy365.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy365.val = yymsp[0].minor.yy0; } -#line 5946 "sql.c" +#line 5988 "sql.c" break; - case 221: /* duration_list ::= duration_literal */ - case 426: /* expression_list ::= expr_or_subquery */ yytestcase(yyruleno==426); + case 222: /* duration_list ::= duration_literal */ + case 427: /* expression_list ::= expr_or_subquery */ yytestcase(yyruleno==427); #line 418 "sql.y" { yylhsminor.yy812 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } -#line 5952 "sql.c" +#line 5994 "sql.c" yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 222: /* duration_list ::= duration_list NK_COMMA duration_literal */ - case 427: /* expression_list ::= expression_list NK_COMMA expr_or_subquery */ yytestcase(yyruleno==427); + case 223: /* duration_list ::= duration_list NK_COMMA duration_literal */ + case 428: /* expression_list ::= expression_list NK_COMMA expr_or_subquery */ yytestcase(yyruleno==428); #line 419 "sql.y" { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } -#line 5959 "sql.c" +#line 6001 "sql.c" yymsp[-2].minor.yy812 = yylhsminor.yy812; break; - case 225: /* rollup_func_name ::= function_name */ + case 226: /* rollup_func_name ::= function_name */ #line 426 "sql.y" { yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[0].minor.yy371, NULL); } -#line 5965 "sql.c" +#line 6007 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 226: /* rollup_func_name ::= FIRST */ - case 227: /* rollup_func_name ::= LAST */ yytestcase(yyruleno==227); - case 285: /* tag_item ::= QTAGS */ yytestcase(yyruleno==285); + case 227: /* rollup_func_name ::= FIRST */ + case 228: /* rollup_func_name ::= LAST */ yytestcase(yyruleno==228); + case 286: /* tag_item ::= QTAGS */ yytestcase(yyruleno==286); #line 427 "sql.y" { yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL); } -#line 5973 "sql.c" +#line 6015 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 230: /* col_name ::= column_name */ - case 286: /* tag_item ::= column_name */ yytestcase(yyruleno==286); + case 231: /* col_name ::= column_name */ + case 287: /* tag_item ::= column_name */ yytestcase(yyruleno==287); #line 435 "sql.y" { yylhsminor.yy452 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy371); } -#line 5980 "sql.c" +#line 6022 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 231: /* cmd ::= SHOW DNODES */ + case 232: /* cmd ::= SHOW DNODES */ #line 438 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DNODES_STMT); } -#line 5986 "sql.c" +#line 6028 "sql.c" break; - case 232: /* cmd ::= SHOW USERS */ + case 233: /* cmd ::= SHOW USERS */ #line 439 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_USERS_STMT); } -#line 5991 "sql.c" +#line 6033 "sql.c" break; - case 233: /* cmd ::= SHOW USER PRIVILEGES */ + case 234: /* cmd ::= SHOW USER PRIVILEGES */ #line 440 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_USER_PRIVILEGES_STMT); } -#line 5996 "sql.c" +#line 6038 "sql.c" break; - case 234: /* cmd ::= SHOW DATABASES */ + case 235: /* cmd ::= SHOW DATABASES */ #line 441 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT); } -#line 6001 "sql.c" +#line 6043 "sql.c" break; - case 235: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ + case 236: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ #line 442 "sql.y" { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, OP_TYPE_LIKE); } -#line 6006 "sql.c" +#line 6048 "sql.c" break; - case 236: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ + case 237: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ #line 443 "sql.y" { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, OP_TYPE_LIKE); } -#line 6011 "sql.c" +#line 6053 "sql.c" break; - case 237: /* cmd ::= SHOW db_name_cond_opt VGROUPS */ + case 238: /* cmd ::= SHOW db_name_cond_opt VGROUPS */ #line 444 "sql.y" { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy452, NULL, OP_TYPE_LIKE); } -#line 6016 "sql.c" +#line 6058 "sql.c" break; - case 238: /* cmd ::= SHOW MNODES */ + case 239: /* cmd ::= SHOW MNODES */ #line 445 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); } -#line 6021 "sql.c" +#line 6063 "sql.c" break; - case 239: /* cmd ::= SHOW QNODES */ + case 240: /* cmd ::= SHOW QNODES */ #line 447 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT); } -#line 6026 "sql.c" +#line 6068 "sql.c" break; - case 240: /* cmd ::= SHOW FUNCTIONS */ + case 241: /* cmd ::= SHOW FUNCTIONS */ #line 448 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); } -#line 6031 "sql.c" +#line 6073 "sql.c" break; - case 241: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ + case 242: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ #line 449 "sql.y" { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[0].minor.yy452, yymsp[-1].minor.yy452, OP_TYPE_EQUAL); } -#line 6036 "sql.c" +#line 6078 "sql.c" break; - case 242: /* cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ + case 243: /* cmd ::= SHOW INDEXES FROM db_name NK_DOT table_name */ #line 450 "sql.y" { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, createIdentifierValueNode(pCxt, &yymsp[-2].minor.yy371), createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371), OP_TYPE_EQUAL); } -#line 6041 "sql.c" +#line 6083 "sql.c" break; - case 243: /* cmd ::= SHOW STREAMS */ + case 244: /* cmd ::= SHOW STREAMS */ #line 451 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT); } -#line 6046 "sql.c" +#line 6088 "sql.c" break; - case 244: /* cmd ::= SHOW ACCOUNTS */ + case 245: /* cmd ::= SHOW ACCOUNTS */ #line 452 "sql.y" { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } -#line 6051 "sql.c" +#line 6093 "sql.c" break; - case 245: /* cmd ::= SHOW APPS */ + case 246: /* cmd ::= SHOW APPS */ #line 453 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_APPS_STMT); } -#line 6056 "sql.c" +#line 6098 "sql.c" break; - case 246: /* cmd ::= SHOW CONNECTIONS */ + case 247: /* cmd ::= SHOW CONNECTIONS */ #line 454 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONNECTIONS_STMT); } -#line 6061 "sql.c" +#line 6103 "sql.c" break; - case 247: /* cmd ::= SHOW LICENCES */ - case 248: /* cmd ::= SHOW GRANTS */ yytestcase(yyruleno==248); + case 248: /* cmd ::= SHOW LICENCES */ + case 249: /* cmd ::= SHOW GRANTS */ yytestcase(yyruleno==249); #line 455 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LICENCES_STMT); } -#line 6067 "sql.c" +#line 6109 "sql.c" break; - case 249: /* cmd ::= SHOW CREATE DATABASE db_name */ + case 250: /* cmd ::= SHOW CREATE DATABASE db_name */ #line 457 "sql.y" { pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy371); } -#line 6072 "sql.c" +#line 6114 "sql.c" break; - case 250: /* cmd ::= SHOW CREATE TABLE full_table_name */ + case 251: /* cmd ::= SHOW CREATE TABLE full_table_name */ #line 458 "sql.y" { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy452); } -#line 6077 "sql.c" +#line 6119 "sql.c" break; - case 251: /* cmd ::= SHOW CREATE STABLE full_table_name */ + case 252: /* cmd ::= SHOW CREATE STABLE full_table_name */ #line 459 "sql.y" { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy452); } -#line 6082 "sql.c" +#line 6124 "sql.c" break; - case 252: /* cmd ::= SHOW QUERIES */ + case 253: /* cmd ::= SHOW QUERIES */ #line 460 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QUERIES_STMT); } -#line 6087 "sql.c" +#line 6129 "sql.c" break; - case 253: /* cmd ::= SHOW SCORES */ + case 254: /* cmd ::= SHOW SCORES */ #line 461 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SCORES_STMT); } -#line 6092 "sql.c" +#line 6134 "sql.c" break; - case 254: /* cmd ::= SHOW TOPICS */ + case 255: /* cmd ::= SHOW TOPICS */ #line 462 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TOPICS_STMT); } -#line 6097 "sql.c" +#line 6139 "sql.c" break; - case 255: /* cmd ::= SHOW VARIABLES */ - case 256: /* cmd ::= SHOW CLUSTER VARIABLES */ yytestcase(yyruleno==256); + case 256: /* cmd ::= SHOW VARIABLES */ + case 257: /* cmd ::= SHOW CLUSTER VARIABLES */ yytestcase(yyruleno==257); #line 463 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VARIABLES_STMT); } -#line 6103 "sql.c" +#line 6145 "sql.c" break; - case 257: /* cmd ::= SHOW LOCAL VARIABLES */ + case 258: /* cmd ::= SHOW LOCAL VARIABLES */ #line 465 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LOCAL_VARIABLES_STMT); } -#line 6108 "sql.c" +#line 6150 "sql.c" break; - case 258: /* cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ + case 259: /* cmd ::= SHOW DNODE NK_INTEGER VARIABLES like_pattern_opt */ #line 466 "sql.y" { pCxt->pRootNode = createShowDnodeVariablesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[-2].minor.yy0), yymsp[0].minor.yy452); } -#line 6113 "sql.c" +#line 6155 "sql.c" break; - case 259: /* cmd ::= SHOW BNODES */ + case 260: /* cmd ::= SHOW BNODES */ #line 467 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_BNODES_STMT); } -#line 6118 "sql.c" +#line 6160 "sql.c" break; - case 260: /* cmd ::= SHOW SNODES */ + case 261: /* cmd ::= SHOW SNODES */ #line 468 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SNODES_STMT); } -#line 6123 "sql.c" +#line 6165 "sql.c" break; - case 261: /* cmd ::= SHOW CLUSTER */ + case 262: /* cmd ::= SHOW CLUSTER */ #line 469 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_STMT); } -#line 6128 "sql.c" +#line 6170 "sql.c" break; - case 262: /* cmd ::= SHOW TRANSACTIONS */ + case 263: /* cmd ::= SHOW TRANSACTIONS */ #line 470 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TRANSACTIONS_STMT); } -#line 6133 "sql.c" +#line 6175 "sql.c" break; - case 263: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + case 264: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ #line 471 "sql.y" { pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy452); } -#line 6138 "sql.c" +#line 6180 "sql.c" break; - case 264: /* cmd ::= SHOW CONSUMERS */ + case 265: /* cmd ::= SHOW CONSUMERS */ #line 472 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONSUMERS_STMT); } -#line 6143 "sql.c" +#line 6185 "sql.c" break; - case 265: /* cmd ::= SHOW SUBSCRIPTIONS */ + case 266: /* cmd ::= SHOW SUBSCRIPTIONS */ #line 473 "sql.y" { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_SUBSCRIPTIONS_STMT); } -#line 6148 "sql.c" +#line 6190 "sql.c" break; - case 266: /* cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ + case 267: /* cmd ::= SHOW TAGS FROM table_name_cond from_db_opt */ #line 474 "sql.y" { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, yymsp[0].minor.yy452, yymsp[-1].minor.yy452, OP_TYPE_EQUAL); } -#line 6153 "sql.c" +#line 6195 "sql.c" break; - case 267: /* cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ + case 268: /* cmd ::= SHOW TAGS FROM db_name NK_DOT table_name */ #line 475 "sql.y" { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TAGS_STMT, createIdentifierValueNode(pCxt, &yymsp[-2].minor.yy371), createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371), OP_TYPE_EQUAL); } -#line 6158 "sql.c" +#line 6200 "sql.c" break; - case 268: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ + case 269: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM table_name_cond from_db_opt */ #line 476 "sql.y" { pCxt->pRootNode = createShowTableTagsStmt(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452, yymsp[-3].minor.yy812); } -#line 6163 "sql.c" +#line 6205 "sql.c" break; - case 269: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ + case 270: /* cmd ::= SHOW TABLE TAGS tag_list_opt FROM db_name NK_DOT table_name */ #line 477 "sql.y" { pCxt->pRootNode = createShowTableTagsStmt(pCxt, createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371), createIdentifierValueNode(pCxt, &yymsp[-2].minor.yy371), yymsp[-4].minor.yy812); } -#line 6168 "sql.c" +#line 6210 "sql.c" break; - case 270: /* cmd ::= SHOW VNODES ON DNODE NK_INTEGER */ + case 271: /* cmd ::= SHOW VNODES ON DNODE NK_INTEGER */ #line 478 "sql.y" { pCxt->pRootNode = createShowVnodesStmt(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0), NULL); } -#line 6173 "sql.c" +#line 6215 "sql.c" break; - case 271: /* cmd ::= SHOW VNODES */ + case 272: /* cmd ::= SHOW VNODES */ #line 479 "sql.y" { pCxt->pRootNode = createShowVnodesStmt(pCxt, NULL, NULL); } -#line 6178 "sql.c" +#line 6220 "sql.c" break; - case 272: /* cmd ::= SHOW db_name_cond_opt ALIVE */ + case 273: /* cmd ::= SHOW db_name_cond_opt ALIVE */ #line 481 "sql.y" { pCxt->pRootNode = createShowAliveStmt(pCxt, yymsp[-1].minor.yy452, QUERY_NODE_SHOW_DB_ALIVE_STMT); } -#line 6183 "sql.c" +#line 6225 "sql.c" break; - case 273: /* cmd ::= SHOW CLUSTER ALIVE */ + case 274: /* cmd ::= SHOW CLUSTER ALIVE */ #line 482 "sql.y" { pCxt->pRootNode = createShowAliveStmt(pCxt, NULL, QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT); } -#line 6188 "sql.c" +#line 6230 "sql.c" break; - case 274: /* db_name_cond_opt ::= */ - case 279: /* from_db_opt ::= */ yytestcase(yyruleno==279); + case 275: /* db_name_cond_opt ::= */ + case 280: /* from_db_opt ::= */ yytestcase(yyruleno==280); #line 484 "sql.y" { yymsp[1].minor.yy452 = createDefaultDatabaseCondValue(pCxt); } -#line 6194 "sql.c" +#line 6236 "sql.c" break; - case 275: /* db_name_cond_opt ::= db_name NK_DOT */ + case 276: /* db_name_cond_opt ::= db_name NK_DOT */ #line 485 "sql.y" { yylhsminor.yy452 = createIdentifierValueNode(pCxt, &yymsp[-1].minor.yy371); } -#line 6199 "sql.c" +#line 6241 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 277: /* like_pattern_opt ::= LIKE NK_STRING */ + case 278: /* like_pattern_opt ::= LIKE NK_STRING */ #line 488 "sql.y" { yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } -#line 6205 "sql.c" +#line 6247 "sql.c" break; - case 278: /* table_name_cond ::= table_name */ + case 279: /* table_name_cond ::= table_name */ #line 490 "sql.y" { yylhsminor.yy452 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371); } -#line 6210 "sql.c" +#line 6252 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 280: /* from_db_opt ::= FROM db_name */ + case 281: /* from_db_opt ::= FROM db_name */ #line 493 "sql.y" { yymsp[-1].minor.yy452 = createIdentifierValueNode(pCxt, &yymsp[0].minor.yy371); } -#line 6216 "sql.c" +#line 6258 "sql.c" break; - case 284: /* tag_item ::= TBNAME */ + case 285: /* tag_item ::= TBNAME */ #line 501 "sql.y" { yylhsminor.yy452 = setProjectionAlias(pCxt, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL), &yymsp[0].minor.yy0); } -#line 6221 "sql.c" +#line 6263 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 287: /* tag_item ::= column_name column_alias */ + case 288: /* tag_item ::= column_name column_alias */ #line 504 "sql.y" { yylhsminor.yy452 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-1].minor.yy371), &yymsp[0].minor.yy371); } -#line 6227 "sql.c" +#line 6269 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 288: /* tag_item ::= column_name AS column_alias */ + case 289: /* tag_item ::= column_name AS column_alias */ #line 505 "sql.y" { yylhsminor.yy452 = setProjectionAlias(pCxt, createColumnNode(pCxt, NULL, &yymsp[-2].minor.yy371), &yymsp[0].minor.yy371); } -#line 6233 "sql.c" +#line 6275 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 289: /* cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ + case 290: /* cmd ::= CREATE SMA INDEX not_exists_opt full_index_name ON full_table_name index_options */ #line 509 "sql.y" { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy667, yymsp[-3].minor.yy452, yymsp[-1].minor.yy452, NULL, yymsp[0].minor.yy452); } -#line 6239 "sql.c" +#line 6281 "sql.c" break; - case 290: /* cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ + case 291: /* cmd ::= CREATE INDEX not_exists_opt full_index_name ON full_table_name NK_LP col_name_list NK_RP */ #line 511 "sql.y" { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_NORMAL, yymsp[-6].minor.yy667, yymsp[-5].minor.yy452, yymsp[-3].minor.yy452, yymsp[-1].minor.yy812, NULL); } -#line 6244 "sql.c" +#line 6286 "sql.c" break; - case 291: /* cmd ::= DROP INDEX exists_opt full_index_name */ + case 292: /* cmd ::= DROP INDEX exists_opt full_index_name */ #line 512 "sql.y" { pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-1].minor.yy667, yymsp[0].minor.yy452); } -#line 6249 "sql.c" +#line 6291 "sql.c" break; - case 292: /* full_index_name ::= index_name */ + case 293: /* full_index_name ::= index_name */ #line 514 "sql.y" { yylhsminor.yy452 = createRealTableNodeForIndexName(pCxt, NULL, &yymsp[0].minor.yy371); } -#line 6254 "sql.c" +#line 6296 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 293: /* full_index_name ::= db_name NK_DOT index_name */ + case 294: /* full_index_name ::= db_name NK_DOT index_name */ #line 515 "sql.y" { yylhsminor.yy452 = createRealTableNodeForIndexName(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371); } -#line 6260 "sql.c" +#line 6302 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 294: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ + case 295: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ #line 518 "sql.y" { yymsp[-9].minor.yy452 = createIndexOption(pCxt, yymsp[-7].minor.yy812, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } -#line 6266 "sql.c" +#line 6308 "sql.c" break; - case 295: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ + case 296: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ #line 521 "sql.y" { yymsp[-11].minor.yy452 = createIndexOption(pCxt, yymsp[-9].minor.yy812, releaseRawExprNode(pCxt, yymsp[-5].minor.yy452), releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } -#line 6271 "sql.c" +#line 6313 "sql.c" break; - case 298: /* func ::= sma_func_name NK_LP expression_list NK_RP */ + case 299: /* func ::= sma_func_name NK_LP expression_list NK_RP */ #line 528 "sql.y" { yylhsminor.yy452 = createFunctionNode(pCxt, &yymsp[-3].minor.yy371, yymsp[-1].minor.yy812); } -#line 6276 "sql.c" +#line 6318 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 299: /* sma_func_name ::= function_name */ - case 513: /* alias_opt ::= table_alias */ yytestcase(yyruleno==513); + case 300: /* sma_func_name ::= function_name */ + case 514: /* alias_opt ::= table_alias */ yytestcase(yyruleno==514); #line 532 "sql.y" { yylhsminor.yy371 = yymsp[0].minor.yy371; } -#line 6283 "sql.c" +#line 6325 "sql.c" yymsp[0].minor.yy371 = yylhsminor.yy371; break; - case 304: /* sma_stream_opt ::= */ - case 345: /* stream_options ::= */ yytestcase(yyruleno==345); + case 305: /* sma_stream_opt ::= */ + case 346: /* stream_options ::= */ yytestcase(yyruleno==346); #line 538 "sql.y" { yymsp[1].minor.yy452 = createStreamOptions(pCxt); } -#line 6290 "sql.c" +#line 6332 "sql.c" break; - case 305: /* sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ + case 306: /* sma_stream_opt ::= sma_stream_opt WATERMARK duration_literal */ #line 539 "sql.y" { ((SStreamOptions*)yymsp[-2].minor.yy452)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } -#line 6295 "sql.c" +#line 6337 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 306: /* sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ + case 307: /* sma_stream_opt ::= sma_stream_opt MAX_DELAY duration_literal */ #line 540 "sql.y" { ((SStreamOptions*)yymsp[-2].minor.yy452)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } -#line 6301 "sql.c" +#line 6343 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 307: /* sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ + case 308: /* sma_stream_opt ::= sma_stream_opt DELETE_MARK duration_literal */ #line 541 "sql.y" { ((SStreamOptions*)yymsp[-2].minor.yy452)->pDeleteMark = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = yymsp[-2].minor.yy452; } -#line 6307 "sql.c" +#line 6349 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 308: /* with_meta ::= AS */ + case 309: /* with_meta ::= AS */ #line 546 "sql.y" { yymsp[0].minor.yy416 = 0; } -#line 6313 "sql.c" +#line 6355 "sql.c" break; - case 309: /* with_meta ::= WITH META AS */ + case 310: /* with_meta ::= WITH META AS */ #line 547 "sql.y" { yymsp[-2].minor.yy416 = 1; } -#line 6318 "sql.c" +#line 6360 "sql.c" break; - case 310: /* with_meta ::= ONLY META AS */ + case 311: /* with_meta ::= ONLY META AS */ #line 548 "sql.y" { yymsp[-2].minor.yy416 = 2; } -#line 6323 "sql.c" +#line 6365 "sql.c" break; - case 311: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ + case 312: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_or_subquery */ #line 550 "sql.y" { pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, yymsp[-3].minor.yy667, &yymsp[-2].minor.yy371, yymsp[0].minor.yy452); } -#line 6328 "sql.c" +#line 6370 "sql.c" break; - case 312: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ + case 313: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta DATABASE db_name */ #line 552 "sql.y" { pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-4].minor.yy667, &yymsp[-3].minor.yy371, &yymsp[0].minor.yy371, yymsp[-2].minor.yy416); } -#line 6333 "sql.c" +#line 6375 "sql.c" break; - case 313: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ + case 314: /* cmd ::= CREATE TOPIC not_exists_opt topic_name with_meta STABLE full_table_name where_clause_opt */ #line 554 "sql.y" { pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-5].minor.yy667, &yymsp[-4].minor.yy371, yymsp[-1].minor.yy452, yymsp[-3].minor.yy416, yymsp[0].minor.yy452); } -#line 6338 "sql.c" +#line 6380 "sql.c" break; - case 314: /* cmd ::= DROP TOPIC exists_opt topic_name */ + case 315: /* cmd ::= DROP TOPIC exists_opt topic_name */ #line 556 "sql.y" { pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } -#line 6343 "sql.c" +#line 6385 "sql.c" break; - case 315: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + case 316: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ #line 557 "sql.y" { pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy667, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371); } -#line 6348 "sql.c" +#line 6390 "sql.c" break; - case 316: /* cmd ::= DESC full_table_name */ - case 317: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==317); + case 317: /* cmd ::= DESC full_table_name */ + case 318: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==318); #line 560 "sql.y" { pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy452); } -#line 6354 "sql.c" +#line 6396 "sql.c" break; - case 318: /* cmd ::= RESET QUERY CACHE */ + case 319: /* cmd ::= RESET QUERY CACHE */ #line 564 "sql.y" { pCxt->pRootNode = createResetQueryCacheStmt(pCxt); } -#line 6359 "sql.c" +#line 6401 "sql.c" break; - case 319: /* cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ - case 320: /* cmd ::= EXPLAIN analyze_opt explain_options insert_query */ yytestcase(yyruleno==320); + case 320: /* cmd ::= EXPLAIN analyze_opt explain_options query_or_subquery */ + case 321: /* cmd ::= EXPLAIN analyze_opt explain_options insert_query */ yytestcase(yyruleno==321); #line 567 "sql.y" { pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy667, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } -#line 6365 "sql.c" +#line 6407 "sql.c" break; - case 323: /* explain_options ::= */ + case 324: /* explain_options ::= */ #line 575 "sql.y" { yymsp[1].minor.yy452 = createDefaultExplainOptions(pCxt); } -#line 6370 "sql.c" +#line 6412 "sql.c" break; - case 324: /* explain_options ::= explain_options VERBOSE NK_BOOL */ + case 325: /* explain_options ::= explain_options VERBOSE NK_BOOL */ #line 576 "sql.y" { yylhsminor.yy452 = setExplainVerbose(pCxt, yymsp[-2].minor.yy452, &yymsp[0].minor.yy0); } -#line 6375 "sql.c" +#line 6417 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 325: /* explain_options ::= explain_options RATIO NK_FLOAT */ + case 326: /* explain_options ::= explain_options RATIO NK_FLOAT */ #line 577 "sql.y" { yylhsminor.yy452 = setExplainRatio(pCxt, yymsp[-2].minor.yy452, &yymsp[0].minor.yy0); } -#line 6381 "sql.c" +#line 6423 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 326: /* cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ + case 327: /* cmd ::= CREATE or_replace_opt agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt language_opt */ #line 582 "sql.y" { pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-7].minor.yy667, yymsp[-9].minor.yy667, &yymsp[-6].minor.yy371, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy310, yymsp[-1].minor.yy416, &yymsp[0].minor.yy371, yymsp[-10].minor.yy667); } -#line 6387 "sql.c" +#line 6429 "sql.c" break; - case 327: /* cmd ::= DROP FUNCTION exists_opt function_name */ + case 328: /* cmd ::= DROP FUNCTION exists_opt function_name */ #line 583 "sql.y" { pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } -#line 6392 "sql.c" +#line 6434 "sql.c" break; - case 332: /* language_opt ::= */ + case 333: /* language_opt ::= */ #line 597 "sql.y" { yymsp[1].minor.yy371 = nil_token; } -#line 6397 "sql.c" +#line 6439 "sql.c" break; - case 333: /* language_opt ::= LANGUAGE NK_STRING */ + case 334: /* language_opt ::= LANGUAGE NK_STRING */ #line 598 "sql.y" { yymsp[-1].minor.yy371 = yymsp[0].minor.yy0; } -#line 6402 "sql.c" +#line 6444 "sql.c" break; - case 336: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ + case 337: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options INTO full_table_name col_list_opt tag_def_or_ref_opt subtable_opt AS query_or_subquery */ #line 608 "sql.y" { pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-9].minor.yy667, &yymsp[-8].minor.yy371, yymsp[-5].minor.yy452, yymsp[-7].minor.yy452, yymsp[-3].minor.yy812, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, yymsp[-4].minor.yy812); } -#line 6407 "sql.c" +#line 6449 "sql.c" break; - case 337: /* cmd ::= DROP STREAM exists_opt stream_name */ + case 338: /* cmd ::= DROP STREAM exists_opt stream_name */ #line 609 "sql.y" { pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } -#line 6412 "sql.c" +#line 6454 "sql.c" break; - case 338: /* cmd ::= PAUSE STREAM exists_opt stream_name */ + case 339: /* cmd ::= PAUSE STREAM exists_opt stream_name */ #line 610 "sql.y" { pCxt->pRootNode = createPauseStreamStmt(pCxt, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } -#line 6417 "sql.c" +#line 6459 "sql.c" break; - case 339: /* cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ + case 340: /* cmd ::= RESUME STREAM exists_opt ignore_opt stream_name */ #line 611 "sql.y" { pCxt->pRootNode = createResumeStreamStmt(pCxt, yymsp[-2].minor.yy667, yymsp[-1].minor.yy667, &yymsp[0].minor.yy371); } -#line 6422 "sql.c" +#line 6464 "sql.c" break; - case 346: /* stream_options ::= stream_options TRIGGER AT_ONCE */ - case 347: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ yytestcase(yyruleno==347); + case 347: /* stream_options ::= stream_options TRIGGER AT_ONCE */ + case 348: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ yytestcase(yyruleno==348); #line 625 "sql.y" { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_TRIGGER_TYPE_SET, &yymsp[0].minor.yy0, NULL); } -#line 6428 "sql.c" +#line 6470 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 348: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + case 349: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ #line 627 "sql.y" { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_TRIGGER_TYPE_SET, &yymsp[-1].minor.yy0, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } -#line 6434 "sql.c" +#line 6476 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 349: /* stream_options ::= stream_options WATERMARK duration_literal */ + case 350: /* stream_options ::= stream_options WATERMARK duration_literal */ #line 628 "sql.y" { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_WATERMARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } -#line 6440 "sql.c" +#line 6482 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 350: /* stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ + case 351: /* stream_options ::= stream_options IGNORE EXPIRED NK_INTEGER */ #line 629 "sql.y" { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_IGNORE_EXPIRED_SET, &yymsp[0].minor.yy0, NULL); } -#line 6446 "sql.c" +#line 6488 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 351: /* stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ + case 352: /* stream_options ::= stream_options FILL_HISTORY NK_INTEGER */ #line 630 "sql.y" { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_FILL_HISTORY_SET, &yymsp[0].minor.yy0, NULL); } -#line 6452 "sql.c" +#line 6494 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 352: /* stream_options ::= stream_options DELETE_MARK duration_literal */ + case 353: /* stream_options ::= stream_options DELETE_MARK duration_literal */ #line 631 "sql.y" { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-2].minor.yy452, SOPT_DELETE_MARK_SET, NULL, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } -#line 6458 "sql.c" +#line 6500 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 353: /* stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ + case 354: /* stream_options ::= stream_options IGNORE UPDATE NK_INTEGER */ #line 632 "sql.y" { yylhsminor.yy452 = setStreamOptions(pCxt, yymsp[-3].minor.yy452, SOPT_IGNORE_UPDATE_SET, &yymsp[0].minor.yy0, NULL); } -#line 6464 "sql.c" +#line 6506 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 355: /* subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ - case 547: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ yytestcase(yyruleno==547); - case 568: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==568); + case 356: /* subtable_opt ::= SUBTABLE NK_LP expression NK_RP */ + case 548: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ yytestcase(yyruleno==548); + case 569: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==569); #line 635 "sql.y" { yymsp[-3].minor.yy452 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy452); } -#line 6472 "sql.c" +#line 6514 "sql.c" break; - case 358: /* cmd ::= KILL CONNECTION NK_INTEGER */ + case 359: /* cmd ::= KILL CONNECTION NK_INTEGER */ #line 643 "sql.y" { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_CONNECTION_STMT, &yymsp[0].minor.yy0); } -#line 6477 "sql.c" +#line 6519 "sql.c" break; - case 359: /* cmd ::= KILL QUERY NK_STRING */ + case 360: /* cmd ::= KILL QUERY NK_STRING */ #line 644 "sql.y" { pCxt->pRootNode = createKillQueryStmt(pCxt, &yymsp[0].minor.yy0); } -#line 6482 "sql.c" +#line 6524 "sql.c" break; - case 360: /* cmd ::= KILL TRANSACTION NK_INTEGER */ + case 361: /* cmd ::= KILL TRANSACTION NK_INTEGER */ #line 645 "sql.y" { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_TRANSACTION_STMT, &yymsp[0].minor.yy0); } -#line 6487 "sql.c" +#line 6529 "sql.c" break; - case 361: /* cmd ::= BALANCE VGROUP */ + case 362: /* cmd ::= BALANCE VGROUP */ #line 648 "sql.y" { pCxt->pRootNode = createBalanceVgroupStmt(pCxt); } -#line 6492 "sql.c" +#line 6534 "sql.c" break; - case 362: /* cmd ::= BALANCE VGROUP LEADER */ + case 363: /* cmd ::= BALANCE VGROUP LEADER */ #line 649 "sql.y" { pCxt->pRootNode = createBalanceVgroupLeaderStmt(pCxt); } -#line 6497 "sql.c" +#line 6539 "sql.c" break; - case 363: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + case 364: /* cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ #line 650 "sql.y" { pCxt->pRootNode = createMergeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } -#line 6502 "sql.c" +#line 6544 "sql.c" break; - case 364: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + case 365: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ #line 651 "sql.y" { pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy812); } -#line 6507 "sql.c" +#line 6549 "sql.c" break; - case 365: /* cmd ::= SPLIT VGROUP NK_INTEGER */ + case 366: /* cmd ::= SPLIT VGROUP NK_INTEGER */ #line 652 "sql.y" { pCxt->pRootNode = createSplitVgroupStmt(pCxt, &yymsp[0].minor.yy0); } -#line 6512 "sql.c" +#line 6554 "sql.c" break; - case 366: /* dnode_list ::= DNODE NK_INTEGER */ + case 367: /* dnode_list ::= DNODE NK_INTEGER */ #line 656 "sql.y" { yymsp[-1].minor.yy812 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } -#line 6517 "sql.c" +#line 6559 "sql.c" break; - case 368: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ + case 369: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ #line 663 "sql.y" { pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } -#line 6522 "sql.c" +#line 6564 "sql.c" break; - case 371: /* insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ + case 372: /* insert_query ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_or_subquery */ #line 672 "sql.y" { yymsp[-6].minor.yy452 = createInsertStmt(pCxt, yymsp[-4].minor.yy452, yymsp[-2].minor.yy812, yymsp[0].minor.yy452); } -#line 6527 "sql.c" +#line 6569 "sql.c" break; - case 372: /* insert_query ::= INSERT INTO full_table_name query_or_subquery */ + case 373: /* insert_query ::= INSERT INTO full_table_name query_or_subquery */ #line 673 "sql.y" { yymsp[-3].minor.yy452 = createInsertStmt(pCxt, yymsp[-1].minor.yy452, NULL, yymsp[0].minor.yy452); } -#line 6532 "sql.c" +#line 6574 "sql.c" break; - case 373: /* literal ::= NK_INTEGER */ + case 374: /* literal ::= NK_INTEGER */ #line 676 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0)); } -#line 6537 "sql.c" +#line 6579 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 374: /* literal ::= NK_FLOAT */ + case 375: /* literal ::= NK_FLOAT */ #line 677 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } -#line 6543 "sql.c" +#line 6585 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 375: /* literal ::= NK_STRING */ + case 376: /* literal ::= NK_STRING */ #line 678 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } -#line 6549 "sql.c" +#line 6591 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 376: /* literal ::= NK_BOOL */ + case 377: /* literal ::= NK_BOOL */ #line 679 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } -#line 6555 "sql.c" +#line 6597 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 377: /* literal ::= TIMESTAMP NK_STRING */ + case 378: /* literal ::= TIMESTAMP NK_STRING */ #line 680 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } -#line 6561 "sql.c" +#line 6603 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 378: /* literal ::= duration_literal */ - case 388: /* signed_literal ::= signed */ yytestcase(yyruleno==388); - case 409: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==409); - case 410: /* expression ::= literal */ yytestcase(yyruleno==410); - case 411: /* expression ::= pseudo_column */ yytestcase(yyruleno==411); - case 412: /* expression ::= column_reference */ yytestcase(yyruleno==412); - case 413: /* expression ::= function_expression */ yytestcase(yyruleno==413); - case 414: /* expression ::= case_when_expression */ yytestcase(yyruleno==414); - case 445: /* function_expression ::= literal_func */ yytestcase(yyruleno==445); - case 494: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==494); - case 498: /* boolean_primary ::= predicate */ yytestcase(yyruleno==498); - case 500: /* common_expression ::= expr_or_subquery */ yytestcase(yyruleno==500); - case 501: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==501); - case 504: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==504); - case 506: /* table_reference ::= table_primary */ yytestcase(yyruleno==506); - case 507: /* table_reference ::= joined_table */ yytestcase(yyruleno==507); - case 511: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==511); - case 570: /* query_simple ::= query_specification */ yytestcase(yyruleno==570); - case 571: /* query_simple ::= union_query_expression */ yytestcase(yyruleno==571); - case 574: /* query_simple_or_subquery ::= query_simple */ yytestcase(yyruleno==574); - case 576: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==576); + case 379: /* literal ::= duration_literal */ + case 389: /* signed_literal ::= signed */ yytestcase(yyruleno==389); + case 410: /* expr_or_subquery ::= expression */ yytestcase(yyruleno==410); + case 411: /* expression ::= literal */ yytestcase(yyruleno==411); + case 412: /* expression ::= pseudo_column */ yytestcase(yyruleno==412); + case 413: /* expression ::= column_reference */ yytestcase(yyruleno==413); + case 414: /* expression ::= function_expression */ yytestcase(yyruleno==414); + case 415: /* expression ::= case_when_expression */ yytestcase(yyruleno==415); + case 446: /* function_expression ::= literal_func */ yytestcase(yyruleno==446); + case 495: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==495); + case 499: /* boolean_primary ::= predicate */ yytestcase(yyruleno==499); + case 501: /* common_expression ::= expr_or_subquery */ yytestcase(yyruleno==501); + case 502: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==502); + case 505: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==505); + case 507: /* table_reference ::= table_primary */ yytestcase(yyruleno==507); + case 508: /* table_reference ::= joined_table */ yytestcase(yyruleno==508); + case 512: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==512); + case 571: /* query_simple ::= query_specification */ yytestcase(yyruleno==571); + case 572: /* query_simple ::= union_query_expression */ yytestcase(yyruleno==572); + case 575: /* query_simple_or_subquery ::= query_simple */ yytestcase(yyruleno==575); + case 577: /* query_or_subquery ::= query_expression */ yytestcase(yyruleno==577); #line 681 "sql.y" { yylhsminor.yy452 = yymsp[0].minor.yy452; } -#line 6587 "sql.c" +#line 6629 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 379: /* literal ::= NULL */ + case 380: /* literal ::= NULL */ #line 682 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } -#line 6593 "sql.c" +#line 6635 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 380: /* literal ::= NK_QUESTION */ + case 381: /* literal ::= NK_QUESTION */ #line 683 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } -#line 6599 "sql.c" +#line 6641 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 381: /* duration_literal ::= NK_VARIABLE */ + case 382: /* duration_literal ::= NK_VARIABLE */ #line 685 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } -#line 6605 "sql.c" +#line 6647 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 382: /* signed ::= NK_INTEGER */ + case 383: /* signed ::= NK_INTEGER */ #line 687 "sql.y" { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } -#line 6611 "sql.c" +#line 6653 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 383: /* signed ::= NK_PLUS NK_INTEGER */ + case 384: /* signed ::= NK_PLUS NK_INTEGER */ #line 688 "sql.y" { yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_UBIGINT, &yymsp[0].minor.yy0); } -#line 6617 "sql.c" +#line 6659 "sql.c" break; - case 384: /* signed ::= NK_MINUS NK_INTEGER */ + case 385: /* signed ::= NK_MINUS NK_INTEGER */ #line 689 "sql.y" { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t); } -#line 6626 "sql.c" +#line 6668 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 385: /* signed ::= NK_FLOAT */ + case 386: /* signed ::= NK_FLOAT */ #line 694 "sql.y" { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } -#line 6632 "sql.c" +#line 6674 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 386: /* signed ::= NK_PLUS NK_FLOAT */ + case 387: /* signed ::= NK_PLUS NK_FLOAT */ #line 695 "sql.y" { yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } -#line 6638 "sql.c" +#line 6680 "sql.c" break; - case 387: /* signed ::= NK_MINUS NK_FLOAT */ + case 388: /* signed ::= NK_MINUS NK_FLOAT */ #line 696 "sql.y" { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t); } -#line 6647 "sql.c" +#line 6689 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 389: /* signed_literal ::= NK_STRING */ + case 390: /* signed_literal ::= NK_STRING */ #line 703 "sql.y" { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } -#line 6653 "sql.c" +#line 6695 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 390: /* signed_literal ::= NK_BOOL */ + case 391: /* signed_literal ::= NK_BOOL */ #line 704 "sql.y" { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } -#line 6659 "sql.c" +#line 6701 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 391: /* signed_literal ::= TIMESTAMP NK_STRING */ + case 392: /* signed_literal ::= TIMESTAMP NK_STRING */ #line 705 "sql.y" { yymsp[-1].minor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } -#line 6665 "sql.c" - break; - case 392: /* signed_literal ::= duration_literal */ - case 394: /* signed_literal ::= literal_func */ yytestcase(yyruleno==394); - case 465: /* star_func_para ::= expr_or_subquery */ yytestcase(yyruleno==465); - case 527: /* select_item ::= common_expression */ yytestcase(yyruleno==527); - case 537: /* partition_item ::= expr_or_subquery */ yytestcase(yyruleno==537); - case 575: /* query_simple_or_subquery ::= subquery */ yytestcase(yyruleno==575); - case 577: /* query_or_subquery ::= subquery */ yytestcase(yyruleno==577); - case 590: /* search_condition ::= common_expression */ yytestcase(yyruleno==590); +#line 6707 "sql.c" + break; + case 393: /* signed_literal ::= duration_literal */ + case 395: /* signed_literal ::= literal_func */ yytestcase(yyruleno==395); + case 466: /* star_func_para ::= expr_or_subquery */ yytestcase(yyruleno==466); + case 528: /* select_item ::= common_expression */ yytestcase(yyruleno==528); + case 538: /* partition_item ::= expr_or_subquery */ yytestcase(yyruleno==538); + case 576: /* query_simple_or_subquery ::= subquery */ yytestcase(yyruleno==576); + case 578: /* query_or_subquery ::= subquery */ yytestcase(yyruleno==578); + case 591: /* search_condition ::= common_expression */ yytestcase(yyruleno==591); #line 706 "sql.y" { yylhsminor.yy452 = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); } -#line 6677 "sql.c" +#line 6719 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 393: /* signed_literal ::= NULL */ + case 394: /* signed_literal ::= NULL */ #line 707 "sql.y" { yylhsminor.yy452 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } -#line 6683 "sql.c" +#line 6725 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 395: /* signed_literal ::= NK_QUESTION */ + case 396: /* signed_literal ::= NK_QUESTION */ #line 709 "sql.y" { yylhsminor.yy452 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } -#line 6689 "sql.c" +#line 6731 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 415: /* expression ::= NK_LP expression NK_RP */ - case 499: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==499); - case 589: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==589); + case 416: /* expression ::= NK_LP expression NK_RP */ + case 500: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==500); + case 590: /* subquery ::= NK_LP subquery NK_RP */ yytestcase(yyruleno==590); #line 770 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } -#line 6697 "sql.c" +#line 6739 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 416: /* expression ::= NK_PLUS expr_or_subquery */ + case 417: /* expression ::= NK_PLUS expr_or_subquery */ #line 771 "sql.y" { SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } -#line 6706 "sql.c" +#line 6748 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 417: /* expression ::= NK_MINUS expr_or_subquery */ + case 418: /* expression ::= NK_MINUS expr_or_subquery */ #line 775 "sql.y" { SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy452), NULL)); } -#line 6715 "sql.c" +#line 6757 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 418: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ + case 419: /* expression ::= expr_or_subquery NK_PLUS expr_or_subquery */ #line 779 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6725 "sql.c" +#line 6767 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 419: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ + case 420: /* expression ::= expr_or_subquery NK_MINUS expr_or_subquery */ #line 784 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6735 "sql.c" +#line 6777 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 420: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ + case 421: /* expression ::= expr_or_subquery NK_STAR expr_or_subquery */ #line 789 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6745 "sql.c" +#line 6787 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 421: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ + case 422: /* expression ::= expr_or_subquery NK_SLASH expr_or_subquery */ #line 794 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6755 "sql.c" +#line 6797 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 422: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ + case 423: /* expression ::= expr_or_subquery NK_REM expr_or_subquery */ #line 799 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_REM, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6765 "sql.c" +#line 6807 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 423: /* expression ::= column_reference NK_ARROW NK_STRING */ + case 424: /* expression ::= column_reference NK_ARROW NK_STRING */ #line 804 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); } -#line 6774 "sql.c" +#line 6816 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 424: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ + case 425: /* expression ::= expr_or_subquery NK_BITAND expr_or_subquery */ #line 808 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6784 "sql.c" +#line 6826 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 425: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ + case 426: /* expression ::= expr_or_subquery NK_BITOR expr_or_subquery */ #line 813 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6794 "sql.c" +#line 6836 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 428: /* column_reference ::= column_name */ + case 429: /* column_reference ::= column_name */ #line 824 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy371, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy371)); } -#line 6800 "sql.c" +#line 6842 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 429: /* column_reference ::= table_name NK_DOT column_name */ + case 430: /* column_reference ::= table_name NK_DOT column_name */ #line 825 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371, createColumnNode(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy371)); } -#line 6806 "sql.c" +#line 6848 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 430: /* pseudo_column ::= ROWTS */ - case 431: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==431); - case 433: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==433); - case 434: /* pseudo_column ::= QEND */ yytestcase(yyruleno==434); - case 435: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==435); - case 436: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==436); - case 437: /* pseudo_column ::= WEND */ yytestcase(yyruleno==437); - case 438: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==438); - case 439: /* pseudo_column ::= IROWTS */ yytestcase(yyruleno==439); - case 440: /* pseudo_column ::= ISFILLED */ yytestcase(yyruleno==440); - case 441: /* pseudo_column ::= QTAGS */ yytestcase(yyruleno==441); - case 447: /* literal_func ::= NOW */ yytestcase(yyruleno==447); + case 431: /* pseudo_column ::= ROWTS */ + case 432: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==432); + case 434: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==434); + case 435: /* pseudo_column ::= QEND */ yytestcase(yyruleno==435); + case 436: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==436); + case 437: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==437); + case 438: /* pseudo_column ::= WEND */ yytestcase(yyruleno==438); + case 439: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==439); + case 440: /* pseudo_column ::= IROWTS */ yytestcase(yyruleno==440); + case 441: /* pseudo_column ::= ISFILLED */ yytestcase(yyruleno==441); + case 442: /* pseudo_column ::= QTAGS */ yytestcase(yyruleno==442); + case 448: /* literal_func ::= NOW */ yytestcase(yyruleno==448); #line 827 "sql.y" { yylhsminor.yy452 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } -#line 6823 "sql.c" +#line 6865 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 432: /* pseudo_column ::= table_name NK_DOT TBNAME */ + case 433: /* pseudo_column ::= table_name NK_DOT TBNAME */ #line 829 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy371)))); } -#line 6829 "sql.c" +#line 6871 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 442: /* function_expression ::= function_name NK_LP expression_list NK_RP */ - case 443: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==443); + case 443: /* function_expression ::= function_name NK_LP expression_list NK_RP */ + case 444: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==444); #line 840 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy371, yymsp[-1].minor.yy812)); } -#line 6836 "sql.c" +#line 6878 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 444: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ + case 445: /* function_expression ::= CAST NK_LP expr_or_subquery AS type_name NK_RP */ #line 843 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy310)); } -#line 6842 "sql.c" +#line 6884 "sql.c" yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 446: /* literal_func ::= noarg_func NK_LP NK_RP */ + case 447: /* literal_func ::= noarg_func NK_LP NK_RP */ #line 846 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy371, NULL)); } -#line 6848 "sql.c" +#line 6890 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 461: /* star_func_para_list ::= NK_STAR */ + case 462: /* star_func_para_list ::= NK_STAR */ #line 870 "sql.y" { yylhsminor.yy812 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } -#line 6854 "sql.c" +#line 6896 "sql.c" yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 466: /* star_func_para ::= table_name NK_DOT NK_STAR */ - case 530: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==530); + case 467: /* star_func_para ::= table_name NK_DOT NK_STAR */ + case 531: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==531); #line 879 "sql.y" { yylhsminor.yy452 = createColumnNode(pCxt, &yymsp[-2].minor.yy371, &yymsp[0].minor.yy0); } -#line 6861 "sql.c" +#line 6903 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 467: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ + case 468: /* case_when_expression ::= CASE when_then_list case_when_else_opt END */ #line 882 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, NULL, yymsp[-2].minor.yy812, yymsp[-1].minor.yy452)); } -#line 6867 "sql.c" +#line 6909 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 468: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ + case 469: /* case_when_expression ::= CASE common_expression when_then_list case_when_else_opt END */ #line 884 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0, createCaseWhenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-2].minor.yy812, yymsp[-1].minor.yy452)); } -#line 6873 "sql.c" +#line 6915 "sql.c" yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 471: /* when_then_expr ::= WHEN common_expression THEN common_expression */ + case 472: /* when_then_expr ::= WHEN common_expression THEN common_expression */ #line 891 "sql.y" { yymsp[-3].minor.yy452 = createWhenThenNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452)); } -#line 6879 "sql.c" +#line 6921 "sql.c" break; - case 473: /* case_when_else_opt ::= ELSE common_expression */ + case 474: /* case_when_else_opt ::= ELSE common_expression */ #line 894 "sql.y" { yymsp[-1].minor.yy452 = releaseRawExprNode(pCxt, yymsp[0].minor.yy452); } -#line 6884 "sql.c" +#line 6926 "sql.c" break; - case 474: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ - case 479: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==479); + case 475: /* predicate ::= expr_or_subquery compare_op expr_or_subquery */ + case 480: /* predicate ::= expr_or_subquery in_op in_predicate_value */ yytestcase(yyruleno==480); #line 897 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy354, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6894 "sql.c" +#line 6936 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 475: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ + case 476: /* predicate ::= expr_or_subquery BETWEEN expr_or_subquery AND expr_or_subquery */ #line 904 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy452), releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6904 "sql.c" +#line 6946 "sql.c" yymsp[-4].minor.yy452 = yylhsminor.yy452; break; - case 476: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ + case 477: /* predicate ::= expr_or_subquery NOT BETWEEN expr_or_subquery AND expr_or_subquery */ #line 910 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy452), releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 6914 "sql.c" +#line 6956 "sql.c" yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 477: /* predicate ::= expr_or_subquery IS NULL */ + case 478: /* predicate ::= expr_or_subquery IS NULL */ #line 915 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), NULL)); } -#line 6923 "sql.c" +#line 6965 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 478: /* predicate ::= expr_or_subquery IS NOT NULL */ + case 479: /* predicate ::= expr_or_subquery IS NOT NULL */ #line 919 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL)); } -#line 6932 "sql.c" +#line 6974 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 480: /* compare_op ::= NK_LT */ + case 481: /* compare_op ::= NK_LT */ #line 931 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_LOWER_THAN; } -#line 6938 "sql.c" +#line 6980 "sql.c" break; - case 481: /* compare_op ::= NK_GT */ + case 482: /* compare_op ::= NK_GT */ #line 932 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_GREATER_THAN; } -#line 6943 "sql.c" +#line 6985 "sql.c" break; - case 482: /* compare_op ::= NK_LE */ + case 483: /* compare_op ::= NK_LE */ #line 933 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_LOWER_EQUAL; } -#line 6948 "sql.c" +#line 6990 "sql.c" break; - case 483: /* compare_op ::= NK_GE */ + case 484: /* compare_op ::= NK_GE */ #line 934 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_GREATER_EQUAL; } -#line 6953 "sql.c" +#line 6995 "sql.c" break; - case 484: /* compare_op ::= NK_NE */ + case 485: /* compare_op ::= NK_NE */ #line 935 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_NOT_EQUAL; } -#line 6958 "sql.c" +#line 7000 "sql.c" break; - case 485: /* compare_op ::= NK_EQ */ + case 486: /* compare_op ::= NK_EQ */ #line 936 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_EQUAL; } -#line 6963 "sql.c" +#line 7005 "sql.c" break; - case 486: /* compare_op ::= LIKE */ + case 487: /* compare_op ::= LIKE */ #line 937 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_LIKE; } -#line 6968 "sql.c" +#line 7010 "sql.c" break; - case 487: /* compare_op ::= NOT LIKE */ + case 488: /* compare_op ::= NOT LIKE */ #line 938 "sql.y" { yymsp[-1].minor.yy354 = OP_TYPE_NOT_LIKE; } -#line 6973 "sql.c" +#line 7015 "sql.c" break; - case 488: /* compare_op ::= MATCH */ + case 489: /* compare_op ::= MATCH */ #line 939 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_MATCH; } -#line 6978 "sql.c" +#line 7020 "sql.c" break; - case 489: /* compare_op ::= NMATCH */ + case 490: /* compare_op ::= NMATCH */ #line 940 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_NMATCH; } -#line 6983 "sql.c" +#line 7025 "sql.c" break; - case 490: /* compare_op ::= CONTAINS */ + case 491: /* compare_op ::= CONTAINS */ #line 941 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_JSON_CONTAINS; } -#line 6988 "sql.c" +#line 7030 "sql.c" break; - case 491: /* in_op ::= IN */ + case 492: /* in_op ::= IN */ #line 945 "sql.y" { yymsp[0].minor.yy354 = OP_TYPE_IN; } -#line 6993 "sql.c" +#line 7035 "sql.c" break; - case 492: /* in_op ::= NOT IN */ + case 493: /* in_op ::= NOT IN */ #line 946 "sql.y" { yymsp[-1].minor.yy354 = OP_TYPE_NOT_IN; } -#line 6998 "sql.c" +#line 7040 "sql.c" break; - case 493: /* in_predicate_value ::= NK_LP literal_list NK_RP */ + case 494: /* in_predicate_value ::= NK_LP literal_list NK_RP */ #line 948 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } -#line 7003 "sql.c" +#line 7045 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 495: /* boolean_value_expression ::= NOT boolean_primary */ + case 496: /* boolean_value_expression ::= NOT boolean_primary */ #line 952 "sql.y" { SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy452), NULL)); } -#line 7012 "sql.c" +#line 7054 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 496: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + case 497: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ #line 957 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 7022 "sql.c" +#line 7064 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 497: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + case 498: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ #line 963 "sql.y" { SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy452); SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy452); yylhsminor.yy452 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 7032 "sql.c" +#line 7074 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 505: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ + case 506: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ #line 981 "sql.y" { yylhsminor.yy452 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy452, yymsp[0].minor.yy452, NULL); } -#line 7038 "sql.c" +#line 7080 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 508: /* table_primary ::= table_name alias_opt */ + case 509: /* table_primary ::= table_name alias_opt */ #line 987 "sql.y" { yylhsminor.yy452 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } -#line 7044 "sql.c" +#line 7086 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 509: /* table_primary ::= db_name NK_DOT table_name alias_opt */ + case 510: /* table_primary ::= db_name NK_DOT table_name alias_opt */ #line 988 "sql.y" { yylhsminor.yy452 = createRealTableNode(pCxt, &yymsp[-3].minor.yy371, &yymsp[-1].minor.yy371, &yymsp[0].minor.yy371); } -#line 7050 "sql.c" +#line 7092 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 510: /* table_primary ::= subquery alias_opt */ + case 511: /* table_primary ::= subquery alias_opt */ #line 989 "sql.y" { yylhsminor.yy452 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452), &yymsp[0].minor.yy371); } -#line 7056 "sql.c" +#line 7098 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 512: /* alias_opt ::= */ + case 513: /* alias_opt ::= */ #line 994 "sql.y" { yymsp[1].minor.yy371 = nil_token; } -#line 7062 "sql.c" +#line 7104 "sql.c" break; - case 514: /* alias_opt ::= AS table_alias */ + case 515: /* alias_opt ::= AS table_alias */ #line 996 "sql.y" { yymsp[-1].minor.yy371 = yymsp[0].minor.yy371; } -#line 7067 "sql.c" +#line 7109 "sql.c" break; - case 515: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - case 516: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==516); + case 516: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + case 517: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==517); #line 998 "sql.y" { yymsp[-2].minor.yy452 = yymsp[-1].minor.yy452; } -#line 7073 "sql.c" +#line 7115 "sql.c" break; - case 517: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + case 518: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ #line 1003 "sql.y" { yylhsminor.yy452 = createJoinTableNode(pCxt, yymsp[-4].minor.yy140, yymsp[-5].minor.yy452, yymsp[-2].minor.yy452, yymsp[0].minor.yy452); } -#line 7078 "sql.c" +#line 7120 "sql.c" yymsp[-5].minor.yy452 = yylhsminor.yy452; break; - case 518: /* join_type ::= */ + case 519: /* join_type ::= */ #line 1007 "sql.y" { yymsp[1].minor.yy140 = JOIN_TYPE_INNER; } -#line 7084 "sql.c" +#line 7126 "sql.c" break; - case 519: /* join_type ::= INNER */ + case 520: /* join_type ::= INNER */ #line 1008 "sql.y" { yymsp[0].minor.yy140 = JOIN_TYPE_INNER; } -#line 7089 "sql.c" +#line 7131 "sql.c" break; - case 520: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + case 521: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ #line 1014 "sql.y" { yymsp[-11].minor.yy452 = createSelectStmt(pCxt, yymsp[-10].minor.yy667, yymsp[-9].minor.yy812, yymsp[-8].minor.yy452); @@ -7101,213 +7143,213 @@ static YYACTIONTYPE yy_reduce( yymsp[-11].minor.yy452 = addEveryClause(pCxt, yymsp[-11].minor.yy452, yymsp[-4].minor.yy452); yymsp[-11].minor.yy452 = addFillClause(pCxt, yymsp[-11].minor.yy452, yymsp[-3].minor.yy452); } -#line 7104 "sql.c" +#line 7146 "sql.c" break; - case 523: /* set_quantifier_opt ::= ALL */ + case 524: /* set_quantifier_opt ::= ALL */ #line 1030 "sql.y" { yymsp[0].minor.yy667 = false; } -#line 7109 "sql.c" +#line 7151 "sql.c" break; - case 526: /* select_item ::= NK_STAR */ + case 527: /* select_item ::= NK_STAR */ #line 1037 "sql.y" { yylhsminor.yy452 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } -#line 7114 "sql.c" +#line 7156 "sql.c" yymsp[0].minor.yy452 = yylhsminor.yy452; break; - case 528: /* select_item ::= common_expression column_alias */ - case 538: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==538); + case 529: /* select_item ::= common_expression column_alias */ + case 539: /* partition_item ::= expr_or_subquery column_alias */ yytestcase(yyruleno==539); #line 1039 "sql.y" { yylhsminor.yy452 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452), &yymsp[0].minor.yy371); } -#line 7121 "sql.c" +#line 7163 "sql.c" yymsp[-1].minor.yy452 = yylhsminor.yy452; break; - case 529: /* select_item ::= common_expression AS column_alias */ - case 539: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==539); + case 530: /* select_item ::= common_expression AS column_alias */ + case 540: /* partition_item ::= expr_or_subquery AS column_alias */ yytestcase(yyruleno==540); #line 1040 "sql.y" { yylhsminor.yy452 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), &yymsp[0].minor.yy371); } -#line 7128 "sql.c" +#line 7170 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 534: /* partition_by_clause_opt ::= PARTITION BY partition_list */ - case 559: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==559); - case 579: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==579); + case 535: /* partition_by_clause_opt ::= PARTITION BY partition_list */ + case 560: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==560); + case 580: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==580); #line 1049 "sql.y" { yymsp[-2].minor.yy812 = yymsp[0].minor.yy812; } -#line 7136 "sql.c" +#line 7178 "sql.c" break; - case 541: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + case 542: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ #line 1062 "sql.y" { yymsp[-5].minor.yy452 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } -#line 7141 "sql.c" +#line 7183 "sql.c" break; - case 542: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ + case 543: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expr_or_subquery NK_RP */ #line 1063 "sql.y" { yymsp[-3].minor.yy452 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } -#line 7146 "sql.c" +#line 7188 "sql.c" break; - case 543: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + case 544: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ #line 1065 "sql.y" { yymsp[-5].minor.yy452 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), NULL, yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } -#line 7151 "sql.c" +#line 7193 "sql.c" break; - case 544: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + case 545: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ #line 1068 "sql.y" { yymsp[-7].minor.yy452 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy452), releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), yymsp[-1].minor.yy452, yymsp[0].minor.yy452); } -#line 7156 "sql.c" +#line 7198 "sql.c" break; - case 545: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ + case 546: /* twindow_clause_opt ::= EVENT_WINDOW START WITH search_condition END WITH search_condition */ #line 1070 "sql.y" { yymsp[-6].minor.yy452 = createEventWindowNode(pCxt, yymsp[-3].minor.yy452, yymsp[0].minor.yy452); } -#line 7161 "sql.c" +#line 7203 "sql.c" break; - case 549: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ + case 550: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ #line 1076 "sql.y" { yymsp[-3].minor.yy452 = createFillNode(pCxt, yymsp[-1].minor.yy844, NULL); } -#line 7166 "sql.c" +#line 7208 "sql.c" break; - case 550: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ + case 551: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA expression_list NK_RP */ #line 1077 "sql.y" { yymsp[-5].minor.yy452 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } -#line 7171 "sql.c" +#line 7213 "sql.c" break; - case 551: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ + case 552: /* fill_opt ::= FILL NK_LP VALUE_F NK_COMMA expression_list NK_RP */ #line 1078 "sql.y" { yymsp[-5].minor.yy452 = createFillNode(pCxt, FILL_MODE_VALUE_F, createNodeListNode(pCxt, yymsp[-1].minor.yy812)); } -#line 7176 "sql.c" +#line 7218 "sql.c" break; - case 552: /* fill_mode ::= NONE */ + case 553: /* fill_mode ::= NONE */ #line 1082 "sql.y" { yymsp[0].minor.yy844 = FILL_MODE_NONE; } -#line 7181 "sql.c" +#line 7223 "sql.c" break; - case 553: /* fill_mode ::= PREV */ + case 554: /* fill_mode ::= PREV */ #line 1083 "sql.y" { yymsp[0].minor.yy844 = FILL_MODE_PREV; } -#line 7186 "sql.c" +#line 7228 "sql.c" break; - case 554: /* fill_mode ::= NULL */ + case 555: /* fill_mode ::= NULL */ #line 1084 "sql.y" { yymsp[0].minor.yy844 = FILL_MODE_NULL; } -#line 7191 "sql.c" +#line 7233 "sql.c" break; - case 555: /* fill_mode ::= NULL_F */ + case 556: /* fill_mode ::= NULL_F */ #line 1085 "sql.y" { yymsp[0].minor.yy844 = FILL_MODE_NULL_F; } -#line 7196 "sql.c" +#line 7238 "sql.c" break; - case 556: /* fill_mode ::= LINEAR */ + case 557: /* fill_mode ::= LINEAR */ #line 1086 "sql.y" { yymsp[0].minor.yy844 = FILL_MODE_LINEAR; } -#line 7201 "sql.c" +#line 7243 "sql.c" break; - case 557: /* fill_mode ::= NEXT */ + case 558: /* fill_mode ::= NEXT */ #line 1087 "sql.y" { yymsp[0].minor.yy844 = FILL_MODE_NEXT; } -#line 7206 "sql.c" +#line 7248 "sql.c" break; - case 560: /* group_by_list ::= expr_or_subquery */ + case 561: /* group_by_list ::= expr_or_subquery */ #line 1096 "sql.y" { yylhsminor.yy812 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 7211 "sql.c" +#line 7253 "sql.c" yymsp[0].minor.yy812 = yylhsminor.yy812; break; - case 561: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ + case 562: /* group_by_list ::= group_by_list NK_COMMA expr_or_subquery */ #line 1097 "sql.y" { yylhsminor.yy812 = addNodeToList(pCxt, yymsp[-2].minor.yy812, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy452))); } -#line 7217 "sql.c" +#line 7259 "sql.c" yymsp[-2].minor.yy812 = yylhsminor.yy812; break; - case 565: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ + case 566: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_COMMA expr_or_subquery NK_RP */ #line 1104 "sql.y" { yymsp[-5].minor.yy452 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy452), releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } -#line 7223 "sql.c" +#line 7265 "sql.c" break; - case 566: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ + case 567: /* range_opt ::= RANGE NK_LP expr_or_subquery NK_RP */ #line 1106 "sql.y" { yymsp[-3].minor.yy452 = createInterpTimePoint(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy452)); } -#line 7228 "sql.c" +#line 7270 "sql.c" break; - case 569: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ + case 570: /* query_expression ::= query_simple order_by_clause_opt slimit_clause_opt limit_clause_opt */ #line 1113 "sql.y" { yylhsminor.yy452 = addOrderByClause(pCxt, yymsp[-3].minor.yy452, yymsp[-2].minor.yy812); yylhsminor.yy452 = addSlimitClause(pCxt, yylhsminor.yy452, yymsp[-1].minor.yy452); yylhsminor.yy452 = addLimitClause(pCxt, yylhsminor.yy452, yymsp[0].minor.yy452); } -#line 7237 "sql.c" +#line 7279 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 572: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ + case 573: /* union_query_expression ::= query_simple_or_subquery UNION ALL query_simple_or_subquery */ #line 1123 "sql.y" { yylhsminor.yy452 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy452, yymsp[0].minor.yy452); } -#line 7243 "sql.c" +#line 7285 "sql.c" yymsp[-3].minor.yy452 = yylhsminor.yy452; break; - case 573: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ + case 574: /* union_query_expression ::= query_simple_or_subquery UNION query_simple_or_subquery */ #line 1125 "sql.y" { yylhsminor.yy452 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy452, yymsp[0].minor.yy452); } -#line 7249 "sql.c" +#line 7291 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 581: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ - case 585: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==585); + case 582: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ + case 586: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==586); #line 1139 "sql.y" { yymsp[-1].minor.yy452 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } -#line 7256 "sql.c" +#line 7298 "sql.c" break; - case 582: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - case 586: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==586); + case 583: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + case 587: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==587); #line 1140 "sql.y" { yymsp[-3].minor.yy452 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } -#line 7262 "sql.c" +#line 7304 "sql.c" break; - case 583: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - case 587: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==587); + case 584: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + case 588: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==588); #line 1141 "sql.y" { yymsp[-3].minor.yy452 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } -#line 7268 "sql.c" +#line 7310 "sql.c" break; - case 588: /* subquery ::= NK_LP query_expression NK_RP */ + case 589: /* subquery ::= NK_LP query_expression NK_RP */ #line 1149 "sql.y" { yylhsminor.yy452 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy452); } -#line 7273 "sql.c" +#line 7315 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 593: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ + case 594: /* sort_specification ::= expr_or_subquery ordering_specification_opt null_ordering_opt */ #line 1163 "sql.y" { yylhsminor.yy452 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy452), yymsp[-1].minor.yy690, yymsp[0].minor.yy399); } -#line 7279 "sql.c" +#line 7321 "sql.c" yymsp[-2].minor.yy452 = yylhsminor.yy452; break; - case 594: /* ordering_specification_opt ::= */ + case 595: /* ordering_specification_opt ::= */ #line 1167 "sql.y" { yymsp[1].minor.yy690 = ORDER_ASC; } -#line 7285 "sql.c" +#line 7327 "sql.c" break; - case 595: /* ordering_specification_opt ::= ASC */ + case 596: /* ordering_specification_opt ::= ASC */ #line 1168 "sql.y" { yymsp[0].minor.yy690 = ORDER_ASC; } -#line 7290 "sql.c" +#line 7332 "sql.c" break; - case 596: /* ordering_specification_opt ::= DESC */ + case 597: /* ordering_specification_opt ::= DESC */ #line 1169 "sql.y" { yymsp[0].minor.yy690 = ORDER_DESC; } -#line 7295 "sql.c" +#line 7337 "sql.c" break; - case 597: /* null_ordering_opt ::= */ + case 598: /* null_ordering_opt ::= */ #line 1173 "sql.y" { yymsp[1].minor.yy399 = NULL_ORDER_DEFAULT; } -#line 7300 "sql.c" +#line 7342 "sql.c" break; - case 598: /* null_ordering_opt ::= NULLS FIRST */ + case 599: /* null_ordering_opt ::= NULLS FIRST */ #line 1174 "sql.y" { yymsp[-1].minor.yy399 = NULL_ORDER_FIRST; } -#line 7305 "sql.c" +#line 7347 "sql.c" break; - case 599: /* null_ordering_opt ::= NULLS LAST */ + case 600: /* null_ordering_opt ::= NULLS LAST */ #line 1175 "sql.y" { yymsp[-1].minor.yy399 = NULL_ORDER_LAST; } -#line 7310 "sql.c" +#line 7352 "sql.c" break; default: break; @@ -7380,7 +7422,7 @@ static void yy_syntax_error( } else if (TSDB_CODE_PAR_DB_NOT_SPECIFIED == pCxt->errCode && TK_NK_FLOAT == TOKEN.type) { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, TOKEN.z); } -#line 7383 "sql.c" +#line 7425 "sql.c" /************ End %syntax_error code ******************************************/ ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ ParseCTX_STORE diff --git a/source/libs/planner/inc/planInt.h b/source/libs/planner/inc/planInt.h index 092fe1741187dcf3706a64a7be64a3032835b44a..24d77cb9a4ea08aa9aa51b6ac49782022b51f484 100644 --- a/source/libs/planner/inc/planInt.h +++ b/source/libs/planner/inc/planInt.h @@ -43,8 +43,14 @@ int32_t splitLogicPlan(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan); int32_t scaleOutLogicPlan(SPlanContext* pCxt, SLogicSubplan* pLogicSubplan, SQueryLogicPlan** pLogicPlan); int32_t createPhysiPlan(SPlanContext* pCxt, SQueryLogicPlan* pLogicPlan, SQueryPlan** pPlan, SArray* pExecNodeList); -bool isPartTableAgg(SAggLogicNode* pAgg); -bool isPartTableWinodw(SWindowLogicNode* pWindow); +bool isPartTableAgg(SAggLogicNode* pAgg); +bool isPartTagAgg(SAggLogicNode* pAgg); +bool isPartTableWinodw(SWindowLogicNode* pWindow); + +#define CLONE_LIMIT 1 +#define CLONE_SLIMIT 1 << 1 +#define CLONE_LIMIT_SLIMIT (CLONE_LIMIT | CLONE_SLIMIT) +bool cloneLimit(SLogicNode* pParent, SLogicNode* pChild, uint8_t cloneWhat); #ifdef __cplusplus } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 16440be5115c877a2cceb53df00571aae8498ab2..69a7b0cf874b7b301ce7b4ec7f056b7ac48d00d7 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -368,8 +368,8 @@ static void scanPathOptSetGroupOrderScan(SScanLogicNode* pScan) { if (pScan->node.pParent && nodeType(pScan->node.pParent) == QUERY_NODE_LOGIC_PLAN_AGG) { SAggLogicNode* pAgg = (SAggLogicNode*)pScan->node.pParent; - bool withSlimit = pAgg->node.pSlimit != NULL || (pAgg->node.pParent && pAgg->node.pParent->pSlimit); - if (withSlimit && isPartTableAgg(pAgg)) { + bool withSlimit = pAgg->node.pSlimit != NULL; + if (withSlimit && (isPartTableAgg(pAgg) || isPartTagAgg(pAgg))) { pScan->groupOrderScan = pAgg->node.forceCreateNonBlockingOptr = true; } } @@ -2679,6 +2679,9 @@ static int32_t tagScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubp } nodesDestroyNode((SNode*)pAgg); tagScanOptCloneAncestorSlimit((SLogicNode*)pScanNode); + + pScanNode->onlyMetaCtbIdx = false; + pCxt->optimized = true; return TSDB_CODE_SUCCESS; } @@ -2698,39 +2701,31 @@ static void swapLimit(SLogicNode* pParent, SLogicNode* pChild) { pParent->pLimit = NULL; } -static void cloneLimit(SLogicNode* pParent, SLogicNode* pChild) { - SLimitNode* pLimit = NULL; - if (pParent->pLimit) { - pChild->pLimit = nodesCloneNode(pParent->pLimit); - pLimit = (SLimitNode*)pChild->pLimit; - pLimit->limit += pLimit->offset; - pLimit->offset = 0; - } - - if (pParent->pSlimit) { - pChild->pSlimit = nodesCloneNode(pParent->pSlimit); - pLimit = (SLimitNode*)pChild->pSlimit; - pLimit->limit += pLimit->offset; - pLimit->offset = 0; - } -} - static bool pushDownLimitHow(SLogicNode* pNodeWithLimit, SLogicNode* pNodeLimitPushTo); static bool pushDownLimitTo(SLogicNode* pNodeWithLimit, SLogicNode* pNodeLimitPushTo) { switch (nodeType(pNodeLimitPushTo)) { case QUERY_NODE_LOGIC_PLAN_WINDOW: { SWindowLogicNode* pWindow = (SWindowLogicNode*)pNodeLimitPushTo; if (pWindow->winType != WINDOW_TYPE_INTERVAL) break; - cloneLimit(pNodeWithLimit, pNodeLimitPushTo); + cloneLimit(pNodeWithLimit, pNodeLimitPushTo, CLONE_LIMIT_SLIMIT); return true; } case QUERY_NODE_LOGIC_PLAN_FILL: case QUERY_NODE_LOGIC_PLAN_SORT: { - cloneLimit(pNodeWithLimit, pNodeLimitPushTo); + cloneLimit(pNodeWithLimit, pNodeLimitPushTo, CLONE_LIMIT_SLIMIT); SNode* pChild = NULL; FOREACH(pChild, pNodeLimitPushTo->pChildren) { pushDownLimitHow(pNodeLimitPushTo, (SLogicNode*)pChild); } return true; } + case QUERY_NODE_LOGIC_PLAN_AGG: { + if (nodeType(pNodeWithLimit) == QUERY_NODE_LOGIC_PLAN_PROJECT && + (isPartTagAgg((SAggLogicNode*)pNodeLimitPushTo) || isPartTableAgg((SAggLogicNode*)pNodeLimitPushTo))) { + // when part by tag, slimit will be cloned to agg, and it will be pipelined. + // The scan below will do scanning with group order + return cloneLimit(pNodeWithLimit, pNodeLimitPushTo, CLONE_SLIMIT); + } + break; + } case QUERY_NODE_LOGIC_PLAN_SCAN: if (nodeType(pNodeWithLimit) == QUERY_NODE_LOGIC_PLAN_PROJECT && pNodeWithLimit->pLimit) { swapLimit(pNodeWithLimit, pNodeLimitPushTo); diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 06859e195dd8fcb2d2077916e6048a1f0ae7168c..c180be173a9e4e5c6b287a3bd2adee3210f31510 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -511,6 +511,20 @@ static int32_t createSimpleScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSub return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, pScan, pPhyNode); } +static int32_t createTagScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SScanLogicNode* pScanLogicNode, + SPhysiNode** pPhyNode) { + STagScanPhysiNode* pScan = + (STagScanPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pScanLogicNode, QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN); + if (NULL == pScan) { + return TSDB_CODE_OUT_OF_MEMORY; + } + vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode); + + pScan->onlyMetaCtbIdx = pScanLogicNode->onlyMetaCtbIdx; + + return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode); +} + static int32_t createLastRowScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SScanLogicNode* pScanLogicNode, SPhysiNode** pPhyNode) { SLastRowScanPhysiNode* pScan = @@ -646,6 +660,7 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, pCxt->hasScan = true; switch (pScanLogicNode->scanType) { case SCAN_TYPE_TAG: + return createTagScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); case SCAN_TYPE_BLOCK_INFO: return createSimpleScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); case SCAN_TYPE_TABLE_COUNT: @@ -872,12 +887,16 @@ static int32_t rewritePrecalcExpr(SPhysiPlanContext* pCxt, SNode* pNode, SNodeLi } static int32_t createAggPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SAggLogicNode* pAggLogicNode, - SPhysiNode** pPhyNode) { + SPhysiNode** pPhyNode, SSubplan* pSubPlan) { SAggPhysiNode* pAgg = (SAggPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pAggLogicNode, QUERY_NODE_PHYSICAL_PLAN_HASH_AGG); if (NULL == pAgg) { return TSDB_CODE_OUT_OF_MEMORY; } + if (pAgg->node.pSlimit) { + pSubPlan->dynamicRowThreshold = true; + pSubPlan->rowsThreshold = ((SLimitNode*)pAgg->node.pSlimit)->limit; + } pAgg->mergeDataBlock = (GROUP_ACTION_KEEP == pAggLogicNode->node.groupAction ? false : true); pAgg->groupKeyOptimized = pAggLogicNode->hasGroupKeyOptimized; @@ -1617,7 +1636,7 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode case QUERY_NODE_LOGIC_PLAN_JOIN: return createJoinPhysiNode(pCxt, pChildren, (SJoinLogicNode*)pLogicNode, pPhyNode); case QUERY_NODE_LOGIC_PLAN_AGG: - return createAggPhysiNode(pCxt, pChildren, (SAggLogicNode*)pLogicNode, pPhyNode); + return createAggPhysiNode(pCxt, pChildren, (SAggLogicNode*)pLogicNode, pPhyNode, pSubplan); case QUERY_NODE_LOGIC_PLAN_PROJECT: return createProjectPhysiNode(pCxt, pChildren, (SProjectLogicNode*)pLogicNode, pPhyNode); case QUERY_NODE_LOGIC_PLAN_EXCHANGE: @@ -1721,6 +1740,8 @@ static SSubplan* makeSubplan(SPhysiPlanContext* pCxt, SLogicSubplan* pLogicSubpl pSubplan->id = pLogicSubplan->id; pSubplan->subplanType = pLogicSubplan->subplanType; pSubplan->level = pLogicSubplan->level; + pSubplan->rowsThreshold = 4096; + pSubplan->dynamicRowThreshold = false; if (NULL != pCxt->pPlanCxt->pUser) { snprintf(pSubplan->user, sizeof(pSubplan->user), "%s", pCxt->pPlanCxt->pUser); } diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 3f6c73b4e5e5002f27aa85ced327140a9164645e..868aee714749d44d3db1a47c396a89054a6e5ba0 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -867,8 +867,16 @@ static int32_t stbSplSplitAggNodeForPartTable(SSplitContext* pCxt, SStableSplitI static int32_t stbSplSplitAggNodeForCrossTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) { SLogicNode* pPartAgg = NULL; int32_t code = stbSplCreatePartAggNode((SAggLogicNode*)pInfo->pSplitNode, &pPartAgg); + + if (TSDB_CODE_SUCCESS == code) { - code = stbSplCreateExchangeNode(pCxt, pInfo->pSplitNode, pPartAgg); + // if slimit was pushed down to agg, agg will be pipelined mode, add sort merge before parent agg + if ((SAggLogicNode*)pInfo->pSplitNode->pSlimit) + code = stbSplCreateMergeNode(pCxt, NULL, pInfo->pSplitNode, NULL, pPartAgg, true); + else + code = stbSplCreateExchangeNode(pCxt, pInfo->pSplitNode, pPartAgg); + } else { + nodesDestroyNode((SNode*)pPartAgg); } if (TSDB_CODE_SUCCESS == code) { code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren, diff --git a/source/libs/planner/src/planUtil.c b/source/libs/planner/src/planUtil.c index 88086cde1d0edb91e2918a26935495be0b3120ce..9febe102f679801247c30a456d0aee318635c18e 100644 --- a/source/libs/planner/src/planUtil.c +++ b/source/libs/planner/src/planUtil.c @@ -349,7 +349,7 @@ static bool stbHasPartTbname(SNodeList* pPartKeys) { return false; } -static SNodeList* stbSplGetPartKeys(SLogicNode* pNode) { +static SNodeList* stbGetPartKeys(SLogicNode* pNode) { if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) { return ((SScanLogicNode*)pNode)->pGroupTags; } else if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) { @@ -367,11 +367,58 @@ bool isPartTableAgg(SAggLogicNode* pAgg) { return stbHasPartTbname(pAgg->pGroupKeys) && stbNotSystemScan((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0)); } - return stbHasPartTbname(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))); + return stbHasPartTbname(stbGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))); } -bool isPartTableWinodw(SWindowLogicNode* pWindow) { - return stbHasPartTbname(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pWindow->node.pChildren, 0))); +static bool stbHasPartTag(SNodeList* pPartKeys) { + if (NULL == pPartKeys) { + return false; + } + SNode* pPartKey = NULL; + FOREACH(pPartKey, pPartKeys) { + if (QUERY_NODE_GROUPING_SET == nodeType(pPartKey)) { + pPartKey = nodesListGetNode(((SGroupingSetNode*)pPartKey)->pParameterList, 0); + } + if ((QUERY_NODE_FUNCTION == nodeType(pPartKey) && FUNCTION_TYPE_TAGS == ((SFunctionNode*)pPartKey)->funcType) || + (QUERY_NODE_COLUMN == nodeType(pPartKey) && COLUMN_TYPE_TAG == ((SColumnNode*)pPartKey)->colType)) { + return true; + } + } + return false; } +bool isPartTagAgg(SAggLogicNode* pAgg) { + if (1 != LIST_LENGTH(pAgg->node.pChildren)) { + return false; + } + if (pAgg->pGroupKeys) { + return stbHasPartTag(pAgg->pGroupKeys) && + stbNotSystemScan((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0)); + } + return stbHasPartTag(stbGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0))); +} +bool isPartTableWinodw(SWindowLogicNode* pWindow) { + return stbHasPartTbname(stbGetPartKeys((SLogicNode*)nodesListGetNode(pWindow->node.pChildren, 0))); +} + +bool cloneLimit(SLogicNode* pParent, SLogicNode* pChild, uint8_t cloneWhat) { + SLimitNode* pLimit; + bool cloned = false; + if (pParent->pLimit && (cloneWhat & CLONE_LIMIT)) { + pChild->pLimit = nodesCloneNode(pParent->pLimit); + pLimit = (SLimitNode*)pChild->pLimit; + pLimit->limit += pLimit->offset; + pLimit->offset = 0; + cloned = true; + } + + if (pParent->pSlimit && (cloneWhat & CLONE_SLIMIT)) { + pChild->pSlimit = nodesCloneNode(pParent->pSlimit); + pLimit = (SLimitNode*)pChild->pSlimit; + pLimit->limit += pLimit->offset; + pLimit->offset = 0; + cloned = true; + } + return cloned; +} diff --git a/source/libs/stream/inc/streamInt.h b/source/libs/stream/inc/streamInt.h index 32d6dc65d93ab1ddf1a6e383645652b70110f351..7a557a744a19b923212f11a50737c663fd4f90da 100644 --- a/source/libs/stream/inc/streamInt.h +++ b/source/libs/stream/inc/streamInt.h @@ -52,7 +52,6 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock) int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq); -int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData); int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet); int32_t streamDoDispatchScanHistoryFinishMsg(SStreamTask* pTask, const SStreamScanHistoryFinishReq* pReq, int32_t vgId, @@ -63,6 +62,7 @@ SStreamQueueItem* streamMergeQueueItem(SStreamQueueItem* dst, SStreamQueueItem* int32_t streamAddEndScanHistoryMsg(SStreamTask* pTask, SRpcHandleInfo* pRpcInfo, SStreamScanHistoryFinishReq* pReq); int32_t streamNotifyUpstreamContinue(SStreamTask* pTask); int32_t streamTaskFillHistoryFinished(SStreamTask* pTask); +int32_t streamTransferStateToStreamTask(SStreamTask* pTask); extern int32_t streamBackendId; extern int32_t streamBackendCfWrapperId; diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index f85ade591ca48f5403c4c1e0ee59f87a5760462a..03a0f3586ddab40a460dd947b292ed03cb2f0b6f 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -142,40 +142,6 @@ int32_t streamSchedExec(SStreamTask* pTask) { return 0; } -int32_t streamTaskEnqueueBlocks(SStreamTask* pTask, const SStreamDispatchReq* pReq, SRpcMsg* pRsp) { - int8_t status = 0; - - SStreamDataBlock* pBlock = createStreamDataFromDispatchMsg(pReq, STREAM_INPUT__DATA_BLOCK, pReq->dataSrcVgId); - if (pBlock == NULL) { - streamTaskInputFail(pTask); - status = TASK_INPUT_STATUS__FAILED; - qError("vgId:%d, s-task:%s failed to receive dispatch msg, reason: out of memory", pTask->pMeta->vgId, - pTask->id.idStr); - } else { - int32_t code = tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pBlock); - // input queue is full, upstream is blocked now - status = (code == TSDB_CODE_SUCCESS)? TASK_INPUT_STATUS__NORMAL:TASK_INPUT_STATUS__BLOCKED; - } - - // rsp by input status - void* buf = rpcMallocCont(sizeof(SMsgHead) + sizeof(SStreamDispatchRsp)); - ((SMsgHead*)buf)->vgId = htonl(pReq->upstreamNodeId); - SStreamDispatchRsp* pDispatchRsp = POINTER_SHIFT(buf, sizeof(SMsgHead)); - - pDispatchRsp->inputStatus = status; - pDispatchRsp->streamId = htobe64(pReq->streamId); - pDispatchRsp->upstreamNodeId = htonl(pReq->upstreamNodeId); - pDispatchRsp->upstreamTaskId = htonl(pReq->upstreamTaskId); - pDispatchRsp->downstreamNodeId = htonl(pTask->info.nodeId); - pDispatchRsp->downstreamTaskId = htonl(pTask->id.taskId); - - pRsp->pCont = buf; - pRsp->contLen = sizeof(SMsgHead) + sizeof(SStreamDispatchRsp); - tmsgSendRsp(pRsp); - - return status == TASK_INPUT_STATUS__NORMAL ? 0 : -1; -} - int32_t streamTaskEnqueueRetrieve(SStreamTask* pTask, SStreamRetrieveReq* pReq, SRpcMsg* pRsp) { SStreamDataBlock* pData = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, 0); int8_t status = TASK_INPUT_STATUS__NORMAL; @@ -235,90 +201,115 @@ int32_t streamTaskOutputResultBlock(SStreamTask* pTask, SStreamDataBlock* pBlock return 0; } -int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) { - qDebug("s-task:%s receive dispatch msg from taskId:0x%x(vgId:%d), msgLen:%" PRId64, pTask->id.idStr, - pReq->upstreamTaskId, pReq->upstreamNodeId, pReq->totalLen); - // todo add the input queue buffer limitation - streamTaskEnqueueBlocks(pTask, pReq, pRsp); - tDeleteStreamDispatchReq(pReq); - if (exec) { - if (streamTryExec(pTask) < 0) { - return -1; - } +static int32_t streamTaskAppendInputBlocks(SStreamTask* pTask, const SStreamDispatchReq* pReq) { + int8_t status = 0; + + SStreamDataBlock* pBlock = createStreamDataFromDispatchMsg(pReq, pReq->type, pReq->srcVgId); + if (pBlock == NULL) { + streamTaskInputFail(pTask); + status = TASK_INPUT_STATUS__FAILED; + qError("vgId:%d, s-task:%s failed to receive dispatch msg, reason: out of memory", pTask->pMeta->vgId, + pTask->id.idStr); } else { - streamSchedExec(pTask); + if (pBlock->type == STREAM_INPUT__TRANS_STATE) { + pTask->status.appendTranstateBlock = true; + } + + int32_t code = tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pBlock); + // input queue is full, upstream is blocked now + status = (code == TSDB_CODE_SUCCESS) ? TASK_INPUT_STATUS__NORMAL : TASK_INPUT_STATUS__BLOCKED; } - return 0; + return status; } -// todo record the idle time for dispatch data -int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code) { - if (code != TSDB_CODE_SUCCESS) { - // dispatch message failed: network error, or node not available. - // in case of the input queue is full, the code will be TSDB_CODE_SUCCESS, the and pRsp>inputStatus will be set - // flag. here we need to retry dispatch this message to downstream task immediately. handle the case the failure - // happened too fast. todo handle the shuffle dispatch failure - if (code == TSDB_CODE_STREAM_TASK_NOT_EXIST) { - qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, no-retry", pTask->id.idStr, - pRsp->downstreamTaskId, tstrerror(code)); - return code; - } else { - qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", pTask->id.idStr, - pRsp->downstreamTaskId, tstrerror(code), ++pTask->msgInfo.retryCount); - return streamDispatchAllBlocks(pTask, pTask->msgInfo.pData); - } +static int32_t buildDispatchRsp(const SStreamTask* pTask, const SStreamDispatchReq* pReq, int32_t status, void** pBuf) { + *pBuf = rpcMallocCont(sizeof(SMsgHead) + sizeof(SStreamDispatchRsp)); + if (*pBuf == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; } - qDebug("s-task:%s receive dispatch rsp, output status:%d code:%d", pTask->id.idStr, pRsp->inputStatus, code); + ((SMsgHead*)(*pBuf))->vgId = htonl(pReq->upstreamNodeId); + SStreamDispatchRsp* pDispatchRsp = POINTER_SHIFT((*pBuf), sizeof(SMsgHead)); - // there are other dispatch message not response yet - if (pTask->outputInfo.type == TASK_OUTPUT__SHUFFLE_DISPATCH) { - int32_t leftRsp = atomic_sub_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1); - qDebug("s-task:%s is shuffle, left waiting rsp %d", pTask->id.idStr, leftRsp); - if (leftRsp > 0) { - return 0; - } + pDispatchRsp->inputStatus = status; + pDispatchRsp->streamId = htobe64(pReq->streamId); + pDispatchRsp->upstreamNodeId = htonl(pReq->upstreamNodeId); + pDispatchRsp->upstreamTaskId = htonl(pReq->upstreamTaskId); + pDispatchRsp->downstreamNodeId = htonl(pTask->info.nodeId); + pDispatchRsp->downstreamTaskId = htonl(pTask->id.taskId); + + return TSDB_CODE_SUCCESS; +} + +void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId) { + SStreamChildEpInfo* pInfo = streamTaskGetUpstreamTaskEpInfo(pTask, taskId); + if (pInfo != NULL) { + pInfo->dataAllowed = false; } +} + +int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) { + qDebug("s-task:%s receive dispatch msg from taskId:0x%x(vgId:%d), msgLen:%" PRId64, pTask->id.idStr, + pReq->upstreamTaskId, pReq->upstreamNodeId, pReq->totalLen); + + int32_t status = 0; + + SStreamChildEpInfo* pInfo = streamTaskGetUpstreamTaskEpInfo(pTask, pReq->upstreamTaskId); + ASSERT(pInfo != NULL); - pTask->msgInfo.retryCount = 0; - ASSERT(pTask->outputInfo.status == TASK_OUTPUT_STATUS__WAIT); - - qDebug("s-task:%s output status is set to:%d", pTask->id.idStr, pTask->outputInfo.status); - - // the input queue of the (down stream) task that receive the output data is full, - // so the TASK_INPUT_STATUS_BLOCKED is rsp - // todo blocking the output status - if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) { - pTask->msgInfo.blockingTs = taosGetTimestampMs(); // record the blocking start time - - int32_t waitDuration = 300; // 300 ms - qError("s-task:%s inputQ of downstream task:0x%x is full, time:%" PRId64 "wait for %dms and retry dispatch data", - pTask->id.idStr, pRsp->downstreamTaskId, pTask->msgInfo.blockingTs, waitDuration); - streamRetryDispatchStreamBlock(pTask, waitDuration); - } else { // pipeline send data in output queue - // this message has been sent successfully, let's try next one. - destroyStreamDataBlock(pTask->msgInfo.pData); - pTask->msgInfo.pData = NULL; - - if (pTask->msgInfo.blockingTs != 0) { - int64_t el = taosGetTimestampMs() - pTask->msgInfo.blockingTs; - qDebug("s-task:%s resume to normal from inputQ blocking, idle time:%"PRId64"ms", pTask->id.idStr, el); - pTask->msgInfo.blockingTs = 0; + if (!pInfo->dataAllowed) { + qWarn("s-task:%s data from task:0x%x is denied, since inputQ is closed for it", pTask->id.idStr, pReq->upstreamTaskId); + status = TASK_INPUT_STATUS__BLOCKED; + } else { + // Current task has received the checkpoint req from the upstream task, from which the message should all be blocked + if (pReq->type == STREAM_INPUT__CHECKPOINT_TRIGGER) { + streamTaskCloseUpstreamInput(pTask, pReq->upstreamTaskId); + qDebug("s-task:%s close inputQ for upstream:0x%x", pTask->id.idStr, pReq->upstreamTaskId); } - // now ready for next data output - atomic_store_8(&pTask->outputInfo.status, TASK_OUTPUT_STATUS__NORMAL); + status = streamTaskAppendInputBlocks(pTask, pReq); + } - // otherwise, continue dispatch the first block to down stream task in pipeline - streamDispatchStreamBlock(pTask); + { + // do send response with the input status + int32_t code = buildDispatchRsp(pTask, pReq, status, &pRsp->pCont); + if (code != TSDB_CODE_SUCCESS) { + // todo handle failure + return code; + } + + pRsp->contLen = sizeof(SMsgHead) + sizeof(SStreamDispatchRsp); + tmsgSendRsp(pRsp); } + tDeleteStreamDispatchReq(pReq); + streamSchedExec(pTask); + return 0; } +//int32_t streamProcessDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) { +// qDebug("s-task:%s receive dispatch msg from taskId:0x%x(vgId:%d), msgLen:%" PRId64, pTask->id.idStr, +// pReq->upstreamTaskId, pReq->upstreamNodeId, pReq->totalLen); +// +// // todo add the input queue buffer limitation +// streamTaskEnqueueBlocks(pTask, pReq, pRsp); +// tDeleteStreamDispatchReq(pReq); +// +// if (exec) { +// if (streamTryExec(pTask) < 0) { +// return -1; +// } +// } else { +// streamSchedExec(pTask); +// } +// +// return 0; +//} + int32_t streamProcessRunReq(SStreamTask* pTask) { if (streamTryExec(pTask) < 0) { return -1; @@ -371,7 +362,7 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { msgLen, ver, total, size + msgLen/1048576.0); } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE || type == STREAM_INPUT__REF_DATA_BLOCK) { - if ((pTask->info.taskLevel == TASK_LEVEL__SOURCE) && (tInputQueueIsFull(pTask))) { + if (/*(pTask->info.taskLevel == TASK_LEVEL__SOURCE) && */(tInputQueueIsFull(pTask))) { qError("s-task:%s input queue is full, capacity:%d size:%d MiB, current(blocks:%d, size:%.2fMiB) abort", pTask->id.idStr, STREAM_TASK_INPUT_QUEUE_CAPACITY, STREAM_TASK_INPUT_QUEUE_CAPACITY_IN_SIZE, total, size); @@ -385,12 +376,15 @@ int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem) { destroyStreamDataBlock((SStreamDataBlock*) pItem); return code; } - } else if (type == STREAM_INPUT__CHECKPOINT) { + } else if (type == STREAM_INPUT__CHECKPOINT || type == STREAM_INPUT__TRANS_STATE) { taosWriteQitem(pTask->inputQueue->queue, pItem); + qDebug("s-task:%s checkpoint/trans-state blockdata enqueue, total in queue:%d, size:%.2fMiB", pTask->id.idStr, total, size); } else if (type == STREAM_INPUT__GET_RES) { // use the default memory limit, refactor later. taosWriteQitem(pTask->inputQueue->queue, pItem); qDebug("s-task:%s data res enqueue, current(blocks:%d, size:%.2fMiB)", pTask->id.idStr, total, size); + } else { + ASSERT(0); } if (type != STREAM_INPUT__GET_RES && type != STREAM_INPUT__CHECKPOINT && pTask->triggerParam != 0) { @@ -433,4 +427,16 @@ SStreamChildEpInfo * streamTaskGetUpstreamTaskEpInfo(SStreamTask* pTask, int32_t } return NULL; -} \ No newline at end of file +} + +void streamTaskOpenAllUpstreamInput(SStreamTask* pTask) { + int32_t num = taosArrayGetSize(pTask->pUpstreamEpInfoList); + if (num == 0) { + return; + } + + for(int32_t i = 0; i < num; ++i) { + SStreamChildEpInfo* pInfo = taosArrayGetP(pTask->pUpstreamEpInfoList, i); + pInfo->dataAllowed = true; + } +} diff --git a/source/libs/stream/src/streamData.c b/source/libs/stream/src/streamData.c index bb4b842787a640435f561d6e75074869da8885af..fc1b788b773941da01535bf098474ba736a38d1f 100644 --- a/source/libs/stream/src/streamData.c +++ b/source/libs/stream/src/streamData.c @@ -204,7 +204,7 @@ void streamFreeQitem(SStreamQueueItem* data) { if (type == STREAM_INPUT__GET_RES) { blockDataDestroy(((SStreamTrigger*)data)->pBlock); taosFreeQitem(data); - } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE) { + } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE || type == STREAM_INPUT__TRANS_STATE) { taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)blockDataFreeRes); taosFreeQitem(data); } else if (type == STREAM_INPUT__DATA_SUBMIT) { diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 6771d0cc283c54b42c958cb8d3916fef31c4e821..694b0808f2869b58c4d805f0ab236566c12b31b6 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -25,6 +25,9 @@ typedef struct SBlockName { char parTbName[TSDB_TABLE_NAME_LEN]; } SBlockName; +static int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, + int32_t numOfBlocks, int64_t dstTaskId, int32_t type); + static void initRpcMsg(SRpcMsg* pMsg, int32_t msgType, void* pCont, int32_t contLen) { pMsg->msgType = msgType; pMsg->pCont = pCont; @@ -35,8 +38,9 @@ static int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatc if (tStartEncode(pEncoder) < 0) return -1; if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->taskId) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->type) < 0) return -1; if (tEncodeI32(pEncoder, pReq->upstreamTaskId) < 0) return -1; - if (tEncodeI32(pEncoder, pReq->dataSrcVgId) < 0) return -1; + if (tEncodeI32(pEncoder, pReq->srcVgId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->upstreamChildId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->upstreamNodeId) < 0) return -1; if (tEncodeI32(pEncoder, pReq->blockNum) < 0) return -1; @@ -88,8 +92,9 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { if (tStartDecode(pDecoder) < 0) return -1; if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->taskId) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->type) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->upstreamTaskId) < 0) return -1; - if (tDecodeI32(pDecoder, &pReq->dataSrcVgId) < 0) return -1; + if (tDecodeI32(pDecoder, &pReq->srcVgId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->upstreamChildId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->upstreamNodeId) < 0) return -1; if (tDecodeI32(pDecoder, &pReq->blockNum) < 0) return -1; @@ -113,14 +118,15 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) { } int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTask* pTask, int32_t vgId, int32_t numOfBlocks, - int64_t dstTaskId) { + int64_t dstTaskId, int32_t type) { pReq->streamId = pTask->id.streamId; - pReq->dataSrcVgId = vgId; + pReq->srcVgId = vgId; pReq->upstreamTaskId = pTask->id.taskId; pReq->upstreamChildId = pTask->info.selfChildId; pReq->upstreamNodeId = pTask->info.nodeId; pReq->blockNum = numOfBlocks; pReq->taskId = dstTaskId; + pReq->type = type; pReq->data = taosArrayInit(numOfBlocks, POINTER_BYTES); pReq->dataLen = taosArrayInit(numOfBlocks, sizeof(int32_t)); @@ -358,7 +364,8 @@ static int32_t doSendDispatchMsg(SStreamTask* pTask, const SStreamDispatchReq* p msg.pCont = buf; msg.msgType = pTask->msgInfo.msgType; - qDebug("s-task:%s dispatch msg to taskId:0x%x vgId:%d data msg", pTask->id.idStr, pReq->taskId, vgId); + qDebug("s-task:%s dispatch msg to taskId:0x%x vgId:%d data msg, len:%d", pTask->id.idStr, pReq->taskId, vgId, + msg.contLen); return tmsgSendReq(pEpSet, &msg); FAIL: @@ -436,9 +443,8 @@ int32_t streamSearchAndAddBlock(SStreamTask* pTask, SStreamDispatchReq* pReqs, S return 0; } -int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { +static int32_t doDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pData) { int32_t code = 0; - int32_t numOfBlocks = taosArrayGetSize(pData->blocks); ASSERT(numOfBlocks != 0); @@ -446,15 +452,15 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat SStreamDispatchReq req = {0}; int32_t downstreamTaskId = pTask->fixedEpDispatcher.taskId; - code = tInitStreamDispatchReq(&req, pTask, pData->srcVgId, numOfBlocks, downstreamTaskId); + code = tInitStreamDispatchReq(&req, pTask, pData->srcVgId, numOfBlocks, downstreamTaskId, pData->type); if (code != TSDB_CODE_SUCCESS) { return code; } for (int32_t i = 0; i < numOfBlocks; i++) { SSDataBlock* pDataBlock = taosArrayGet(pData->blocks, i); - code = streamAddBlockIntoDispatchMsg(pDataBlock, &req); + code = streamAddBlockIntoDispatchMsg(pDataBlock, &req); if (code != TSDB_CODE_SUCCESS) { taosArrayDestroyP(req.data, taosMemoryFree); taosArrayDestroy(req.dataLen); @@ -487,7 +493,7 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat for (int32_t i = 0; i < vgSz; i++) { SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - code = tInitStreamDispatchReq(&pReqs[i], pTask, pData->srcVgId, 0, pVgInfo->taskId); + code = tInitStreamDispatchReq(&pReqs[i], pTask, pData->srcVgId, 0, pVgInfo->taskId, pData->type); if (code != TSDB_CODE_SUCCESS) { goto FAIL_SHUFFLE_DISPATCH; } @@ -497,8 +503,7 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat SSDataBlock* pDataBlock = taosArrayGet(pData->blocks, i); // TODO: do not use broadcast - if (pDataBlock->info.type == STREAM_DELETE_RESULT) { - + if (pDataBlock->info.type == STREAM_DELETE_RESULT || pDataBlock->info.type == STREAM_CHECKPOINT || pDataBlock->info.type == STREAM_TRANS_STATE) { for (int32_t j = 0; j < vgSz; j++) { if (streamAddBlockIntoDispatchMsg(pDataBlock, &pReqs[j]) < 0) { goto FAIL_SHUFFLE_DISPATCH; @@ -518,14 +523,14 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat } } - qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to %d vgroups", pTask->id.idStr, pTask->info.selfChildId, - numOfBlocks, vgSz); + qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to %d vgroups", pTask->id.idStr, + pTask->info.selfChildId, numOfBlocks, vgSz); for (int32_t i = 0; i < vgSz; i++) { if (pReqs[i].blockNum > 0) { SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to vgId:%d", pTask->id.idStr, pTask->info.selfChildId, - pReqs[i].blockNum, pVgInfo->vgId); + qDebug("s-task:%s (child taskId:%d) shuffle-dispatch blocks:%d to vgId:%d", pTask->id.idStr, + pTask->info.selfChildId, pReqs[i].blockNum, pVgInfo->vgId); code = doSendDispatchMsg(pTask, &pReqs[i], pVgInfo->vgId, &pVgInfo->epSet); if (code < 0) { @@ -536,7 +541,7 @@ int32_t streamDispatchAllBlocks(SStreamTask* pTask, const SStreamDataBlock* pDat code = 0; - FAIL_SHUFFLE_DISPATCH: + FAIL_SHUFFLE_DISPATCH: for (int32_t i = 0; i < vgSz; i++) { taosArrayDestroyP(pReqs[i].data, taosMemoryFree); taosArrayDestroy(pReqs[i].dataLen); @@ -559,7 +564,7 @@ static void doRetryDispatchData(void* param, void* tmrId) { ASSERT(pTask->outputInfo.status == TASK_OUTPUT_STATUS__WAIT); - int32_t code = streamDispatchAllBlocks(pTask, pTask->msgInfo.pData); + int32_t code = doDispatchAllBlocks(pTask, pTask->msgInfo.pData); if (code != TSDB_CODE_SUCCESS) { if (!streamTaskShouldStop(&pTask->status)) { qDebug("s-task:%s reset the waitRspCnt to be 0 before launch retry dispatch", pTask->id.idStr); @@ -607,12 +612,13 @@ int32_t streamDispatchStreamBlock(SStreamTask* pTask) { } pTask->msgInfo.pData = pBlock; - ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK); + ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK || pBlock->type == STREAM_INPUT__CHECKPOINT_TRIGGER || + pBlock->type == STREAM_INPUT__TRANS_STATE); int32_t retryCount = 0; while (1) { - int32_t code = streamDispatchAllBlocks(pTask, pBlock); + int32_t code = doDispatchAllBlocks(pTask, pBlock); if (code == TSDB_CODE_SUCCESS) { break; } @@ -729,3 +735,88 @@ int32_t streamNotifyUpstreamContinue(SStreamTask* pTask) { num); return 0; } + +int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, int32_t code) { + const char* id = pTask->id.idStr; + + if (code != TSDB_CODE_SUCCESS) { + // dispatch message failed: network error, or node not available. + // in case of the input queue is full, the code will be TSDB_CODE_SUCCESS, the and pRsp>inputStatus will be set + // flag. here we need to retry dispatch this message to downstream task immediately. handle the case the failure + // happened too fast. + // todo handle the shuffle dispatch failure + if (code == TSDB_CODE_STREAM_TASK_NOT_EXIST) { // destination task does not exist, not retry anymore + qWarn("s-task:%s failed to dispatch msg to task:0x%x, no retry, since it is destroyed already", id, pRsp->downstreamTaskId); + } else { + qError("s-task:%s failed to dispatch msg to task:0x%x, code:%s, retry cnt:%d", id, pRsp->downstreamTaskId, + tstrerror(code), ++pTask->msgInfo.retryCount); + int32_t ret = doDispatchAllBlocks(pTask, pTask->msgInfo.pData); + if (ret != TSDB_CODE_SUCCESS) { + } + } + + return TSDB_CODE_SUCCESS; + } + + qDebug("s-task:%s recv dispatch rsp from 0x%x, downstream task input status:%d code:%d", id, pRsp->downstreamTaskId, + pRsp->inputStatus, code); + + // there are other dispatch message not response yet + if (pTask->outputInfo.type == TASK_OUTPUT__SHUFFLE_DISPATCH) { + int32_t leftRsp = atomic_sub_fetch_32(&pTask->shuffleDispatcher.waitingRspCnt, 1); + qDebug("s-task:%s is shuffle, left waiting rsp %d", id, leftRsp); + if (leftRsp > 0) { + return 0; + } + } + + // transtate msg has been sent to downstream successfully. let's transfer the fill-history task state + SStreamDataBlock* p = pTask->msgInfo.pData; + if (p->type == STREAM_INPUT__TRANS_STATE) { + qDebug("s-task:%s dispatch transtate msg to downstream successfully, start to transfer state", id); + ASSERT(pTask->info.fillHistory == 1); + code = streamTransferStateToStreamTask(pTask); + if (code != TSDB_CODE_SUCCESS) { // todo: do nothing if error happens + } + + streamFreeQitem(pTask->msgInfo.pData); + return TSDB_CODE_SUCCESS; + } + + pTask->msgInfo.retryCount = 0; + ASSERT(pTask->outputInfo.status == TASK_OUTPUT_STATUS__WAIT); + + qDebug("s-task:%s output status is set to:%d", id, pTask->outputInfo.status); + + // the input queue of the (down stream) task that receive the output data is full, + // so the TASK_INPUT_STATUS_BLOCKED is rsp + if (pRsp->inputStatus == TASK_INPUT_STATUS__BLOCKED) { + pTask->inputStatus = TASK_INPUT_STATUS__BLOCKED; // block the input of current task, to push pressure to upstream + pTask->msgInfo.blockingTs = taosGetTimestampMs(); // record the blocking start time + qError("s-task:%s inputQ of downstream task:0x%x is full, time:%" PRId64 " wait for %dms and retry dispatch data", + id, pRsp->downstreamTaskId, pTask->msgInfo.blockingTs, DISPATCH_RETRY_INTERVAL_MS); + streamRetryDispatchStreamBlock(pTask, DISPATCH_RETRY_INTERVAL_MS); + } else { // pipeline send data in output queue + // this message has been sent successfully, let's try next one. + destroyStreamDataBlock(pTask->msgInfo.pData); + pTask->msgInfo.pData = NULL; + + if (pTask->msgInfo.blockingTs != 0) { + int64_t el = taosGetTimestampMs() - pTask->msgInfo.blockingTs; + qDebug("s-task:%s downstream task:0x%x resume to normal from inputQ blocking, blocking time:%" PRId64 "ms", id, + pRsp->downstreamTaskId, el); + pTask->msgInfo.blockingTs = 0; + + // put data into inputQ of current task is also allowed + pTask->inputStatus = TASK_INPUT_STATUS__NORMAL; + } + + // now ready for next data output + atomic_store_8(&pTask->outputInfo.status, TASK_OUTPUT_STATUS__NORMAL); + + // otherwise, continue dispatch the first block to down stream task in pipeline + streamDispatchStreamBlock(pTask); + } + + return 0; +} diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index c7da80fdaf216896a6838d372cda4650990b7e90..fa3379308779f048f03758f60e10bce4a6710415 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -191,6 +191,12 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSize) { return 0; } + if (pTask->inputStatus == TASK_INPUT_STATUS__BLOCKED) { + qDebug("s-task:%s inputQ is blocked, wait for 10sec and retry", pTask->id.idStr); + taosMsleep(10000); + continue; + } + SSDataBlock* output = NULL; uint64_t ts = 0; code = qExecTask(exec, &output, &ts); @@ -287,21 +293,32 @@ static void waitForTaskIdle(SStreamTask* pTask, SStreamTask* pStreamTask) { } } -static int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { +int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { SStreamMeta* pMeta = pTask->pMeta; SStreamTask* pStreamTask = streamMetaAcquireTask(pMeta, pTask->streamTaskId.streamId, pTask->streamTaskId.taskId); if (pStreamTask == NULL) { - // todo: destroy the fill-history task here - qError("s-task:%s failed to find related stream task:0x%x, it may have been destroyed or closed", pTask->id.idStr, - pTask->streamTaskId.taskId); + qError( + "s-task:%s failed to find related stream task:0x%x, it may have been destroyed or closed, destroy the related " + "fill-history task", + pTask->id.idStr, pTask->streamTaskId.taskId); + + // 1. free it and remove fill-history task from disk meta-store + streamMetaUnregisterTask(pMeta, pTask->id.streamId, pTask->id.taskId); + + // 2. save to disk + taosWLockLatch(&pMeta->lock); + if (streamMetaCommit(pMeta) < 0) { + // persist to disk + } + taosWUnLockLatch(&pMeta->lock); return TSDB_CODE_STREAM_TASK_NOT_EXIST; } else { qDebug("s-task:%s fill-history task end, update related stream task:%s info, transfer exec state", pTask->id.idStr, pStreamTask->id.idStr); } - ASSERT(pStreamTask->historyTaskId.taskId == pTask->id.taskId && pTask->status.transferState == true); + ASSERT(pStreamTask->historyTaskId.taskId == pTask->id.taskId && pTask->status.appendTranstateBlock == true); STimeWindow* pTimeWindow = &pStreamTask->dataRange.window; @@ -380,34 +397,52 @@ static int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { return TSDB_CODE_SUCCESS; } -static int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { +int32_t streamTransferStateToStreamTask(SStreamTask* pTask) { int32_t code = TSDB_CODE_SUCCESS; - if (!pTask->status.transferState) { - return code; - } + ASSERT(pTask->status.appendTranstateBlock == 1); int32_t level = pTask->info.taskLevel; if (level == TASK_LEVEL__SOURCE) { streamTaskFillHistoryFinished(pTask); - streamTaskEndScanWAL(pTask); - } else if (level == TASK_LEVEL__AGG) { // do transfer task operator states. + } + + if (level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) { // do transfer task operator states. code = streamDoTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { // todo handle this - return code; - } } return code; } -static int32_t extractMsgFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInput, int32_t* numOfBlocks, - const char* id) { - int32_t retryTimes = 0; - int32_t MAX_RETRY_TIMES = 5; +static int32_t extractBlocksFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInput, int32_t* numOfBlocks) { + int32_t retryTimes = 0; + int32_t MAX_RETRY_TIMES = 5; + const char* id = pTask->id.idStr; + + if (pTask->info.taskLevel == TASK_LEVEL__SINK) { // extract block from inputQ, one-by-one + while (1) { + if (streamTaskShouldPause(&pTask->status) || streamTaskShouldStop(&pTask->status)) { + qDebug("s-task:%s task should pause, extract input blocks:%d", pTask->id.idStr, *numOfBlocks); + return TSDB_CODE_SUCCESS; + } + + SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue); + if (qItem == NULL) { + qDebug("===stream===break batchSize:%d, %s", *numOfBlocks, id); + return TSDB_CODE_SUCCESS; + } + qDebug("s-task:%s sink task handle block one-by-one, type:%d", id, qItem->type); + + *numOfBlocks = 1; + *pInput = qItem; + return TSDB_CODE_SUCCESS; + } + } + + // non sink task while (1) { - if (streamTaskShouldPause(&pTask->status)) { - qDebug("s-task:%s task should pause, input blocks:%d", pTask->id.idStr, *numOfBlocks); + if (streamTaskShouldPause(&pTask->status) || streamTaskShouldStop(&pTask->status)) { + qDebug("s-task:%s task should pause, extract input blocks:%d", pTask->id.idStr, *numOfBlocks); return TSDB_CODE_SUCCESS; } @@ -415,49 +450,109 @@ static int32_t extractMsgFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInpu if (qItem == NULL) { if (pTask->info.taskLevel == TASK_LEVEL__SOURCE && (++retryTimes) < MAX_RETRY_TIMES) { taosMsleep(10); - qDebug("===stream===try again batchSize:%d, retry:%d", *numOfBlocks, retryTimes); + qDebug("try again batchSize:%d, retry:%d, %s", *numOfBlocks, retryTimes, id); continue; } - qDebug("===stream===break batchSize:%d", *numOfBlocks); + qDebug("break batchSize:%d, %s", *numOfBlocks, id); return TSDB_CODE_SUCCESS; } - // do not merge blocks for sink node - if (pTask->info.taskLevel == TASK_LEVEL__SINK) { - *numOfBlocks = 1; - *pInput = qItem; - return TSDB_CODE_SUCCESS; - } - - if (*pInput == NULL) { - ASSERT((*numOfBlocks) == 0); - *pInput = qItem; + // do not merge blocks for sink node and check point data block + if (qItem->type == STREAM_INPUT__CHECKPOINT || qItem->type == STREAM_INPUT__CHECKPOINT_TRIGGER || + qItem->type == STREAM_INPUT__TRANS_STATE) { + if (*pInput == NULL) { + qDebug("s-task:%s checkpoint/transtate msg extracted, start to process immediately", id); + *numOfBlocks = 1; + *pInput = qItem; + return TSDB_CODE_SUCCESS; + } else { + // previous existed blocks needs to be handle, before handle the checkpoint msg block + qDebug("s-task:%s checkpoint/transtate msg extracted, handle previous blocks, numOfBlocks:%d", id, *numOfBlocks); + streamQueueProcessFail(pTask->inputQueue); + return TSDB_CODE_SUCCESS; + } } else { - // todo we need to sort the data block, instead of just appending into the array list. - void* newRet = streamMergeQueueItem(*pInput, qItem); - if (newRet == NULL) { - if (terrno == 0) { - qDebug("s-task:%s failed to merge blocks from inputQ, numOfBlocks:%d", id, *numOfBlocks); - } else { - qDebug("s-task:%s failed to merge blocks from inputQ, numOfBlocks:%d, code:%s", id, *numOfBlocks, - tstrerror(terrno)); + if (*pInput == NULL) { + ASSERT((*numOfBlocks) == 0); + *pInput = qItem; + } else { + // todo we need to sort the data block, instead of just appending into the array list. + void* newRet = streamMergeQueueItem(*pInput, qItem); + if (newRet == NULL) { + qError("s-task:%s failed to merge blocks from inputQ, numOfBlocks:%d", id, *numOfBlocks); + streamQueueProcessFail(pTask->inputQueue); + return TSDB_CODE_SUCCESS; } - streamQueueProcessFail(pTask->inputQueue); + + *pInput = newRet; + } + + *numOfBlocks += 1; + streamQueueProcessSuccess(pTask->inputQueue); + + if (*numOfBlocks >= MAX_STREAM_EXEC_BATCH_NUM) { + qDebug("s-task:%s batch size limit:%d reached, start to process blocks", id, MAX_STREAM_EXEC_BATCH_NUM); return TSDB_CODE_SUCCESS; } + } + } +} - *pInput = newRet; +int32_t streamProcessTranstateBlock(SStreamTask* pTask, SStreamDataBlock* pBlock) { + const char* id = pTask->id.idStr; + int32_t code = TSDB_CODE_SUCCESS; + + int32_t level = pTask->info.taskLevel; + if (level == TASK_LEVEL__AGG || level == TASK_LEVEL__SINK) { + int32_t remain = streamAlignTransferState(pTask); + if (remain > 0) { + streamFreeQitem((SStreamQueueItem*)pBlock); + qDebug("s-task:%s receive upstream transfer state msg, remain:%d", id, remain); + return 0; } + } - *numOfBlocks += 1; - streamQueueProcessSuccess(pTask->inputQueue); + // dispatch the tran-state block to downstream task immediately + int32_t type = pTask->outputInfo.type; - if (*numOfBlocks >= MAX_STREAM_EXEC_BATCH_NUM) { - qDebug("s-task:%s batch size limit:%d reached, start to process blocks", id, MAX_STREAM_EXEC_BATCH_NUM); - return TSDB_CODE_SUCCESS; + // transfer the ownership of executor state + if (type == TASK_OUTPUT__FIXED_DISPATCH || type == TASK_OUTPUT__SHUFFLE_DISPATCH) { + if (level == TASK_LEVEL__SOURCE) { + qDebug("s-task:%s add transfer-state block into outputQ", id); + } else { + qDebug("s-task:%s all upstream tasks send transfer-state block, add transfer-state block into outputQ", id); + ASSERT(pTask->streamTaskId.taskId != 0 && pTask->info.fillHistory == 1); + } + + // agg task should dispatch trans-state msg to sink task, to flush all data to sink task. + if (level == TASK_LEVEL__AGG || level == TASK_LEVEL__SOURCE) { + pBlock->srcVgId = pTask->pMeta->vgId; + code = taosWriteQitem(pTask->outputInfo.queue->queue, pBlock); + if (code == 0) { + streamDispatchStreamBlock(pTask); + } else { + streamFreeQitem((SStreamQueueItem*)pBlock); + } + } else { // level == TASK_LEVEL__SINK + streamFreeQitem((SStreamQueueItem*)pBlock); + } + } else { // non-dispatch task, do task state transfer directly + streamFreeQitem((SStreamQueueItem*)pBlock); + if (level != TASK_LEVEL__SINK) { + qDebug("s-task:%s non-dispatch task, start to transfer state directly", id); + ASSERT(pTask->info.fillHistory == 1); + code = streamTransferStateToStreamTask(pTask); + + if (code != TSDB_CODE_SUCCESS) { + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + } + } else { + qDebug("s-task:%s sink task does not transfer state", id); } } + + return code; } /** @@ -478,12 +573,17 @@ int32_t streamExecForAll(SStreamTask* pTask) { // merge multiple input data if possible in the input queue. qDebug("s-task:%s start to extract data block from inputQ", id); - /*int32_t code = */extractMsgFromInputQ(pTask, &pInput, &batchSize, id); + /*int32_t code = */extractBlocksFromInputQ(pTask, &pInput, &batchSize); if (pInput == NULL) { ASSERT(batchSize == 0); break; } + if (pInput->type == STREAM_INPUT__TRANS_STATE) { + streamProcessTranstateBlock(pTask, (SStreamDataBlock*)pInput); + continue; + } + if (pTask->info.taskLevel == TASK_LEVEL__SINK) { ASSERT(pInput->type == STREAM_INPUT__DATA_BLOCK); qDebug("s-task:%s sink task start to sink %d blocks", id, batchSize); @@ -551,27 +651,6 @@ bool streamTaskIsIdle(const SStreamTask* pTask) { pTask->status.taskStatus == TASK_STATUS__DROPPING); } -int32_t streamTaskEndScanWAL(SStreamTask* pTask) { - const char* id = pTask->id.idStr; - double el = (taosGetTimestampMs() - pTask->tsInfo.step2Start) / 1000.0; - qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, el); - - // 1. notify all downstream tasks to transfer executor state after handle all history blocks. - int32_t code = streamDispatchTransferStateMsg(pTask); - if (code != TSDB_CODE_SUCCESS) { - // todo handle error - } - - // 2. do transfer stream task operator states. - pTask->status.transferState = true; - code = streamDoTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { // todo handle error - return code; - } - - return TSDB_CODE_SUCCESS; -} - int32_t streamTryExec(SStreamTask* pTask) { // this function may be executed by multi-threads, so status check is required. int8_t schedStatus = @@ -587,27 +666,13 @@ int32_t streamTryExec(SStreamTask* pTask) { } // todo the task should be commit here - if (taosQueueEmpty(pTask->inputQueue->queue)) { - // fill-history WAL scan has completed - if (pTask->status.transferState) { - code = streamTransferStateToStreamTask(pTask); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - streamSchedExec(pTask); - } else { - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), - pTask->status.schedStatus); - } - } else { - atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); - qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), - pTask->status.schedStatus); + atomic_store_8(&pTask->status.schedStatus, TASK_SCHED_STATUS__INACTIVE); + qDebug("s-task:%s exec completed, status:%s, sched-status:%d", id, streamGetTaskStatusStr(pTask->status.taskStatus), + pTask->status.schedStatus); - if ((!streamTaskShouldStop(&pTask->status)) && (!streamTaskShouldPause(&pTask->status))) { - streamSchedExec(pTask); - } + if (!(taosQueueEmpty(pTask->inputQueue->queue) || streamTaskShouldStop(&pTask->status) || + streamTaskShouldPause(&pTask->status))) { + streamSchedExec(pTask); } } else { qDebug("s-task:%s already started to exec by other thread, status:%s, sched-status:%d", id, diff --git a/source/libs/stream/src/streamQueue.c b/source/libs/stream/src/streamQueue.c index aaf9fdec724cf6765232cb8a77adfb36754ce6d9..65135ec9a127e87881e036ce3760ec65cbfa7e49 100644 --- a/source/libs/stream/src/streamQueue.c +++ b/source/libs/stream/src/streamQueue.c @@ -130,11 +130,11 @@ SStreamQueueItem* doReadMultiBlocksFromQueue(SQueueReader* pReader, const char* if (pReader->taskLevel == TASK_LEVEL__SOURCE && numOfBlocks < MIN_STREAM_EXEC_BATCH_NUM && tryCount < pReader->waitDuration) { tryCount++; taosMsleep(1); - qDebug("===stream===try again batchSize:%d", numOfBlocks); + qDebug("try again batchSize:%d", numOfBlocks); continue; } - qDebug("===stream===break batchSize:%d", numOfBlocks); + qDebug("break batchSize:%d", numOfBlocks); break; } diff --git a/source/libs/stream/src/streamRecover.c b/source/libs/stream/src/streamRecover.c index 1e17ef7ef1b42ab76027402bfcf804ac7946c618..2506dbaead9bba294bd86ca83b0606ba3dcb5702 100644 --- a/source/libs/stream/src/streamRecover.c +++ b/source/libs/stream/src/streamRecover.c @@ -372,68 +372,35 @@ int32_t streamDispatchScanHistoryFinishMsg(SStreamTask* pTask) { return 0; } -static int32_t doDispatchTransferMsg(SStreamTask* pTask, const SStreamTransferReq* pReq, int32_t vgId, SEpSet* pEpSet) { - void* buf = NULL; - int32_t code = -1; - SRpcMsg msg = {0}; - - int32_t tlen; - tEncodeSize(tEncodeStreamScanHistoryFinishReq, pReq, tlen, code); - if (code < 0) { - return -1; +int32_t appendTranstateIntoInputQ(SStreamTask* pTask) { + SStreamDataBlock* pTranstate = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, sizeof(SSDataBlock)); + if (pTranstate == NULL) { + return TSDB_CODE_OUT_OF_MEMORY; } - buf = rpcMallocCont(sizeof(SMsgHead) + tlen); - if (buf == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - ((SMsgHead*)buf)->vgId = htonl(vgId); - void* abuf = POINTER_SHIFT(buf, sizeof(SMsgHead)); - - SEncoder encoder; - tEncoderInit(&encoder, abuf, tlen); - if ((code = tEncodeStreamScanHistoryFinishReq(&encoder, pReq)) < 0) { - if (buf) { - rpcFreeCont(buf); - } - return code; + SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock)); + if (pBlock == NULL) { + taosFreeQitem(pTranstate); + return TSDB_CODE_OUT_OF_MEMORY; } - tEncoderClear(&encoder); - - msg.contLen = tlen + sizeof(SMsgHead); - msg.pCont = buf; - msg.msgType = TDMT_STREAM_TRANSFER_STATE; - msg.info.noResp = 1; - - tmsgSendReq(pEpSet, &msg); - qDebug("s-task:%s level:%d, status:%s dispatch transfer state msg to taskId:0x%x (vgId:%d)", pTask->id.idStr, - pTask->info.taskLevel, streamGetTaskStatusStr(pTask->status.taskStatus), pReq->downstreamTaskId, vgId); - - return 0; -} + pTranstate->type = STREAM_INPUT__TRANS_STATE; -int32_t streamDispatchTransferStateMsg(SStreamTask* pTask) { - SStreamTransferReq req = { .streamId = pTask->id.streamId, .childId = pTask->info.selfChildId }; + pBlock->info.type = STREAM_TRANS_STATE; + pBlock->info.rows = 1; + pBlock->info.childId = pTask->info.selfChildId; - // serialize - if (pTask->outputInfo.type == TASK_OUTPUT__FIXED_DISPATCH) { - req.downstreamTaskId = pTask->fixedEpDispatcher.taskId; - doDispatchTransferMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet); - } else if (pTask->outputInfo.type == TASK_OUTPUT__SHUFFLE_DISPATCH) { - SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos; + pTranstate->blocks = taosArrayInit(4, sizeof(SSDataBlock));//pBlock; + taosArrayPush(pTranstate->blocks, pBlock); - int32_t numOfVgs = taosArrayGetSize(vgInfo); - for (int32_t i = 0; i < numOfVgs; i++) { - SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i); - req.downstreamTaskId = pVgInfo->taskId; - doDispatchTransferMsg(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet); - } + taosMemoryFree(pBlock); + if (tAppendDataToInputQueue(pTask, (SStreamQueueItem*)pTranstate) < 0) { + taosFreeQitem(pTranstate); + return TSDB_CODE_OUT_OF_MEMORY; } - return 0; + pTask->status.appendTranstateBlock = true; + return TSDB_CODE_SUCCESS; } // agg diff --git a/source/libs/sync/src/syncRaftStore.c b/source/libs/sync/src/syncRaftStore.c index bd15567c874d6d2051210ddf5b4c69a65b75bf20..051106b99dead384b55c7f6e76302c1e1dde173d 100644 --- a/source/libs/sync/src/syncRaftStore.c +++ b/source/libs/sync/src/syncRaftStore.c @@ -42,7 +42,7 @@ int32_t raftStoreReadFile(SSyncNode *pNode) { const char *file = pNode->raftStorePath; SRaftStore *pStore = &pNode->raftStore; - if (taosStatFile(file, NULL, NULL) < 0) { + if (taosStatFile(file, NULL, NULL, NULL) < 0) { sInfo("vgId:%d, raft store file:%s not exist, use default value", pNode->vgId, file); pStore->currentTerm = 0; pStore->voteFor.addr = 0; diff --git a/source/libs/sync/src/syncUtil.c b/source/libs/sync/src/syncUtil.c index ae1c775a18f6c47291f3065f83db0c2ff8cee94e..9acc17e130bd1d2d3dc09be29df869afa22b9049 100644 --- a/source/libs/sync/src/syncUtil.c +++ b/source/libs/sync/src/syncUtil.c @@ -21,6 +21,7 @@ #include "syncRaftCfg.h" #include "syncRaftStore.h" #include "syncSnapshot.h" +#include "tglobal.h" void syncCfg2SimpleStr(const SSyncCfg* pCfg, char* buf, int32_t bufLen) { int32_t len = snprintf(buf, bufLen, "{num:%d, as:%d, [", pCfg->replicaNum, pCfg->myIndex); @@ -41,7 +42,22 @@ void syncUtilNodeInfo2EpSet(const SNodeInfo* pInfo, SEpSet* pEpSet) { } bool syncUtilNodeInfo2RaftId(const SNodeInfo* pInfo, SyncGroupId vgId, SRaftId* raftId) { - uint32_t ipv4 = taosGetIpv4FromFqdn(pInfo->nodeFqdn); + uint32_t ipv4 = 0xFFFFFFFF; + sDebug("vgId:%d, start to resolve sync addr fqdn in %d seconds, " + "dnode:%d cluster:%" PRId64 " fqdn:%s port:%u ", + vgId, tsResolveFQDNRetryTime, + pInfo->nodeId, pInfo->clusterId, pInfo->nodeFqdn, pInfo->nodePort); + for(int i = 0; i < tsResolveFQDNRetryTime; i++){ + ipv4 = taosGetIpv4FromFqdn(pInfo->nodeFqdn); + if (ipv4 == 0xFFFFFFFF || ipv4 == 1) { + sError("failed to resolve ipv4 addr, fqdn:%s, wait one second", pInfo->nodeFqdn); + taosSsleep(1); + } + else{ + break; + } + } + if (ipv4 == 0xFFFFFFFF || ipv4 == 1) { sError("failed to resolve ipv4 addr, fqdn:%s", pInfo->nodeFqdn); terrno = TSDB_CODE_TSC_INVALID_FQDN; diff --git a/source/libs/wal/src/walMeta.c b/source/libs/wal/src/walMeta.c index 01d23a7e96a8313e0e111ee0a1fe3f361bf9b219..e700ef3d0a21150b932f75e463d2168d8942d3b6 100644 --- a/source/libs/wal/src/walMeta.c +++ b/source/libs/wal/src/walMeta.c @@ -20,6 +20,7 @@ #include "tutil.h" #include "walInt.h" + bool FORCE_INLINE walLogExist(SWal* pWal, int64_t ver) { return !walIsEmpty(pWal) && walGetFirstVer(pWal) <= ver && walGetLastVer(pWal) >= ver; } @@ -53,7 +54,7 @@ static FORCE_INLINE int64_t walScanLogGetLastVer(SWal* pWal, int32_t fileIdx) { walBuildLogName(pWal, pFileInfo->firstVer, fnameStr); int64_t fileSize = 0; - taosStatFile(fnameStr, &fileSize, NULL); + taosStatFile(fnameStr, &fileSize, NULL, NULL); TdFilePtr pFile = taosOpenFile(fnameStr, TD_FILE_READ | TD_FILE_WRITE); if (pFile == NULL) { @@ -304,7 +305,7 @@ int walRepairLogFileTs(SWal* pWal, bool* updateMeta) { walBuildLogName(pWal, pFileInfo->firstVer, fnameStr); int32_t mtime = 0; - if (taosStatFile(fnameStr, NULL, &mtime) < 0) { + if (taosStatFile(fnameStr, NULL, &mtime, NULL) < 0) { terrno = TAOS_SYSTEM_ERROR(errno); wError("vgId:%d, failed to stat file due to %s, file:%s", pWal->cfg.vgId, strerror(errno), fnameStr); return -1; @@ -353,7 +354,7 @@ int walTrimIdxFile(SWal* pWal, int32_t fileIdx) { walBuildIdxName(pWal, pFileInfo->firstVer, fnameStr); int64_t fileSize = 0; - taosStatFile(fnameStr, &fileSize, NULL); + taosStatFile(fnameStr, &fileSize, NULL, NULL); int64_t records = TMAX(0, pFileInfo->lastVer - pFileInfo->firstVer + 1); int64_t lastEndOffset = records * sizeof(SWalIdxEntry); @@ -436,7 +437,7 @@ int walCheckAndRepairMeta(SWal* pWal) { SWalFileInfo* pFileInfo = taosArrayGet(pWal->fileInfoSet, fileIdx); walBuildLogName(pWal, pFileInfo->firstVer, fnameStr); - int32_t code = taosStatFile(fnameStr, &fileSize, NULL); + int32_t code = taosStatFile(fnameStr, &fileSize, NULL, NULL); if (code < 0) { terrno = TAOS_SYSTEM_ERROR(errno); wError("failed to stat file since %s. file:%s", terrstr(), fnameStr); @@ -522,7 +523,7 @@ int walCheckAndRepairIdxFile(SWal* pWal, int32_t fileIdx) { walBuildLogName(pWal, pFileInfo->firstVer, fLogNameStr); int64_t fileSize = 0; - if (taosStatFile(fnameStr, &fileSize, NULL) < 0 && errno != ENOENT) { + if (taosStatFile(fnameStr, &fileSize, NULL, NULL) < 0 && errno != ENOENT) { wError("vgId:%d, failed to stat file due to %s. file:%s", pWal->cfg.vgId, strerror(errno), fnameStr); terrno = TAOS_SYSTEM_ERROR(errno); return -1; @@ -935,7 +936,7 @@ int walLoadMeta(SWal* pWal) { walBuildMetaName(pWal, metaVer, fnameStr); // read metafile int64_t fileSize = 0; - taosStatFile(fnameStr, &fileSize, NULL); + taosStatFile(fnameStr, &fileSize, NULL, NULL); if (fileSize == 0) { (void)taosRemoveFile(fnameStr); wDebug("vgId:%d, wal find empty meta ver %d", pWal->cfg.vgId, metaVer); diff --git a/source/os/src/osFile.c b/source/os/src/osFile.c index dd670595f00e77275977978b87e7e293061df91f..c4309b2c55d55c89c6e2d53804a80a57e6f0b5df 100644 --- a/source/os/src/osFile.c +++ b/source/os/src/osFile.c @@ -191,7 +191,7 @@ int32_t taosRenameFile(const char *oldName, const char *newName) { #endif } -int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime) { +int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime, int32_t *atime) { #ifdef WINDOWS struct _stati64 fileStat; int32_t code = _stati64(path, &fileStat); @@ -211,6 +211,10 @@ int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime) { *mtime = fileStat.st_mtime; } + if (atime != NULL) { + *atime = fileStat.st_mtime; + } + return 0; } int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno) { @@ -540,7 +544,7 @@ int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int32_t *mtime) { #ifdef WINDOWS struct __stat64 fileStat; - int32_t code = _fstat64(pFile->fd, &fileStat); + int32_t code = _fstat64(pFile->fd, &fileStat); #else struct stat fileStat; int32_t code = fstat(pFile->fd, &fileStat); @@ -897,17 +901,17 @@ int32_t taosCompressFile(char *srcFileName, char *destFileName) { goto cmp_end; } - dstFp = gzdopen(pFile->fd, "wb6f"); - if (dstFp == NULL) { - ret = -3; - taosCloseFile(&pFile); - goto cmp_end; - } + dstFp = gzdopen(pFile->fd, "wb6f"); + if (dstFp == NULL) { + ret = -3; + taosCloseFile(&pFile); + goto cmp_end; + } - while (!feof(pSrcFile->fp)) { - len = (int32_t)fread(data, 1, compressSize, pSrcFile->fp); - (void)gzwrite(dstFp, data, len); - } + while (!feof(pSrcFile->fp)) { + len = (int32_t)fread(data, 1, compressSize, pSrcFile->fp); + (void)gzwrite(dstFp, data, len); + } cmp_end: if (pSrcFile) { diff --git a/source/os/src/osRand.c b/source/os/src/osRand.c index 83c36a422d37b0af4b20a20992e79812c1544b02..9cb6f6e52a648b8b0a818f3874ff4ab67fbdbed0 100644 --- a/source/os/src/osRand.c +++ b/source/os/src/osRand.c @@ -27,11 +27,11 @@ void taosSeedRand(uint32_t seed) { return srand(seed); } uint32_t taosRand(void) { #ifdef WINDOWS - unsigned int pSeed; - rand_s(&pSeed); - return pSeed; + unsigned int pSeed; + rand_s(&pSeed); + return pSeed; #else - return rand(); + return rand(); #endif } @@ -80,6 +80,15 @@ void taosRandStr(char* str, int32_t size) { const char* set = "abcdefghijklmnopqrstuvwxyz0123456789-_."; int32_t len = 39; + for (int32_t i = 0; i < size; ++i) { + str[i] = set[taosRand() % len]; + } +} + +void taosRandStr2(char* str, int32_t size) { + const char* set = "abcdefghijklmnopqrstuvwxyz0123456789"; + int32_t len = 36; + for (int32_t i = 0; i < size; ++i) { str[i] = set[taosRand() % len]; } diff --git a/source/util/src/terror.c b/source/util/src/terror.c index b0b407e2a5bbe402a8c67330c5f1ae644e6094b3..466b9985e70a912d5511b8caad2c8b21551b17a2 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -151,6 +151,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SHOWOBJ, "Data expired") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, "Invalid query id") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, "Invalid connection id") TAOS_DEFINE_ERROR(TSDB_CODE_MND_USER_DISABLED, "User is disabled") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_PLATFORM, "Unsupported feature on this platform") // mnode-sdb TAOS_DEFINE_ERROR(TSDB_CODE_SDB_OBJ_ALREADY_THERE, "Object already there") diff --git a/source/util/src/tlog.c b/source/util/src/tlog.c index de7ad848ed5dd522bbab43bc9a40c921f1ee8d26..4a15b5b9762197a9f29bc073aee2650aedf38e09 100644 --- a/source/util/src/tlog.c +++ b/source/util/src/tlog.c @@ -17,8 +17,8 @@ #include "tlog.h" #include "os.h" #include "tconfig.h" -#include "tjson.h" #include "tglobal.h" +#include "tjson.h" #define LOG_MAX_LINE_SIZE (10024) #define LOG_MAX_LINE_BUFFER_SIZE (LOG_MAX_LINE_SIZE + 3) @@ -74,12 +74,12 @@ static SLogObj tsLogObj = {.fileNum = 1}; static int64_t tsAsyncLogLostLines = 0; static int32_t tsDaylightActive; /* Currently in daylight saving time. */ -bool tsLogEmbedded = 0; -bool tsAsyncLog = true; +bool tsLogEmbedded = 0; +bool tsAsyncLog = true; #ifdef ASSERT_NOT_CORE -bool tsAssert = false; +bool tsAssert = false; #else -bool tsAssert = true; +bool tsAssert = true; #endif int32_t tsNumOfLogLines = 10000000; int32_t tsLogKeepDays = 0; @@ -160,7 +160,7 @@ int32_t taosInitSlowLog() { tsLogObj.slowHandle = taosLogBuffNew(LOG_SLOW_BUF_SIZE); if (tsLogObj.slowHandle == NULL) return -1; - + taosUmaskFile(0); tsLogObj.slowHandle->pFile = taosOpenFile(fullName, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_APPEND); if (tsLogObj.slowHandle->pFile == NULL) { @@ -403,13 +403,13 @@ static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum) { strcpy(name, fn); strcat(name, ".0"); } - bool log0Exist = taosStatFile(name, NULL, &logstat0_mtime) >= 0; + bool log0Exist = taosStatFile(name, NULL, &logstat0_mtime, NULL) >= 0; if (strlen(fn) < LOG_FILE_NAME_LEN + 50 - 2) { strcpy(name, fn); strcat(name, ".1"); } - bool log1Exist = taosStatFile(name, NULL, &logstat1_mtime) >= 0; + bool log1Exist = taosStatFile(name, NULL, &logstat1_mtime, NULL) >= 0; // if none of the log files exist, open 0, if both exists, open the old one if (!log0Exist && !log1Exist) { @@ -576,7 +576,7 @@ void taosPrintSlowLog(const char *format, ...) { } else { taosWriteFile(tsLogObj.slowHandle->pFile, buffer, len); } - + taosMemoryFree(buffer); } @@ -769,12 +769,12 @@ static void taosWriteLog(SLogBuff *pLogBuf) { static void *taosAsyncOutputLog(void *param) { SLogBuff *pLogBuf = (SLogBuff *)tsLogObj.logHandle; SLogBuff *pSlowBuf = (SLogBuff *)tsLogObj.slowHandle; - + setThreadName("log"); int32_t count = 0; int32_t updateCron = 0; int32_t writeInterval = 0; - + while (1) { writeInterval = TMIN(pLogBuf->writeInterval, pSlowBuf->writeInterval); count += writeInterval; @@ -834,12 +834,12 @@ bool taosAssertDebug(bool condition, const char *file, int32_t line, const char return true; } -void taosLogCrashInfo(char* nodeType, char* pMsg, int64_t msgLen, int signum, void *sigInfo) { +void taosLogCrashInfo(char *nodeType, char *pMsg, int64_t msgLen, int signum, void *sigInfo) { const char *flags = "UTL FATAL "; ELogLevel level = DEBUG_FATAL; int32_t dflag = 255; - char filepath[PATH_MAX] = {0}; - TdFilePtr pFile = NULL; + char filepath[PATH_MAX] = {0}; + TdFilePtr pFile = NULL; if (pMsg && msgLen > 0) { snprintf(filepath, sizeof(filepath), "%s%s.%sCrashLog", tsLogDir, TD_DIRSEP, nodeType); @@ -856,16 +856,16 @@ void taosLogCrashInfo(char* nodeType, char* pMsg, int64_t msgLen, int signum, vo int64_t writeSize = taosWriteFile(pFile, &msgLen, sizeof(msgLen)); if (sizeof(msgLen) != writeSize) { taosUnLockFile(pFile); - taosPrintLog(flags, level, dflag, "failed to write len to file:%s,%p wlen:%" PRId64 " tlen:%lu since %s", - filepath, pFile, writeSize, sizeof(msgLen), terrstr()); + taosPrintLog(flags, level, dflag, "failed to write len to file:%s,%p wlen:%" PRId64 " tlen:%lu since %s", + filepath, pFile, writeSize, sizeof(msgLen), terrstr()); goto _return; } writeSize = taosWriteFile(pFile, pMsg, msgLen); if (msgLen != writeSize) { taosUnLockFile(pFile); - taosPrintLog(flags, level, dflag, "failed to write file:%s,%p wlen:%" PRId64 " tlen:%" PRId64 " since %s", - filepath, pFile, writeSize, msgLen, terrstr()); + taosPrintLog(flags, level, dflag, "failed to write file:%s,%p wlen:%" PRId64 " tlen:%" PRId64 " since %s", + filepath, pFile, writeSize, msgLen, terrstr()); goto _return; } @@ -883,7 +883,7 @@ _return: taosPrintTrace(flags, level, dflag, 4); #elif !defined(WINDOWS) taosPrintLog(flags, level, dflag, "sender PID:%d cmdline:%s", ((siginfo_t *)sigInfo)->si_pid, - taosGetCmdlineByPID(((siginfo_t *)sigInfo)->si_pid)); + taosGetCmdlineByPID(((siginfo_t *)sigInfo)->si_pid)); taosPrintTrace(flags, level, dflag, 3); #else taosPrintTrace(flags, level, dflag, 8); @@ -892,17 +892,17 @@ _return: taosMemoryFree(pMsg); } -void taosReadCrashInfo(char* filepath, char** pMsg, int64_t* pMsgLen, TdFilePtr* pFd) { +void taosReadCrashInfo(char *filepath, char **pMsg, int64_t *pMsgLen, TdFilePtr *pFd) { const char *flags = "UTL FATAL "; ELogLevel level = DEBUG_FATAL; int32_t dflag = 255; TdFilePtr pFile = NULL; bool truncateFile = false; - char* buf = NULL; + char *buf = NULL; if (NULL == *pFd) { int64_t filesize = 0; - if (taosStatFile(filepath, &filesize, NULL) < 0) { + if (taosStatFile(filepath, &filesize, NULL, NULL) < 0) { if (ENOENT == errno) { return; } @@ -916,7 +916,7 @@ void taosReadCrashInfo(char* filepath, char** pMsg, int64_t* pMsgLen, TdFilePtr* return; } - pFile = taosOpenFile(filepath, TD_FILE_READ|TD_FILE_WRITE); + pFile = taosOpenFile(filepath, TD_FILE_READ | TD_FILE_WRITE); if (pFile == NULL) { if (ENOENT == errno) { return; @@ -926,7 +926,7 @@ void taosReadCrashInfo(char* filepath, char** pMsg, int64_t* pMsgLen, TdFilePtr* taosPrintLog(flags, level, dflag, "failed to open file:%s since %s", filepath, terrstr()); return; } - + taosLockFile(pFile); } else { pFile = *pFd; @@ -937,8 +937,8 @@ void taosReadCrashInfo(char* filepath, char** pMsg, int64_t* pMsgLen, TdFilePtr* if (sizeof(msgLen) != readSize) { truncateFile = true; if (readSize < 0) { - taosPrintLog(flags, level, dflag, "failed to read len from file:%s,%p wlen:%" PRId64 " tlen:%lu since %s", - filepath, pFile, readSize, sizeof(msgLen), terrstr()); + taosPrintLog(flags, level, dflag, "failed to read len from file:%s,%p wlen:%" PRId64 " tlen:%lu since %s", + filepath, pFile, readSize, sizeof(msgLen), terrstr()); } goto _return; } @@ -948,12 +948,12 @@ void taosReadCrashInfo(char* filepath, char** pMsg, int64_t* pMsgLen, TdFilePtr* taosPrintLog(flags, level, dflag, "failed to malloc buf, size:%" PRId64, msgLen); goto _return; } - + readSize = taosReadFile(pFile, buf, msgLen); if (msgLen != readSize) { truncateFile = true; - taosPrintLog(flags, level, dflag, "failed to read file:%s,%p wlen:%" PRId64 " tlen:%" PRId64 " since %s", - filepath, pFile, readSize, msgLen, terrstr()); + taosPrintLog(flags, level, dflag, "failed to read file:%s,%p wlen:%" PRId64 " tlen:%" PRId64 " since %s", filepath, + pFile, readSize, msgLen, terrstr()); goto _return; } @@ -981,7 +981,7 @@ void taosReleaseCrashLogFile(TdFilePtr pFile, bool truncateFile) { if (truncateFile) { taosFtruncateFile(pFile, 0); } - + taosUnLockFile(pFile); taosCloseFile(&pFile); } diff --git a/tests/develop-test/2-query/table_count_scan.py b/tests/develop-test/2-query/table_count_scan.py index 758d28948dd38ee6d411e08412cdc4a8d7906a39..d6e49964ebabc7301aa931a7ed631c1c1bc785d7 100644 --- a/tests/develop-test/2-query/table_count_scan.py +++ b/tests/develop-test/2-query/table_count_scan.py @@ -65,7 +65,7 @@ class TDTestCase: tdSql.query('select count(*),db_name, stable_name from information_schema.ins_tables group by db_name, stable_name;') tdSql.checkRows(3) - tdSql.checkData(0, 0, 24) + tdSql.checkData(0, 0, 23) tdSql.checkData(0, 1, 'information_schema') tdSql.checkData(0, 2, None) tdSql.checkData(1, 0, 3) @@ -77,7 +77,7 @@ class TDTestCase: tdSql.query('select count(1) v,db_name, stable_name from information_schema.ins_tables group by db_name, stable_name order by v desc;') tdSql.checkRows(3) - tdSql.checkData(0, 0, 24) + tdSql.checkData(0, 0, 23) tdSql.checkData(0, 1, 'information_schema') tdSql.checkData(0, 2, None) tdSql.checkData(1, 0, 5) @@ -93,7 +93,7 @@ class TDTestCase: tdSql.checkData(1, 1, 'performance_schema') tdSql.checkData(0, 0, 3) tdSql.checkData(0, 1, 'tbl_count') - tdSql.checkData(2, 0, 24) + tdSql.checkData(2, 0, 23) tdSql.checkData(2, 1, 'information_schema') tdSql.query("select count(*) from information_schema.ins_tables where db_name='tbl_count'") @@ -106,7 +106,7 @@ class TDTestCase: tdSql.query('select count(*) from information_schema.ins_tables') tdSql.checkRows(1) - tdSql.checkData(0, 0, 32) + tdSql.checkData(0, 0, 31) tdSql.execute('create table stba (ts timestamp, c1 bool, c2 tinyint, c3 smallint, c4 int, c5 bigint, c6 float, c7 double, c8 binary(10), c9 nchar(10), c10 tinyint unsigned, c11 smallint unsigned, c12 int unsigned, c13 bigint unsigned) TAGS(t1 int, t2 binary(10), t3 double);') @@ -189,7 +189,7 @@ class TDTestCase: tdSql.checkData(2, 0, 5) tdSql.checkData(2, 1, 'performance_schema') tdSql.checkData(2, 2, None) - tdSql.checkData(3, 0, 24) + tdSql.checkData(3, 0, 23) tdSql.checkData(3, 1, 'information_schema') tdSql.checkData(3, 2, None) @@ -204,7 +204,7 @@ class TDTestCase: tdSql.checkData(2, 0, 5) tdSql.checkData(2, 1, 'performance_schema') tdSql.checkData(2, 2, None) - tdSql.checkData(3, 0, 24) + tdSql.checkData(3, 0, 23) tdSql.checkData(3, 1, 'information_schema') tdSql.checkData(3, 2, None) @@ -215,7 +215,7 @@ class TDTestCase: tdSql.checkData(0, 1, 'tbl_count') tdSql.checkData(1, 0, 5) tdSql.checkData(1, 1, 'performance_schema') - tdSql.checkData(2, 0, 24) + tdSql.checkData(2, 0, 23) tdSql.checkData(2, 1, 'information_schema') tdSql.query("select count(*) from information_schema.ins_tables where db_name='tbl_count'") @@ -228,7 +228,7 @@ class TDTestCase: tdSql.query('select count(*) from information_schema.ins_tables') tdSql.checkRows(1) - tdSql.checkData(0, 0, 33) + tdSql.checkData(0, 0, 32) tdSql.execute('drop database tbl_count') diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 0a6534097680520a2b5b190ff8d6acc4e624c210..741226f1017cdbc91c5e873f348308a63477db22 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -1204,6 +1204,9 @@ ,,y,script,./test.sh -f tsim/tag/drop_tag.sim ,,y,script,./test.sh -f tsim/tag/tbNameIn.sim ,,y,script,./test.sh -f tmp/monitor.sim +,,y,script,./test.sh -f tsim/tagindex/add_index.sim +,,n,script,./test.sh -f tsim/tagindex/sma_and_tag_index.sim + #develop test ,,n,develop-test,python3 ./test.py -f 2-query/table_count_scan.py diff --git a/tests/parallel_test/container_build.sh b/tests/parallel_test/container_build.sh index 5ae061072af3de05b65ac2d2e8ea47f1d7dd33d6..f5e426057edb954fe00eba35f6f90eb4bafee101 100755 --- a/tests/parallel_test/container_build.sh +++ b/tests/parallel_test/container_build.sh @@ -60,6 +60,7 @@ docker run \ -v /root/.cargo/git:/root/.cargo/git \ -v /root/go/pkg/mod:/root/go/pkg/mod \ -v /root/.cache/go-build:/root/.cache/go-build \ + -v /root/.cos-local.1:/root/.cos-local.1 \ -v ${REP_REAL_PATH}/enterprise/src/plugins/taosx/target:${REP_DIR}/enterprise/src/plugins/taosx/target \ -v ${REP_REAL_PATH}/community/tools/taosws-rs/target:${REP_DIR}/community/tools/taosws-rs/target \ -v ${REP_REAL_PATH}/community/contrib/cJson/:${REP_DIR}/community/contrib/cJson \ @@ -88,6 +89,7 @@ docker run \ -v /root/.cargo/git:/root/.cargo/git \ -v /root/go/pkg/mod:/root/go/pkg/mod \ -v /root/.cache/go-build:/root/.cache/go-build \ + -v /root/.cos-local.1:/root/.cos-local.1 \ -v ${REP_REAL_PATH}/enterprise/src/plugins/taosx/target:${REP_DIR}/enterprise/src/plugins/taosx/target \ -v ${REP_REAL_PATH}/community/tools/taosws-rs/target:${REP_DIR}/community/tools/taosws-rs/target \ -v ${REP_REAL_PATH}/community/contrib/cJson/:${REP_DIR}/community/contrib/cJson \ diff --git a/tests/script/tsim/query/sys_tbname.sim b/tests/script/tsim/query/sys_tbname.sim index f49a8e0a7d7e4c0780e77bb3ad3f1ae8ef5a3b65..6ed978aa15825838653c9fc99cfadae2fe6a4048 100644 --- a/tests/script/tsim/query/sys_tbname.sim +++ b/tests/script/tsim/query/sys_tbname.sim @@ -58,7 +58,7 @@ endi sql select tbname from information_schema.ins_tables; print $rows $data00 -if $rows != 33 then +if $rows != 32 then return -1 endi if $data00 != @ins_tables@ then diff --git a/tests/script/tsim/query/tableCount.sim b/tests/script/tsim/query/tableCount.sim index 6e65852dcc4ccab82e44fc0260227fe5709c2259..524b43620c19917ce7789a349649079b2aa58521 100644 --- a/tests/script/tsim/query/tableCount.sim +++ b/tests/script/tsim/query/tableCount.sim @@ -53,7 +53,7 @@ sql select stable_name,count(table_name) from information_schema.ins_tables grou if $rows != 3 then return -1 endi -if $data01 != 30 then +if $data01 != 29 then return -1 endi if $data11 != 10 then @@ -72,7 +72,7 @@ endi if $data11 != 5 then return -1 endi -if $data21 != 24 then +if $data21 != 23 then return -1 endi if $data31 != 5 then @@ -97,7 +97,7 @@ endi if $data42 != 3 then return -1 endi -if $data52 != 24 then +if $data52 != 23 then return -1 endi if $data62 != 5 then diff --git a/tests/script/tsim/sma/drop_sma.sim b/tests/script/tsim/sma/drop_sma.sim index 8fd8ebdcfd28849d64a85fe23df0727d232287ab..fcf48f2b36e8f34815df0e8b44ab378b2417d4b6 100644 --- a/tests/script/tsim/sma/drop_sma.sim +++ b/tests/script/tsim/sma/drop_sma.sim @@ -52,19 +52,35 @@ sql create sma index sma_index_name1 on stb function(max(c1),max(c2),min(c1)) in print --> show sma sql show indexes from stb from d1; -if $rows != 1 then +if $rows != 2 then return -1 endi -if $data[0][0] != sma_index_name1 then - return -1 -endi -if $data[0][1] != d1 then - return -1 -endi -if $data[0][2] != stb then - return -1 + +if $data[0][6] == tag_index then + if $data[1][0] != sma_index_name1 then + return -1 + endi + if $data[1][1] != d1 then + return -1 + endi + if $data[1][2] != stb then + return -1 + endi +else + if $data[0][0] != sma_index_name1 then + return -1 + endi + if $data[0][1] != d1 then + return -1 + endi + if $data[0][2] != stb then + return -1 + endi endi + + + print --> drop stb sql drop table stb; @@ -78,17 +94,30 @@ sql create sma index sma_index_name1 on stb function(max(c1),max(c2),min(c1)) in print --> show sma sql show indexes from stb from d1; -if $rows != 1 then - return -1 -endi -if $data[0][0] != sma_index_name1 then +if $rows != 2 then return -1 endi -if $data[0][1] != d1 then - return -1 -endi -if $data[0][2] != stb then - return -1 + +if $data[0][6] == tag_index then + if $data[1][0] != sma_index_name1 then + return -1 + endi + if $data[1][1] != d1 then + return -1 + endi + if $data[1][2] != stb then + return -1 + endi +else + if $data[0][0] != sma_index_name1 then + return -1 + endi + if $data[0][1] != d1 then + return -1 + endi + if $data[0][2] != stb then + return -1 + endi endi print --> drop stb diff --git a/tests/script/tsim/tagindex/add_index.sim b/tests/script/tsim/tagindex/add_index.sim index cfbec905426a64547c8695905af0986be668d586..a6e9cae6701526b4ba85fe8a1adaabefc766d2dd 100644 --- a/tests/script/tsim/tagindex/add_index.sim +++ b/tests/script/tsim/tagindex/add_index.sim @@ -7,7 +7,7 @@ print ======== step0 $dbPrefix = ta_3_db $tbPrefix = ta_3_tb $mtPrefix = ta_3_mt -$tbNum = 500 +$tbNum = 50 $rowNum = 20 $totalNum = 200 @@ -48,12 +48,16 @@ while $i < $tbNum $i = $i + 1 endw - +sql_error create index ti1 on $mtPrefix (t1) sql create index ti2 on $mtPrefix (t2) sql create index ti5 on $mtPrefix (t5) print ==== test name conflict # + +sql_error create index ti1 on $mtPrefix(t1) +sql_error create index ti11 on $mtPrefix(t1) + sql_error create index ti3 on $mtPrefix(t2) sql_error create index ti2 on $mtPrefix(t2) @@ -73,6 +77,15 @@ while $i < $tbNum $i = $i + 1 endw +$i = 0 +while $i < $tbNum + sql select * from $mtPrefix where t1= $i ; + if $rows != 1 then + return -1 + endi + $i = $i + 1 +endw + print ===== test operator great equal @@ -250,7 +263,7 @@ endw print === show index sql select * from information_schema.ins_indexes -if $rows != 1 then +if $rows != 2 then return -1 endi @@ -259,12 +272,41 @@ print === drop index ti2 sql drop index ti2 print === drop not exist index + +sql select * from information_schema.ins_indexes +if $rows != 1 then + return -1 +endi + +sql drop index $data[0][0] + +if $rows != 0 then + return -1 +endi + + sql_error drop index t2 sql_error drop index t3 +sql create index ti0 on $mtPrefix (t1) + +$i = $interval +while $i < $limit + sql select * from $mtPrefix where t1 <= $i ; + + $tmp = $i - $interval + $tmp = $tmp + 1 + if $rows != $tmp then + return -1 + endi + $i = $i + 1 +endw sql_error create index ti0 on $mtPrefix (t1) +sql_error create index ti2 on $mtPrefix (t1) + + sql_error create index t2i on ta_3_tb17 (t2) diff --git a/tests/script/tsim/tagindex/sma_and_tag_index.sim b/tests/script/tsim/tagindex/sma_and_tag_index.sim index b15d22d43996ef82f6733698abefcb0f6b0054ed..e7e4682810f051562d41e4787cfad67efd4eefc9 100644 --- a/tests/script/tsim/tagindex/sma_and_tag_index.sim +++ b/tests/script/tsim/tagindex/sma_and_tag_index.sim @@ -69,7 +69,7 @@ sql create sma index smat2i on $mtPrefix function(max(c1)) interval(6m,10s) slid sql select * from information_schema.ins_indexes -if $rows != 2 then +if $rows != 3 then return -1 endi @@ -84,7 +84,7 @@ while $i < 5 endw sql select * from information_schema.ins_indexes -if $rows != 6 then +if $rows != 7 then return -1 endi @@ -114,13 +114,13 @@ sql use $dbPrefix sql create table if not exists $mtPrefix (ts timestamp, c1 int) tags (t1 int, t2 int, t3 int, t4 int, t5 int) sql create index tagt2i on $mtPrefix (t2) sql select * from information_schema.ins_indexes -if $rows != 1 then +if $rows != 2 then return -1 endi sql alter table $mtPrefix drop tag t2 sql select * from information_schema.ins_indexes -if $rows != 0 then +if $rows != 1 then return -1 endi @@ -128,18 +128,22 @@ endi print ==== rename tag name, and update index colName sql create index tagt3i on $mtPrefix (t3) sql select * from information_schema.ins_indexes -if $rows != 1 then +if $rows != 2 then return -1 endi sql alter table $mtPrefix rename tag t3 txxx sql select * from information_schema.ins_indexes -if $rows != 1 then +if $rows != 2 then return -1 endi -if $data05 != txxx then - return -1 +if $data05 == txxx then + print "manual created index" +elif $data15 == txxx then + print "auto created index at tag0" +else + return -1; endi @@ -153,7 +157,7 @@ sql create table if not exists $mtPrefix (ts timestamp, c1 int) tags (t1 int, t2 sql create index tagt3i on $mtPrefix (t3) sql select * from information_schema.ins_indexes -if $rows != 2 then +if $rows != 4 then return -1 endi diff --git a/tests/script/wtest.bat b/tests/script/wtest.bat index b642bad285864fd2fd423d0e28c739bc4680bcd0..88ae703b7cba6bb79aac5de73aba28678f2ab88f 100644 --- a/tests/script/wtest.bat +++ b/tests/script/wtest.bat @@ -17,6 +17,9 @@ rem echo SIM_DIR: %SIM_DIR% set "TSIM_DIR=%SIM_DIR%tsim\" rem echo TSIM_DIR: %TSIM_DIR% +set "DATA_DIR=%TSIM_DIR%data\" +rem echo DATA_DIR: %DATA_DIR% + set "CFG_DIR=%TSIM_DIR%cfg\" rem echo CFG_DIR: %CFG_DIR% @@ -30,25 +33,30 @@ if not exist %SIM_DIR% mkdir %SIM_DIR% if not exist %TSIM_DIR% mkdir %TSIM_DIR% if exist %CFG_DIR% rmdir /s/q %CFG_DIR% if exist %LOG_DIR% rmdir /s/q %LOG_DIR% +if exist %DATA_DIR% rmdir /s/q %DATA_DIR% if not exist %CFG_DIR% mkdir %CFG_DIR% if not exist %LOG_DIR% mkdir %LOG_DIR% +if not exist %DATA_DIR% mkdir %DATA_DIR% set "fqdn=localhost" for /f "skip=1" %%A in ( 'wmic computersystem get caption' ) do if not defined fqdn set "fqdn=%%A" -echo firstEp %fqdn% > %TAOS_CFG% +echo firstEp %fqdn%:7100 > %TAOS_CFG% +echo secondEp %fqdn%:7200 >> %TAOS_CFG% echo fqdn %fqdn% >> %TAOS_CFG% echo serverPort 7100 >> %TAOS_CFG% +echo dataDir %DATA_DIR% >> %TAOS_CFG% echo logDir %LOG_DIR% >> %TAOS_CFG% echo scriptDir %SCRIPT_DIR% >> %TAOS_CFG% echo numOfLogLines 100000000 >> %TAOS_CFG% echo rpcDebugFlag 143 >> %TAOS_CFG% echo tmrDebugFlag 131 >> %TAOS_CFG% -echo cDebugFlag 135 >> %TAOS_CFG% +echo cDebugFlag 143 >> %TAOS_CFG% echo qDebugFlag 143 >> %TAOS_CFG% -echo udebugFlag 135 >> %TAOS_CFG% +echo uDebugFlag 143 >> %TAOS_CFG% +echo debugFlag 143 >> %TAOS_CFG% echo wal 0 >> %TAOS_CFG% echo asyncLog 0 >> %TAOS_CFG% echo locale en_US.UTF-8 >> %TAOS_CFG% diff --git a/tests/system-test/0-others/information_schema.py b/tests/system-test/0-others/information_schema.py index 762361f0511d0a19fcadeffca40de45687694f39..f7788d1d507ecb3957581de6efba64beb84f770a 100644 --- a/tests/system-test/0-others/information_schema.py +++ b/tests/system-test/0-others/information_schema.py @@ -55,7 +55,7 @@ class TDTestCase: ] self.binary_str = 'taosdata' self.nchar_str = '涛思数据' - self.ins_list = ['ins_dnodes','ins_mnodes','ins_modules','ins_qnodes','ins_snodes','ins_cluster','ins_databases','ins_functions',\ + self.ins_list = ['ins_dnodes','ins_mnodes','ins_qnodes','ins_snodes','ins_cluster','ins_databases','ins_functions',\ 'ins_indexes','ins_stables','ins_tables','ins_tags','ins_columns','ins_users','ins_grants','ins_vgroups','ins_configs','ins_dnode_variables',\ 'ins_topics','ins_subscriptions','ins_streams','ins_stream_tasks','ins_vnodes','ins_user_privileges'] self.perf_list = ['perf_connections','perf_queries','perf_consumers','perf_trans','perf_apps'] diff --git a/tests/system-test/0-others/show.py b/tests/system-test/0-others/show.py index 4ef323db22f536e63d837a11e5681be5c8eb415b..d9cc4895b13dd361aa5a0448d9edc0b34e50b58a 100644 --- a/tests/system-test/0-others/show.py +++ b/tests/system-test/0-others/show.py @@ -210,6 +210,66 @@ class TDTestCase: licences_info = tdSql.queryResult tdSql.checkEqual(grants_info,licences_info) + def show_create_table_with_col_comment(self): + tdSql.execute("create database comment_test_db") + tdSql.execute("use comment_test_db") + tdSql.execute("create table normal_table(ts timestamp, c2 int comment 'c2 comment')") + tdSql.execute("create stable super_table(ts timestamp comment 'ts', c2 int comment 'c2 comment') tags(tg int comment 'tg comment')") + + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int)" + tdSql.query('show create table normal_table') + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + tdSql.query('show create table super_table') + create_sql = "create stable `super_table` (`ts` timestamp, `c2` int) tags (`tg` int)" + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + tdSql.query("desc normal_table") + tdSql.checkCols(5) + tdSql.checkData(0, 4, "") + + tdSql.query("desc super_table") + tdSql.checkCols(5) + tdSql.checkData(0, 4, "") + + tdSql.execute("drop database comment_test_db") + + def alter_table_with_col_comment(self): + tdSql.execute("create database comment_test_db") + tdSql.execute("use comment_test_db") + tdSql.execute("create table normal_table(ts timestamp, c2 int comment 'c2 comment')") + tdSql.execute("create stable super_table(ts timestamp comment 'ts', c2 int comment 'c2 comment') tags(tg int comment 'tg comment')") + + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int, `c3` int)" + tdSql.execute("alter table normal_table add column c3 int comment 'c3 comment'", queryTimes=1) + tdSql.query("show create table normal_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int, `c3` int, `c4` varchar(255))" + tdSql.execute("alter table normal_table add column c4 varchar(255) comment 'c4 comment'", queryTimes=1) + tdSql.query("show create table normal_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create table `normal_table` (`ts` timestamp, `c2` int, `c3` int, `c4` varchar(255), `c5` varchar(255))" + tdSql.execute("alter table normal_table add column c5 varchar(255)", queryTimes=1) + tdSql.query("show create table normal_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create stable `super_table` (`ts` timestamp, `c2` int, `c3` int) tags (`tg` int) sma(`ts`,`c2`)" + tdSql.execute("alter table super_table add column c3 int comment 'c3 comment'", queryTimes=1) + tdSql.query("show create table super_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create stable `super_table` (`ts` timestamp, `c2` int, `c3` int, `c4` varchar(255)) tags (`tg` int) sma(`ts`,`c2`)" + tdSql.execute("alter table super_table add column c4 varchar(255) comment 'c4 comment'", queryTimes=1) + tdSql.query("show create table super_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + + create_sql = "create stable `super_table` (`ts` timestamp, `c2` int, `c3` int, `c4` varchar(256)) tags (`tg` int) sma(`ts`,`c2`)" + tdSql.execute("alter table super_table modify column c4 varchar(256) comment 'c4 256 comment'", queryTimes=1) + tdSql.query("show create table super_table") + tdSql.checkEqual(tdSql.queryResult[0][1].lower(), create_sql) + tdSql.execute("drop database comment_test_db") + def run(self): self.check_gitinfo() self.show_base() @@ -218,6 +278,8 @@ class TDTestCase: self.show_create_sql() self.show_create_sysdb_sql() self.show_create_systb_sql() + self.show_create_table_with_col_comment() + self.alter_table_with_col_comment() def stop(self): tdSql.close() diff --git a/tests/system-test/0-others/show_tag_index.py b/tests/system-test/0-others/show_tag_index.py index 663426b7ffdb6fcee2394b9913984fd0a980cb31..d39f9eaab9bc941f2bd4d303cf66092aa3b17701 100644 --- a/tests/system-test/0-others/show_tag_index.py +++ b/tests/system-test/0-others/show_tag_index.py @@ -59,14 +59,18 @@ class TDTestCase: tdSql.checkData(1, 2, 2) def check_indexes(self): - tdSql.checkRows(1) - tdSql.checkCols(7) - tdSql.checkData(0, 0, 'idx1') - tdSql.checkData(0, 1, 'db') - tdSql.checkData(0, 2, 'stb') - tdSql.checkData(0, 3, None) - tdSql.checkData(0, 5, 't1') - tdSql.checkData(0, 6, 'tag_index') + tdSql.checkRows(2) + for i in range(2): + col_name = tdSql.getData(i, 5) + if col_name == "t0": + continue + tdSql.checkCols(7) + tdSql.checkData(i, 0, 'idx1') + tdSql.checkData(i, 1, 'db') + tdSql.checkData(i, 2, 'stb') + tdSql.checkData(i, 3, None) + tdSql.checkData(i, 5, 't1') + tdSql.checkData(i, 6, 'tag_index') def run(self): tdSql.execute(f'create database db') diff --git a/tests/system-test/0-others/tag_index_basic.py b/tests/system-test/0-others/tag_index_basic.py index 72ed559ffd94f808a906d0547c8b10f2ea6f1500..c1e1d521d2042966e40c1f16455ca0f0d70f5c3d 100644 --- a/tests/system-test/0-others/tag_index_basic.py +++ b/tests/system-test/0-others/tag_index_basic.py @@ -118,12 +118,15 @@ class TDTestCase: def show_tagidx(self, stbname): sql = f'select index_name,column_name from information_schema.ins_indexes where db_name="db"' tdSql.query(sql) - rows = len(self.tag_dict.keys())-1 + rows = len(self.tag_dict.keys()) tdSql.checkRows(rows) for i in range(rows): col_name = tdSql.getData(i, 1) idx_name = f'idx_{col_name}' + # skip first tag + if col_name == "t1": + continue tdSql.checkData(i, 0, idx_name) tdLog.info(f' show {rows} tag indexs ok.') @@ -201,7 +204,7 @@ class TDTestCase: # check idx result is 0 sql = f'select index_name,column_name from information_schema.ins_indexes where db_name="db"' tdSql.query(sql) - tdSql.checkRows(0) + tdSql.checkRows(1) tdLog.info(f' drop {cnt} tag indexs ok.') # create long name idx diff --git a/tests/system-test/0-others/walRetention.py b/tests/system-test/0-others/walRetention.py index 2b340b79697f874a1e300970fac74f90529f0cc9..5257b7644a2ec9310ab4133e78cf0bfa8118dbd8 100644 --- a/tests/system-test/0-others/walRetention.py +++ b/tests/system-test/0-others/walRetention.py @@ -460,8 +460,7 @@ class TDTestCase: #self.test_db("db2", 5, 10*24*3600, 2*1024) # 2M size # period + size - self.test_db("db", checkTime = 5*60, wal_period = 60, wal_size_kb=10) - #self.test_db("db", checkTime = 3*60, wal_period = 0, wal_size_kb=0) + self.test_db("db", checkTime = 3*60, wal_period = 60, wal_size_kb=500) def stop(self): diff --git a/tests/system-test/2-query/interp.py b/tests/system-test/2-query/interp.py index 986c63839b1c6e9cfc8c8c6b857a668146d03237..c2eb7bee2e5e9a05d41f4cb635b11dc21c4ad6af 100644 --- a/tests/system-test/2-query/interp.py +++ b/tests/system-test/2-query/interp.py @@ -20,6 +20,7 @@ class TDTestCase: tbname = "tb" tbname1 = "tb1" tbname2 = "tb2" + tbname3 = "tb3" stbname = "stb" ctbname1 = "ctb1" ctbname2 = "ctb2" @@ -5607,6 +5608,44 @@ class TDTestCase: tdSql.query(f"select _irowts, _isfilled, interp(c0) from {dbname}.{stbname_single} partition by tbname range('2020-02-01 00:00:06') fill(linear)") tdSql.checkRows(0) + #### TS-3799 #### + + tdSql.execute( + f'''create table if not exists {dbname}.{tbname3} (ts timestamp, c0 double)''' + ) + + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:51.000000000', 4.233947800000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:52.000000000', 3.606781000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:52.500000000', 3.162353500000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:53.000000000', 3.162292500000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:53.500000000', 4.998230000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:54.400000000', 8.800414999999999)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:54.900000000', 8.853271500000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:55.900000000', 7.507751500000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:56.400000000', 7.510681000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:56.900000000', 7.841614000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:57.900000000', 8.153809000000001)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:58.500000000', 6.866455000000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-06 23:59:59.000000000', 6.869140600000000)") + tdSql.execute(f"insert into {dbname}.{tbname3} values ('2023-08-07 00:00:00.000000000', 0.261475000000001)") + + tdSql.query(f"select _irowts, interp(c0) from {dbname}.{tbname3} range('2023-08-06 23:59:00','2023-08-06 23:59:59') every(1m) fill(next)") + tdSql.checkRows(1); + tdSql.checkData(0, 0, '2023-08-06 23:59:00') + tdSql.checkData(0, 1, 4.233947800000000) + + tdSql.query(f"select _irowts, interp(c0) from {dbname}.{tbname3} range('2023-08-06 23:59:00','2023-08-06 23:59:59') every(1m) fill(value, 1)") + tdSql.checkRows(1); + tdSql.checkData(0, 0, '2023-08-06 23:59:00') + tdSql.checkData(0, 1, 1) + + tdSql.query(f"select _irowts, interp(c0) from {dbname}.{tbname3} range('2023-08-06 23:59:00','2023-08-06 23:59:59') every(1m) fill(null)") + tdSql.checkRows(1); + tdSql.checkData(0, 0, '2023-08-06 23:59:00') + tdSql.checkData(0, 1, None) + + + def stop(self): tdSql.close() tdLog.success(f"{__file__} successfully executed") diff --git a/tests/system-test/2-query/sml.py b/tests/system-test/2-query/sml.py index b3aeb7219439415cb06ac4661a524466429a105d..cae012ece11c7c4a2cdc44899d125a28113e1a08 100644 --- a/tests/system-test/2-query/sml.py +++ b/tests/system-test/2-query/sml.py @@ -110,6 +110,11 @@ class TDTestCase: tdSql.query(f"select * from ts3724.`stb2.`") tdSql.checkRows(1) + + # tdSql.query(f"select * from td24559.stb order by _ts") + # tdSql.checkRows(4) + # tdSql.checkData(0, 2, "POINT (4.343000 89.342000)") + # tdSql.checkData(3, 2, "GEOMETRYCOLLECTION (MULTIPOINT ((0.000000 0.000000), (1.000000 1.000000)), POINT (3.000000 4.000000), LINESTRING (2.000000 3.000000, 3.000000 4.000000))") return def run(self): diff --git a/tests/system-test/7-tmq/tmqCommon.py b/tests/system-test/7-tmq/tmqCommon.py index 3ea8273e7f79bc2ae05358825d36f2fd59037386..7f972d857e2856ea378424672b0748db33aeeaf1 100644 --- a/tests/system-test/7-tmq/tmqCommon.py +++ b/tests/system-test/7-tmq/tmqCommon.py @@ -578,18 +578,40 @@ class TMQCom: tdLog.info("wait subscriptions exit for %d s"%wait_cnt) def killProcesser(self, processerName): - killCmd = ( - "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs kill -TERM > /dev/null 2>&1" - % processerName - ) - - psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % processerName - processID = subprocess.check_output(psCmd, shell=True) - + if platform.system().lower() == 'windows': + killCmd = ("wmic process where name=\"%s.exe\" call terminate > NUL 2>&1" % processerName) + psCmd = ("wmic process where name=\"%s.exe\" | findstr \"%s.exe\"" % (processerName, processerName)) + else: + killCmd = ( + "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs kill -TERM > /dev/null 2>&1" + % processerName + ) + psCmd = ("ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % processerName) + + processID = "" + + try: + processID = subprocess.check_output(psCmd, shell=True) + except Exception as err: + processID = "" + print('**** warn: ', err) + while processID: os.system(killCmd) time.sleep(1) - processID = subprocess.check_output(psCmd, shell=True) + try: + processID = subprocess.check_output(psCmd, shell=True) + except Exception as err: + processID = "" + print('**** warn: ', err) + + def startProcess(self, processName, param): + if platform.system().lower() == 'windows': + cmd = f"mintty -h never %s %s > NUL 2>&1" % (processName, param) + else: + cmd = f"nohup %s %s > /dev/null 2>&1 &" % (processName, param) + tdLog.info("%s"%(cmd)) + os.system(cmd) def close(self): self.cursor.close() diff --git a/tests/system-test/7-tmq/tmqDropConsumer.py b/tests/system-test/7-tmq/tmqDropConsumer.py index 06ce4c0fd7b411d5118797ece846fa90f5afab2e..137b5c658405aaca8f03fce3e5f8a857076b5a7e 100644 --- a/tests/system-test/7-tmq/tmqDropConsumer.py +++ b/tests/system-test/7-tmq/tmqDropConsumer.py @@ -176,9 +176,7 @@ class TDTestCase: # use taosBenchmark to subscribe binPath = self.getPath() - cmd = "nohup %s -f ./7-tmq/tmqDropConsumer.json > /dev/null 2>&1 & " % binPath - tdLog.info("%s"%(cmd)) - os.system(cmd) + tmqCom.startProcess(binPath, "-f ./7-tmq/tmqDropConsumer.json") expectTopicNum = len(topicNameList) consumerThreadNum = 2 diff --git a/tests/system-test/7-tmq/tmqMaxGroupIds.py b/tests/system-test/7-tmq/tmqMaxGroupIds.py index d22b79a44cfbae0cf35584503ce3976f94b2b787..75e2993a5bf0a3237027e8bdf31d04b39a6d8338 100644 --- a/tests/system-test/7-tmq/tmqMaxGroupIds.py +++ b/tests/system-test/7-tmq/tmqMaxGroupIds.py @@ -176,9 +176,7 @@ class TDTestCase: # use taosBenchmark to subscribe binPath = self.getPath() - cmd = "nohup %s -f ./7-tmq/tmqMaxGroupIds.json > /dev/null 2>&1 & " % binPath - tdLog.info("%s"%(cmd)) - os.system(cmd) + tmqCom.startProcess(binPath, "-f ./7-tmq/tmqMaxGroupIds.json") expectTopicNum = 1 expectConsumerNUm = 99 diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index e9dd067ac49b1dbc3c90b55fc4e75d12faa33ae6..e084f97fb5d0459a3f4332dd95ff768891b664c6 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -18,9 +18,9 @@ #define _GNU_SOURCE #define _XOPEN_SOURCE #define _DEFAULT_SOURCE -#include "shellInt.h" -#include "shellAuto.h" #include "geosWrapper.h" +#include "shellAuto.h" +#include "shellInt.h" static bool shellIsEmptyCommand(const char *cmd); static int32_t shellRunSingleCommand(char *command); @@ -41,9 +41,9 @@ static bool shellIsCommentLine(char *line); static void shellSourceFile(const char *file); static void shellGetGrantInfo(); -static void shellCleanup(void *arg); -static void *shellCancelHandler(void *arg); -static void *shellThreadLoop(void *arg); +static void shellCleanup(void *arg); +static void *shellCancelHandler(void *arg); +static void *shellThreadLoop(void *arg); bool shellIsEmptyCommand(const char *cmd) { for (char c = *cmd++; c != 0; c = *cmd++) { @@ -66,7 +66,7 @@ int32_t shellRunSingleCommand(char *command) { if (shellRegexMatch(command, "^[\t ]*clear[ \t;]*$", REG_EXTENDED | REG_ICASE)) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" - system("clear"); + system("clear"); #pragma GCC diagnostic pop return 0; } @@ -142,8 +142,8 @@ int32_t shellRunCommand(char *command, bool recordHistory) { return 0; } - // add help or help; - if(strncasecmp(command, "help;", 5) == 0) { + // add help or help; + if (strncasecmp(command, "help;", 5) == 0) { showHelp(); return 0; } @@ -223,14 +223,14 @@ void shellRunSingleCommandImp(char *command) { } // pre string - char * pre = "Query OK"; + char *pre = "Query OK"; if (shellRegexMatch(command, "^\\s*delete\\s*from\\s*.*", REG_EXTENDED | REG_ICASE)) { pre = "Delete OK"; - } else if(shellRegexMatch(command, "^\\s*insert\\s*into\\s*.*", REG_EXTENDED | REG_ICASE)) { + } else if (shellRegexMatch(command, "^\\s*insert\\s*into\\s*.*", REG_EXTENDED | REG_ICASE)) { pre = "Insert OK"; - } else if(shellRegexMatch(command, "^\\s*create\\s*.*", REG_EXTENDED | REG_ICASE)) { + } else if (shellRegexMatch(command, "^\\s*create\\s*.*", REG_EXTENDED | REG_ICASE)) { pre = "Create OK"; - } else if(shellRegexMatch(command, "^\\s*drop\\s*.*", REG_EXTENDED | REG_ICASE)) { + } else if (shellRegexMatch(command, "^\\s*drop\\s*.*", REG_EXTENDED | REG_ICASE)) { pre = "Drop OK"; } @@ -295,7 +295,7 @@ char *shellFormatTimestamp(char *buf, int64_t val, int32_t precision) { if (taosLocalTime(&tt, &ptm, buf) == NULL) { return buf; } - size_t pos = strftime(buf, 35, "%Y-%m-%d %H:%M:%S", &ptm); + size_t pos = strftime(buf, 35, "%Y-%m-%d %H:%M:%S", &ptm); if (precision == TSDB_TIME_PRECISION_NANO) { sprintf(buf + pos, ".%09d", ms); @@ -387,22 +387,20 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i break; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: - case TSDB_DATA_TYPE_JSON: - { - int32_t bufIndex = 0; - for (int32_t i = 0; i < length; i++) { + case TSDB_DATA_TYPE_JSON: { + int32_t bufIndex = 0; + for (int32_t i = 0; i < length; i++) { + buf[bufIndex] = val[i]; + bufIndex++; + if (val[i] == '\"') { buf[bufIndex] = val[i]; bufIndex++; - if (val[i] == '\"') { - buf[bufIndex] = val[i]; - bufIndex++; - } } - buf[bufIndex] = 0; - - taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); } - break; + buf[bufIndex] = 0; + + taosFprintfFile(pFile, "%s%s%s", quotationStr, buf, quotationStr); + } break; case TSDB_DATA_TYPE_GEOMETRY: shellDumpHexValue(buf, val, length); taosFprintfFile(pFile, "%s", buf); @@ -535,12 +533,10 @@ void shellPrintString(const char *str, int32_t width) { if (width == 0) { printf("%s", str); - } - else if (len > width) { + } else if (len > width) { if (width <= 3) { printf("%.*s.", width - 1, str); - } - else { + } else { printf("%.*s...", width - 3, str); } } else { @@ -549,7 +545,7 @@ void shellPrintString(const char *str, int32_t width) { } void shellPrintGeometry(const unsigned char *val, int32_t length, int32_t width) { - if (length == 0) { //empty value + if (length == 0) { // empty value shellPrintString("", width); return; } @@ -565,7 +561,7 @@ void shellPrintGeometry(const unsigned char *val, int32_t length, int32_t width) char *outputWKT = NULL; code = doAsText(val, length, &outputWKT); if (code != TSDB_CODE_SUCCESS) { - shellPrintString(getThreadLocalGeosCtx()->errMsg, width); //should NOT happen + shellPrintString(getThreadLocalGeosCtx()->errMsg, width); // should NOT happen return; } @@ -612,27 +608,26 @@ void shellPrintField(const char *val, TAOS_FIELD *field, int32_t width, int32_t break; case TSDB_DATA_TYPE_FLOAT: if (tsEnableScience) { - printf("%*.7e",width,GET_FLOAT_VAL(val)); + printf("%*.7e", width, GET_FLOAT_VAL(val)); } else { n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.7f", width, GET_FLOAT_VAL(val)); if (n > SHELL_FLOAT_WIDTH) { - - printf("%*.7e", width,GET_FLOAT_VAL(val)); + printf("%*.7e", width, GET_FLOAT_VAL(val)); } else { - printf("%s", buf); + printf("%s", buf); } } break; case TSDB_DATA_TYPE_DOUBLE: if (tsEnableScience) { - snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.15e", width,GET_DOUBLE_VAL(val)); + snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.15e", width, GET_DOUBLE_VAL(val)); printf("%s", buf); } else { n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.15f", width, GET_DOUBLE_VAL(val)); if (n > SHELL_DOUBLE_WIDTH) { - printf("%*.15e", width, GET_DOUBLE_VAL(val)); + printf("%*.15e", width, GET_DOUBLE_VAL(val)); } else { - printf("%*s", width,buf); + printf("%*s", width, buf); } } break; @@ -776,7 +771,7 @@ int32_t shellCalcColWidth(TAOS_FIELD *field, int32_t precision) { if (field->bytes > shell.args.displayWidth) { return TMAX(shell.args.displayWidth, width); } else { - return TMAX(field->bytes, width); + return TMAX(field->bytes + 2, width); } case TSDB_DATA_TYPE_NCHAR: @@ -785,7 +780,7 @@ int32_t shellCalcColWidth(TAOS_FIELD *field, int32_t precision) { if (bytes > shell.args.displayWidth) { return TMAX(shell.args.displayWidth, width); } else { - return TMAX(bytes, width); + return TMAX(bytes + 2, width); } } @@ -905,7 +900,7 @@ void shellReadHistory() { TdFilePtr pFile = taosOpenFile(pHistory->file, TD_FILE_READ | TD_FILE_STREAM); if (pFile == NULL) return; - char *line = taosMemoryMalloc(TSDB_MAX_ALLOWED_SQL_LEN + 1); + char *line = taosMemoryMalloc(TSDB_MAX_ALLOWED_SQL_LEN + 1); int32_t read_size = 0; while ((read_size = taosGetsFile(pFile, TSDB_MAX_ALLOWED_SQL_LEN, line)) != -1) { line[read_size - 1] = '\0'; @@ -922,8 +917,8 @@ void shellReadHistory() { taosMemoryFreeClear(line); taosCloseFile(&pFile); int64_t file_size; - if (taosStatFile(pHistory->file, &file_size, NULL) == 0 && file_size > SHELL_MAX_COMMAND_SIZE) { - TdFilePtr pFile = taosOpenFile(pHistory->file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_STREAM | TD_FILE_TRUNC); + if (taosStatFile(pHistory->file, &file_size, NULL, NULL) == 0 && file_size > SHELL_MAX_COMMAND_SIZE) { + TdFilePtr pFile = taosOpenFile(pHistory->file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_STREAM | TD_FILE_TRUNC); if (pFile == NULL) return; int32_t endIndex = pHistory->hstart; if (endIndex != 0) { @@ -945,7 +940,7 @@ void shellReadHistory() { void shellWriteHistory() { SShellHistory *pHistory = &shell.history; if (pHistory->hend == pHistory->hstart) return; - TdFilePtr pFile = taosOpenFile(pHistory->file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_STREAM | TD_FILE_APPEND); + TdFilePtr pFile = taosOpenFile(pHistory->file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_STREAM | TD_FILE_APPEND); if (pFile == NULL) return; for (int32_t i = pHistory->hstart; i != pHistory->hend;) { @@ -991,7 +986,7 @@ void shellSourceFile(const char *file) { tstrncpy(fullname, file, PATH_MAX); } - sprintf(sourceFileCommand, "source %s;",fullname); + sprintf(sourceFileCommand, "source %s;", fullname); shellRecordCommandToHistory(sourceFileCommand); TdFilePtr pFile = taosOpenFile(fullname, TD_FILE_READ | TD_FILE_STREAM); @@ -1001,7 +996,7 @@ void shellSourceFile(const char *file) { return; } - char *line = taosMemoryMalloc(TSDB_MAX_ALLOWED_SQL_LEN + 1); + char *line = taosMemoryMalloc(TSDB_MAX_ALLOWED_SQL_LEN + 1); while ((read_len = taosGetsFile(pFile, TSDB_MAX_ALLOWED_SQL_LEN, line)) != -1) { if (read_len >= TSDB_MAX_ALLOWED_SQL_LEN) continue; line[--read_len] = '\0'; @@ -1044,7 +1039,8 @@ void shellGetGrantInfo() { int32_t code = taos_errno(tres); if (code != TSDB_CODE_SUCCESS) { - if (code != TSDB_CODE_OPS_NOT_SUPPORT && code != TSDB_CODE_MND_NO_RIGHTS && code != TSDB_CODE_PAR_PERMISSION_DENIED) { + if (code != TSDB_CODE_OPS_NOT_SUPPORT && code != TSDB_CODE_MND_NO_RIGHTS && + code != TSDB_CODE_PAR_PERMISSION_DENIED) { fprintf(stderr, "Failed to check Server Edition, Reason:0x%04x:%s\r\n\r\n", code, taos_errstr(tres)); } return; @@ -1080,7 +1076,8 @@ void shellGetGrantInfo() { } else if (strcmp(expiretime, "unlimited") == 0) { fprintf(stdout, "Server is Enterprise %s Edition, %s and will never expire.\r\n", serverVersion, sinfo); } else { - fprintf(stdout, "Server is Enterprise %s Edition, %s and will expire at %s.\r\n", serverVersion, sinfo, expiretime); + fprintf(stdout, "Server is Enterprise %s Edition, %s and will expire at %s.\r\n", serverVersion, sinfo, + expiretime); } taos_free_result(tres); @@ -1123,9 +1120,9 @@ void *shellCancelHandler(void *arg) { #ifdef WEBSOCKET } #endif - #ifdef WINDOWS +#ifdef WINDOWS printf("\n%s", shell.info.promptHeader); - #endif +#endif } return NULL; @@ -1165,8 +1162,7 @@ void *shellThreadLoop(void *arg) { } int32_t shellExecute() { - printf(shell.info.clientVersion, shell.info.cusName, - taos_get_client_info(), shell.info.cusName); + printf(shell.info.clientVersion, shell.info.cusName, taos_get_client_info(), shell.info.cusName); fflush(stdout); SShellArgs *pArgs = &shell.args; @@ -1233,13 +1229,13 @@ int32_t shellExecute() { taosSetSignal(SIGTERM, shellQueryInterruptHandler); taosSetSignal(SIGHUP, shellQueryInterruptHandler); taosSetSignal(SIGINT, shellQueryInterruptHandler); - + #ifdef WEBSOCKET if (!shell.args.restful && !shell.args.cloud) { #endif #ifndef WINDOWS printfIntroduction(); -#endif +#endif shellGetGrantInfo(); #ifdef WEBSOCKET } diff --git a/utils/test/c/CMakeLists.txt b/utils/test/c/CMakeLists.txt index 3f52fc8e5d5557f8f9ba52296ebd1f6d1632e589..b96814c13b7f4c9b5e894391084a80a72c7e62a3 100644 --- a/utils/test/c/CMakeLists.txt +++ b/utils/test/c/CMakeLists.txt @@ -31,7 +31,7 @@ target_link_libraries( ) target_link_libraries( tmq_sim - PUBLIC taos + PUBLIC ${TAOS_LIB} PUBLIC util PUBLIC common PUBLIC os diff --git a/utils/test/c/sml_test.c b/utils/test/c/sml_test.c index e4ed6037a34d207ae32d4f0d62525c343413a82b..237bfc50926f6ec68b4bbee02bc74a25bea27002 100644 --- a/utils/test/c/sml_test.c +++ b/utils/test/c/sml_test.c @@ -1552,12 +1552,45 @@ int sml_ts3724_Test() { return code; } +int sml_td24559_Test() { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + + TAOS_RES *pRes = taos_query(taos, "drop database if exists td24559"); + taos_free_result(pRes); + + pRes = taos_query(taos, "create database if not exists td24559"); + taos_free_result(pRes); + + const char *sql[] = { + "stb,t1=1 f1=283i32,f2=g\"Point(4.343 89.342)\" 1632299372000", + "stb,t1=1 f2=G\"Point(4.343 89.342)\",f1=106i32 1632299373000", + "stb,t2=1 f2=G\"Point(4.343 89.342)\",f1=106i32 1632299374000", + "stb,t1=1 f1=106i32,f2=G\"GEOMETRYCOLLECTION (MULTIPOINT((0 0), (1 1)), POINT(3 4), LINESTRING(2 3, 3 4))\" 1632299378000", + }; + + pRes = taos_query(taos, "use td24559"); + taos_free_result(pRes); + + pRes = taos_schemaless_insert(taos, (char **)sql, sizeof(sql) / sizeof(sql[0]), TSDB_SML_LINE_PROTOCOL, + TSDB_SML_TIMESTAMP_MILLI_SECONDS); + + int code = taos_errno(pRes); + printf("%s result0:%s\n", __FUNCTION__, taos_errstr(pRes)); + taos_free_result(pRes); + + taos_close(taos); + + return code; +} + int main(int argc, char *argv[]) { if (argc == 2) { taos_options(TSDB_OPTION_CONFIGDIR, argv[1]); } int ret = 0; + ret = sml_td24559_Test(); + ASSERT(!ret); ret = sml_td24070_Test(); ASSERT(!ret); ret = sml_td23881_Test(); diff --git a/utils/test/c/tmqDemo.c b/utils/test/c/tmqDemo.c index ce069c2b05878cb6806f2784be896942cb701ae4..64f536433ea511036b55c3b06e0918b759f7aa10 100644 --- a/utils/test/c/tmqDemo.c +++ b/utils/test/c/tmqDemo.c @@ -221,7 +221,7 @@ int64_t getDirectorySize(char* dir) { totalSize += subDirSize; } else if (0 == strcmp(strchr(fileName, '.'), ".log")) { // only calc .log file size, and not include .idx file int64_t file_size = 0; - taosStatFile(subdir, &file_size, NULL); + taosStatFile(subdir, &file_size, NULL, NULL); totalSize += file_size; } } @@ -702,4 +702,3 @@ int main(int32_t argc, char* argv[]) { taosCloseFile(&g_fp); return 0; } - diff --git a/utils/tsim/CMakeLists.txt b/utils/tsim/CMakeLists.txt index c2cf7ac3c5380c4e116e96753fa78f486d918566..209982c659db877d5722e8e0b5c27d3409f5de31 100644 --- a/utils/tsim/CMakeLists.txt +++ b/utils/tsim/CMakeLists.txt @@ -2,7 +2,7 @@ aux_source_directory(src TSIM_SRC) add_executable(tsim ${TSIM_SRC}) target_link_libraries( tsim - PUBLIC taos_static + PUBLIC ${TAOS_LIB} PUBLIC util PUBLIC common PUBLIC os