diff --git a/.gitignore b/.gitignore index f2440b4f..4d3c44ec 100644 --- a/.gitignore +++ b/.gitignore @@ -181,6 +181,8 @@ obproxy-tmp* src/.DS_Store unittest/.DS_Store ob_proxy_parser.output +.vscode/* +rpm/.dep_create deps/3rd/home deps/3rd/var deps/3rd/usr diff --git a/.secignore b/.secignore index 44c80e24..ebe3fd78 100644 --- a/.secignore +++ b/.secignore @@ -42,7 +42,8 @@ http://www.quicklz.com/) http://www.goof.com/pcg/marc/liblzf.html) http://www.fastlz.org/ - http://stackoverflow.com/a/32095106/646947 + http://stackoverflow.com/* + https://stackoverflow.com/* http://fastcompression.blogspot.com/p/lz4.html https://groups.google.com/forum/# https://github.com/mcmilk/zstdmt diff --git a/build.sh b/build.sh index 24d27923..e5201ad2 100755 --- a/build.sh +++ b/build.sh @@ -77,16 +77,16 @@ function do_config() ./configure --with-gcc-version=9.3.0 --with-coverage=yes --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no echo -e "\033[31m ===build gcov version=== \033[0m" ;; - xperf) - # configure for perf - ./configure --with-gcc-version=9.3.0 --with-coverage=no --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no --with-release --with-perf - echo -e "\033[31m ===build perf version=== \033[0m" - ;; xasan) # configure for asan ./configure --with-gcc-version=9.3.0 --with-coverage=no --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no --with-asan echo -e "\033[31m ===build asan version=== \033[0m" ;; + xso) + # configure for obproxy_so + ./configure --with-gcc-version=9.3.0 --with-coverage=no --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no --with-release --with-so + echo -e "\033[31m ===build so version=== \033[0m" + ;; *) # configure for release ./configure --with-gcc-version=9.3.0 --with-coverage=no --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no --with-release @@ -121,7 +121,7 @@ function do_rpm() cd ${TMP_DIR}/BUILD echo "[BUILD] make rpms..._prefix=${PREFIX} spec_file=${SPEC_FILE}" - rpmbuild --define "_topdir ${TMP_DIR}" --define "NAME ${PACKAGE}" --define "VERSION ${VERSION}" --define "_prefix ${PREFIX}" --define "RELEASE ${RELEASE}" -ba ${TOPDIR}/deps/3rd/${SPEC_FILE} || exit 2 + rpmbuild --define "_topdir ${TMP_DIR}" --define "NAME ${PACKAGE}" --define "VERSION ${VERSION}" --define "_prefix ${PREFIX}" --define "RELEASE ${RELEASE}" --define "rpm_path ${TOPDIR}" -ba ${TOPDIR}/deps/3rd/${SPEC_FILE} || exit 2 echo "[BUILD] make rpms done." cd ${TOPDIR} diff --git a/configure.ac b/configure.ac index b710617e..8c3530a6 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ AC_INIT([OceanBase], - [4.0.0], + [4.1.0.0], [wgs13579@gmail.com], [obproxy-ce], [http://oceanbase.taobao.org/]) - obapi_version="4.0.0" + obapi_version="4.1.0.0" AC_SUBST(obapi_version) AC_DISABLE_STATIC @@ -26,12 +26,12 @@ if test "$withval" = "yes"; then case "$host_cpu" in *aarch64* ) - AM_CXXFLAGS="-g -O2 -D_OB_VERSION=1000 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -Wextra -Wno-unused-parameter -Wformat -Wno-conversion -Wno-deprecated -Wno-invalid-offsetof -Wno-unused-result -Wno-format-security -finline-functions -fno-strict-aliasing -mtune=generic -march=armv8-a+crc -Wno-psabi -Wno-sign-compare -Wno-class-memaccess -Wno-deprecated-copy -Wno-ignored-qualifiers -Wno-aligned-new -Wno-format-truncation -Wno-literal-suffix -Wno-format-overflow -Wno-stringop-truncation -Wno-memset-elt-size -Wno-cast-function-type -Wno-address-of-packed-member -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" - AM_CFLAGS="-g -O2 -D_OB_VERSION=1000 -DCOMPATIBLE -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNDEBUG -finline-functions -fno-strict-aliasing -Wall -mtune=generic -Wno-psabi -Wno-sign-compare -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" + AM_CXXFLAGS="-g -O2 -D_OB_VERSION=1000 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -Wextra -Wno-unused-parameter -Wformat -Wno-conversion -Wno-deprecated -Wno-invalid-offsetof -Wno-unused-result -Wno-format-security -finline-functions -fno-strict-aliasing -mtune=generic -march=armv8-a+crc -Wno-psabi -Wno-sign-compare -Wno-class-memaccess -Wno-deprecated-copy -Wno-ignored-qualifiers -Wno-aligned-new -Wno-format-truncation -Wno-literal-suffix -Wno-format-overflow -Wno-stringop-truncation -Wno-memset-elt-size -Wno-cast-function-type -Wno-address-of-packed-member -fno-omit-frame-pointer" + AM_CFLAGS="-g -O2 -D_OB_VERSION=1000 -DCOMPATIBLE -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNDEBUG -finline-functions -fno-strict-aliasing -Wall -mtune=generic -Wno-psabi -Wno-sign-compare" ;; * ) - AM_CXXFLAGS="-g -O2 -D_OB_VERSION=1000 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -Wextra -Wno-unused-parameter -Wformat -Wno-conversion -Wno-deprecated -Wno-invalid-offsetof -Wno-unused-result -Wno-format-security -finline-functions -fno-strict-aliasing -mtune=core2 -Wno-psabi -Wno-sign-compare -Wno-class-memaccess -Wno-deprecated-copy -Wno-ignored-qualifiers -Wno-aligned-new -Wno-format-truncation -Wno-literal-suffix -Wno-format-overflow -Wno-stringop-truncation -Wno-memset-elt-size -Wno-cast-function-type -Wno-address-of-packed-member -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" - AM_CFLAGS="-g -O2 -D_OB_VERSION=1000 -DCOMPATIBLE -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNDEBUG -finline-functions -fno-strict-aliasing -Wall -mtune=core2 -Wno-psabi -Wno-sign-compare -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" + AM_CXXFLAGS="-g -O2 -D_OB_VERSION=1000 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -Wextra -Wno-unused-parameter -Wformat -Wno-conversion -Wno-deprecated -Wno-invalid-offsetof -Wno-unused-result -Wno-format-security -finline-functions -fno-strict-aliasing -mtune=core2 -Wno-psabi -Wno-sign-compare -Wno-class-memaccess -Wno-deprecated-copy -Wno-ignored-qualifiers -Wno-aligned-new -Wno-format-truncation -Wno-literal-suffix -Wno-format-overflow -Wno-stringop-truncation -Wno-memset-elt-size -Wno-cast-function-type -Wno-address-of-packed-member -fno-omit-frame-pointer" + AM_CFLAGS="-g -O2 -D_OB_VERSION=1000 -DCOMPATIBLE -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNDEBUG -finline-functions -fno-strict-aliasing -Wall -mtune=core2 -Wno-psabi -Wno-sign-compare" ;; esac fi @@ -41,6 +41,26 @@ ] ) + AC_ARG_WITH([so], + AS_HELP_STRING([--with-so], + [with so support (default is NO)]), + [ + if test "$withval" = "yes"; then + support_so=yes + AM_CXXFLAGS="${AM_CXXFLAGS} -fPIC" + AM_CFLAGS="${AM_CFLAGS} -fPIC" + fi + ], + [support_so=no] + ) + + AM_CONDITIONAL([HAVE_SO], test x$support_so = xyes ) + + if test "$support_so" == "no"; then + AM_CXXFLAGS="${AM_CXXFLAGS} -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" + AM_CFLAGS="${AM_CFLAGS} -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" + fi + #check gcc version, add -Wno-ignored-qualifiers flag for gcc version greater than 4.3.0 GCC_VERSION=`$CC -dumpfullversion -dumpversion` if test $? -eq 0; then @@ -101,23 +121,6 @@ ], []) - AC_ARG_WITH([perf], - AS_HELP_STRING([--with-perf], - [with perf (default is NO)]), - [ - if test "$withval" = "yes"; then - # The following parameters are options for using gperftools, - # currently not using tcmalloc - # test_perf=yes - # AM_CXXFLAGS="${AM_CXXFLAGS} -D__NEED_PERF__" - # AM_LDFLAGS="${AM_LDFLAGS} -lprofiler" - AM_CXXFLAGS="${AM_CXXFLAGS} -fno-omit-frame-pointer" - AM_CFLAGS="${AM_CFLAGS} -fno-omit-frame-pointer" - fi - ], - [with_perf=no] - ) - AC_ARG_WITH([asan], AS_HELP_STRING([--with-asan], [with asan (default is NO)]), diff --git a/deps/3rd/obproxy.spec b/deps/3rd/obproxy.spec index 2fccee9d..03169a2e 100644 --- a/deps/3rd/obproxy.spec +++ b/deps/3rd/obproxy.spec @@ -34,16 +34,29 @@ OceanBase Database Proxy %setup %build -./configure CXX=${CXX} CC=${CC} --with-gcc-version=9.3.0 RELEASEID=%{RELEASE} --prefix=%{_prefix} --with-test-case=no --with-release=yes --with-tblib-root=/opt/csr/common --with-easy-root=/usr --with-easy-lib-path=/usr/lib64 --with-svnfile --enable-shared=default --enable-silent-rules -mkdir -p unittest +mkdir -p lib +cp ${TOOLS_DIR}/lib64/libstdc++.so.6.0.28 lib/libstdc++.so.6 + +#./configure CXX=${CXX} CC=${CC} --with-gcc-version=9.3.0 --with-so --prefix=%{_prefix} --with-test-case=no --with-release=yes --with-tblib-root=/opt/csr/common --with-easy-root=/usr --with-easy-lib-path=/usr/lib64 --with-svnfile --enable-shared=default --enable-silent-rules CPU_CORES=`grep -c ^processor /proc/cpuinfo` MAKE_ARGS="-j $CPU_CORES" +#make $MAKE_ARGS +#cp src/obproxy/.libs/libobproxy_so.so.0.0.0 lib/libobproxy_so.so + +#make distclean >/dev/null 2>&1 +#find . -path ./tools/codestyle/astyle/build -prune -o -path ./doc -prune -o -name Makefile -exec rm -f {} \; +#find . -name .deps -prune -exec rm -rf {} \; + +./configure CXX=${CXX} CC=${CC} --with-gcc-version=9.3.0 RELEASEID=%{RELEASE} --prefix=%{_prefix} --with-test-case=no --with-release=yes --with-tblib-root=/opt/csr/common --with-easy-root=/usr --with-easy-lib-path=/usr/lib64 --with-svnfile --enable-shared=default --enable-silent-rules +mkdir -p unittest make $MAKE_ARGS %install make DESTDIR=$RPM_BUILD_ROOT install mkdir -p $RPM_BUILD_ROOT%{install_dir}/bin +mkdir -p $RPM_BUILD_ROOT%{install_dir}/lib cp src/obproxy/obproxy $RPM_BUILD_ROOT%{install_dir}/bin +cp -r lib/* $RPM_BUILD_ROOT%{install_dir}/lib cp script/deploy/obproxyd.sh $RPM_BUILD_ROOT%{install_dir}/bin %clean @@ -54,12 +67,19 @@ rm -rf $RPM_BUILD_ROOT %dir %{install_dir}/bin %{install_dir}/bin/obproxy %{install_dir}/bin/obproxyd.sh +%{install_dir}/lib/libstdc++.so.6 %pre rm -rf %{install_dir}/log rm -rf %{install_dir}/bin rm -rf %{install_dir}/etc rm -rf %{install_dir}/.conf +rm -rf /u01/obproxy/lib +mkdir -p /u01/obproxy/lib %post chown -R admin:admin %{install_dir} +ln -s %{install_dir}/lib/libobproxy_so.so /u01/obproxy/lib/libobproxy_so.so.0 +ln -s %{install_dir}/lib/libobproxy_so.so /u01/obproxy/lib/libobproxy_so.so +ln -s %{install_dir}/lib/libprotobuf.so.18 /u01/obproxy/lib/libprotobuf.so.18 +ln -s %{install_dir}/lib/libstdc++.so.6 /u01/obproxy/lib/libstdc++.so.6 diff --git a/deps/easy/src/io/easy_ssl.c b/deps/easy/src/io/easy_ssl.c index f7bfa8de..e8e246c3 100644 --- a/deps/easy/src/io/easy_ssl.c +++ b/deps/easy/src/io/easy_ssl.c @@ -1601,14 +1601,6 @@ static int easy_ssl_dhparam(easy_ssl_ctx_t *ssl, char *file) DH *dh; BIO *bio; - /* - * -----BEGIN DH PARAMETERS----- - * MIGHAoGBALu8LcrYRnSQfEP89YDpz9vZWKP1aLQtSwju1OsPs1BMbAMCducQgAxc - * y7qokiYUxb7spWWl/fHSh6K8BJvmd4Bg6RqSp1fjBI9osHb302zI8pul34HcLKcl - * 7OZicMyaUDXYzs7vnqAnSmOrHlj6/UmI0PZdFGdX2gcd8EXP4WubAgEC - * -----END DH PARAMETERS----- - */ - static unsigned char dh1024_p[] = { 0xBB, 0xBC, 0x2D, 0xCA, 0xD8, 0x46, 0x74, 0x90, 0x7C, 0x43, 0xFC, 0xF5, 0x80, 0xE9, 0xCF, 0xDB, 0xD9, 0x58, 0xA3, 0xF5, 0x68, 0xB4, 0x2D, 0x4B, @@ -1677,19 +1669,6 @@ static int easy_ssl_dhparam_mysql(easy_ssl_ctx_t *ssl) { DH *dh; - /* - Diffie-Hellman key. - Generated using: >openssl dhparam -5 -C 2048 - - -----BEGIN DH PARAMETERS----- - MIIBCAKCAQEAil36wGZ2TmH6ysA3V1xtP4MKofXx5n88xq/aiybmGnReZMviCPEJ - 46+7VCktl/RZ5iaDH1XNG1dVQmznt9pu2G3usU+k1/VB4bQL4ZgW4u0Wzxh9PyXD - glm99I9Xyj4Z5PVE4MyAsxCRGA1kWQpD9/zKAegUBPLNqSo886Uqg9hmn8ksyU9E - BV5eAEciCuawh6V0O+Sj/C3cSfLhgA0GcXp3OqlmcDu6jS5gWjn3LdP1U0duVxMB - h/neTSCSvtce4CAMYMjKNVh9P1nu+2d9ZH2Od2xhRIqMTfAS1KTqF3VmSWzPFCjG - mjxx/bg6bOOjpgZapvB6ABWlWmRmAAWFtwIBBQ== - -----END DH PARAMETERS----- - */ static unsigned char dh2048_p[]= { 0x8A, 0x5D, 0xFA, 0xC0, 0x66, 0x76, 0x4E, 0x61, 0xFA, 0xCA, 0xC0, 0x37, diff --git a/rpm/obproxy-ce-VER.txt b/rpm/obproxy-ce-VER.txt index fcdb2e10..16f4c78f 100644 --- a/rpm/obproxy-ce-VER.txt +++ b/rpm/obproxy-ce-VER.txt @@ -1 +1 @@ -4.0.0 +4.1.0.0 diff --git a/src/common/cache/ob_kv_storecache.h b/src/common/cache/ob_kv_storecache.h index a8fd09e9..dc19d62c 100644 --- a/src/common/cache/ob_kv_storecache.h +++ b/src/common/cache/ob_kv_storecache.h @@ -131,8 +131,10 @@ enum ObKVCachePolicy struct ObKVCacheConfig { public: - ObKVCacheConfig(); - void reset(); + /* this function is defined for c driver client compile */ + ObKVCacheConfig() {}; + /* this function is defined for c driver client compile */ + void reset() {}; bool is_valid_; int64_t priority_; char cache_name_[MAX_CACHE_NAME_LENGTH]; @@ -267,9 +269,12 @@ class ObKVCacheInstMap; class ObKVCacheInstHandle { public: - ObKVCacheInstHandle(); - virtual ~ObKVCacheInstHandle(); - void reset(); + /* this function is defined for c driver client compile */ + ObKVCacheInstHandle() {}; + /* this function is defined for c driver client compile */ + virtual ~ObKVCacheInstHandle() {}; + /* this function is defined for c driver client compile */ + void reset() {}; inline ObKVCacheInst *get_inst() { return inst_; } private: friend class ObKVCacheInstMap; @@ -291,8 +296,10 @@ struct ObKVCacheInfo class ObKVCacheInstMap { public: - ObKVCacheInstMap(); - virtual ~ObKVCacheInstMap(); + /* this function is defined for c driver client compile */ + ObKVCacheInstMap() {}; + /* this function is defined for c driver client compile */ + virtual ~ObKVCacheInstMap() {}; int init(const int64_t max_entry_cnt, const ObKVCacheConfig *configs); void destroy(); int get_cache_inst( @@ -319,8 +326,10 @@ class ObKVCacheInstMap class ObKVCacheStore { public: - ObKVCacheStore(); - virtual ~ObKVCacheStore(); + /* this function is defined for c driver client compile */ + ObKVCacheStore() {}; + /* this function is defined for c driver client compile */ + virtual ~ObKVCacheStore() {}; int init(ObKVCacheInstMap &insts, const int64_t max_cache_size, const int64_t block_size); void destroy(); int set_priority(const int64_t cache_id, const int64_t old_priority, const int64_t new_priority); @@ -394,8 +403,10 @@ class ObKVCacheStore class ObKVCacheMap { public: - ObKVCacheMap(); - virtual ~ObKVCacheMap(); + /* this function is defined for c driver client compile */ + ObKVCacheMap() {}; + /* this function is defined for c driver client compile */ + virtual ~ObKVCacheMap() {}; int init(const int64_t bucket_num, ObKVCacheStore *store); void destroy(); int erase_all(); @@ -452,19 +463,23 @@ class ObKVCacheHandle; class ObKVGlobalCache { public: - static ObKVGlobalCache &get_instance(); + /* this function is defined for c driver client compile */ + static ObKVGlobalCache &get_instance() {return *(new ObKVGlobalCache());}; int init(const int64_t bucket_num = DEFAULT_BUCKET_NUM, const int64_t max_cache_size = DEFAULT_MAX_CACHE_SIZE, const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE); void destroy(); - void reload_priority(); + /* this function is defined for c driver client compile */ + void reload_priority() {}; int get_tenant_cache_info(const uint64_t tenant_id, ObIArray &infos); int get_all_cache_info(ObIArray &infos); private: template friend class ObKVCache; friend class ObKVCacheHandle; - ObKVGlobalCache(); - virtual ~ObKVGlobalCache(); + /* this function is defined for c driver client compile */ + ObKVGlobalCache() {} + /* this function is defined for c driver client compile */ + virtual ~ObKVGlobalCache() {} int register_cache(const char *cache_name, const int64_t priority, int64_t &cache_id); void deregister_cache(const int64_t cache_id); int set_priority(const int64_t cache_id, const int64_t priority); @@ -482,7 +497,8 @@ class ObKVGlobalCache ObKVMemBlockHandle *&mb_handle); int erase(const int64_t cache_id, const ObIKVCacheKey &key); void revert(ObKVMemBlockHandle *mb_handle); - void wash(); + /* this function is defined for c driver client compile */ + void wash() {}; private: static const int64_t DEFAULT_BUCKET_NUM = 10000000L; static const int64_t DEFAULT_MAX_CACHE_SIZE = 1024L * 1024L * 1024L * 1024L; //1T diff --git a/src/common/mysql_proxy/ob_isql_client.h b/src/common/mysql_proxy/ob_isql_client.h index cd1293fe..65dc7be3 100644 --- a/src/common/mysql_proxy/ob_isql_client.h +++ b/src/common/mysql_proxy/ob_isql_client.h @@ -58,10 +58,13 @@ class ObISQLClient public: friend class ObISQLClient; - ReadResult(); - virtual ~ReadResult(); + /* this function is defined for c driver client compile */ + ReadResult() {} + /* this function is defined for c driver client compile */ + virtual ~ReadResult() {} - sqlclient::ObMySQLResult *mysql_result(); + /* this function is defined for c driver client compile */ + sqlclient::ObMySQLResult *mysql_result() {return nullptr;} // FIXME : remove sqlclient::ObMySQLResult *get_result() { return mysql_result(); } diff --git a/src/common/ob_obj_cast.cpp b/src/common/ob_obj_cast.cpp index 3c73f315..684d180f 100644 --- a/src/common/ob_obj_cast.cpp +++ b/src/common/ob_obj_cast.cpp @@ -1563,7 +1563,7 @@ static int double_float(const ObObjType expect_type, ObObjCastParams ¶ms, ret = OB_ERR_UNEXPECTED; LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type)); - } else if (CAST_FAIL(real_range_check(expect_type, in.get_double(), value))) { + } else if (!lib::is_oracle_mode() && CAST_FAIL(real_range_check(expect_type, in.get_double(), value))) { } else { out.set_float(expect_type, value); } @@ -2975,17 +2975,30 @@ static int string_datetime(const ObObjType expect_type, ObObjCastParams ¶ms, { int ret = OB_SUCCESS; ObScale res_scale = -1; + ObString utf8_string; + if (OB_UNLIKELY((ObStringTC != in.get_type_class() && ObTextTC != in.get_type_class()) || ObDateTimeTC != ob_obj_type_class(expect_type))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid input type", - K(ret), K(in), K(expect_type)); + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid input type", + K(ret), K(in), K(expect_type)); + } else if (lib::is_oracle_mode() && in.is_blob()) { + ret = OB_NOT_SUPPORTED; + LOG_ERROR("invalid use of blob type", K(ret), K(in), K(expect_type)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "Cast to blob type"); + } else if (OB_FAIL(convert_string_collation(in.get_string(), in.get_collation_type(), utf8_string, ObCharset::get_system_collation(), params))) { + LOG_WARN("convert_string_collation", K(ret)); } else { - const ObTimeZoneInfo *tz_info = (ObTimestampType == expect_type) ? params.dtc_params_.tz_info_ : NULL; int64_t value = 0; - if (CAST_FAIL(ObTimeConverter::str_to_datetime(in.get_string(), tz_info, value, &res_scale))) { + ObTimeConvertCtx cvrt_ctx(params.dtc_params_.tz_info_, ObTimestampType == expect_type); + if (lib::is_oracle_mode()) { + cvrt_ctx.oracle_nls_format_ = params.dtc_params_.get_nls_format(ObDateTimeType); + CAST_FAIL(ObTimeConverter::str_to_date_oracle(utf8_string, cvrt_ctx, value)); } else { + CAST_FAIL(ObTimeConverter::str_to_datetime(utf8_string, cvrt_ctx.tz_info_, value, &res_scale)); + } + if(OB_SUCC(ret)) { SET_RES_DATETIME(out); } } @@ -3067,29 +3080,56 @@ static int string_string(const ObObjType expect_type, ObObjCastParams ¶ms, ObString str; in.get_string(str); if (0 != str.length() - && CS_TYPE_BINARY != in.get_collation_type() - && CS_TYPE_BINARY != params.dest_collation_ + // in mysql mode if charset is binary then not convert + // in oracle mode if charset is binary then convert + && ((CS_TYPE_BINARY != in.get_collation_type() && CS_TYPE_BINARY != params.dest_collation_) + || lib::is_oracle_mode()) && CS_TYPE_INVALID != in.get_collation_type() && CS_TYPE_INVALID != params.dest_collation_ && (ObCharset::charset_type_by_coll(in.get_collation_type()) != ObCharset::charset_type_by_coll(params.dest_collation_))) { char *buf = NULL; - // buf_len is related to the encoding length, gbk uses 2 bytes to encode a character, utf8mb4 uses 1 to 4 bytes - // CharConvertFactorNum is a multiple of the requested memory size - const int32_t CharConvertFactorNum = 2; + const int32_t CharConvertFactorNum = 4; int32_t buf_len = str.length() * CharConvertFactorNum; uint32_t result_len = 0; if (OB_UNLIKELY(NULL == (buf = static_cast(params.alloc(buf_len))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("alloc memory failed", K(ret)); - } else if (OB_FAIL(ObCharset::charset_convert(in.get_collation_type(), - str.ptr(), - str.length(), - params.dest_collation_, - buf, - buf_len, - result_len))) { - LOG_WARN("charset convert failed", K(ret), K(in.get_collation_type()), K(params.dest_collation_)); + } else { + ret = ObCharset::charset_convert(in.get_collation_type(), + str.ptr(), + str.length(), + params.dest_collation_, + buf, + buf_len, + result_len); + if (OB_SUCCESS != ret) { + int32_t str_offset = 0; + int32_t buf_offset = 0; + ObString question_mark("?"); + while (str_offset < str.length() && buf_offset + question_mark.length() <= buf_len) { + int64_t offset = ObCharset::charpos(in.get_collation_type(), str.ptr() + str_offset, + str.length() - str_offset, 1); + ret = ObCharset::charset_convert(in.get_collation_type(), str.ptr() + str_offset, + static_cast(offset), params.dest_collation_, buf + buf_offset, buf_len - buf_offset, result_len); + str_offset += static_cast(offset); + if (OB_SUCCESS == ret && result_len > 0) { + buf_offset += result_len; + } else { + MEMCPY(buf + buf_offset, question_mark.ptr(), question_mark.length()); + buf_offset += question_mark.length(); + } + } + if (str_offset < str.length()) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("size overflow", K(ret), K(str)); + } else { + // The log is printed here to remind that there are characters that fail to convert and are replaced by '?' + LOG_DEBUG("charset convert failed", K(ret), K(in.get_collation_type()), K(params.dest_collation_)); + result_len = static_cast(buf_offset); + ret = OB_SUCCESS; + } + } } LOG_DEBUG("convert result", K(str), "result", ObHexEscapeSqlStr(ObString(result_len, buf))); diff --git a/src/common/ob_obj_type.h b/src/common/ob_obj_type.h index 625e4bba..4e034eb6 100644 --- a/src/common/ob_obj_type.h +++ b/src/common/ob_obj_type.h @@ -90,6 +90,8 @@ enum ObObjType ObNCharType = 44, // nchar ObURowIDType = 45, // UROWID ObLobType = 46, // Oracle Lob + ObJsonType = 47, // Json Type + ObGeometryType = 48, // Geometry type ObMaxType // invalid type, or count of obj type }; @@ -295,7 +297,7 @@ inline bool ob_is_blob(const ObObjType type, const ObCollationType cs_type) inline bool is_obj_type_supported(ObObjType type) { return (type > ObNullType && type < ObUnknownType) - || ob_is_otimestamp_type(type); + || ob_is_otimestamp_type(type) || ob_is_number_tc(type); } // to_string adapter diff --git a/src/common/ob_object.cpp b/src/common/ob_object.cpp index 33b29d48..774296ab 100644 --- a/src/common/ob_object.cpp +++ b/src/common/ob_object.cpp @@ -249,7 +249,7 @@ int64_t ObObj::get_deep_copy_size() const int64_t ret = 0; if (is_string_type()) { ret += val_len_; - } else if (ObNumberType == meta_.get_type() || ObUNumberType == meta_.get_type()) { + } else if (ob_is_number_tc(get_type())) { ret += (sizeof(uint32_t) * nmb_desc_.len_); } return ret; @@ -443,7 +443,7 @@ ObObjTypeFuncs OBJ_FUNCS[ObMaxType] = DEF_FUNC_ENTRY(ObRawType), // 39, raw DEF_FUNC_ENTRY(ObNullType), // 40 DEF_FUNC_ENTRY(ObNullType), // 41 - DEF_FUNC_ENTRY(ObNullType), // 42 + DEF_FUNC_ENTRY(ObNumberFloatType), // 42 DEF_FUNC_ENTRY(ObNVarchar2Type), // 43, nvarchar2 DEF_FUNC_ENTRY(ObNCharType), // 44, nchar }; diff --git a/src/common/ob_object.h b/src/common/ob_object.h index 8db10adb..f29788d3 100644 --- a/src/common/ob_object.h +++ b/src/common/ob_object.h @@ -383,6 +383,13 @@ class ObObj void set_time_value(const int64_t value); void set_year_value(const uint8_t value); + void set_timestamp_tz(const int64_t time_us, const uint32_t time_ctx_desc) { set_otimestamp_value(ObTimestampTZType, time_us, time_ctx_desc); } + void set_timestamp_ltz(const int64_t time_us, const uint16_t time_desc) { set_otimestamp_value(ObTimestampLTZType, time_us, time_desc); } + void set_timestamp_nano(const int64_t time_us, const uint16_t time_desc) { set_otimestamp_value(ObTimestampNanoType, time_us, time_desc); } + void set_timestamp_tz(const ObOTimestampData &value) { set_otimestamp_value(ObTimestampTZType, value); } + void set_timestamp_ltz(const ObOTimestampData &value) { set_otimestamp_value(ObTimestampLTZType, value); } + void set_timestamp_nano(const ObOTimestampData &value) { set_otimestamp_value(ObTimestampNanoType, value); } + void set_string(const ObObjType type, const char *ptr, const ObString::obstr_size_t size); void set_string(const ObObjType type, const ObString &value); void set_varchar(const ObString &value); diff --git a/src/common/ob_partition_key.h b/src/common/ob_partition_key.h index 426dc957..0947578e 100644 --- a/src/common/ob_partition_key.h +++ b/src/common/ob_partition_key.h @@ -49,8 +49,10 @@ struct ObPartitionKey int init(const uint64_t table_id, const int32_t partition_idx, const int32_t partition_cnt); int parse(const char* str); - void reset(); - bool is_valid() const; + /* this function is defined for c driver client compile */ + void reset() {}; + /* this function is defined for c driver client compile */ + bool is_valid() const {return true;}; uint64_t hash() const; uint64_t inner_hash() const; int compare(const ObPartitionKey &other) const; diff --git a/src/common/ob_queue_thread.h b/src/common/ob_queue_thread.h index 243fd6e1..22618a17 100644 --- a/src/common/ob_queue_thread.h +++ b/src/common/ob_queue_thread.h @@ -40,11 +40,19 @@ class ObCond static const int64_t SPIN_WAIT_NUM = 0; static const int64_t BUSY_INTERVAL = 1000; public: - explicit ObCond(const int64_t spin_wait_num = SPIN_WAIT_NUM); - ~ObCond(); + /* this function is defined for c driver client compile */ + explicit ObCond(const int64_t spin_wait_num = SPIN_WAIT_NUM) :spin_wait_num_(spin_wait_num) {} + /* this function is defined for c driver client compile */ + ~ObCond() {} public: - void signal(); - int timedwait(const int64_t time_us); + /* this function is defined for c driver client compile */ + void signal() {} + /* this function is defined for c driver client compile */ + int timedwait(const int64_t time_us) + { + UNUSED(time_us); + return OB_NOT_IMPLEMENT; + } int wait(); private: const int64_t spin_wait_num_; diff --git a/src/common/ob_range2.h b/src/common/ob_range2.h index f208a81b..c41c12f0 100644 --- a/src/common/ob_range2.h +++ b/src/common/ob_range2.h @@ -19,6 +19,8 @@ #include "common/ob_range.h" #include "lib/utility/utility.h" #include "lib/regex/ob_regex.h" +#include "lib/allocator/ob_allocator.h" +#include "obproxy/opsql/expr_parser/ob_expr_parse_result.h" namespace oceanbase @@ -100,6 +102,45 @@ struct ObNewRange : public RowkeyInfoHolder return ret; } + int build_row_key(int64_t columns_num, ObIAllocator &allocator) { + // build row key like (min, min, min : max, max, max) + int ret = OB_SUCCESS; + if (columns_num < 0 || columns_num > OBPROXY_MAX_PART_LEVEL) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "invalid", K(columns_num)); + } else { + void *start_objs_buf = NULL; + void *end_objs_buf = NULL; + if (OB_ISNULL((start_objs_buf = allocator.alloc(sizeof(ObObj) * columns_num))) && columns_num != 0) { + ret = OB_ALLOCATE_MEMORY_FAILED; + COMMON_LOG(WARN, "fail to alloc new obj", K(ret), K(columns_num)); + } else if (OB_ISNULL(end_objs_buf = allocator.alloc(sizeof(ObObj) * columns_num)) && columns_num !=0) { + ret = OB_ALLOCATE_MEMORY_FAILED; + COMMON_LOG(WARN, "fail to alloc new obj", K(ret), K(columns_num)); + } else { + for (int i = 0; OB_SUCC(ret) && i < columns_num; i++) { + ObObj *start = NULL; + ObObj *end = NULL; + if (OB_ISNULL(start = new (reinterpret_cast(start_objs_buf) + i) ObObj())) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "failed to do placement new", K(start_objs_buf), K(ret)); + } else if (OB_ISNULL(end = new (reinterpret_cast(end_objs_buf) + i) ObObj())) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "failed to do placement new", K(end_objs_buf), K(ret)); + } else { + start->set_min_value(); + end->set_max_value(); + } + } + if (OB_SUCC(ret)) { + start_key_.assign(reinterpret_cast(start_objs_buf), columns_num); + end_key_.assign(reinterpret_cast(end_objs_buf), columns_num); + } + } + } + return ret; + } + // new compare func for tablet.range and scan_param.range inline int compare_with_endkey2(const ObNewRange &r) const { diff --git a/src/common/obsm_utils.cpp b/src/common/obsm_utils.cpp index 9ee7818d..6ecb0e8d 100644 --- a/src/common/obsm_utils.cpp +++ b/src/common/obsm_utils.cpp @@ -310,6 +310,12 @@ int ObSMUtils::get_ob_type(ObObjType &ob_type, EMySQLFieldType mysql_type) case OB_MYSQL_TYPE_OB_UROWID: ob_type = ObURowIDType; break; + case OB_MYSQL_TYPE_JSON: + ob_type = ObJsonType; + break; + case OB_MYSQL_TYPE_GEOMETRY: + ob_type = ObGeometryType; + break; default: _OB_LOG(WARN, "unsupport MySQL type %d", mysql_type); ret = OB_OBJ_TYPE_ERROR; diff --git a/src/lib/Makemodule.am b/src/lib/Makemodule.am index 25b2d24a..a828a2be 100644 --- a/src/lib/Makemodule.am +++ b/src/lib/Makemodule.am @@ -47,6 +47,7 @@ lib/charset/ob_ctype_uca.c\ lib/charset/ob_ctype_mb.c\ lib/charset/ob_ctype_bin.c\ lib/charset/ob_ctype_simple.c\ +lib/charset/ob_ctype_latin1.c\ lib/charset/ob_mysql_global.h\ lib/charset/ob_config.h\ lib/charset/ob_dtoa.h\ @@ -157,6 +158,7 @@ lib/oblog/ob_trace_log.h\ lib/oblog/ob_trace_log.cpp\ lib/oblog/ob_warning_buffer.h\ lib/oblog/ob_warning_buffer.cpp\ +lib/oblog/ob_simple_trace.h\ lib/queue/ob_dedup_queue.h\ lib/queue/ob_dedup_queue.cpp\ lib/queue/ob_fixed_queue.h\ diff --git a/src/lib/allocator/ob_concurrent_fifo_allocator.h b/src/lib/allocator/ob_concurrent_fifo_allocator.h index 10c0cdd3..496d747a 100644 --- a/src/lib/allocator/ob_concurrent_fifo_allocator.h +++ b/src/lib/allocator/ob_concurrent_fifo_allocator.h @@ -21,17 +21,36 @@ namespace common class ObConcurrentFIFOAllocator : public common::ObIAllocator { public: - ObConcurrentFIFOAllocator(); - virtual ~ObConcurrentFIFOAllocator(); + /* this function is defined for c driver client compile */ + ObConcurrentFIFOAllocator() {}; + /* this function is defined for c driver client compile */ + virtual ~ObConcurrentFIFOAllocator() {}; public: + /* this function is defined for c driver client compile */ int init(const int64_t total_limit, const int64_t hold_limit, - const int64_t page_size); - void destroy(); + const int64_t page_size) + { + UNUSED(total_limit); + UNUSED(hold_limit); + UNUSED(page_size); + return OB_NOT_IMPLEMENT; + } + /* this function is defined for c driver client compile */ + void destroy() {}; public: void set_mod_id(const int64_t mod_id); - void *alloc(const int64_t size); - void free(void *ptr); + /* this function is defined for c driver client compile */ + void *alloc(const int64_t size) + { + UNUSED(size); + return nullptr; + } + /* this function is defined for c driver client compile */ + void free(void *ptr) + { + UNUSED(ptr); + } int64_t allocated(); int64_t hold() const {return 0;} int64_t get_direct_alloc_count(); diff --git a/src/lib/allocator/ob_fifo_allocator.h b/src/lib/allocator/ob_fifo_allocator.h index 2db3b588..c57b38df 100644 --- a/src/lib/allocator/ob_fifo_allocator.h +++ b/src/lib/allocator/ob_fifo_allocator.h @@ -89,16 +89,26 @@ class ObFIFOAllocator : public common::ObIAllocator static const int64_t ALREADY_FREE = 0xf5eebef0; static const int64_t SPECIAL_FLAG = -1; public: - ObFIFOAllocator(); - ~ObFIFOAllocator(); - + /* this function is defined for c driver client compile */ + ObFIFOAllocator() {}; + /* this function is defined for c driver client compile */ + ~ObFIFOAllocator() {}; + + /* this function is defined for c driver client compile */ int init(ObIAllocator *allocator, const int64_t page_size, - const int64_t page_hold_limit = 32); - void reset(); + const int64_t page_hold_limit = 32) + { + UNUSED(allocator); + UNUSED(page_size); + UNUSED(page_hold_limit); + return OB_NOT_IMPLEMENT; + } + /* this function is defined for c driver client compile */ + void reset() { /* not support */ } void reuse() { /* not support */ } - void *alloc(const int64_t size); + void *alloc(const int64_t size) { UNUSED(size); return NULL; } void *alloc_align(const int64_t size, const int64_t align); - void free(void *p); + void free(void *p) { UNUSED(p); } void set_mod_id(int64_t mod_id); inline int64_t used() const diff --git a/src/lib/allocator/ob_lf_fifo_allocator.h b/src/lib/allocator/ob_lf_fifo_allocator.h index 477ef1c4..d8b78cdf 100644 --- a/src/lib/allocator/ob_lf_fifo_allocator.h +++ b/src/lib/allocator/ob_lf_fifo_allocator.h @@ -54,8 +54,10 @@ struct HazardSlot class ObLfFIFOAllocator : public common::ObIAllocator { public: - ObLfFIFOAllocator(); - virtual ~ObLfFIFOAllocator(); + /* this function is defined for c driver client compile */ + ObLfFIFOAllocator() {} + /* this function is defined for c driver client compile */ + virtual ~ObLfFIFOAllocator() {} public: int init(const int64_t page_size, const int64_t mod_id, @@ -64,8 +66,9 @@ class ObLfFIFOAllocator : public common::ObIAllocator const int64_t total_limit = INT64_MAX); void destroy(); public: - void *alloc(const int64_t size); - void free(void *ptr); + /* this function is defined for c driver client compile */ + void *alloc(const int64_t size) { UNUSED(size); return NULL; } + void free(void *ptr) { UNUSED(ptr); } bool is_fragment(void *ptr); int64_t allocated() { return allocated_size_; } void set_mod_id(const int64_t mod_id) { mem_attr_.mod_id_ = mod_id; } diff --git a/src/lib/charset/ob_charset.cpp b/src/lib/charset/ob_charset.cpp index 33d4a41c..2f786eba 100644 --- a/src/lib/charset/ob_charset.cpp +++ b/src/lib/charset/ob_charset.cpp @@ -26,6 +26,7 @@ const ObCharsetWrapper ObCharset::charset_wrap_arr_[CHARSET_WRAPPER_COUNT] = {CHARSET_GBK, "GBK charset", CS_TYPE_GBK_CHINESE_CI, 2}, {CHARSET_UTF16, "UTF-16 Unicode", CS_TYPE_UTF16_GENERAL_CI, 2}, {CHARSET_GB18030, "GB18030 charset", CS_TYPE_GB18030_CHINESE_CI, 4}, + {CHARSET_LATIN1, "cp1252 West European", CS_TYPE_LATIN1_SWEDISH_CI, 1} }; const ObCollationWrapper ObCharset::collation_wrap_arr_[COLLATION_WRAPPER_COUNT] = @@ -41,11 +42,13 @@ const ObCollationWrapper ObCharset::collation_wrap_arr_[COLLATION_WRAPPER_COUNT] {CS_TYPE_INVALID, CHARSET_INVALID, CS_TYPE_INVALID, false, false, 1}, {CS_TYPE_GB18030_CHINESE_CI, CHARSET_GB18030, CS_TYPE_GB18030_CHINESE_CI, true, true, 1}, {CS_TYPE_GB18030_BIN, CHARSET_GB18030, CS_TYPE_GB18030_BIN, false, true, 1}, + {CS_TYPE_LATIN1_SWEDISH_CI, CHARSET_LATIN1, CS_TYPE_LATIN1_SWEDISH_CI,true, true, 1}, + {CS_TYPE_LATIN1_BIN, CHARSET_LATIN1, CS_TYPE_LATIN1_BIN,false, true, 1} }; void *ObCharset::charset_arr[CS_TYPE_MAX] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 0 ~ 7 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 8 + &ob_charset_latin1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 8 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 16 NULL, NULL, NULL, NULL, &ob_charset_gbk_chinese_ci, // 24 NULL, NULL, NULL, // 29 @@ -53,7 +56,7 @@ void *ObCharset::charset_arr[CS_TYPE_MAX] = { NULL, NULL, NULL, NULL, NULL, // 40 &ob_charset_utf8mb4_general_ci, // 45 &ob_charset_utf8mb4_bin, // 46 - NULL, // 47 + &ob_charset_latin1_bin, // 47 NULL, NULL, NULL, NULL, NULL, NULL, // 48 &ob_charset_utf16_general_ci,// 54 &ob_charset_utf16_bin, // 55 @@ -236,8 +239,11 @@ uint32_t ObCharset::locate(ObCollationType collation_type, if (OB_UNLIKELY(start < 0 || start > str1_len)) { result = 0; } else { - start = static_cast(charpos(collation_type, str1, str1_len, start)); - if (static_cast(start) + str2_len > str1_len) { + int ret = OB_SUCCESS; + start = static_cast(charpos(collation_type, str1, str1_len, start, &ret)); + if (OB_FAIL(ret)) { + result = 0; + } else if (static_cast(start) + str2_len > str1_len) { result = 0; } else if (0 == str2_len) { result = static_cast(start) + 1; @@ -513,12 +519,15 @@ int ObCharset::well_formed_len(ObCollationType collation_type, const char *str, } return ret; } + +// Be careful with this function. The return value may be out of range. size_t ObCharset::charpos(const ObCollationType collation_type, - const char *str, - const int64_t str_len, - const int64_t length) + const char *str, + const int64_t str_len, + const int64_t length, + int *ret) { - size_t ret = 0; + size_t res_pos = 0; if (OB_UNLIKELY(collation_type <= CS_TYPE_INVALID || collation_type >= CS_TYPE_MAX) || OB_ISNULL(ObCharset::charset_arr[collation_type])) { @@ -528,10 +537,16 @@ size_t ObCharset::charpos(const ObCollationType collation_type, if (OB_ISNULL(cs->cset)) { LOG_ERROR("unexpected error. invalid argument(s)", K(cs), K(cs->cset)); } else { - ret = cs->cset->charpos(cs, str, str + str_len, length); + res_pos = cs->cset->charpos(cs, str, str + str_len, length); + if (res_pos > str_len) { + res_pos = str_len; + if (OB_NOT_NULL(ret)) { + *ret = OB_ERROR_OUT_OF_RANGE; + } + } } } - return ret; + return res_pos; } bool ObCharset::wildcmp(ObCollationType collation_type, @@ -613,7 +628,7 @@ int ObCharset::wc_mb(ObCollationType collation_type, int32_t wc, char *buff, int int tmp = cs->cset->wc_mb(cs, wc, reinterpret_cast(buff), reinterpret_cast(buff + buff_len)); if (tmp <= 0) { - ret = OB_ERROR; + ret = OB_ERR_INCORRECT_STRING_VALUE; } else { ret = OB_SUCCESS; length = tmp; @@ -647,6 +662,10 @@ const char *ObCharset::charset_name(ObCharsetType charset_type) ret_name = "gb18030"; break; } + case CHARSET_LATIN1: { + ret_name = "latin1"; + break; + } default: { break; } @@ -743,6 +762,10 @@ ObCharsetType ObCharset::charset_type(const ObString &cs_name) charset_type = CHARSET_GBK; } else if (0 == cs_name.case_compare(ob_charset_utf16_general_ci.csname)) { charset_type = CHARSET_UTF16; + } else if (0 == cs_name.case_compare(ob_charset_latin1.csname)) { + charset_type = CHARSET_LATIN1; + } else if (0 == cs_name.case_compare(ob_charset_latin1_bin.csname)) { + charset_type = CHARSET_LATIN1; } return charset_type; } @@ -785,6 +808,10 @@ ObCollationType ObCharset::collation_type(const ObString &cs_name) collation_type = CS_TYPE_UTF16_BIN; } else if (0 == cs_name.case_compare(ob_charset_utf16_general_ci.name)) { collation_type = CS_TYPE_UTF16_GENERAL_CI; + } else if (0 == cs_name.case_compare(ob_charset_latin1.name)) { + collation_type = CS_TYPE_LATIN1_SWEDISH_CI; + } else if (0 == cs_name.case_compare(ob_charset_latin1_bin.name)) { + collation_type = CS_TYPE_LATIN1_BIN; } return collation_type; } @@ -821,6 +848,11 @@ bool ObCharset::is_valid_collation(ObCharsetType charset_type, ObCollationType c || CS_TYPE_UTF16_GENERAL_CI == collation_type) { ret = true; } + } else if (CHARSET_LATIN1 == charset_type) { + if (CS_TYPE_LATIN1_BIN == collation_type + || CS_TYPE_LATIN1_SWEDISH_CI == collation_type) { + ret = true; + } } return ret; } @@ -836,7 +868,9 @@ bool ObCharset::is_valid_collation(int64_t collation_type_int) || CS_TYPE_GBK_BIN == collation_type || CS_TYPE_GBK_CHINESE_CI == collation_type || CS_TYPE_UTF16_BIN == collation_type - || CS_TYPE_UTF16_GENERAL_CI == collation_type; + || CS_TYPE_UTF16_GENERAL_CI == collation_type + || CS_TYPE_LATIN1_BIN == collation_type + || CS_TYPE_LATIN1_SWEDISH_CI == collation_type; } bool ObCharset::is_valid_charset(int64_t cs_type_int) @@ -846,7 +880,8 @@ bool ObCharset::is_valid_charset(int64_t cs_type_int) || CHARSET_UTF8MB4 == charset_type || CHARSET_GBK == charset_type || CHARSET_UTF16 == charset_type - || CHARSET_GB18030 == charset_type; + || CHARSET_GB18030 == charset_type + || CHARSET_LATIN1 == charset_type; } ObCharsetType ObCharset::charset_type_by_coll(ObCollationType collation_type) @@ -878,6 +913,11 @@ ObCharsetType ObCharset::charset_type_by_coll(ObCollationType collation_type) charset_type = CHARSET_UTF16; break; } + case CS_TYPE_LATIN1_SWEDISH_CI: + case CS_TYPE_LATIN1_BIN: { + charset_type = CHARSET_LATIN1; + break; + } default: { break; } @@ -1104,6 +1144,10 @@ ObCollationType ObCharset::get_default_collation(ObCharsetType charset_type) collation_type = CS_TYPE_UTF16_GENERAL_CI; break; } + case CHARSET_LATIN1: { + collation_type = CS_TYPE_LATIN1_SWEDISH_CI; + break; + } default: { break; } @@ -1135,6 +1179,10 @@ ObCollationType ObCharset::get_default_collation_oracle(ObCharsetType charset_ty collation_type = CS_TYPE_UTF16_BIN; break; } + case CHARSET_LATIN1: { + collation_type = CS_TYPE_LATIN1_BIN; + break; + } default: { break; } @@ -1166,6 +1214,10 @@ int ObCharset::get_default_collation(ObCharsetType charset_type, ObCollationType collation_type = CS_TYPE_UTF16_GENERAL_CI; break; } + case CHARSET_LATIN1: { + collation_type = CS_TYPE_LATIN1_SWEDISH_CI; + break; + } default: { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid charset type", K(ret), K(charset_type)); @@ -1199,6 +1251,10 @@ ObCollationType ObCharset::get_bin_collation(ObCharsetType charset_type) collation_type = CS_TYPE_UTF16_BIN; break; } + case CHARSET_LATIN1: { + collation_type = CS_TYPE_LATIN1_BIN; + break; + } default: { break; } diff --git a/src/lib/charset/ob_charset.h b/src/lib/charset/ob_charset.h index b831f0b3..b209c97c 100644 --- a/src/lib/charset/ob_charset.h +++ b/src/lib/charset/ob_charset.h @@ -30,15 +30,18 @@ enum ObCharsetType CHARSET_GBK = 3, CHARSET_UTF16 = 4, CHARSET_GB18030 = 5, + CHARSET_LATIN1 = 6, CHARSET_MAX, }; enum ObCollationType { CS_TYPE_INVALID = 0, + CS_TYPE_LATIN1_SWEDISH_CI = 8, CS_TYPE_GBK_CHINESE_CI = 28, CS_TYPE_UTF8MB4_GENERAL_CI = 45, CS_TYPE_UTF8MB4_BIN = 46, + CS_TYPE_LATIN1_BIN = 47, CS_TYPE_UTF16_GENERAL_CI = 54, CS_TYPE_UTF16_BIN = 55, CS_TYPE_BINARY = 63, @@ -100,8 +103,8 @@ class ObCharset virtual ~ObCharset() {}; public: - static const int64_t CHARSET_WRAPPER_COUNT = 5; - static const int64_t COLLATION_WRAPPER_COUNT = 11; + static const int64_t CHARSET_WRAPPER_COUNT = 6; + static const int64_t COLLATION_WRAPPER_COUNT = 13; static double strntod(const char *str, size_t str_len, @@ -201,7 +204,8 @@ class ObCharset static size_t charpos(ObCollationType collation_type, const char *str, const int64_t str_len, - const int64_t length); + const int64_t length, + int *ret = NULL); // match like pattern static bool wildcmp(ObCollationType collation_type, const ObString &str, diff --git a/src/lib/charset/ob_ctype.h b/src/lib/charset/ob_ctype.h index 734cfd6d..b11d9467 100644 --- a/src/lib/charset/ob_ctype.h +++ b/src/lib/charset/ob_ctype.h @@ -36,6 +36,10 @@ extern "C" { #define OB_UTF16_BIN OB_UTF16 "_bin" #define OB_UTF16_UNICODE_CI OB_UTF16 "_unicode_ci" +#define OB_LATIN1 "latin1" +#define OB_LATIN1_SWEDISH_CI OB_LATIN1 "_swedish_ci" +#define OB_LATIN1_BIN OB_LATIN1 "_bin" + /* wm_wc and wc_mb return codes */ #define OB_CS_ILSEQ 0 // mb_wc wrong sequence #define OB_CS_ILUNI 0 // wc_mb fail to encode Unicode to charset @@ -376,6 +380,7 @@ typedef struct ObCharsetInfo #define ob_toprint(c) ((c) | 64) #define ob_toupper(s,c) (char) ((s)->to_upper[(uchar) (c)]) #define ob_tolower(s,c) (char) ((s)->to_lower[(uchar) (c)]) +#define ob_sort_order(s,c) (char)((s)->sort_order[(uchar)(c)]) #define ob_isalpha(s, c) ((s)->ctype != NULL ? ((s)->ctype+1)[(uchar) (c)] & (_MY_U | _MY_L) : 0) #define ob_isupper(s, c) ((s)->ctype != NULL ? ((s)->ctype+1)[(uchar) (c)] & _MY_U : 0) #define ob_islower(s, c) ((s)->ctype != NULL ? ((s)->ctype+1)[(uchar) (c)] & _MY_L : 0) @@ -412,6 +417,7 @@ extern ObCharsetInfo ob_charset_bin; extern ObCharsetInfo ob_charset_utf8mb4_bin; extern ObCharsetInfo ob_charset_utf8mb4_general_ci; extern ObCharsetInfo ob_charset_latin1; +extern ObCharsetInfo ob_charset_latin1_bin; extern ObCharsetInfo ob_charset_gbk_chinese_ci; extern ObCharsetInfo ob_charset_gbk_bin; extern ObCharsetInfo ob_charset_utf16_general_ci; @@ -422,6 +428,8 @@ extern ObCharsetInfo ob_charset_gb18030_bin; extern ObCollationHandler ob_collation_mb_bin_handler; extern ObCharsetHandler ob_charset_utf8mb4_handler; extern ObCharsetHandler ob_charset_utf16_handler; +extern ObCollationHandler ob_collation_binary_handler; +extern ObCollationHandler ob_collation_8bit_simple_ci_handler; //============================================================================= @@ -582,6 +590,43 @@ int ob_wildcmp_unicode(const ObCharsetInfo *cs, size_t ob_strxfrm_pad(const ObCharsetInfo *cs, uchar *str, uchar *frmend, uchar *strend, uint nweights, uint flags); +uint ob_mbcharlen_8bit(const ObCharsetInfo *cs __attribute__((unused)), + uint c __attribute__((unused))); + +size_t ob_numchars_8bit(const ObCharsetInfo *cs __attribute__((unused)), + const char *b, const char *e); + +size_t ob_charpos_8bit(const ObCharsetInfo *cs __attribute__((unused)), + const char *b __attribute__((unused)), + const char *e __attribute__((unused)), + size_t pos); + + +size_t ob_max_bytes_charpos_8bit(const ObCharsetInfo *cs __attribute__((unused)), + const char *b __attribute__((unused)), + const char *e __attribute__((unused)), + size_t max_bytes, + size_t *char_len); + +size_t ob_well_formed_len_8bit(const ObCharsetInfo *cs __attribute__((unused)), + const char *start, const char *end, + size_t nchars, int *error); + +size_t ob_lengthsp_binary(const ObCharsetInfo *cs __attribute__((unused)), + const char *ptr __attribute__((unused)), + size_t length); + +int ob_mb_ctype_8bit(const ObCharsetInfo *cs, int *ctype, + const uchar *s, const uchar *e); + +size_t ob_caseup_8bit(const ObCharsetInfo *cs __attribute__((unused)), + char* src __attribute__((unused)), size_t srclen __attribute__((unused)), + char* dst __attribute__((unused)), size_t dstlen __attribute__((unused))); + +size_t ob_casedn_8bit(const ObCharsetInfo *cs __attribute__((unused)), + char* src __attribute__((unused)), size_t srclen __attribute__((unused)), + char* dst __attribute__((unused)), size_t dstlen __attribute__((unused))); + #ifdef __cplusplus } #endif diff --git a/src/lib/charset/ob_ctype_bin.c b/src/lib/charset/ob_ctype_bin.c index 31719d75..00c07062 100644 --- a/src/lib/charset/ob_ctype_bin.c +++ b/src/lib/charset/ob_ctype_bin.c @@ -128,7 +128,7 @@ static int ob_wc_mb_bin(const ObCharsetInfo *cs __attribute__((unused)), return OB_CS_ILUNI; } -static int ob_mb_ctype_8bit(const ObCharsetInfo *cs, int *ctype, +int ob_mb_ctype_8bit(const ObCharsetInfo *cs, int *ctype, const unsigned char *str, const unsigned char *end) { if (str >= end) { @@ -375,7 +375,7 @@ static ObCharsetHandler ob_charset_handler= ob_scan_8bit }; -static ObCollationHandler ob_collation_binary_handler = +ObCollationHandler ob_collation_binary_handler = { ob_strnncoll_binary, ob_strnncollsp_binary, diff --git a/src/lib/charset/ob_ctype_latin1.c b/src/lib/charset/ob_ctype_latin1.c new file mode 100644 index 00000000..27262d00 --- /dev/null +++ b/src/lib/charset/ob_ctype_latin1.c @@ -0,0 +1,407 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +/* +* +* Version: $Id +* +* Authors: +* - initial release +* +*/ +#include "lib/charset/ob_mysql_global.h" +#include "lib/charset/ob_ctype.h" +#include "lib/utility/ob_macro_utils.h" + +static unsigned char ctype_latin1[] = { + 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 16, 16, 16, 16, 16, + 16, 16, 129, 129, 129, 129, 129, 129, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, + 16, 16, 130, 130, 130, 130, 130, 130, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, + 32, 16, 0, 16, 2, 16, 16, 16, 16, 16, 16, 1, 16, 1, 0, 1, + 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 2, 0, 2, + 1, 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, + 2}; + +static unsigned char to_lower_latin1[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 215, 248, 249, 250, 251, 252, 253, 254, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255}; + +static unsigned char to_upper_latin1[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 247, 216, 217, 218, 219, 220, 221, 222, + 255}; + +static unsigned char sort_order_latin1[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 65, 65, 65, + 65, 92, 91, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73, 68, 78, + 79, 79, 79, 79, 93, 215, 216, 85, 85, 85, 89, 89, 222, 223, 65, + 65, 65, 65, 92, 91, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73, + 68, 78, 79, 79, 79, 79, 93, 247, 216, 85, 85, 85, 89, 89, 222, + 255}; + + +static unsigned short cs_to_uni[] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, + 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, + 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, + 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, + 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, + 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F, + 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, + 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178, 0x00A0, 0x00A1, + 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, + 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, + 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, + 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, + 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, + 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, + 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, + 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, + 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, + 0x00FC, 0x00FD, 0x00FE, 0x00FF}; +static unsigned char pl00[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, + 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x8F, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9D, 0x00, 0x00, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, + 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, + 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, + 0xFC, 0xFD, 0xFE, 0xFF}; +static unsigned char pl01[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x9C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8A, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; +static unsigned char pl02[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; +static unsigned char pl20[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, 0x86, 0x87, 0x95, 0x00, + 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x9B, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; +static unsigned char pl21[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; +static unsigned char *uni_to_cs[] = { + pl00, pl01, pl02, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + pl20, pl21, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + + +static int ob_mb_wc_latin1(const ObCharsetInfo *cs __attribute__((unused)), + ob_wc_t *pwc, const unsigned char *str, const unsigned char *end) { + + if (str >= end) return OB_CS_TOOSMALL; + *pwc = cs_to_uni[*str]; + return (!pwc[0] && str[0]) ? -1 : 1; + +} + +static int ob_wc_mb_latin1(const ObCharsetInfo *cs __attribute__((unused)), + ob_wc_t wc, unsigned char *str, unsigned char *end) { + const unsigned char *pl; + + if (str >= end) return OB_CS_TOOSMALL; + + if (wc > 0xFFFF) return OB_CS_ILUNI; + + pl = uni_to_cs[wc >> 8]; + str[0] = pl ? pl[wc & 0xFF] : '\0'; + return (!str[0] && wc) ? OB_CS_ILUNI : 1; +} + + + +static ObCharsetHandler ob_charset_latin1_handler= +{ + //NULL, /* init */ + NULL, /* ismbchar */ + ob_mbcharlen_8bit, /* mbcharlen */ + ob_numchars_8bit, + ob_charpos_8bit, + ob_max_bytes_charpos_8bit, + ob_well_formed_len_8bit, + ob_lengthsp_binary, + //ob_numcells_8bit, + ob_mb_wc_latin1, + ob_wc_mb_latin1, + ob_mb_ctype_8bit, + //ob_case_str_bin, + //ob_case_str_bin, + ob_caseup_8bit, + ob_casedn_8bit, + //ob_snprintf_8bit, + //ob_long10_to_str_8bit, + //ob_longlong10_to_str_8bit, + ob_fill_8bit, + ob_strntol_8bit, + ob_strntoul_8bit, + ob_strntoll_8bit, + ob_strntoull_8bit, + ob_strntod_8bit, + //ob_strtoll10_8bit, + ob_strntoull10rnd_8bit, + ob_scan_8bit +}; + + + + + +ObCharsetInfo ob_charset_latin1 = { + 8,0,0, /* number */ + OB_CS_COMPILED | OB_CS_PRIMARY, /* state */ + OB_LATIN1, /* cs name */ + OB_LATIN1_SWEDISH_CI, /* name */ + "cp1252 West European", /* comment */ + NULL, /* tailoring */ + //NULL, /* coll_param */ + ctype_latin1, + to_lower_latin1, + to_upper_latin1, + sort_order_latin1, + NULL, /* uca */ + //NULL, /* tab_to_uni */ + //NULL, /* tab_from_uni */ + &ob_unicase_default, /* caseinfo */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ + 1, /* mbminlen */ + 1, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + 1, /* levels_for_compare */ + 1, /* levels_for_order */ + &ob_charset_latin1_handler, + &ob_collation_8bit_simple_ci_handler}; + +ObCharsetInfo ob_charset_latin1_bin = { + 47,0,0, /* number */ + OB_CS_COMPILED | OB_CS_BINSORT, /* state */ + OB_LATIN1, /* cs name */ + OB_LATIN1_BIN, /* name */ + "cp1252 West European", /* comment */ + NULL, /* tailoring */ + ctype_latin1, + to_lower_latin1, + to_upper_latin1, + NULL, /* sort_order */ + NULL, /* uca */ + //NULL, /* tab_to_uni */ + //NULL, /* tab_from_uni */ + &ob_unicase_default, /* caseinfo */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ + 1, /* mbminlen */ + 1, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + 1, /* levels_for_compare */ + 1, /* levels_for_order */ + &ob_charset_latin1_handler, + &ob_collation_binary_handler}; + diff --git a/src/lib/charset/ob_ctype_simple.c b/src/lib/charset/ob_ctype_simple.c index 9fbee870..601f3906 100644 --- a/src/lib/charset/ob_ctype_simple.c +++ b/src/lib/charset/ob_ctype_simple.c @@ -814,3 +814,262 @@ size_t ob_strxfrm_pad(const ObCharsetInfo *cs, unsigned char *str, unsigned char return frm_end - str; } +size_t ob_caseup_8bit(const ObCharsetInfo *cs __attribute__((unused)), + char* src __attribute__((unused)), size_t srclen __attribute__((unused)), + char* dst __attribute__((unused)), size_t dstlen __attribute__((unused))){ + const char *end = src + srclen; + ob_charset_assert(src == dst && srclen == dstlen); + for (; src != end; src++) *src = ob_toupper(cs,*src); + return srclen; +} + +size_t ob_casedn_8bit(const ObCharsetInfo *cs __attribute__((unused)), + char* src __attribute__((unused)), size_t srclen __attribute__((unused)), + char* dst __attribute__((unused)), size_t dstlen __attribute__((unused))){ + char *end = src + srclen; + ob_charset_assert(src == dst && srclen == dstlen); + for (; src != end; src++) *src = ob_tolower(cs,*src); + return srclen; +} + +int ob_strnncoll_simple(const ObCharsetInfo *cs __attribute__((unused)), + const uchar *s, size_t slen, + const uchar *t, size_t tlen, + bool is_prefix) +{ + size_t len = (slen > tlen) ? tlen : slen; + if (is_prefix && slen > tlen) slen = tlen; + while (len--) { + if(ob_sort_order(cs,*s)!=ob_sort_order(cs,*t)) { + return (int)ob_sort_order(cs,*s) - (int)ob_sort_order(cs,*t); + } + s++; + t++; + } + return slen > tlen ? 1 : slen < tlen ? -1 : 0; +} + +static int ob_strnncollsp_simple(const ObCharsetInfo *cs + __attribute__((unused)), + const uchar *s, size_t slen, + const uchar *t, size_t tlen, + bool diff_if_only_endspace_difference + __attribute__((unused))) +{ + size_t len = (slen > tlen) ? tlen : slen; + for (size_t i = 0; i < len; i++){ + if(ob_sort_order(cs,*s)!=ob_sort_order(cs,*t)) { + return (int)ob_sort_order(cs,*s) - (int)ob_sort_order(cs,*t); + } + s++; + t++; + } + int res = 0; + if (slen != tlen) { + int swap = 1; + if (diff_if_only_endspace_difference){ + res=1; + } + /* + Check the next not space character of the longer key. If it's < ' ', + then it's smaller than the other key. + */ + if (slen < tlen) { + slen = tlen; + + s = t; + swap = -1; + res = -res; + } + /* + "a" == "a " + "a\0" < "a" + "a\0" < "a " + */ + for (const unsigned char* end = s + slen - len; s < end; s++) { + if (ob_sort_order(cs,*s) != ob_sort_order(cs,(int)(' '))) + return ob_sort_order(cs,*s) < ob_sort_order(cs,(int)(' ')) ? -swap : swap; + } + } + return res; +} + + + +static size_t ob_strnxfrm_simple(const ObCharsetInfo* cs __attribute__((unused)), unsigned char* dst, size_t dstlen, + uint nweights, const unsigned char* src, size_t srclen, unsigned int flags, bool* is_valid_unicode) +{ + uchar *dst0 = dst; + const uchar *end; + const uchar *remainder; + size_t frmlen; + frmlen = dstlen > nweights ? nweights : dstlen; + frmlen = frmlen > srclen ? srclen : frmlen; + end = src + frmlen; + remainder = src + (frmlen % 8); + for (; src < remainder;) *dst++ = ob_sort_order(cs,*src++); + while(src < end) { + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + } + return ob_strxfrm_pad_desc_and_reverse(cs, dst0, dst, dst0 + dstlen, nweights - srclen, flags, 0); +} + +#define likeconv(s, A) (A) +#define INC_PTR(cs, A, B) (A)++ + +static int ob_wildcmp_8bit_impl(const ObCharsetInfo* cs, const char* str_ptr, const char* str_end_ptr, + const char* wild_str, const char* wild_end, int escape_char, int w_one_char, int w_many_char, int recurse_level) +{ + int cmp_result = -1; + + while (wild_str != wild_end) { + while (*wild_str != w_many_char && *wild_str != w_one_char) { + if (*wild_str == escape_char && wild_str + 1 != wild_end) { + wild_str++; + } + if (str_ptr == str_end_ptr || likeconv(cs, *wild_str++) != likeconv(cs, *str_ptr++)) { + return 1; + } + if (wild_str == wild_end) { + return str_ptr != str_end_ptr; + } + cmp_result = 1; + } + if (*wild_str == w_one_char) { + do { + if (str_ptr == str_end_ptr) { + return (cmp_result); + } + INC_PTR(cs, str_ptr, str_end_ptr); + } while (++wild_str < wild_end && *wild_str == w_one_char); + if (wild_str == wild_end) { + break; + } + } + if (*wild_str == w_many_char) { + unsigned char cmp = 0; + wild_str++; + for (; wild_str != wild_end; wild_str++) { + if (*wild_str == w_many_char) { + continue; + } + if (*wild_str == w_one_char) { + if (str_ptr == str_end_ptr) { + return (-1); + } + INC_PTR(cs, str_ptr, str_end_ptr); + continue; + } + break; + } + if (wild_str == wild_end) { + return (0); + } + if (str_ptr == str_end_ptr) { + return (-1); + } + + if ((cmp = *wild_str) == escape_char && wild_str + 1 != wild_end) { + cmp = *++wild_str; + } + + INC_PTR(cs, wild_str, wild_end); + cmp = likeconv(cs, cmp); + do { + while (str_ptr != str_end_ptr && (unsigned char)likeconv(cs, *str_ptr) != cmp) { + str_ptr++; + } + if (str_ptr++ == str_end_ptr) { + return -1; + } + do { + int tmp = ob_wildcmp_8bit_impl( + cs, str_ptr, str_end_ptr, wild_str, wild_end, escape_char, w_one_char, w_many_char, recurse_level + 1); + if (tmp <= 0) { + return tmp; + } + } while (0); + } while (str_ptr != str_end_ptr); + return -1; + } + } + return str_ptr != str_end_ptr ? 1 : 0; +} + +int ob_wildcmp_8bit(const ObCharsetInfo* cs, const char* str, const char* str_end, const char* wildstr, + const char* wildend, int escape, int w_one, int w_many) +{ + return ob_wildcmp_8bit_impl(cs, str, str_end, wildstr, wildend, escape, w_one, w_many, 1); +} + + +uint ob_instr_simple(const ObCharsetInfo* cs __attribute__((unused)), const char* b, size_t b_length, + const char* s, size_t s_length, ob_match_t* match, uint nmatch) +{ + register const unsigned char *str, *search, *end, *search_end; + + if (s_length <= b_length) { + if (!s_length) { + if (nmatch) { + match->beg = 0; + match->end = 0; + match->mb_len = 0; + } + return 1; /* Empty string is always found */ + } + + str = (const unsigned char*)b; + search = (const unsigned char*)s; + end = (const unsigned char*)b + b_length - s_length + 1; + search_end = (const unsigned char*)s + s_length; + + skip: + while (str != end) { + if ((*str++) == (*search)) { + register const unsigned char *i, *j; + + i = str; + j = search + 1; + + while (j != search_end) + if ((*i++) != (*j++)) + goto skip; + + if (nmatch > 0) { + match[0].beg = 0; + match[0].end = (size_t)(str - (const unsigned char*)b - 1); + match[0].mb_len = match[0].end; + + if (nmatch > 1) { + match[1].beg = match[0].end; + match[1].end = match[0].end + s_length; + match[1].mb_len = match[1].end - match[1].beg; + } + } + return 2; + } + } + } + return 0; +} + + +ObCollationHandler ob_collation_8bit_simple_ci_handler = { + // NULL /* init */ + ob_strnncoll_simple, + ob_strnncollsp_simple, + ob_strnxfrm_simple, + //ob_strnxfrmlen_simple, + ob_like_range_simple, + ob_wildcmp_8bit, + //NULL,//ob_strcasecmp_8bit, + ob_instr_simple, + ob_hash_sort_simple, + ob_propagate_simple}; diff --git a/src/lib/hash/ob_build_in_hashmap.h b/src/lib/hash/ob_build_in_hashmap.h index 61fb13c8..20bfb26d 100644 --- a/src/lib/hash/ob_build_in_hashmap.h +++ b/src/lib/hash/ob_build_in_hashmap.h @@ -16,6 +16,7 @@ #include "lib/hash_func/ob_hash_func.h" #include "lib/hash/ob_hashutils.h" #include "lib/list/ob_intrusive_list.h" +#include "lib/lock/ob_drw_lock.h" namespace oceanbase { @@ -240,11 +241,117 @@ class ObBuildInHashMap return ret; } -private: +protected: ObBuildInBucket buckets_[bucket_num]; int64_t count_; // of elements stored in the map. BucketChain bucket_chain_; }; + +template +class ObBuildInHashMapForRefCount : public ObBuildInHashMap { +public: + // Make embedded types easier to use by importing them to the class namespace. + typedef H Hasher; // Rename and promote. + typedef typename Hasher::Key Key; // Key type. + typedef typename Hasher::Value Value; // Stored value (element) type. + typedef typename Hasher::ListHead ListHead; // Anchor for value chain. + + ObBuildInHashMapForRefCount() : ObBuildInHashMap() {} + + // put a key value pair into HashMap + // @retval OB_SUCCESS for success + // @retval OB_HASH_EXIST when the value's pointer already exist + int set_refactored(Value *value) + { + int ret = OB_SUCCESS; + Key key = Hasher::key(value); + obsys::CWLockGuard wlock(locks_[Hasher::hash(key) % bucket_num]); + ret = ObBuildInHashMap::set_refactored(value); + if (OB_SUCC(ret)) { + Hasher::inc_ref(value); + } + return ret; + } + + // put a key value pair into HashMap + // @retval OB_SUCCESS for success + // @retval OB_HASH_EXIST when the value's key already exist + int unique_set(Value *value) + { + int ret = OB_SUCCESS; + Key key = Hasher::key(value); + obsys::CWLockGuard wlock(locks_[Hasher::hash(key) % bucket_num]); + struct ObBuildInHashMap::ObBuildInBucket &bucket = ObBuildInHashMap::buckets_[Hasher::hash(key) % bucket_num]; + if (!bucket.chain_.in(value)) { + Value *v = bucket.chain_.head_; + while (NULL != v && ((!Hasher::equal(key, Hasher::key(v)) && (v != value)) || 0 == Hasher::get_ref(v))) { + v = ListHead::next(v); + } + if (NULL == v) { + bucket.chain_.push(value); + ++ObBuildInHashMap::count_; + // not empty, put it on the non-empty list. + if (1 == ++(bucket.count_)) { + ObBuildInHashMap::bucket_chain_.push(&bucket); + } + } else { + ret = OB_HASH_EXIST; + } + } else { + ret = OB_HASH_EXIST; + } + if (OB_SUCC(ret)) { + Hasher::inc_ref(value); + } + return ret; + } + + // @retval OB_SUCCESS for success + // @retval OB_HASH_NOT_EXIST for key not exist + int get_refactored(Key key, Value *&value) + { + int ret = OB_HASH_NOT_EXIST; + obsys::CRLockGuard rlock(locks_[Hasher::hash(key) % bucket_num]); + const struct ObBuildInHashMap::ObBuildInBucket &bucket = ObBuildInHashMap::buckets_[Hasher::hash(key) % bucket_num]; + Value *v = bucket.chain_.head_; + while (NULL != v && (!Hasher::equal(key, Hasher::key(v)) || 0 == Hasher::get_ref(v))) { + v = ListHead::next(v); + } + if (NULL != (value = v)) { + ret = OB_SUCCESS;; + } + if (OB_SUCC(ret)) { + while (true) { + int64_t ref = Hasher::get_ref(v); + if(ref > 0) { + if (!Hasher::bcas_ref(value, ref, ref + 1)) { + PAUSE(); + } else { + break; + } + } else { + ret = OB_HASH_NOT_EXIST; + value = NULL; + break; + } + } + } + return ret; + } + + void remove(Value* value) + { + if (NULL != value) { + obsys::CWLockGuard wlock(locks_[Hasher::hash(Hasher::key(value)) % bucket_num]); + ObBuildInHashMap::remove(value); + Hasher::destroy(value); + } + } + +protected: + mutable obsys::CRWLock locks_[bucket_num]; +}; + } // namespace hash } // namespace common } // namespace oceanbase diff --git a/src/lib/lock/ob_bucket_lock.h b/src/lib/lock/ob_bucket_lock.h index 3e850cbb..a4ef58a3 100644 --- a/src/lib/lock/ob_bucket_lock.h +++ b/src/lib/lock/ob_bucket_lock.h @@ -23,8 +23,10 @@ namespace common class ObBucketLock { public: - ObBucketLock(); - virtual ~ObBucketLock(); + /* this function is defined for c driver client compile */ + ObBucketLock() {} + /* this function is defined for c driver client compile */ + virtual ~ObBucketLock() {} int init( const uint64_t bucket_cnt, const uint32_t latch_id = ObLatchIds::DEFAULT_BUCKET_LOCK, diff --git a/src/lib/lock/ob_latch.cpp b/src/lib/lock/ob_latch.cpp index a53ef883..9d717f82 100644 --- a/src/lib/lock/ob_latch.cpp +++ b/src/lib/lock/ob_latch.cpp @@ -279,7 +279,10 @@ int ObLatchWaitQueue::try_lock( COMMON_LOG(ERROR, "Fail to add proc to wait list, ", K(ret)); } } - proc.wait_ = 1; + + if (OB_EAGAIN == ret) { + proc.wait_ = 1; + } } unlock_bucket(bucket); diff --git a/src/lib/net/ob_addr.cpp b/src/lib/net/ob_addr.cpp index ee6fa0ba..eda722a7 100644 --- a/src/lib/net/ob_addr.cpp +++ b/src/lib/net/ob_addr.cpp @@ -28,29 +28,49 @@ namespace common // -------------------------------------------------------- // class ObAddr implements // -------------------------------------------------------- -uint32_t ObAddr::convert_ipv4_addr(const char *ip) +int ObAddr::convert_ipv4_addr(const char *ip) { - in_addr binary; - int iret = 0; - uint32_t result = 0; + int ret = OB_SUCCESS; + in_addr in; if (!OB_ISNULL(ip)) { - memset(&binary, 0, sizeof (binary)); - iret = inet_pton(AF_INET, ip, &binary); - if (iret == -1) { // no support family - binary.s_addr = 0; - } else if (iret == 0) { // invalid ip string - binary.s_addr = 0; + MEMSET(&in, 0, sizeof (in)); + int rt = inet_pton(AF_INET, ip, &in); + if (rt != 1) { // wrong ip or error + in.s_addr = 0; + ret = OB_ERR_UNEXPECTED; + LOG_WARN("convert ipv4 addr failed", K(ip)); + } else { + ip_.v4_ = ntohl(in.s_addr); } - result = ntohl(binary.s_addr); } - return result; + return ret; +} + +int ObAddr::convert_ipv6_addr(const char *ip) +{ + int ret = OB_SUCCESS; + in6_addr in6; + if (!OB_ISNULL(ip)) { + memset(&in6, 0, sizeof(in6)); + ret = inet_pton(AF_INET6, ip, &in6); + if (ret != 1) { + memset(&in6, 0, sizeof(in6)); + ret = OB_ERR_UNEXPECTED; + LOG_WARN("convert ipv6 addr failed", K(ip)); + } else { + ret = OB_SUCCESS; + // Stored here in big-endian format + MEMCPY(ip_.v6_, in6.s6_addr, sizeof(ip_.v6_)); + } + } + return ret; } int ObAddr::parse_from_cstring(const char *ipport) { int ret = OB_SUCCESS; - char buf[INET6_ADDRSTRLEN] = ""; + char buf[MAX_IP_ADDR_LENGTH] = ""; int port = 0; if (!OB_ISNULL(ipport)) { @@ -73,15 +93,16 @@ int ObAddr::parse_from_cstring(const char *ipport) if (OB_SUCC(ret)) { if ('[' != buf[0]) { // IPV4 format - if (false == set_ipv4_addr(buf, port)) - { + if (false == set_ipv4_addr(buf, port)) { ret = OB_INVALID_ARGUMENT; } } else { // IPV6 format const char *ipv6 = buf + 1; if (']' == buf[strlen(buf) - 1]) { buf[strlen(buf) - 1] = '\0'; - IGNORE_RETURN set_ipv6_addr(ipv6, port); + if (!set_ipv6_addr(ipv6, port)) { + ret = OB_INVALID_ARGUMENT; + } } else { ret = OB_INVALID_ARGUMENT; } @@ -109,6 +130,17 @@ int64_t ObAddr::to_string(char *buffer, const int64_t size) const (ip_.v4_ >> 8) & 0xFF, (ip_.v4_) & 0xFF); } + } else if (version_ == IPV6) { + char buf[MAX_IP_ADDR_LENGTH]; + struct in6_addr in6; + memset(buf, 0, sizeof(buf)); + MEMCPY(in6.s6_addr, ip_.v6_, sizeof(ip_.v6_)); + inet_ntop(AF_INET6, &in6, buf, MAX_IP_ADDR_LENGTH); + if (port_ > 0) { + databuff_printf(buffer, size, pos, "\"[%s]:%d\"", buf, port_); + } else { + databuff_printf(buffer, size, pos, "\"%s\"", buf); + } } } return pos; @@ -124,6 +156,13 @@ bool ObAddr::ip_to_string(char *buffer, const int32_t size) const (ip_.v4_ >> 16) & 0xFF, (ip_.v4_ >> 8) & 0xFF, (ip_.v4_) & 0xFF); + } else if (version_ == IPV6) { + char buf[MAX_IP_ADDR_LENGTH]; + struct in6_addr in6; + memset(buf, 0, sizeof(buf)); + MEMCPY(in6.s6_addr, ip_.v6_, sizeof(ip_.v6_)); + inet_ntop(AF_INET6, &in6, buf, MAX_IP_ADDR_LENGTH); + snprintf(buffer, size, "%s", buf); } res = true; } @@ -133,58 +172,74 @@ bool ObAddr::ip_to_string(char *buffer, const int32_t size) const int ObAddr::ip_port_to_string(char *buffer, const int32_t size) const { int ret = OB_SUCCESS; + int ret_len = 0; if (NULL == buffer || size <= 0) { ret = OB_INVALID_ARGUMENT; } else if (version_ == IPV6) { - ret = OB_NOT_SUPPORTED; + char buf[MAX_IP_ADDR_LENGTH]; + struct in6_addr in6; + memset(buf, 0, sizeof(buf)); + MEMCPY(in6.s6_addr, ip_.v6_, sizeof(ip_.v6_)); + inet_ntop(AF_INET6, &in6, buf, MAX_IP_ADDR_LENGTH); + ret_len = snprintf(buffer, size, "[%s]:%d", buf, port_); } else { - int ret_len = snprintf(buffer, size, "%d.%d.%d.%d:%d", + ret_len = snprintf(buffer, size, "%d.%d.%d.%d:%d", (ip_.v4_ >> 24) & 0XFF, (ip_.v4_ >> 16) & 0xFF, (ip_.v4_ >> 8) & 0xFF, (ip_.v4_) & 0xFF, port_); - if (ret_len < 0) { - ret = OB_ERR_SYS; - } else if (ret_len >= size) { - ret = OB_SIZE_OVERFLOW; - } + } + + if (ret_len < 0) { + ret = OB_ERR_SYS; + } else if (ret_len >= size) { + ret = OB_SIZE_OVERFLOW; } return ret; } bool ObAddr::set_ipv6_addr(const char *ip, const int32_t port) { - UNUSED(ip); - UNUSED(port); - _OB_LOG(WARN, "set ipv6 address is not complete"); - return false; -} + bool bret = true; + int ret = OB_SUCCESS; + if (NULL == ip || port < 0) { + bret = false; + } else if (OB_FAIL(convert_ipv6_addr(ip))) { + bret = false; + } else { + version_ = IPV6; + port_ = port; + } + return bret; +} bool ObAddr::set_ipv4_addr(const char *ip, const int32_t port) { - bool ret = true; - if (NULL == ip || port <= 0) { - ret = false; + bool bret = true; + int ret = OB_SUCCESS; + if (NULL == ip || port < 0) { + bret = false; + } else if (OB_FAIL(convert_ipv4_addr(ip))) { + bret = false; } else { version_ = IPV4; - ip_.v4_ = convert_ipv4_addr(ip); port_ = port; } - return ret; + return bret; } -bool ObAddr::set_ipv4_addr(const ObString &ip, const int32_t port) +bool ObAddr::set_ip_addr(const ObString &ip, const int32_t port) { bool ret = true; - char ip_buf[OB_IP_STR_BUFF] = ""; - if (ip.length() >= OB_IP_STR_BUFF) { + char ip_buf[MAX_IP_ADDR_LENGTH] = ""; + if (ip.length() >= MAX_IP_ADDR_LENGTH) { ret = false; } else { // ObString may be not terminated by '\0' MEMCPY(ip_buf, ip.ptr(), ip.length()); - ret = set_ipv4_addr(ip_buf, port); + ret = set_ip_addr(ip_buf, port); } return ret; } @@ -194,8 +249,12 @@ bool ObAddr::is_valid() const bool valid = true; if (port_ <= 0) { valid = false; + } else if (IPV4 == version_) { + valid = (0 != ip_.v4_); + } else if (IPV6 == version_) { + valid = ((0 != ip_.v6_[0]) || (0 != ip_.v6_[1]) || (0 != ip_.v6_[2]) || (0 != ip_.v6_[3])); } else { - valid = (IPV4 == version_) && (0 != ip_.v4_); + valid = false; } return valid; } @@ -235,10 +294,17 @@ void ObAddr::set_ipv4_server_id(const int64_t ipv4_server_id) bool ObAddr::operator <(const ObAddr &rv) const { - if ((version_ != rv.version_) || (IPV4 != version_)) { + int64_t ipcmp = 0; + if (version_ != rv.version_) { LOG_ERROR("comparision between different IP versions hasn't supported!"); + } else if (IPV4 == version_) { + ipcmp = static_cast(ip_.v4_) - static_cast(rv.ip_.v4_); + } else if (IPV6 == version_) { + int pos = 0; + for (; ipcmp == 0 && pos < IPV6_LEN; pos++) { + ipcmp = ip_.v6_[pos] - rv.ip_.v6_[pos]; + } } - int ipcmp = ip_.v4_ - rv.ip_.v4_; return (ipcmp < 0) || (0 == ipcmp && port_ < rv.port_); } @@ -271,6 +337,68 @@ void ObAddr::set_port(int32_t port) port_ = port; } +struct sockaddr_storage ObAddr::get_sockaddr() const +{ + struct sockaddr_storage sock_addr; + memset(&sock_addr, 0, sizeof(struct sockaddr_storage)); + if (version_ == IPV4) { + struct sockaddr_in in; + memset(&in, 0, sizeof(struct sockaddr_in)); + in.sin_family = AF_INET; + in.sin_port = (htons)(static_cast(port_)); + in.sin_addr.s_addr = htonl(ip_.v4_); + MEMCPY(&sock_addr, &in, sizeof(in)); + } else if (version_ == IPV6) { + struct sockaddr_in6 in6; + memset(&in6, 0, sizeof(struct sockaddr_in6)); + in6.sin6_family = AF_INET6; + in6.sin6_port = (htons)(static_cast(port_)); + MEMCPY(in6.sin6_addr.s6_addr, ip_.v6_, sizeof(ip_.v6_)); + MEMCPY(&sock_addr, &in6, sizeof(in6)); + } + + return sock_addr; +} + +void ObAddr::set_sockaddr(const struct sockaddr &sock_addr) +{ + if (sock_addr.sa_family == AF_INET) { + version_ = IPV4; + const struct sockaddr_in &in = (struct sockaddr_in&)(sock_addr); + port_ = ntohs(in.sin_port); + ip_.v4_ = ntohl(in.sin_addr.s_addr); + } else if (sock_addr.sa_family == AF_INET6) { + version_ = IPV6; + const struct sockaddr_in6 &in6 = (struct sockaddr_in6&)(sock_addr); + port_ = ntohs(in6.sin6_port); + MEMCPY(ip_.v6_, in6.sin6_addr.s6_addr, sizeof(ip_.v6_)); + } +} + +bool ObAddr::set_ip_addr(const char *ip, const int32_t port) +{ + bool bret = false; + const char *ch = strchr(ip, ':'); + if (NULL != ch) { + bret = set_ipv6_addr(ip, port); + } else { + bret = set_ipv4_addr(ip, port); + } + return bret; +} + +bool ObAddr::set_ipv6_addr(const uint64_t ipv6_high, const uint64_t ipv6_low, const int32_t port) +{ + bool ret = true; + uint64_t *high = reinterpret_cast(&ip_.v6_[0]); + uint64_t *low = reinterpret_cast(&ip_.v6_[8]); + *high = ipv6_high; + *low = ipv6_low; + version_ = IPV6; + port_= port; + return ret; +} + OB_SERIALIZE_MEMBER(ObAddr, version_, ip_.v6_[0], ip_.v6_[1], ip_.v6_[2], ip_.v6_[3], port_); } // end namespace common diff --git a/src/lib/net/ob_addr.h b/src/lib/net/ob_addr.h index 9b9d0096..21383a88 100644 --- a/src/lib/net/ob_addr.h +++ b/src/lib/net/ob_addr.h @@ -19,28 +19,33 @@ #include "lib/container/ob_se_array.h" #include "lib/json/ob_yson.h" #include "lib/ob_name_id_def.h" +#include "iocore/net/ob_inet.h" namespace oceanbase { namespace common { +#define IPV6_LEN 16 + class ObAddr { OB_UNIS_VERSION(1); public: enum VER { - IPV4 = 4, IPV6 = 6 + IPV4 = 4, + IPV6 = 6, + IPINVALID, }; ObAddr() - : version_(IPV4), ip_(), port_(0) + : version_(IPINVALID), ip_(), port_(0) { memset(&ip_, 0, sizeof(ip_)); } ObAddr(VER version, const char *ip, const int32_t port) - : version_(IPV4), ip_(), port_(0) + : version_(IPINVALID), ip_(), port_(0) { memset(&ip_, 0, sizeof(ip_)); if (version == IPV4) { @@ -50,15 +55,20 @@ class ObAddr } } + // The server_id format cannot be used in the case of IPV6 + // TODO: Consider removing it explicit ObAddr(const int64_t ipv4_server_id) - : version_(IPV4), ip_(), port_(0) + : version_(IPINVALID), ip_(), port_(0) { + // server_id only supports IPV4 format + version_ = IPV4; ip_.v4_ = static_cast(0x00000000ffffffff & (ipv4_server_id >> 32)); port_ = static_cast(0x00000000ffffffff & ipv4_server_id); } void reset() { + version_ = IPINVALID; port_ = 0; memset(&ip_, 0, sizeof (ip_)); } @@ -68,7 +78,10 @@ class ObAddr return (IPV4 == version_ && INADDR_LOOPBACK == ip_.v4_) || (IPV6 == version_ && IN6_IS_ADDR_LOOPBACK(ip_.v6_)); } - static uint32_t convert_ipv4_addr(const char *ip); + int convert_ipv4_addr(const char *ip); + int convert_ipv6_addr(const char *ip); + struct sockaddr_storage get_sockaddr() const; + void set_sockaddr(const struct sockaddr &sock_addr); int64_t to_string(char *buffer, const int64_t size) const; bool ip_to_string(char *buffer, const int32_t size) const; @@ -76,10 +89,12 @@ class ObAddr TO_YSON_KV(ID(ip), ip_.v4_, ID(port), port_); + bool set_ip_addr(const char *ip, const int32_t port); + bool set_ip_addr(const ObString &ip, const int32_t port); bool set_ipv6_addr(const char *ip, const int32_t port); + bool set_ipv6_addr(const uint64_t ipv6_high, const uint64_t ipv6_low, const int32_t port); bool set_ipv4_addr(const char *ip, const int32_t port); bool set_ipv4_addr(const uint32_t ip, const int32_t port); - bool set_ipv4_addr(const ObString &ip, const int32_t port); int parse_from_cstring(const char *ip_str); int64_t get_ipv4_server_id() const; @@ -89,6 +104,7 @@ class ObAddr bool operator !=(const ObAddr &rv) const; bool operator ==(const ObAddr &rv) const; bool operator < (const ObAddr &rv) const; + ObAddr& operator = (const ObAddr &rv); int compare(const ObAddr &rv) const; bool is_equal_except_port(const ObAddr &rv) const; inline int32_t get_version() const { return version_; } @@ -106,6 +122,8 @@ class ObAddr VER version_; union { + // v4 addresses are stored in native byte order, + // v6 addresses are stored in network byte order uint32_t v4_; //host byte order uint32_t v6_[4]; } ip_; @@ -139,6 +157,16 @@ bool ObAddr::operator ==(const ObAddr &rv) const && ip_.v6_[2] == rv.ip_.v6_[2] && ip_.v6_[3] == rv.ip_.v6_[3]; } +ObAddr& ObAddr::operator =(const ObAddr &rv) +{ + if (this != &rv) { + version_ = rv.version_; + port_ = rv.port_; + MEMCPY(ip_.v6_, rv.ip_.v6_, sizeof(ip_.v6_)); + } + return *this; +} + int ObAddr::compare(const ObAddr &rv) const { return memcmp(this, &rv, sizeof(ObAddr)); diff --git a/src/lib/ob_define.h b/src/lib/ob_define.h index 968ee82f..e80ff17f 100644 --- a/src/lib/ob_define.h +++ b/src/lib/ob_define.h @@ -53,7 +53,7 @@ const int64_t OB_MAX_CLUSTER_ID = 4294901759; const int64_t OB_INVALID_CLUSTER_ID = -1; const int64_t OB_INVALID_ORG_CLUSTER_ID = 0; const int64_t OB_MAX_ITERATOR = 16; -const int64_t MAX_IP_ADDR_LENGTH = 32; +const int64_t MAX_IP_ADDR_LENGTH = 64; const int64_t MAX_IP_PORT_LENGTH = MAX_IP_ADDR_LENGTH + 5; const int64_t MAX_IP_PORT_SQL_LENGTH = MAX_IP_ADDR_LENGTH + 10; const int64_t OB_MAX_SQL_ID_LENGTH = 32; @@ -178,7 +178,6 @@ const int64_t OB_MAX_BATCH_NUMBER = 100; const int64_t OB_MAX_TABLET_LIST_NUMBER = 64; const int64_t OB_MAX_DISK_NUMBER = 16; // must no more than ObTimer::MAX_TASK_NUM const int64_t OB_MAX_TIME_STR_LENGTH = 64; -const int64_t OB_IP_STR_BUFF = 30; //TODO: uniform IP/PORR length const int64_t OB_IP_PORT_STR_BUFF = 64; const int64_t OB_RANGE_STR_BUFSIZ = 512; const int64_t OB_MAX_FETCH_CMD_LENGTH = 2048; @@ -573,6 +572,9 @@ static const char *const OB_MYSQL_CLIENT_JDBC_CLIENT_MODE = "__ob_jdbc_client"; // for java client static const char *const OB_MYSQL_JAVA_CLIENT_MODE_NAME = "__ob_java_client"; +// conn attr which transparent transit to observer +static const char *const OB_MYSQL_OB_CLIENT = "__ob_client"; + // for obproxy and observer compatibility enum ObCapabilityFlagShift { @@ -592,6 +594,7 @@ enum ObCapabilityFlagShift OB_CAP_PROXY_SESSION_SYNC_SHIFT, // 13 OB_CAP_PROXY_FULL_LINK_TRACING_SHIFT, // 14 OB_CAP_PROXY_NEW_EXTRA_INFO_SHIFT, // 15 + OB_CAP_PROXY_SESSION_VAR_SYNC_SHIFT, // 16 }; #define OB_TEST_CAPABILITY(cap, tg_cap) (((cap) & (tg_cap)) == (tg_cap)) @@ -610,6 +613,7 @@ enum ObCapabilityFlagShift #define OB_CAP_PROXY_SESSION_SYNC OB_CAP_GET_TYPE(common::OB_CAP_PROXY_SESSION_SYNC_SHIFT) #define OB_CAP_PROXY_FULL_LINK_TRACING OB_CAP_GET_TYPE(common::OB_CAP_PROXY_FULL_LINK_TRACING_SHIFT) #define OB_CAP_PROXY_NEW_EXTRA_INFO OB_CAP_GET_TYPE(common::OB_CAP_PROXY_NEW_EXTRA_INFO_SHIFT) +#define OB_CAP_PROXY_SESSION_VAR_SYNC OB_CAP_GET_TYPE(common::OB_CAP_PROXY_SESSION_VAR_SYNC_SHIFT) // for obproxy debug diff --git a/src/lib/ob_errno.cpp b/src/lib/ob_errno.cpp index 1b1266da..9814f317 100644 --- a/src/lib/ob_errno.cpp +++ b/src/lib/ob_errno.cpp @@ -8,11 +8,6 @@ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. - * - * ************************************************************* - * - * DO NOT EDIT. This file is automatically generated from `ob_errno.def'. - * */ #include "ob_errno.h" @@ -2657,6 +2652,14 @@ static struct ObStrErrorInit SQLSTATE[-OB_TRANS_RPC_TIMEOUT] = "25000"; STR_ERROR[-OB_TRANS_RPC_TIMEOUT] = "transaction rpc timeout"; STR_USER_ERROR[-OB_TRANS_RPC_TIMEOUT] = "transaction rpc timeout"; + + // in transaction internal routing, if sql not supported to be executed on participant sent to participant + // server return OB_TRANS_FREE_ROUTE_NOT_SUPPORTED + // proxy downgrade transaction internal routing and send the rest of sql to coordinator + MYSQL_ERRNO[-OB_TRANS_FREE_ROUTE_NOT_SUPPORTED] = -1; + SQLSTATE[-OB_TRANS_FREE_ROUTE_NOT_SUPPORTED] = "HY000"; + STR_ERROR[-OB_TRANS_FREE_ROUTE_NOT_SUPPORTED] = "Query is not supported to be executed on txn participant node"; + STR_USER_ERROR[-OB_TRANS_FREE_ROUTE_NOT_SUPPORTED] = "Query is not supported to be executed on txn participant node"; MYSQL_ERRNO[-OB_LOG_ID_NOT_FOUND] = -1; SQLSTATE[-OB_LOG_ID_NOT_FOUND] = "HY000"; STR_ERROR[-OB_LOG_ID_NOT_FOUND] = "log id not found"; @@ -2883,8 +2886,8 @@ static struct ObStrErrorInit STR_USER_ERROR[-OB_ERR_NULL_DB_VAL_TESTLOAD_TABLE_MAP] = "Null database variable for testload table map to execute testload query"; MYSQL_ERRNO[-OB_ERR_BATCH_INSERT_FOUND] = -1; SQLSTATE[-OB_ERR_BATCH_INSERT_FOUND] = "HY000"; - STR_ERROR[-OB_ERR_BATCH_INSERT_FOUND] = "Batch insert is not supported for sharding table"; - STR_USER_ERROR[-OB_ERR_BATCH_INSERT_FOUND] = "Batch insert is not supported for sharding table"; + STR_ERROR[-OB_ERR_BATCH_INSERT_FOUND] = "Batch insert is not supported"; + STR_USER_ERROR[-OB_ERR_BATCH_INSERT_FOUND] = "Batch insert is not supported"; MYSQL_ERRNO[-OB_ERR_UNSUPPORT_DIFF_TOPOLOGY] = 7202; SQLSTATE[-OB_ERR_UNSUPPORT_DIFF_TOPOLOGY] = "HY000"; STR_ERROR[-OB_ERR_UNSUPPORT_DIFF_TOPOLOGY] = "Not support different topology table join"; diff --git a/src/lib/ob_errno.h b/src/lib/ob_errno.h index 39f10dbe..df603c1e 100644 --- a/src/lib/ob_errno.h +++ b/src/lib/ob_errno.h @@ -8,10 +8,6 @@ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. - * - * ************************************************************* - * - * DO NOT EDIT. This file is automatically generated from `ob_errno.def'. */ #ifndef OCEANBASE_LIB_OB_ERRNO_H_ @@ -23,6 +19,7 @@ namespace oceanbase { namespace common { + static const int OB_INTERNAL_ERROR = -600; static const int OB_ORA_FATAL_ERROR = -603; static const int64_t OB_MAX_ERROR_CODE = 10000; static const int OB_LAST_ERROR_CODE = -8003; @@ -704,6 +701,7 @@ namespace common static const int OB_PARTITION_IS_STOPPED = -6228; static const int OB_PARTITION_IS_BLOCKED = -6229; static const int OB_TRANS_RPC_TIMEOUT = -6230; + static const int OB_TRANS_FREE_ROUTE_NOT_SUPPORTED = -6279; static const int OB_LOG_ID_NOT_FOUND = -6301; static const int OB_LSR_THREAD_STOPPED = -6302; static const int OB_NO_LOG = -6303; @@ -1425,6 +1423,7 @@ namespace common #define OB_PARTITION_IS_STOPPED__USER_ERROR_MSG "Partition has been stopped" #define OB_PARTITION_IS_BLOCKED__USER_ERROR_MSG "Partition has been blocked" #define OB_TRANS_RPC_TIMEOUT__USER_ERROR_MSG "transaction rpc timeout" +#define OB_TRANS_FREE_ROUTE_NOT_SUPPORTED__USER_ERROR_MSG "Query is not supported to be executed on txn participant node" #define OB_LOG_ID_NOT_FOUND__USER_ERROR_MSG "log id not found" #define OB_LSR_THREAD_STOPPED__USER_ERROR_MSG "log scan runnable thread stop" #define OB_NO_LOG__USER_ERROR_MSG "no log ever scanned" diff --git a/src/lib/ob_name_id_def.h b/src/lib/ob_name_id_def.h index b9cb2d46..c77b060a 100644 --- a/src/lib/ob_name_id_def.h +++ b/src/lib/ob_name_id_def.h @@ -334,7 +334,8 @@ enum ObNameId }; // get name at runtime -const char* get_name(int32_t id); +/* this function is defined for c driver client compile */ +inline const char* get_name(int32_t id) {((void)(id)); return nullptr;}; const char* get_description(int32_t id); } // end namespace name_id_map } // end namespace oceanbase diff --git a/src/lib/oblog/ob_async_log_struct.h b/src/lib/oblog/ob_async_log_struct.h index c4ea05d5..79876ece 100644 --- a/src/lib/oblog/ob_async_log_struct.h +++ b/src/lib/oblog/ob_async_log_struct.h @@ -38,6 +38,7 @@ enum ObLogFDType { FD_POOL_FILE, FD_POOL_STAT_FILE, FD_TRACE_FILE, // ob20 full link trace interface + FD_DRIVER_CLIENT_FILE, MAX_FD_FILE, }; diff --git a/src/lib/oblog/ob_log.cpp b/src/lib/oblog/ob_log.cpp index 0b6928d5..2b9d7e08 100644 --- a/src/lib/oblog/ob_log.cpp +++ b/src/lib/oblog/ob_log.cpp @@ -375,7 +375,7 @@ ObLogger::~ObLogger() (void)pthread_mutex_destroy(&file_size_mutex_); } -void ObLogger::destory_async_log_thread() +void ObLogger::destroy_async_log_thread() { set_enable_async_log(false); set_stop_flush(); diff --git a/src/lib/oblog/ob_log.h b/src/lib/oblog/ob_log.h index 26359f58..bab4572a 100644 --- a/src/lib/oblog/ob_log.h +++ b/src/lib/oblog/ob_log.h @@ -283,7 +283,7 @@ class ObLogger public: ~ObLogger(); - void destory_async_log_thread(); + void destroy_async_log_thread(); int init_async_log_thread(const int64_t stacksize = 0); void destroy_free_litem_queue(); diff --git a/src/lib/oblog/ob_log_module.h b/src/lib/oblog/ob_log_module.h index 5f836b2d..1f6249cf 100644 --- a/src/lib/oblog/ob_log_module.h +++ b/src/lib/oblog/ob_log_module.h @@ -261,6 +261,11 @@ LOG_MOD_END(STORAGETEST) #define _OBPROXY_TRACE_LOG(level, _fmt_, args...) \ (OB_MONITOR_LOG_NEED_TO_PRINT(level) ? _OB_PRINT_TYPE(FD_TRACE_FILE, NULL, level, _fmt_, ##args) : (void) 0) +#define OBPROXY_DRIVER_CLIENT_LOG(level, infoString, args...) \ + (OB_LOG_NEED_TO_PRINT(level) ? OB_PRINT_TYPE(FD_DRIVER_CLIENT_FILE, NULL, level, infoString, ##args) : (void) 0) +#define _OBPROXY_DRIVER_CLIENT_LOG(level, _fmt_, args...) \ + (OB_LOG_NEED_TO_PRINT(level) ? _OB_PRINT_TYPE(FD_DRIVER_CLIENT_FILE, NULL, level, _fmt_, ##args) : (void) 0) + #define _OB_NUM_LEVEL_LOG(level, _fmt_, args...) \ (OB_LOGGER.need_to_print(level) ? \ diff --git a/src/lib/oblog/ob_log_print_kv.h b/src/lib/oblog/ob_log_print_kv.h index fedee40e..af937bd4 100644 --- a/src/lib/oblog/ob_log_print_kv.h +++ b/src/lib/oblog/ob_log_print_kv.h @@ -21,6 +21,7 @@ #include "lib/utility/ob_macro_utils.h" #include "lib/utility/ob_template_utils.h" #include "lib/alloc/alloc_assist.h" +#include "obproxy/ob_proxy_init.h" #define LOG_N_TRUE "true" #define LOG_N_FLASE "false" @@ -37,8 +38,8 @@ int logdata_printf(char *buf, const int64_t buf_len, int64_t &pos, const char *f __attribute__((format(printf, 4, 5))); int logdata_vprintf(char *buf, const int64_t buf_len, int64_t &pos, const char *fmt, va_list args); -#define LOG_STDERR(...) do {if(isatty(STDERR_FILENO)) {fprintf(stderr, __VA_ARGS__); }} while(0) -#define LOG_STDOUT(...) do {if(isatty(STDOUT_FILENO)) {fprintf(stdout, __VA_ARGS__); }} while(0) +#define LOG_STDERR(...) do { if(oceanbase::obproxy::RUN_MODE_PROXY == oceanbase::obproxy::g_run_mode && isatty(STDERR_FILENO)) {fprintf(stderr, __VA_ARGS__); }} while(0) +#define LOG_STDOUT(...) do {if(oceanbase::obproxy::RUN_MODE_PROXY == oceanbase::obproxy::g_run_mode && isatty(STDOUT_FILENO)) {fprintf(stdout, __VA_ARGS__); }} while(0) //print errmsg of errno.As strerror not thread-safe, need //to call ERRMSG, KERRMSG which use this class. @@ -370,6 +371,46 @@ int logdata_print_kv(char *buf, const int64_t buf_len, int64_t &pos, const char return logdata_print_key_obj(buf, buf_len, pos, key, false, obj); } +class ObILogKV +{ +public: + virtual int print(char *buf, int64_t buf_len, int64_t &pos, const bool with_comma) const = 0; +}; + +template +class ObLogKV; + +template +class ObLogKV : public ObILogKV +{ +public: + ObLogKV(const char *key, const T &value) : key_(key), value_(value) {} + int print(char *buf, int64_t buf_len, int64_t &pos, const bool with_comma) const override + { + return logdata_print_key_obj(buf, buf_len, pos, key_, + with_comma, value_); + } +private: + const char *key_; + const T &value_; +}; + +template T& unmove(T&& v) { return v; } + +template +class ObLogKV : public ObILogKV +{ +public: + ObLogKV(const char *key, const T &&value) : key_(key), value_(unmove(value)) {} + int print(char *buf, int64_t buf_len, int64_t &pos, const bool with_comma) const override + { + return logdata_print_key_obj(buf, buf_len, pos, key_, + with_comma, value_); + } +private: + const char *key_; + const T &value_; +}; } } @@ -679,4 +720,35 @@ int logdata_print_kv(char *buf, const int64_t buf_len, int64_t &pos, const char log_buffer.check_and_unlock(); \ } +#define LOG_KV(key, obj) \ + (::oceanbase::common::ObILogKV&&)::oceanbase::common::ObLogKV::value>(key, obj) +#define LOG_KVS_0() +#define LOG_KVS_1() +#define LOG_KVS_2(key, obj) , LOG_KV(key, obj) +#define LOG_KVS_4(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_2(args) +#define LOG_KVS_6(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_4(args) +#define LOG_KVS_8(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_6(args) +#define LOG_KVS_10(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_8(args) +#define LOG_KVS_12(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_10(args) +#define LOG_KVS_14(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_12(args) +#define LOG_KVS_16(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_14(args) +#define LOG_KVS_18(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_16(args) +#define LOG_KVS_20(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_18(args) +#define LOG_KVS_22(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_20(args) +#define LOG_KVS_24(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_22(args) +#define LOG_KVS_26(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_24(args) +#define LOG_KVS_28(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_26(args) +#define LOG_KVS_30(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_28(args) +#define LOG_KVS_32(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_30(args) +#define LOG_KVS_34(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_32(args) +#define LOG_KVS_36(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_34(args) +#define LOG_KVS_38(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_36(args) +#define LOG_KVS_40(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_38(args) +#define LOG_KVS_42(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_40(args) +#define LOG_KVS_44(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_42(args) + +#define LOG_KVS_(N, ...) CONCAT(LOG_KVS_, N)(__VA_ARGS__) +#define LOG_KVS(...) "placeholder" LOG_KVS_(ARGS_NUM(__VA_ARGS__), __VA_ARGS__) + #endif diff --git a/src/lib/oblog/ob_simple_trace.h b/src/lib/oblog/ob_simple_trace.h new file mode 100644 index 00000000..bd960bc9 --- /dev/null +++ b/src/lib/oblog/ob_simple_trace.h @@ -0,0 +1,190 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef _OB_SIMPLE_TRACE_H +#define _OB_SIMPLE_TRACE_H + +#include "lib/oblog/ob_log.h" + +namespace oceanbase +{ +namespace common +{ + +template +class ObSimpleTraceBase +{ +public: + ObSimpleTraceBase() { reset(); } + ~ObSimpleTraceBase() { } + void reset() + { + pos_ = 0; + buf_[0] = '\0'; + } + template + int log_it(const char *info, Args const & ... args) + { + int ret = common::OB_SUCCESS; + const int64_t saved_pos = pos_; + const char delimiter1[] = " | "; + const char delimiter2[] = "... | "; + if (OB_FAIL(fill_buffer(buf_, BUFFER_SIZE - sizeof(delimiter2), pos_, info, args...))) { + if ((BUFFER_SIZE - saved_pos) >= BUFFER_SIZE / 2) { + // rewrite ret + ret = OB_SUCCESS; + (void)databuff_printf(buf_, BUFFER_SIZE, pos_, delimiter2); + } + } else { + (void)databuff_printf(buf_, BUFFER_SIZE, pos_, delimiter1); + } + if (OB_FAIL(ret)) { + pos_ = saved_pos; + buf_[pos_] = '\0'; + } + return ret; + } + int64_t to_string(char *buf, const int64_t buf_len) const + { + int64_t pos = 0; + databuff_printf(buf, buf_len, pos, "%s", buf_); + return pos; + } +private: + int fill_kv(char *buf, const int64_t buf_len, int64_t &pos, + const bool with_comma) + { + UNUSED(buf); + UNUSED(buf_len); + UNUSED(pos); + UNUSED(with_comma); + return common::OB_SUCCESS; + } + + int fill_kv(char *buf, const int64_t buf_len, int64_t &pos, + const bool with_comma, + const ObILogKV &kv) + { + return kv.print(buf, buf_len, pos, with_comma); + } + + template + int fill_kv(char *buf, const int64_t buf_len, int64_t &pos, + const bool with_comma, + const Key &key, + const Value &value, + Args const & ... args) + { + int ret = OB_SUCCESS; + ret = fill_kv(buf, buf_len, pos, with_comma, LOG_KV(key, value)); + if (OB_SUCC(ret)) { + ret = fill_kv(buf, buf_len, pos, 1, args...); + } + return ret; + } + template + int fill_buffer(char *data, const int64_t buf_len, + int64_t &pos, + const char *info, + Args const & ... args) + { + int ret = OB_SUCCESS; + int64_t tmp_pos = pos; + ret = databuff_printf(data, buf_len, pos, "%s ", info); + if (OB_SUCC(ret)) { + ret = fill_kv(data, buf_len, pos, 0, args...); + } + if (OB_SUCC(ret) && OB_UNLIKELY(OB_LOGGER.get_log_level() >= OB_LOG_LEVEL_TRACE)) { + char tmp_buf[1024]; + memset(tmp_buf, 0, sizeof(tmp_buf)); + int64_t copy_len = pos - tmp_pos > 1023 ? 1023 : pos - tmp_pos; + MEMCPY(tmp_buf, data + tmp_pos, copy_len); + OB_LOG(TRACE, "trace_log", K(tmp_buf)); + } + return ret; + } +private: + char buf_[BUFFER_SIZE]; + int64_t pos_; +}; + +template +class ObSimpleTrace +{ +public: + ObSimpleTrace() { reset(); } + ~ObSimpleTrace() { } + void reset() + { + first_idx_ = 0; + cur_idx_ = 0; + need_print_ = false; + for (int64_t i = 0; i < BASE_TRACE_CNT; i++) { + traces_[i].reset(); + } + } + template + void log_it(const char *info, Args const & ... args) + { + if (need_print_) { + int ret = common::OB_SUCCESS; + for (int64_t i = 0; i < 2; i++) { + cur_idx_ = (cur_idx_ + i) % BASE_TRACE_CNT; + if (1 == i) { + if (cur_idx_ == first_idx_) { + if (OB_UNLIKELY(OB_LOGGER.get_log_level() >= OB_LOG_LEVEL_TRACE)) { + // _LOG(TRACE, "print_trace_log", K(*this)); + } else { + first_idx_ = (first_idx_ + 1) % BASE_TRACE_CNT; + } + } + traces_[cur_idx_].reset(); + } + if (OB_SUCC(traces_[cur_idx_].log_it(info, args...))) { + break; + } + } + (void)ret; + } + } + int64_t to_string(char *buf, const int64_t buf_len) const + { + int64_t pos = 0; + for (int64_t i = 0; i < BASE_TRACE_CNT; i++) { + if (pos < buf_len) { + const int64_t idx = (first_idx_ + i) % BASE_TRACE_CNT; + const int64_t size = traces_[idx].to_string(buf + pos, buf_len - pos); + pos = pos + size; + if (idx == cur_idx_) { + break; + } + } else { + break; + } + } + return pos; + } + void set_need_print(const bool &need_print) { need_print_ = need_print; } +private: + static const int64_t BASE_TRACE_CNT = 4; + static const int64_t BUFFER_SIZE = TRACE_SIZE / BASE_TRACE_CNT; +private: + ObSimpleTraceBase traces_[BASE_TRACE_CNT]; + int64_t first_idx_; + int64_t cur_idx_; + bool need_print_; +}; + +} // end namespace common +} // end namespace oceanbase + +#endif /* _OB_TRACE_EVENT_H */ diff --git a/src/lib/profile/ob_trace_id.h b/src/lib/profile/ob_trace_id.h index c1e56cbc..80b620ed 100644 --- a/src/lib/profile/ob_trace_id.h +++ b/src/lib/profile/ob_trace_id.h @@ -37,6 +37,7 @@ struct ObCurTraceId inline bool is_invalid() { return id_.seq_ == 0 ? true : false; } inline void init(const ObAddr &ip_port) { + // TODO: Consider whether to support IPv6 id_.seq_ = ATOMIC_AAF(&(SeqGenerator::seq_generator_), 1); id_.ip_ = ip_port.get_ipv4(); id_.reserved_ = 0; @@ -114,6 +115,8 @@ struct ObCurTraceId } }; +uint64_t ObCurTraceId::SeqGenerator::seq_generator_ = 0; + int32_t LogExtraHeaderCallback(char *buf, int32_t buf_size, int level, const char *file, int line, const char *function, pthread_t tid); diff --git a/src/lib/rowid/ob_urowid.cpp b/src/lib/rowid/ob_urowid.cpp index 8aba8730..c114edf7 100644 --- a/src/lib/rowid/ob_urowid.cpp +++ b/src/lib/rowid/ob_urowid.cpp @@ -135,7 +135,8 @@ int ObURowIDData::inner_get_pk_value(const uint8_t *rowid_buf, *(reinterpret_cast(rowid_buf + pos)); \ pos += sizeof(ObNumberDesc); \ int64_t digits_len = sizeof(uint32_t) * num_desc.len_; \ - if (OB_LIKELY(pos + digits_len <= rowid_buf_len)) { \ + if (OB_LIKELY(0 <= digits_len && digits_len <= rowid_buf_len \ + && pos + digits_len <= rowid_buf_len)) { \ const uint32_t *digits = reinterpret_cast(rowid_buf + pos); \ pos += digits_len; \ pk_val.set_##type(num_desc, const_cast(digits)); \ @@ -161,7 +162,7 @@ int ObURowIDData::inner_get_pk_value(const uint8_t *rowid_buf, int32_t char_len = \ *(reinterpret_cast(rowid_buf + pos)); \ pos += 4; \ - if (OB_LIKELY(pos + char_len <= rowid_buf_len)) { \ + if (OB_LIKELY(0 <= char_len && pos + char_len <= rowid_buf_len)) { \ const char *str_val = (const char *)rowid_buf + pos; \ pos += char_len; \ ObString str_value(char_len, str_val); \ @@ -208,19 +209,19 @@ DEF_GET_POD_PK_VALUE(ObIntType, int, int64_t); DEF_GET_POD_PK_VALUE(ObFloatType, float, float); DEF_GET_POD_PK_VALUE(ObDoubleType, double, double); DEF_GET_POD_PK_VALUE(ObDateTimeType, datetime, int64_t); -// DEF_GET_POD_PK_VALUE(ObIntervalYMType, interval_ym, int64_t); +//DEF_GET_POD_PK_VALUE(ObIntervalYMType, interval_ym, int64_t); DEF_GET_NUMBER_PK_VALUE(ObNumberType, number); DEF_GET_NUMBER_PK_VALUE(ObNumberFloatType, number_float); DEF_GET_CHAR_PK_VALUE(ObVarcharType, varchar); DEF_GET_CHAR_PK_VALUE(ObCharType, char); -// DEF_GET_CHAR_PK_VALUE(ObNVarchar2Type, nvarchar2); -// DEF_GET_CHAR_PK_VALUE(ObNCharType, nchar); +DEF_GET_CHAR_PK_VALUE(ObNVarchar2Type, nvarchar2); +DEF_GET_CHAR_PK_VALUE(ObNCharType, nchar); -// DEF_GET_OTIME_PK_VALUE(ObTimestampTZType, timestamp_tz, uint32_t); -// DEF_GET_OTIME_PK_VALUE(ObTimestampLTZType, timestamp_ltz, uint16_t); -// DEF_GET_OTIME_PK_VALUE(ObTimestampNanoType, timestamp_nano, uint16_t); +DEF_GET_OTIME_PK_VALUE(ObTimestampTZType, timestamp_tz, uint32_t); +DEF_GET_OTIME_PK_VALUE(ObTimestampLTZType, timestamp_ltz, uint16_t); +DEF_GET_OTIME_PK_VALUE(ObTimestampNanoType, timestamp_nano, uint16_t); #define ALL_TYPES_USED_IN_INNER_FUNC \ ObNullType, \ @@ -937,7 +938,8 @@ int ObURowIDData::get_rowkey_for_heap_organized_table(ObIArray &rowkey) int ObURowIDData::get_obobj_or_partition_id_from_decoded(obproxy::proxy::ObProxyPartInfo &part_info, obproxy::opsql::ObExprResolverResult &resolve_result, - int64_t &partition_id) + int64_t &partition_id, + common::ObIAllocator &allocator) { int ret = OB_SUCCESS; @@ -970,7 +972,7 @@ int ObURowIDData::get_obobj_or_partition_id_from_decoded(obproxy::proxy::ObProxy case NO_PK_ROWID_VERSION: case PK_ROWID_VERSION: { // ob2.x 3.x - if (OB_FAIL(get_obobj_from_decoded(part_info, resolve_result))) { + if (OB_FAIL(get_obobj_from_decoded(part_info, resolve_result, allocator))) { COMMON_LOG(WARN, "fail to get obobj from decoded", K(ret)); } break; @@ -986,7 +988,8 @@ int ObURowIDData::get_obobj_or_partition_id_from_decoded(obproxy::proxy::ObProxy // used for ob2.x 3.x int ObURowIDData::get_obobj_from_decoded(obproxy::proxy::ObProxyPartInfo &part_info, - obproxy::opsql::ObExprResolverResult &resolve_result) + obproxy::opsql::ObExprResolverResult &resolve_result, + common::ObIAllocator &allocator) { int ret = OB_SUCCESS; @@ -995,43 +998,55 @@ int ObURowIDData::get_obobj_from_decoded(obproxy::proxy::ObProxyPartInfo &part_i COMMON_LOG(WARN, "fail to get pk vals", K(ret)); } else { ObProxyPartKeyInfo &key_info = part_info.get_part_key_info(); - bool set_level_one_obj = false; - bool set_level_two_obj = false; for (int64_t i = 0; OB_SUCC(ret) && i < key_info.key_num_; ++i) { ObProxyPartKey &part_key = key_info.part_keys_[i]; - int8_t idx = -1; - if ((part_key.level_ == PART_KEY_LEVEL_ONE || part_key.level_ == PART_KEY_LEVEL_BOTH) - && !set_level_one_obj) { - idx = 0; - } else if (part_key.level_ == PART_KEY_LEVEL_TWO - && !set_level_two_obj) { - idx = 1; + if (PART_KEY_LEVEL_ONE == part_key.level_ && !resolve_result.ranges_[0].start_key_.is_valid()) { + if (OB_FAIL(resolve_result.ranges_[0].build_row_key(part_info.get_part_columns().count(), allocator))) { + COMMON_LOG(WARN, "fail to build row key", K(ret)); + } + } else if (PART_KEY_LEVEL_TWO == part_key.level_ && !resolve_result.ranges_[1].start_key_.is_valid()) { + if (OB_FAIL(resolve_result.ranges_[1].build_row_key(part_info.get_sub_part_columns().count(), allocator))) { + COMMON_LOG(WARN, "fail to build row key", K(ret)); + } } - if (idx != -1) { - if (part_key.idx_in_rowid_ >= 0 - && part_key.idx_in_rowid_ < pk_vals.count()) { - ObObj &obj = pk_vals.at(part_key.idx_in_rowid_); - if (is_valid_obj_type(obj.get_type())) { - resolve_result.ranges_[idx].start_key_.assign(&obj, 1); - resolve_result.ranges_[idx].end_key_.assign(&obj, 1); - resolve_result.ranges_[idx].border_flag_.set_inclusive_start(); - resolve_result.ranges_[idx].border_flag_.set_inclusive_end(); - if (idx == 0) { - set_level_one_obj = true; + if (part_key.idx_in_rowid_ >= 0 + && part_key.idx_in_rowid_ < pk_vals.count()) { + ObObj &obj = pk_vals.at(part_key.idx_in_rowid_); + ObObjType type = obj.get_type(); + if (ObCharType == type || ObNCharType == type) { + int32_t val_len = obj.get_val_len(); + const char* obj_str = obj.get_string_ptr(); + while (val_len > 1) { + if (OB_PADDING_CHAR == *(obj_str + val_len - 1)) { + --val_len; } else { - set_level_two_obj = true; + break; } - COMMON_LOG(DEBUG, "succ to get obobj from rowid", K(idx), K(part_key.idx_in_rowid_), K(obj)); - } else { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "invalid obj type resolved from rowid content", K(ret), K(obj.get_type())); } - } else { + obj.set_string(type, obj.get_string_ptr(), val_len); + } + + if (part_key.level_ == 0 || part_key.level_ > 2) { ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "calc partition id using rowid failed", K(part_key.idx_in_rowid_), K(pk_vals.count())); + COMMON_LOG(WARN, "part key level unexpected", K(part_key.level_)); + } else { + int level = static_cast(part_key.level_ - 1); + ObObj *target_start = const_cast(resolve_result.ranges_[level].start_key_.get_obj_ptr()) + + part_key.idx_in_part_columns_; + ObObj *target_end = const_cast(resolve_result.ranges_[level].end_key_.get_obj_ptr()) + + part_key.idx_in_part_columns_; + // no need to deep copy + *target_start = obj; + *target_end = obj; + resolve_result.ranges_[level].border_flag_.set_inclusive_start(); + resolve_result.ranges_[level].border_flag_.set_inclusive_end(); + COMMON_LOG(DEBUG, "succ to get val from rowid", K(obj), K(level), K(part_key.idx_in_part_columns_)); } + } else { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "calc partition id using rowid failed", K(part_key.idx_in_rowid_), K(pk_vals.count())); } } // for } // else diff --git a/src/lib/rowid/ob_urowid.h b/src/lib/rowid/ob_urowid.h index 8599314f..6346e74f 100644 --- a/src/lib/rowid/ob_urowid.h +++ b/src/lib/rowid/ob_urowid.h @@ -154,7 +154,8 @@ friend class TestURowID; int get_rowkey_for_heap_organized_table(ObIArray &rowkey); int get_obobj_or_partition_id_from_decoded(obproxy::proxy::ObProxyPartInfo &part_info, obproxy::opsql::ObExprResolverResult &resolve_result, - int64_t &partition_id); + int64_t &partition_id, + common::ObIAllocator &allocator); // if highest bit is 1, lower 7 bits of version filed indicates how many primar key obj static bool is_valid_part_gen_col_version(int64_t v) @@ -231,7 +232,8 @@ friend class TestURowID; int parse_ext_heap_organized_table_rowid(uint64_t &tablet_id, uint64_t &auto_inc); int get_obobj_from_decoded(obproxy::proxy::ObProxyPartInfo &part_info, - obproxy::opsql::ObExprResolverResult &resolve_result); + obproxy::opsql::ObExprResolverResult &resolve_result, + common::ObIAllocator &allocator); }; } // end namespace common diff --git a/src/lib/timezone/ob_time_convert.cpp b/src/lib/timezone/ob_time_convert.cpp index 8e92be2a..94cd069f 100644 --- a/src/lib/timezone/ob_time_convert.cpp +++ b/src/lib/timezone/ob_time_convert.cpp @@ -409,6 +409,32 @@ int ObTimeConverter::str_to_datetime(const ObString &str, const ObTimeZoneInfo * return ret; } +/** + * @brief cast str to oracle date with format + * + * @param str input string of date + * @param cvrt_ctx + * @param value out param, oracle DATE result + * @return int + */ +int ObTimeConverter::str_to_date_oracle(const ObString &str, + const ObTimeConvertCtx &cvrt_ctx, + ObDateTime &value) +{ + int ret = OB_SUCCESS; + ObTime ob_time; + ObDateTime result_value = 0; + ObScale scale = 0; + if (OB_FAIL(str_to_ob_time_oracle_dfm(str, cvrt_ctx, ObDateTimeType, ob_time, scale))) { + LOG_WARN("failed to convert str to ob_time", K(str), K(cvrt_ctx.oracle_nls_format_)); + } else if (OB_FAIL(ob_time_to_datetime(ob_time, cvrt_ctx.tz_info_, result_value))) { + LOG_WARN("convert ob_time to datetime failed", K(ret), K(ob_time)); + } else { + value = result_value; + } + return ret; +} + int ObTimeConverter::str_to_datetime_format(const ObString &str, const ObString &fmt, const ObTimeZoneInfo *tz_info, int64_t &value, int16_t *scale) { @@ -3111,7 +3137,7 @@ int ObTimeConverter::ob_time_to_str(const ObTime &ob_time, ObDTMode mode, int16_ int ObTimeConverter::data_fmt_nd(char *buffer, int64_t buf_len, int64_t &pos, const int64_t n, int64_t target) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(n <= 0 || target < 0 || target > 999999)) { + if (OB_UNLIKELY(n <= 0 || target < 0 || target > 999999999)) { ret = OB_ERR_UNEXPECTED; LIB_TIME_LOG(ERROR, "invalid argument", K(ret), K(n), K(target)); } else if (OB_UNLIKELY(n > buf_len - pos)) { @@ -3698,6 +3724,8 @@ int ObTimeConverter::ob_time_to_str_oracle_dfm(const ObTime &ob_time, break; } case ObDFMFlag::FF: { + // FF default FF9 in oracle + int64_t scale = ObDFMFlag::FF9 - ObDFMFlag::FF1 + 1; if (OB_UNLIKELY(!HAS_TYPE_ORACLE(ob_time.mode_))) { ret = OB_INVALID_DATE_FORMAT; } else if (0 == scale) { diff --git a/src/lib/timezone/ob_time_convert.h b/src/lib/timezone/ob_time_convert.h index e5e3a5b7..863a26ee 100644 --- a/src/lib/timezone/ob_time_convert.h +++ b/src/lib/timezone/ob_time_convert.h @@ -251,6 +251,7 @@ class ObTimeConverter static int int_to_time(int64_t int64, int64_t &value); static int int_to_year(int64_t int64, uint8_t &value); static int str_to_datetime(const ObString &str, const ObTimeZoneInfo *tz_info, int64_t &value, int16_t *scale = NULL); + static int str_to_date_oracle(const ObString &str, const ObTimeConvertCtx &cvrt_ctx, ObDateTime &value); static int str_to_datetime_format(const ObString &str, const ObString &fmt, const ObTimeZoneInfo *tz_info, int64_t &value, int16_t *scale = NULL); static int str_is_date_format(const ObString &str, bool &date_flag); @@ -345,7 +346,7 @@ class ObTimeConverter ObDTMode mode, int32_t &delta); static int ob_time_to_str_oracle_dfm(const ObTime &ob_time, ObScale scale, const ObString &format, char *buf, int64_t buf_len, int64_t &pos); - static int ob_time_to_datetime(ObTime &ob_time, const ObTimeZoneInfo *sp, int64_t &value); + static int ob_time_to_datetime(ObTime &ob_time, const ObTimeZoneInfo *tz_info, int64_t &value); static int32_t ob_time_to_date(ObTime &ob_time); static int ob_time_to_otimestamp(ObTime &ob_time, ObOTimestampData &value); static int64_t ob_time_to_time(const ObTime &ob_time); diff --git a/src/lib/trace/ob_trace.cpp b/src/lib/trace/ob_trace.cpp index 3ed4cafc..8c7a3cd1 100644 --- a/src/lib/trace/ob_trace.cpp +++ b/src/lib/trace/ob_trace.cpp @@ -439,6 +439,7 @@ ObSpanCtx* ObTrace::begin_span(uint32_t span_type, uint8_t level, bool is_follow new_span = freed_span_.remove_last(); current_span_.add_first(new_span); new_span->span_type_ = static_cast(span_type); + new_span->span_id_.high_ = 0; new_span->span_id_.low_ = ++seq_; new_span->source_span_ = last_active_span_; new_span->is_follow_ = is_follow; @@ -565,4 +566,4 @@ void ObTrace::dump_span() } } -} \ No newline at end of file +} diff --git a/src/obproxy/Makemodule.am b/src/obproxy/Makemodule.am index df2de637..4a08e92a 100644 --- a/src/obproxy/Makemodule.am +++ b/src/obproxy/Makemodule.am @@ -10,7 +10,11 @@ AM_CPPFLAGS += -I${top_srcdir}/src/obproxy\ obproxy_libobproxy_la_LIBADD := dbconfig/libdbconfig.la lib/regex/regex/libregex.la prometheus/libprometheus_exporter.la noinst_LTLIBRARIES += obproxy/libobproxy.la -bin_PROGRAMS += obproxy/obproxy +if HAVE_SO + lib_LTLIBRARIES += obproxy/libobproxy_so.la +else + bin_PROGRAMS += obproxy/obproxy +endif include obproxy/iocore/eventsystem/Makemodule.am include obproxy/iocore/net/Makemodule.am @@ -30,6 +34,7 @@ include obproxy/opsql/Makemodule.am include obproxy/packet/Makemodule.am include obproxy/dbconfig/Makemodule.am include obproxy/engine/Makemodule.am +include obproxy/driver/c/Makemodule.am include obproxy/optimizer/Makemodule.am include obproxy/executor/Makemodule.am include obproxy/qos/Makemodule.am @@ -41,6 +46,9 @@ pub_source = \ obproxy/ob_proxy_main.cpp \ obproxy/ob_proxy.h \ obproxy/ob_proxy.cpp +init_so_source =\ + obproxy/ob_proxy_init.h\ + obproxy/ob_proxy_init.cpp obproxy_sources :=\ ${iocore_eventsystem_sources}\ @@ -51,6 +59,7 @@ ${proxy_api_sources}\ ${proxy_plugins_sources}\ ${proxy_mysqllib_sources}\ ${proxy_mysql_client_sources}\ +${obproxy_c_driver_sources}\ ${proxy_mysql_route_sources}\ ${proxy_mysql_shard_sources}\ ${obutils_sources}\ @@ -70,6 +79,8 @@ ${obproxy_executor_sources}\ ${obproxy_optimizer_sources}\ ${obproxy_engine_sources}\ ${qos_sources}\ +${init_so_source}\ +${pub_source}\ ${omt_sources} obproxy_libobproxy_la_SOURCES :=\ @@ -80,8 +91,15 @@ ${rpc_obmysql_packet_sources} ${obproxy_rpc_obmysql_sources} ${rpc_common_source ${obproxy_sql_sources}\ ${obproxy_sources} +if HAVE_SO + obproxy_libobproxy_so_la_SOURCES := + obproxy_libobproxy_so_la_LIBADD := obproxy/libobproxy.la lib/compress/libzlib_1.0.la lib/compress/libzstd_1.3.8.la ${BIN_LDFLAGS} ${DEP_DIR}/lib64/libprometheus-cpp-pull.a ${DEP_DIR}/lib64/libprometheus-cpp-core.a ${RUNTIME_DIR}/lib/libob_sql_proxy_parser_static.a ${DEP_DIR}/lib/libssl.a ${DEP_DIR}/lib/libcrypto.a -lpthread + + obproxy_libobproxy_so_la_LDFLAGS :=${AM_LDFLAGS} ${DEP_DIR}/lib/libgrpc++.a -lpthread -lc -lm -lrt ${DEP_DIR}/lib/libcurl.a -ldl -L${DEP_DIR}/lib -llber ${DEP_DIR}/lib/sqlite/libsqlite3.a ${DEP_DIR}/lib/libgrpc_cronet.a ${DEP_DIR}/lib/libgrpc++_cronet.a -shared ${DEP_DIR}/lib64/libprotobuf.a -fPIC +endif + nodist_obproxy_libobproxy_la_SOURCES = build_version.c -obproxy_obproxy_SOURCES := obproxy/main.cpp ${pub_source} +obproxy_obproxy_SOURCES := obproxy/main.cpp obproxy_obproxy_LDADD_BASE := obproxy/libobproxy.la lib/compress/libzlib_1.0.la lib/compress/libzstd_1.3.8.la ${BIN_LDFLAGS} ${DEP_DIR}/lib64/libprotobuf.a ${DEP_DIR}/lib/libgrpc.a ${DEP_DIR}/lib/libgrpc++.a ${DEP_DIR}/lib/libgrpc_unsecure.a ${DEP_DIR}/lib/libgrpc++_unsecure.a ${DEP_DIR}/lib/libgrpc++_reflection.a ${DEP_DIR}/lib/libgrpcpp_channelz.a ${DEP_DIR}/lib/libgrpc++_error_details.a ${DEP_DIR}/lib/libgrpc_cronet.a ${DEP_DIR}/lib/libgrpc++_cronet.a ${DEP_DIR}/lib/libgpr.a ${DEP_DIR}/lib/libaddress_sorting.a ${DEP_DIR}/lib/libcares.a ${DEP_DIR}/lib64/libprometheus-cpp-pull.a ${DEP_DIR}/lib64/libprometheus-cpp-core.a ${RUNTIME_DIR}/lib/libob_sql_proxy_parser_static.a ${DEP_DIR}/lib/libssl.a ${DEP_DIR}/lib/libcrypto.a -lpthread ${DEP_DIR}/lib/libcurl.a ${DEP_DIR}/lib/libcrypto.a ${DEP_DIR}/lib/sqlite/libsqlite3.a obproxy_obproxy_LDFLAGS :=${AM_LDFLAGS} -lpthread -lc -lm -lrt -ldl -L${DEP_DIR}/lib diff --git a/src/obproxy/cmd/ob_cmd_handler.cpp b/src/obproxy/cmd/ob_cmd_handler.cpp index 5adcd4d9..39e13505 100644 --- a/src/obproxy/cmd/ob_cmd_handler.cpp +++ b/src/obproxy/cmd/ob_cmd_handler.cpp @@ -88,8 +88,7 @@ int ObCmdHandler::reset() } else { internal_buf_->reset(); seq_ = original_seq_; - protocol_ = ObProxyProtocol::PROTOCOL_NORMAL; - ob20_param_.reset(); + // could not reset protocol and ob20 param, cause we need fill external buf according to protocol } return ret; } diff --git a/src/obproxy/cmd/ob_dds_config_handler.cpp b/src/obproxy/cmd/ob_dds_config_handler.cpp index 8a8cb1d6..4bd3ceb9 100644 --- a/src/obproxy/cmd/ob_dds_config_handler.cpp +++ b/src/obproxy/cmd/ob_dds_config_handler.cpp @@ -361,7 +361,6 @@ int ObDdsConfigHandler::handle_parse_where_fields(ObArenaAllocator* allocator, O } else { ObExprParser expr_parser(*allocator, parse_mode); expr_result.part_key_info_.key_num_ = 0; - expr_result.target_mask_ = 0; if (OB_FAIL(expr_parser.parse_reqsql(sql, sql_parse_result.get_parsed_length(), expr_result, sql_parse_result.get_stmt_type(), connection_collation))) { diff --git a/src/obproxy/cmd/ob_internal_cmd_handler.cpp b/src/obproxy/cmd/ob_internal_cmd_handler.cpp index c8446a53..be03c433 100644 --- a/src/obproxy/cmd/ob_internal_cmd_handler.cpp +++ b/src/obproxy/cmd/ob_internal_cmd_handler.cpp @@ -111,8 +111,7 @@ int ObInternalCmdHandler::reset() } else { internal_buf_->reset(); seq_ = original_seq_; - protocol_ = ObProxyProtocol::PROTOCOL_NORMAL; - ob20_param_.reset(); + // could not reset protocol and ob20_param in handler, cause we need filll external buf according to protocol } return ret; } @@ -621,7 +620,8 @@ int ObInternalCmdHandler::handle_callback(int event, void *data) MUTEX_TRY_LOCK(lock, action_.mutex_, submit_thread_); if (lock.is_locked()) { if (!action_.cancelled_) { - if (INTERNAL_CMD_EVENTS_SUCCESS == saved_event_ && OB_SUCCESS != fill_external_buf()) { + if (INTERNAL_CMD_EVENTS_SUCCESS == saved_event_ + && OB_SUCCESS != fill_external_buf()) { saved_event_ = INTERNAL_CMD_EVENTS_FAILED; } DEBUG_ICMD("do callback now", K_(saved_event)); diff --git a/src/obproxy/cmd/ob_sequence_info_handler.cpp b/src/obproxy/cmd/ob_sequence_info_handler.cpp index abe8f4a5..d0fc0450 100644 --- a/src/obproxy/cmd/ob_sequence_info_handler.cpp +++ b/src/obproxy/cmd/ob_sequence_info_handler.cpp @@ -175,7 +175,8 @@ int ObSequenceInfoHandler::handle_shard_sequence_params() } else if (!param_.tnt_id_.empty() && param_.tnt_col_.empty()) { snprintf(err_msg_, SEQUENCE_ERR_MSG_SIZE, "tnt_col is empty while tnt_id used"); ret = OB_ERR_UNEXPECTED; - } else if (OB_FAIL(ObProxyShardUtils::get_real_info(*logic_db_info, + } else if (OB_FAIL(ObProxyShardUtils::get_real_info(session_info, + *logic_db_info, sequence_table_name, parse_result, shard_conn, @@ -211,6 +212,9 @@ int ObSequenceInfoHandler::handle_shard_sequence_params() table_id_ = table_id; group_id_ = group_id; eid_ = es_id; + session_info.set_group_id(group_id); + session_info.set_table_id(table_id); + session_info.set_es_id(es_id); snprintf(seq_id_buf_, 2048, "%.*s-%.*s-%.*s-%.*s-%.*s-%.*s-%02ld-%02ld-%02ld", logic_tenant_name_.config_string_.length(), logic_tenant_name_.config_string_.ptr(), @@ -222,6 +226,11 @@ int ObSequenceInfoHandler::handle_shard_sequence_params() group_id_, table_id_, eid_); param_.seq_id_ = ObString(seq_id_buf_); } + + if (NULL != logic_db_info) { + logic_db_info->dec_ref(); + logic_db_info = NULL; + } LOG_DEBUG("Left handle_shard_sequence_params", K(param_), K(table_id_), K(group_id_), K(eid_)); return ret; } diff --git a/src/obproxy/cmd/ob_show_route_handler.cpp b/src/obproxy/cmd/ob_show_route_handler.cpp index 96df7710..fcbc4996 100644 --- a/src/obproxy/cmd/ob_show_route_handler.cpp +++ b/src/obproxy/cmd/ob_show_route_handler.cpp @@ -463,8 +463,6 @@ int ObShowRouteHandler::dump_table_item(const ObTableEntry &entry) int ret = OB_SUCCESS; const int64_t count = entry.get_server_count(); ObSqlString server_addr; - uint32_t ipv4 = 0; - int32_t port = 0; ObRole role = INVALID_ROLE; ObReplicaType replica_type = REPLICA_TYPE_MAX; const ObTenantServer *ts = NULL; @@ -479,30 +477,24 @@ int ObShowRouteHandler::dump_table_item(const ObTableEntry &entry) part_info = entry.get_part_info(); } for (int64_t i = 0; i < count && OB_SUCC(ret); ++i) { + char ip_port_buf[MAX_IP_ADDR_LENGTH]; + memset(ip_port_buf, 0, sizeof(ip_port_buf)); if (NULL != ts) { - ipv4 = ts->get_replica_location(i)->server_.get_ipv4(); - port = ts->get_replica_location(i)->server_.get_port(); role = ts->get_replica_location(i)->role_; replica_type = ts->get_replica_location(i)->replica_type_; + ts->get_replica_location(i)->server_.ip_port_to_string(ip_port_buf, sizeof(ip_port_buf)); } else if (NULL != pl) { - ipv4 = pl->get_replica(i)->server_.get_ipv4(); - port = pl->get_replica(i)->server_.get_port(); role = pl->get_replica(i)->role_; replica_type = pl->get_replica(i)->replica_type_; + pl->get_replica(i)->server_.ip_port_to_string(ip_port_buf, sizeof(ip_port_buf)); } else { - ipv4 = 0; - port = -1; role = INVALID_ROLE; replica_type = REPLICA_TYPE_MAX; } const ObString &string = ObProxyReplicaLocation::get_replica_type_string(replica_type); - if (OB_FAIL(server_addr.append_fmt("server[%ld]=%d.%d.%d.%d:%d,%s,%.*s; ", + if (OB_FAIL(server_addr.append_fmt("server[%ld]=%s,%s,%.*s; ", i, - (ipv4 >> 24) & 0XFF, - (ipv4 >> 16) & 0xFF, - (ipv4 >> 8) & 0xFF, - (ipv4) & 0xFF, - port, + ip_port_buf, role2str(role), string.length(), string.ptr()))) { WARN_ICMD("fail to append server_addr", K(i), K(ret)); @@ -674,24 +666,18 @@ int ObShowRouteHandler::dump_partition_item(const ObPartitionEntry &entry) int ret = OB_SUCCESS; const int64_t count = entry.get_server_count(); ObSqlString server_addr; - uint32_t ipv4 = 0; - int32_t port = 0; ObRole role = INVALID_ROLE; ObReplicaType replica_type = REPLICA_TYPE_MAX; const ObProxyPartitionLocation &pl = entry.get_pl(); for (int64_t i = 0; i < count && OB_SUCC(ret); ++i) { - ipv4 = pl.get_replica(i)->server_.get_ipv4(); - port = pl.get_replica(i)->server_.get_port(); role = pl.get_replica(i)->role_; replica_type = pl.get_replica(i)->replica_type_; const ObString &string = ObProxyReplicaLocation::get_replica_type_string(replica_type); - if (OB_FAIL(server_addr.append_fmt("server[%ld]=%d.%d.%d.%d:%d,%s,%.*s; ", + char ip_port_buf[MAX_IP_ADDR_LENGTH]; + pl.get_replica(i)->server_.ip_port_to_string(ip_port_buf, sizeof(ip_port_buf)); + if (OB_FAIL(server_addr.append_fmt("server[%ld]=%s,%s,%.*s; ", i, - (ipv4 >> 24) & 0XFF, - (ipv4 >> 16) & 0xFF, - (ipv4 >> 8) & 0xFF, - (ipv4) & 0xFF, - port, + ip_port_buf, role2str(role), string.length(), string.ptr()))) { WARN_ICMD("fail to append server_addr", K(i), K(ret)); diff --git a/src/obproxy/cmd/ob_show_sqlaudit_handler.cpp b/src/obproxy/cmd/ob_show_sqlaudit_handler.cpp index 001d31e2..73a7282b 100644 --- a/src/obproxy/cmd/ob_show_sqlaudit_handler.cpp +++ b/src/obproxy/cmd/ob_show_sqlaudit_handler.cpp @@ -368,9 +368,10 @@ enum OB_SSA_SERVER_SEND_SAVED_LOGIN_TIME, OB_SSA_SERVER_SEND_USE_DATABASE_TIME, OB_SSA_SERVER_SEND_SESSION_VARIABLE_TIME, + OB_SSA_SERVER_SEND_SESSION_USER_VARIABLE_TIME, OB_SSA_SERVER_SEND_ALL_SESSION_VARIABLE_TIME, - OB_SSA_SERVER_SEND_LAST_INSERT_ID_TIME, OB_SSA_SERVER_SEND_START_TRANS_TIME, + OB_SSA_SERVER_SEND_XA_START_TIME, OB_SSA_BUILD_SERVER_REQUEST_TIME, OB_SSA_PLUGIN_COMPRESS_REQUEST_TIME, OB_SSA_PREPARE_SEND_REQUEST_TO_SERVER_TIME, @@ -408,9 +409,10 @@ const ObProxyColumnSchema SSA_COLUMN_ARRAY[OB_SSA_MAX_COLUMN_ID] = { ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_SAVED_LOGIN_TIME, "server_send_saved_login_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_USE_DATABASE_TIME, "server_send_use_database_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_SESSION_VARIABLE_TIME, "server_send_session_variable_ns", obmysql::OB_MYSQL_TYPE_LONG), + ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_SESSION_USER_VARIABLE_TIME, "server_send_session_user_variable_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_ALL_SESSION_VARIABLE_TIME, "server_send_all_session_variable_ns", obmysql::OB_MYSQL_TYPE_LONG), - ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_LAST_INSERT_ID_TIME, "server_send_last_insert_id_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_START_TRANS_TIME, "server_send_start_trans_ns", obmysql::OB_MYSQL_TYPE_LONG), + ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_XA_START_TIME, "server_send_xa_start_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_BUILD_SERVER_REQUEST_TIME, "build_server_request_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_PLUGIN_COMPRESS_REQUEST_TIME, "plugin_compress_request_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_PREPARE_SEND_REQUEST_TO_SERVER_TIME, "prepare_send_request_to_server_ns", obmysql::OB_MYSQL_TYPE_LONG), @@ -549,9 +551,10 @@ int ObShowSqlauditHandler::dump_sqlaudit_record(ObSqlauditRecord &record) cells[OB_SSA_SERVER_SEND_SAVED_LOGIN_TIME].set_int(record.cmd_time_stat_.server_send_saved_login_time_); cells[OB_SSA_SERVER_SEND_USE_DATABASE_TIME].set_int(record.cmd_time_stat_.server_send_use_database_time_); cells[OB_SSA_SERVER_SEND_SESSION_VARIABLE_TIME].set_int(record.cmd_time_stat_.server_send_session_variable_time_); + cells[OB_SSA_SERVER_SEND_SESSION_USER_VARIABLE_TIME].set_int(record.cmd_time_stat_.server_send_session_user_variable_time_); cells[OB_SSA_SERVER_SEND_ALL_SESSION_VARIABLE_TIME].set_int(record.cmd_time_stat_.server_send_all_session_variable_time_); - cells[OB_SSA_SERVER_SEND_LAST_INSERT_ID_TIME].set_int(record.cmd_time_stat_.server_send_last_insert_id_time_); cells[OB_SSA_SERVER_SEND_START_TRANS_TIME].set_int(record.cmd_time_stat_.server_send_start_trans_time_); + cells[OB_SSA_SERVER_SEND_XA_START_TIME].set_int(record.cmd_time_stat_.server_send_xa_start_time_); cells[OB_SSA_BUILD_SERVER_REQUEST_TIME].set_int(record.cmd_time_stat_.build_server_request_time_); cells[OB_SSA_PLUGIN_COMPRESS_REQUEST_TIME].set_int(record.cmd_time_stat_.plugin_compress_request_time_); cells[OB_SSA_PLUGIN_DECOMPRESS_RESPONSE_TIME].set_int(record.cmd_time_stat_.plugin_decompress_response_time_); diff --git a/src/obproxy/cmd/ob_show_topology_handler.cpp b/src/obproxy/cmd/ob_show_topology_handler.cpp index 76100493..341ee436 100644 --- a/src/obproxy/cmd/ob_show_topology_handler.cpp +++ b/src/obproxy/cmd/ob_show_topology_handler.cpp @@ -13,8 +13,8 @@ #define USING_LOG_PREFIX PROXY_CMD #include "cmd/ob_show_topology_handler.h" -#include "iocore/eventsystem/ob_event_processor.h" #include "dbconfig/ob_proxy_db_config_info.h" +#include "iocore/eventsystem/ob_event_processor.h" #include "lib/string/ob_sql_string.h" using namespace oceanbase::common; @@ -45,17 +45,38 @@ static const EMySQLFieldType column_type[OB_TC_MAX_COLUMN_ID] = { OB_MYSQL_TYPE_LONG }; +//TopologyColumnID for sharding +enum +{ + OB_TC_ID = 0, + OB_TC_GROUP_NAME, + OB_TC_TABLE_NAME, + OB_TC_SCHEMA_TYPE, + OB_TC_SHARD_KEY, + OB_TC_SHARD_RULE, + OB_TC_SHARD_MAX_COLUMN_ID, +}; + +const ObProxyColumnSchema SHOW_TOPOLOGY_ARRAY[OB_TC_SHARD_MAX_COLUMN_ID] = { + ObProxyColumnSchema::make_schema(OB_TC_ID, "id", OB_MYSQL_TYPE_LONG), + ObProxyColumnSchema::make_schema(OB_TC_GROUP_NAME, "group_name", OB_MYSQL_TYPE_VARCHAR), + ObProxyColumnSchema::make_schema(OB_TC_TABLE_NAME, "table_name", OB_MYSQL_TYPE_VARCHAR), + ObProxyColumnSchema::make_schema(OB_TC_SCHEMA_TYPE, "schema_type", OB_MYSQL_TYPE_VARCHAR), + ObProxyColumnSchema::make_schema(OB_TC_SHARD_KEY, "shard_key", OB_MYSQL_TYPE_VARCHAR), + ObProxyColumnSchema::make_schema(OB_TC_SHARD_RULE, "shard_rule", OB_MYSQL_TYPE_VARCHAR), +}; + ObShowTopologyHandler::ObShowTopologyHandler(ObMIOBuffer *buf, ObCmdInfo &info) : ObCmdHandler(buf, info) { } -int ObShowTopologyHandler::handle_show_topology(const ObString &tenant_name, - const ObString &db_name, - const ObString &group_name) +int ObShowTopologyHandler::handle_show_elastic_id(const ObString &tenant_name, + const ObString &db_name, + const ObString &group_name) { int ret = OB_SUCCESS; - if (OB_FAIL(dump_topology_header())) { + if (OB_FAIL(dump_elastic_id_header())) { WARN_CMD("fail to dump_header", K(ret)); } else { ObDbConfigCache &dbconfig_cache = get_global_dbconfig_cache(); @@ -144,7 +165,7 @@ int ObShowTopologyHandler::dump_elastic_id(const int64_t eid) return ret; } -int ObShowTopologyHandler::dump_topology_header() +int ObShowTopologyHandler::dump_elastic_id_header() { int ret = OB_SUCCESS; if (OB_FAIL(encode_header(column_name, column_type, OB_TC_MAX_COLUMN_ID))) { @@ -153,7 +174,7 @@ int ObShowTopologyHandler::dump_topology_header() return ret; } -int ObShowTopologyHandler::show_topology_cmd_callback(ObMIOBuffer *buf, +int ObShowTopologyHandler::show_elastic_id_cmd_callback(ObMIOBuffer *buf, ObCmdInfo &info, const ObString &logic_tenant_name, const ObString &logic_database_name, @@ -167,7 +188,7 @@ int ObShowTopologyHandler::show_topology_cmd_callback(ObMIOBuffer *buf, ERROR_CMD("fail to new ObShowTopologyHandler", K(ret)); } else if (OB_FAIL(handler->init())) { WARN_CMD("fail to init for ObShowTopologyHandler"); - } else if (OB_FAIL(handler->handle_show_topology(logic_tenant_name, logic_database_name, group_name))){ + } else if (OB_FAIL(handler->handle_show_elastic_id(logic_tenant_name, logic_database_name, group_name))){ WARN_CMD("fail to handle show topology", K(logic_tenant_name), K(logic_database_name), K(group_name), K(ret)); } @@ -178,6 +199,255 @@ int ObShowTopologyHandler::show_topology_cmd_callback(ObMIOBuffer *buf, return ret; } + +int ObShowTopologyHandler::show_topology_cmd_callback(ObMIOBuffer *buf, + ObCmdInfo &info, + const ObString &logic_tenant_name, + const ObString &logic_database_name, + const ObString &table_name) +{ + int ret = OB_SUCCESS; + ObShowTopologyHandler *handler = NULL; + + if (OB_ISNULL(handler = new(std::nothrow) ObShowTopologyHandler(buf, info))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + ERROR_CMD("fail to new ObShowTopologyHandler", K(ret)); + } else if (OB_FAIL(handler->init())) { + WARN_CMD("fail to init for ObShowTopologyHandler"); + } else if (OB_FAIL(handler->handle_show_topology(logic_tenant_name, logic_database_name, table_name))){ + WARN_CMD("fail to handle show topology", K(logic_tenant_name), K(logic_database_name), K(ret)); + } + + if (OB_LIKELY(NULL != handler)) { + delete handler; + handler = NULL; + } + return ret; +} + +int ObShowTopologyHandler::handle_show_topology(const ObString &tenant_name, + const ObString &db_name, + const ObString &table_name) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(encode_header(SHOW_TOPOLOGY_ARRAY, OB_TC_SHARD_MAX_COLUMN_ID))) { + WARN_CMD("fail to dump_header", K(ret)); + } else { + ObDbConfigCache &dbconfig_cache = get_global_dbconfig_cache(); + ObDbConfigLogicDb *db_info = NULL; + ObShardRule *shard_rule = NULL; + if (OB_ISNULL(db_info = dbconfig_cache.get_exist_db_info(tenant_name, db_name))) { + ret = OB_ERR_BAD_DATABASE; + WARN_CMD("logic database not exist", K(tenant_name), K(db_name), K(ret)); + } else if (OB_UNLIKELY(db_info->is_single_shard_db_table())) { + if (OB_FAIL(dump_shard_topology_for_single_db(table_name))) { + WARN_CMD("fail to encode topology packet for single db", K(tenant_name), K(db_name), K(ret)); + } + } else if (OB_FAIL(db_info->get_shard_rule(shard_rule, table_name))) { + // no logic table + ret = OB_TABLE_NOT_EXIST; + } else if (OB_UNLIKELY((1 == shard_rule->db_size_) && (1 == shard_rule->tb_size_))) { + if (OB_FAIL(dump_shard_topology_for_shard_db_single_tb(table_name))) { + WARN_CMD("fail to encode topology packet for shard_db_single_tb", K(tenant_name), K(db_name), K(shard_rule->db_size_), K(shard_rule->tb_size_), K(ret)); + } + } else if (OB_UNLIKELY(1 == shard_rule->tb_size_)) { + if (OB_FAIL(dump_shard_topology_for_shard_db_non_shard_tb(table_name, shard_rule))) { + WARN_CMD("fail to encode topology packet for shard_db_non_shard_tb", K(tenant_name), K(db_name), K(shard_rule->db_size_), K(shard_rule->tb_size_), K(ret)); + } + } else { + if (OB_FAIL(dump_shard_topology_for_shard_db_shard_tb(shard_rule))) { + WARN_CMD("fail to encode topology packet for shard_db_shard_tb", K(tenant_name), K(db_name), K(shard_rule->db_size_), K(shard_rule->tb_size_), K(ret)); + } + } + + if (NULL != db_info) { + db_info->dec_ref(); + db_info = NULL; + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(encode_eof_packet())) { + WARN_CMD("fail to encode eof packet", K(ret)); + } + } + + if (OB_FAIL(ret)) { + if (OB_FAIL(encode_err_packet(ret))) { + WARN_CMD("fail to encode internal err packet, callback", K(ret)); + } else { + INFO_CMD("succ to encode internal err packet, callback"); + ret = OB_SUCCESS; + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(fill_external_buf())) { + WARN_CMD("fail to fill_external_buf", K(ret)); + } + } + return ret; +} + +int ObShowTopologyHandler::dump_shard_topology_for_single_db(ObString table_name) +{ + int ret = OB_SUCCESS; + ObNewRow row; + ObObj cells[OB_TC_SHARD_MAX_COLUMN_ID]; + cells[OB_TC_ID].set_int(0); + cells[OB_TC_GROUP_NAME].set_varchar("group_00"); + cells[OB_TC_TABLE_NAME].set_varchar(table_name); + cells[OB_TC_SCHEMA_TYPE].set_varchar("SINGLE"); + cells[OB_TC_SHARD_KEY].set_null(); + cells[OB_TC_SHARD_RULE].set_null(); + row.cells_ = cells; + row.count_ = OB_TC_SHARD_MAX_COLUMN_ID; + if (OB_FAIL(encode_row_packet(row))) { + WARN_CMD("fail to encode row packet for shard", K(row), K(ret)); + } + return ret; +} + +int ObShowTopologyHandler::dump_shard_topology_for_shard_db_single_tb(ObString table_name) +{ + int ret = OB_SUCCESS; + ObNewRow row; + ObObj cells[OB_TC_SHARD_MAX_COLUMN_ID]; + cells[OB_TC_ID].set_int(0); + cells[OB_TC_GROUP_NAME].set_varchar("group_00"); + cells[OB_TC_TABLE_NAME].set_varchar(table_name); + cells[OB_TC_SCHEMA_TYPE].set_varchar("SHARD"); + cells[OB_TC_SHARD_KEY].set_null(); + cells[OB_TC_SHARD_RULE].set_null(); + row.cells_ = cells; + row.count_ = OB_TC_SHARD_MAX_COLUMN_ID; + if (OB_FAIL(encode_row_packet(row))) { + WARN_CMD("fail to encode row packet for shard", K(row), K(ret)); + } + return ret; +} + +int ObShowTopologyHandler::dump_shard_topology_for_shard_db_non_shard_tb(ObString table_name, ObShardRule *shard_rule) +{ + int ret = OB_SUCCESS; + ObNewRow row; + ObObj cells[OB_TC_SHARD_MAX_COLUMN_ID]; + int size = OB_TC_SHARD_MAX_COLUMN_ID; + ObString real_group_name; + ObString real_table_name = table_name; + char group_name_buf[OB_MAX_TABLEGROUP_NAME_LENGTH]; + ObString schema_type("SHARD"); + char shard_key_buf[OB_MAX_COLUMN_NAME_LENGTH]; + ObString shard_key_str = get_shard_key_str(*shard_rule, shard_key_buf, OB_MAX_COLUMN_NAME_LENGTH); + ObString shard_rule_str = get_shard_rule_str(*shard_rule); + + int64_t count = shard_rule->db_size_; + for(int64_t index = 0; index < count; ++index) { + int64_t group_index = index; + shard_rule->get_real_name_by_index(shard_rule->db_size_, + shard_rule->db_suffix_len_, group_index, + shard_rule->db_prefix_.config_string_, + shard_rule->db_tail_.config_string_, + group_name_buf, OB_MAX_TABLEGROUP_NAME_LENGTH); + real_group_name = ObString::make_string(group_name_buf); + cells[OB_TC_ID].set_int(index); + cells[OB_TC_GROUP_NAME].set_varchar(real_group_name); + cells[OB_TC_TABLE_NAME].set_varchar(real_table_name); + cells[OB_TC_SCHEMA_TYPE].set_varchar(schema_type); + cells[OB_TC_SHARD_KEY].set_varchar(shard_key_str); + cells[OB_TC_SHARD_RULE].set_varchar(shard_rule_str); + row.cells_ = cells; + row.count_ = size; + if (OB_FAIL(encode_row_packet(row))) { + WARN_CMD("fail to encode row packet for shard", K(row), K(ret)); + } + } + return ret; +} + +int ObShowTopologyHandler::dump_shard_topology_for_shard_db_shard_tb(ObShardRule *shard_rule) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY((0 == shard_rule->db_size_) || (shard_rule->tb_size_ < shard_rule->db_size_))) { + WARN_CMD("wrong shard rule for shard_db_shard_tb", K(shard_rule->db_size_), K(shard_rule->tb_size_), K(ret)); + } else { + ObNewRow row; + ObObj cells[OB_TC_SHARD_MAX_COLUMN_ID]; + int size = OB_TC_SHARD_MAX_COLUMN_ID; + ObString real_group_name; + ObString real_table_name; + char group_name_buf[OB_MAX_TABLEGROUP_NAME_LENGTH]; + char table_name_buf[OB_MAX_USER_TABLE_NAME_LENGTH]; + char shard_key_buf[OB_MAX_COLUMN_NAME_LENGTH]; + ObString schema_type("SHARD"); + ObString shard_key_str = get_shard_key_str(*shard_rule, shard_key_buf, OB_MAX_COLUMN_NAME_LENGTH); + ObString shard_rule_str = get_shard_rule_str(*shard_rule); + + int64_t count = shard_rule->tb_size_; + for(int64_t index = 0; index < count; ++index) { + int64_t group_index = index / (shard_rule->tb_size_ / shard_rule->db_size_); + shard_rule->get_real_name_by_index(shard_rule->db_size_, + shard_rule->db_suffix_len_, group_index, + shard_rule->db_prefix_.config_string_, + shard_rule->db_tail_.config_string_, + group_name_buf, OB_MAX_TABLEGROUP_NAME_LENGTH); + shard_rule->get_real_name_by_index(shard_rule->tb_size_, + shard_rule->tb_suffix_len_, index, + shard_rule->tb_prefix_.config_string_, + shard_rule->tb_tail_.config_string_, + table_name_buf, OB_MAX_USER_TABLE_NAME_LENGTH); + real_group_name = ObString::make_string(group_name_buf); + real_table_name = ObString::make_string(table_name_buf); + cells[OB_TC_ID].set_int(index); + cells[OB_TC_GROUP_NAME].set_varchar(real_group_name); + cells[OB_TC_TABLE_NAME].set_varchar(real_table_name); + cells[OB_TC_SCHEMA_TYPE].set_varchar(schema_type); + cells[OB_TC_SHARD_KEY].set_varchar(shard_key_str); + cells[OB_TC_SHARD_RULE].set_varchar(shard_rule_str); + row.cells_ = cells; + row.count_ = size; + if (OB_FAIL(encode_row_packet(row))) { + WARN_CMD("fail to encode row packet for shard", K(row), K(ret)); + } + } + } + return ret; +} + +ObString ObShowTopologyHandler::get_shard_key_str(dbconfig::ObShardRule& shard_rule, char* const target_buf, const int target_buf_len) +{ + ObString ret_str = ObString::make_string("empty shard key"); + if (OB_LIKELY(0 != shard_rule.tb_rules_.count())) { + ObString& origin_string = shard_rule.tb_rules_.at(0).shard_rule_str_.config_string_; + for(int i = 0; i < origin_string.length(); ++i) { + if(origin_string[i] != '#') { + continue; + } else { + int j = i + 1; + while(j < origin_string.length() && origin_string[j] != '#') { + ++j; + } + if((j == origin_string.length()) || (j - i - 1) >= target_buf_len) { + ret_str = ObString::make_string("error shard key"); + } else { + MEMCPY(target_buf, origin_string.ptr() + i + 1, j - i - 1); + ret_str.assign_ptr(target_buf, j - i - 1); + } + break; + } + } + } + return ret_str; +} + +ObString ObShowTopologyHandler::get_shard_rule_str(dbconfig::ObShardRule& shard_rule) +{ + ObString ret_str = ObString::make_string("empty shard rule"); + if (OB_LIKELY(0 != shard_rule.tb_rules_.count())) { + ret_str = shard_rule.tb_rules_.at(0).shard_rule_str_.config_string_; + } + return ret_str; +} } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/cmd/ob_show_topology_handler.h b/src/obproxy/cmd/ob_show_topology_handler.h index b250c563..0cb0c667 100644 --- a/src/obproxy/cmd/ob_show_topology_handler.h +++ b/src/obproxy/cmd/ob_show_topology_handler.h @@ -22,7 +22,9 @@ namespace obproxy namespace dbconfig { class ObGroupCluster; +class ObShardRule; } + namespace obutils { class ObShowTopologyHandler : public ObCmdHandler @@ -31,22 +33,37 @@ class ObShowTopologyHandler : public ObCmdHandler ObShowTopologyHandler(event::ObMIOBuffer *buf, ObCmdInfo &info); virtual ~ObShowTopologyHandler() {} + int handle_show_elastic_id(const common::ObString &tenant_name, + const common::ObString &db_name, + const common::ObString &group_name); + static int show_elastic_id_cmd_callback(event::ObMIOBuffer *buf, + ObCmdInfo &info, + const common::ObString &logic_tenant_name, + const common::ObString &logic_database_name, + const common::ObString &group_name); int handle_show_topology(const common::ObString &tenant_name, const common::ObString &db_name, - const common::ObString &group_name); + const common::ObString &table_name); static int show_topology_cmd_callback(event::ObMIOBuffer *buf, ObCmdInfo &info, const common::ObString &logic_tenant_name, const common::ObString &logic_database_name, - const common::ObString &group_name); + const common::ObString &table_name); public: static const int64_t OB_MAX_ELASTIC_ID_COUNT = 256; private: - int dump_topology_header(); + int dump_elastic_id_header(); int dump_elastic_id(const int64_t eid); + int dump_shard_topology_for_single_db(ObString table_name); + int dump_shard_topology_for_shard_db_single_tb(ObString table_name); + int dump_shard_topology_for_shard_db_non_shard_tb(ObString table_name, dbconfig::ObShardRule *shard_rule); + int dump_shard_topology_for_shard_db_shard_tb(dbconfig::ObShardRule *shard_rule); + + ObString get_shard_key_str(dbconfig::ObShardRule& shard_rule, char* const target_buf, const int target_buf_len); + ObString get_shard_rule_str(dbconfig::ObShardRule& shard_rule); private: DISALLOW_COPY_AND_ASSIGN(ObShowTopologyHandler); }; diff --git a/src/obproxy/cmd/ob_show_vip_handler.cpp b/src/obproxy/cmd/ob_show_vip_handler.cpp index 54921222..2574107e 100644 --- a/src/obproxy/cmd/ob_show_vip_handler.cpp +++ b/src/obproxy/cmd/ob_show_vip_handler.cpp @@ -16,6 +16,8 @@ #include "utils/ob_proxy_utils.h" #include "iocore/eventsystem/ob_task.h" #include "iocore/eventsystem/ob_event_processor.h" +#include "share/config/ob_config.h" +#include "obutils/ob_config_processor.h" using namespace oceanbase::common; using namespace oceanbase::share; @@ -68,7 +70,6 @@ int ObShowVipHandler::main_handler(int event, void *data) } else if (OB_FAIL(dump_header())) { WARN_ICMD("fail to dump header", K(ret)); } else { - ObVipTenantCache &vt_cache = get_global_vip_tenant_processor().get_vt_cache(); ObVipTenant vip_tenant; if (!like_name_.empty()) { //dump one vip tenant @@ -87,9 +88,9 @@ int ObShowVipHandler::main_handler(int event, void *data) WARN_ICMD("unexpected argument", K(vip_string), K(match_name), K(ret)); } else if (OB_FAIL(get_int_value(match_name, vport))) { WARN_ICMD("fail to get_int_value", K(match_name), K(vport), K(ret)); - } else if (!vip_addr.addr_.set_ipv4_addr(vip_string, static_cast(vport))) { + } else if (!vip_addr.addr_.set_ip_addr(vip_string, static_cast(vport))) { ret = OB_INVALID_ARGUMENT; - WARN_ICMD("fail to set_ipv4_addr", K(vip_string), K(vport), K(ret)); + WARN_ICMD("fail to set_ip_addr", K(vip_string), K(vport), K(ret)); } else if (!vip_addr.is_valid()) { ret = OB_INVALID_ARGUMENT; WARN_ICMD("invalid vip_addr", K(vip_addr), K(match_name), K(ret)); @@ -99,32 +100,38 @@ int ObShowVipHandler::main_handler(int event, void *data) } if (OB_SUCC(ret)) { - if (OB_FAIL(vt_cache.get(vip_addr, vip_tenant))) { - WARN_ICMD("fail to get vip_tenant", K(ret)); - if (OB_ENTRY_NOT_EXIST == ret) { - //empty result - ret = OB_SUCCESS; + ObConfigItem tenant_item; + ObConfigItem cluster_item; + bool found = false; + vip_tenant.vip_addr_ = vip_addr; + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + vip_tenant.vip_addr_, "", "", "proxy_tenant_name", tenant_item, "LEVEL_VIP", found))) { + WARN_ICMD("get proxy tenant name config failed", K(vip_tenant.vip_addr_), K(ret)); + } + if (OB_SUCC(ret) && found) { + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + vip_tenant.vip_addr_, "", "", "rootservice_cluster_name", cluster_item, "LEVEL_VIP", found))) { + WARN_ICMD("get cluster name config failed", K(vip_tenant.vip_addr_), K(ret)); + } + } + if (OB_SUCC(ret) && found) { + if (OB_FAIL(vip_tenant.set_tenant_cluster(tenant_item.str(), cluster_item.str()))) { + WARN_ICMD("set tenant and cluster name failed", K(tenant_item), K(cluster_item), K(ret)); + } else if (OB_FAIL(dump_item(vip_tenant))) { + WARN_ICMD("fail to dump item", K(vip_tenant), K(ret)); } - } else if (OB_FAIL(dump_item(vip_tenant))) { - WARN_ICMD("fail to dump item", K(vip_tenant), K(ret)); + } else { + WARN_ICMD("fail to get vip_tenant", K(ret)); } } else { ret = OB_ERR_OPERATOR_UNKNOWN;//return this errno } } else { //dump all vip tenant - ObVipTenantCache::VTHashMap *cache_map = NULL; - obsys::CRLockGuard guard(vt_cache.rwlock_); - if (OB_ISNULL(cache_map = vt_cache.get_cache_map())) { - ret = OB_ERR_UNEXPECTED; - WARN_ICMD("cache_map is null", K(ret)); - } else { - for (ObVipTenantCache::VTHashMap::iterator it = cache_map->begin(); - OB_SUCC(ret) && it != cache_map->end(); ++it) { - if (OB_FAIL(dump_item(*it))) { - WARN_ICMD("fail to dump item", K(*it), K(ret)); - } - } + const char* select_sql = "SELECT a.vid, a.vip, a.vport, a.value, b.value FROM proxy_config as a, proxy_config as b " + "where a.name = 'proxy_tenant_nane' and b.name = 'rootservice_cluster_name';"; + if (get_global_config_processor().execute(select_sql, ObShowVipHandler::sqlite3_callback, this)) { + WARN_ICMD("fail to execute sql", K(ret)); } } } @@ -180,6 +187,40 @@ int ObShowVipHandler::dump_item(const ObVipTenant &vip_tenant) return ret; } +int ObShowVipHandler::sqlite3_callback(void *data, int argc, char **argv, char **column_name) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(NULL == data || NULL == argv || NULL == column_name || 5 != argc)) { + ret = OB_ERR_UNEXPECTED; + WARN_ICMD("argument is unexpected", K(argc), K(ret)); + } else { + ObShowVipHandler *handler = reinterpret_cast(data); + char* vip; + int64_t vport = 0; + int64_t vid = -1; + ObVipTenant vip_tenant; + ObString tenant; + ObString cluster; + if (OB_UNLIKELY(NULL == argv[0] || NULL == argv[1] || NULL == argv[2] || NULL == argv[3] || NULL == argv[4])) { + ret = OB_ERR_UNEXPECTED; + WARN_ICMD("argument is unexpected", K(ret)); + } else { + vid = atoi(argv[0]); + vip = argv[1]; + vport = atoi(argv[2]); + tenant = argv[3]; + cluster = argv[4]; + vip_tenant.vip_addr_.set(vip, static_cast(vport), vid); + if (OB_FAIL(vip_tenant.set_tenant_cluster(tenant, cluster))) { + WARN_ICMD("fail to set tenant cluster", K(vip_tenant), K(ret)); + } else if (OB_FAIL(handler->dump_item(vip_tenant))) { + WARN_ICMD("fail to dump item", K(vip_tenant), K(ret)); + } + } + } + return ret; +} + static int show_vip_cmd_callback(ObContinuation *cont, ObInternalCmdInfo &info, ObMIOBuffer *buf, ObAction *&action) { diff --git a/src/obproxy/cmd/ob_show_vip_handler.h b/src/obproxy/cmd/ob_show_vip_handler.h index b02c9084..07f60b49 100644 --- a/src/obproxy/cmd/ob_show_vip_handler.h +++ b/src/obproxy/cmd/ob_show_vip_handler.h @@ -25,7 +25,8 @@ namespace obutils class ObShowVipHandler : public ObInternalCmdHandler { public: - ObShowVipHandler(event::ObContinuation *cont, event::ObMIOBuffer *buf, const ObInternalCmdInfo &info); + ObShowVipHandler(event::ObContinuation *cont, event::ObMIOBuffer *buf, + const ObInternalCmdInfo &info); virtual ~ObShowVipHandler() {} int main_handler(int event, void *data); @@ -33,6 +34,7 @@ class ObShowVipHandler : public ObInternalCmdHandler int dump_header(); int dump_body(); int dump_item(const ObVipTenant &vip_tenant); + static int sqlite3_callback(void *data, int argc, char **argv, char **column_name); DISALLOW_COPY_AND_ASSIGN(ObShowVipHandler); }; diff --git a/src/obproxy/dbconfig/grpc/ob_proxy_grpc_client.cpp b/src/obproxy/dbconfig/grpc/ob_proxy_grpc_client.cpp index 0aa658bb..d2fdaf1d 100644 --- a/src/obproxy/dbconfig/grpc/ob_proxy_grpc_client.cpp +++ b/src/obproxy/dbconfig/grpc/ob_proxy_grpc_client.cpp @@ -156,15 +156,15 @@ int ObGrpcClient::fill_request_node(DiscoveryRequest &request) const char *is_sidecar = getenv("IS_SIDECAR"); if (OB_NOT_NULL(is_sidecar) && OB_UNLIKELY(strncmp(is_sidecar, "false", strlen(is_sidecar)) == 0)) {// app is not in sidecar - char ipstr[OB_IP_STR_BUFF]; - MEMSET(ipstr, 0, OB_IP_STR_BUFF); + char ipstr[MAX_IP_ADDR_LENGTH]; + MEMSET(ipstr, 0, MAX_IP_ADDR_LENGTH); ObSEArray labels; char json[MAX_REQUEST_LABELS_LENGTH]; MEMSET(json, 0, sizeof(json)); - if (OB_FAIL(getip_from_nodeid(ipstr, OB_IP_STR_BUFF))) { + if (OB_FAIL(getip_from_nodeid(ipstr, MAX_IP_ADDR_LENGTH))) { LOG_WARN("can not get ip from node id", K(ret)); } else if (OB_UNLIKELY(strlen(ipstr) == 0)) { ret = OB_ERR_UNEXPECTED; @@ -227,7 +227,7 @@ int ObGrpcClient::getip_from_nodeid(char *ipstr, int64_t length) if (OB_SUCC(ret)) { if (OB_UNLIKELY(length < ip.length())) { ret = OB_SIZE_OVERFLOW; - LOG_WARN("IP string in node id is longer than OB_IP_STR_BUFF", K(length), K(ip.length()), K(ret)); + LOG_WARN("IP string in node id is longer than MAX_IP_ADDR_LENGTH", K(length), K(ip.length()), K(ret)); } else { memcpy(ipstr, ip.ptr(), ip.length()); ipstr[ip.length()] = '\0'; @@ -321,7 +321,17 @@ int ObGrpcClient::to_json(ObIArray& labels, char *json, int bool ObGrpcClient::sync_read(DiscoveryResponse &response) { - return stream_->Read(&response); + bool status = false; + int ret = OB_SUCCESS; + status = stream_->Read(&response); + if (!status) { + LOG_INFO("the stream has been closed, will rebuild the grpc client stream"); + finish_rpc(); + if (OB_FAIL(init_stream())) { + LOG_WARN("fail to init stream", K(ret)); + } + } + return status; } void ObGrpcClient::finish_rpc() diff --git a/src/obproxy/dbconfig/ob_proxy_db_config_info.cpp b/src/obproxy/dbconfig/ob_proxy_db_config_info.cpp index c2e2ac01..be5030c6 100644 --- a/src/obproxy/dbconfig/ob_proxy_db_config_info.cpp +++ b/src/obproxy/dbconfig/ob_proxy_db_config_info.cpp @@ -1636,10 +1636,9 @@ int ObShardRule::get_physic_index(const SqlFieldResult &sql_result, const ObProxyShardRuleInfo &rule = rules.at(i); ObProxyExprCtx expr_ctx(physic_size, type, is_elastic_index, &allocator); ObProxyExpr *proxy_expr = rule.expr_; - ObObj result_obj; ObSEArray result_array; int64_t tmp_index = OBPROXY_MAX_DBMESH_ID; - + int64_t tmp_index_for_one_obj = OBPROXY_MAX_DBMESH_ID; LOG_DEBUG("begin to calc rule", K(rule)); ObProxyExprCalcItem calc_item(const_cast(&sql_result)); @@ -1654,16 +1653,23 @@ int ObShardRule::get_physic_index(const SqlFieldResult &sql_result, LOG_WARN("calc proxy expr failed", K(ret)); } } else { - result_obj = result_array.at(0); - ObObj tmp_obj; - if (OB_FAIL(ObProxyFuncExpr::get_int_obj(result_obj, tmp_obj))) { - LOG_WARN("get int obj failed", K(result_obj), K(ret)); - } else if (OB_FAIL(tmp_obj.get_int(tmp_index))) { - LOG_WARN("get int failed", K(ret)); - } else { - if (tmp_index < 0 || tmp_index >= physic_size) { - ret = OB_EXPR_CALC_ERROR; - LOG_WARN("invalid index", K(tmp_index), K(physic_size), K(ret)); + for(int64_t j = 0; OB_SUCC(ret) && j < result_array.count(); j++) { + ObObj& result_obj = result_array.at(j); + ObObj tmp_obj; + if (OB_FAIL(ObProxyFuncExpr::get_int_obj(result_obj, tmp_obj, allocator))) { + LOG_WARN("get int obj failed", K(result_obj), K(ret)); + } else if (OB_FAIL(tmp_obj.get_int(tmp_index_for_one_obj))) { + LOG_WARN("get int failed", K(ret)); + } else if (tmp_index_for_one_obj < 0 || tmp_index_for_one_obj >= physic_size) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("invalid index", K(tmp_index_for_one_obj), K(physic_size), K(ret)); + } else if (OBPROXY_MAX_DBMESH_ID == tmp_index) { + tmp_index = tmp_index_for_one_obj; + } else if (tmp_index != tmp_index_for_one_obj) { + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + LOG_WARN("different physic index for one sharding key is not supported", K(tmp_index), K(last_index), K(ret)); + } else { + //nothing } } } @@ -1749,7 +1755,7 @@ int ObShardRule::get_physic_index_array(const SqlFieldResult &sql_result, for (int64_t i = 0; OB_SUCC(ret) && i < result_obj_array.count(); i++) { ObObj tmp_obj; int64_t tmp_index; - if (OB_FAIL(ObProxyFuncExpr::get_int_obj(result_obj_array.at(i), tmp_obj))) { + if (OB_FAIL(ObProxyFuncExpr::get_int_obj(result_obj_array.at(i), tmp_obj, allocator))) { LOG_WARN("get int obj failed", K(ret), K(result_obj_array.at(i))); } else if (OB_FAIL(tmp_obj.get_int(tmp_index))) { LOG_WARN("get int failed", K(ret)); @@ -2009,6 +2015,91 @@ int ObDbConfigLogicDb::get_shard_router(const ObString &tb_name, ObShardRouter * return ret; } +int ObDbConfigLogicDb::get_first_group_shard_connector(ObShardConnector *&shard_conn, int64_t es_id, + bool is_read_stmt, ObTestLoadType testload_type) +{ + int ret = OB_SUCCESS; + + ObShardTpo *shard_tpo = NULL; + ObGroupCluster *gc_info = NULL; + + if (OB_FAIL(get_shard_tpo(shard_tpo))) { + LOG_WARN("fail to get shard tpo info", K(ret)); + } else if (OB_ISNULL(shard_tpo)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("shard tpo info is null", K(ret)); + } else if (is_single_shard_db_table()) { + ObShardTpo::GCHashMap::iterator it = (const_cast(shard_tpo->gc_map_)).begin(); + gc_info = &(*it); + } else { + ObShardRule *logic_tb_info = NULL; + { + ObDbConfigCache &dbconfig_cache = get_global_dbconfig_cache(); + obsys::CRLockGuard guard(dbconfig_cache.rwlock_); + ObDbConfigChildArrayInfo::CCRHashMap &map = const_cast::CCRHashMap &>(sr_array_.ccr_map_); + for (ObDbConfigChildArrayInfo::CCRHashMap::iterator it = map.begin(); it != map.end(); ++it) { + ObShardRouter::MarkedRuleHashMap &mr_map = it->mr_map_; + for (ObShardRouter::MarkedRuleHashMap::iterator sub_it = mr_map.begin(); + sub_it != mr_map.end(); ++sub_it) { + logic_tb_info = &(*sub_it); + break; + } + } + } + + if (OB_SUCC(ret)) { + char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; + if (OB_FAIL(logic_tb_info->get_real_name_by_index(logic_tb_info->db_size_, logic_tb_info->db_suffix_len_, 0, + logic_tb_info->db_prefix_.config_string_, + logic_tb_info->db_tail_.config_string_, + real_database_name, OB_MAX_DATABASE_NAME_LENGTH))) { + LOG_WARN("fail to get real group name", KPC(logic_tb_info), K(ret)); + } else if (OB_FAIL(shard_tpo->get_group_cluster(ObString::make_string(real_database_name), gc_info))) { + LOG_DEBUG("group does not exist", "phy_db_name", real_database_name, K(ret)); + } else if (OB_ISNULL(gc_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("group cluster info is null", "phy_db_name", real_database_name, K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + // Calculate es_id + int64_t es_size = gc_info->get_es_size(); + ObString shard_name; + if (-1 == es_id || OBPROXY_MAX_DBMESH_ID == es_id) { + if (OB_FAIL(gc_info->get_elastic_id_by_weight(es_id, is_read_stmt))) { + LOG_WARN("fail to get eid by read weight", KPC(gc_info)); + } else { + LOG_DEBUG("succ to get eid by weight", K(es_id)); + } + } else if (OB_UNLIKELY(es_id >= es_size)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("es index is larger than elastic array", K(es_id), K(es_size), K(ret)); + } + } + + if (OB_SUCC(ret)) { + ObString shard_name; + if (FALSE_IT(shard_name = gc_info->get_shard_name_by_eid(es_id))) { + } else if (TESTLOAD_NON != testload_type) { + if (OB_FAIL(get_testload_shard_connector(shard_name, testload_prefix_.config_string_, shard_conn))) { + LOG_WARN("testload shard connector not exist", "testload_type", get_testload_type_str(testload_type), + K(shard_name), "testload_prefix", testload_prefix_, K(ret)); + } + } else if (OB_FAIL(get_shard_connector(shard_name, shard_conn))) { + LOG_WARN("shard connector does not exist", K(shard_name), K(ret)); + } + } + + if (NULL != shard_tpo) { + shard_tpo->dec_ref(); + shard_tpo = NULL; + } + + return ret; +} + int ObDbConfigLogicDb::get_all_shard_table(ObIArray &all_table) { int ret = OB_SUCCESS; @@ -3729,7 +3820,8 @@ int ObDbConfigLogicDb::get_shard_table_info(const ObString &table_name, char *real_table_name, int64_t tb_name_len, int64_t &group_index, int64_t &tb_index, int64_t &es_index, const ObString &hint_table, ObTestLoadType testload_type, - const bool is_read_stmt) + const bool is_read_stmt, + const int64_t last_es_index /*OBPROXY_MAX_DBMESH_ID*/) { int ret = OB_SUCCESS; @@ -3766,7 +3858,12 @@ int ObDbConfigLogicDb::get_shard_table_info(const ObString &table_name, bool is_elastic_index = true; ObString shard_name; if (-1 == es_index || (OBPROXY_MAX_DBMESH_ID == es_index && logic_tb_info->es_rules_.empty())) { - if (OB_FAIL(gc_info->get_elastic_id_by_weight(es_index, is_read_stmt))) { + if (is_read_stmt + && (last_es_index >= 0) + && (last_es_index < es_size)) { + //In multiple statements, the read request can use the effective es id of the previous statement + es_index = last_es_index; + } else if (OB_FAIL(gc_info->get_elastic_id_by_weight(es_index, is_read_stmt))) { LOG_WARN("fail to get eid by read weight", KPC(gc_info)); } else { LOG_DEBUG("succ to get eid by weight", K(es_index)); @@ -3850,7 +3947,7 @@ int ObDbConfigLogicDb::get_single_table_info(const ObString &table_name, char *real_table_name, int64_t tb_name_len, int64_t &group_id, int64_t &table_id, int64_t &es_id, const ObString &hint_table, ObTestLoadType testload_type, - const bool is_read_stmt) + const bool is_read_stmt, const int64_t last_es_id/*OBPROXY_MAX_DBMESH_ID*/) { int ret = OB_SUCCESS; @@ -3871,7 +3968,12 @@ int ObDbConfigLogicDb::get_single_table_info(const ObString &table_name, const ObGroupCluster &gc_info = *it; int64_t es_size = gc_info.get_es_size(); if (es_id < 0 || OBPROXY_MAX_DBMESH_ID == es_id) { - if (OB_FAIL(gc_info.get_elastic_id_by_weight(es_id, is_read_stmt))) { + if (is_read_stmt + && (last_es_id >= 0) + && (last_es_id < es_size)) { + //In multiple statements, the read request can use the effective es id of the previous statement + es_id = last_es_id; + } if (OB_FAIL(gc_info.get_elastic_id_by_weight(es_id, is_read_stmt))) { LOG_WARN("fail to get random eid", K(gc_info)); } } else if (OB_UNLIKELY(es_id >= es_size)) { @@ -4557,8 +4659,8 @@ int ObDbConfigLogicDb::get_table_name_by_index(ObSqlParseResult &parse_result, { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(parse_result.get_proxy_stmt()); - ObProxySelectStmt::ExprMap &table_exprs_map = select_stmt->get_table_exprs_map(); + ObProxyDMLStmt *dml_stmt = static_cast(parse_result.get_proxy_stmt()); + ObProxyDMLStmt::ExprMap &table_exprs_map = dml_stmt->get_table_exprs_map(); SqlFieldResult &sql_result = parse_result.get_sql_filed_result(); char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; @@ -4570,8 +4672,8 @@ int ObDbConfigLogicDb::get_table_name_by_index(ObSqlParseResult &parse_result, for (int64_t i = 0; OB_SUCC(ret) && i < table_index_array.count(); i++) { int64_t tb_index = table_index_array.at(i); - ObProxySelectStmt::ExprMap::iterator iter = table_exprs_map.begin(); - ObProxySelectStmt::ExprMap::iterator end = table_exprs_map.end(); + ObProxyDMLStmt::ExprMap::iterator iter = table_exprs_map.begin(); + ObProxyDMLStmt::ExprMap::iterator end = table_exprs_map.end(); table_name_map_wrapper.reuse(); for (; OB_SUCC(ret) && iter != end; iter++) { diff --git a/src/obproxy/dbconfig/ob_proxy_db_config_info.h b/src/obproxy/dbconfig/ob_proxy_db_config_info.h index 7465e7e4..faf21f07 100644 --- a/src/obproxy/dbconfig/ob_proxy_db_config_info.h +++ b/src/obproxy/dbconfig/ob_proxy_db_config_info.h @@ -936,7 +936,8 @@ class ObDbConfigLogicDb : public ObDbConfigChild char *real_table_name, int64_t tb_name_len, int64_t &group_id, int64_t &table_id, int64_t &es_id, const common::ObString &hint_table, - ObTestLoadType testload_type, const bool is_read_stmt); + ObTestLoadType testload_type, const bool is_read_stmt, + const int64_t last_es_id = OBPROXY_MAX_DBMESH_ID); int get_shard_table_info(const common::ObString &table_name, obutils::SqlFieldResult &sql_result, ObShardConnector *&shard_conn, @@ -944,7 +945,8 @@ class ObDbConfigLogicDb : public ObDbConfigChild char *real_table_name, int64_t tb_name_len, int64_t &group_index, int64_t &tb_index, int64_t &es_index, const common::ObString &hint_table, - ObTestLoadType testload_type, const bool is_read_stmt); + ObTestLoadType testload_type, const bool is_read_stmt, + const int64_t last_es_index = OBPROXY_MAX_DBMESH_ID); int get_shard_prop(const common::ObString & shard_name, ObShardProp* &shard_prop); int get_real_table_name(const ObString &table_name, obutils::SqlFieldResult &sql_result, @@ -968,6 +970,8 @@ class ObDbConfigLogicDb : public ObDbConfigChild int64_t es_index, common::ObIArray &group_index_array, common::ObIArray &shard_connector_array); + int get_first_group_shard_connector(ObShardConnector *&shard_conn, int64_t es_id, + bool is_read_stmt, ObTestLoadType testload_type); int get_table_name_by_index(obutils::ObSqlParseResult &parse_result, ObTestLoadType testload_type, ObIAllocator &allocator, diff --git a/src/obproxy/driver/c/Makemodule.am b/src/obproxy/driver/c/Makemodule.am new file mode 100644 index 00000000..ffb8c232 --- /dev/null +++ b/src/obproxy/driver/c/Makemodule.am @@ -0,0 +1,3 @@ +obproxy_c_driver_sources:=\ +obproxy/driver/c/ob_proxy_vc_c.h\ +obproxy/driver/c/ob_proxy_vc_c.cpp \ No newline at end of file diff --git a/src/obproxy/driver/c/ob_proxy_vc_c.cpp b/src/obproxy/driver/c/ob_proxy_vc_c.cpp new file mode 100644 index 00000000..b5d8e17f --- /dev/null +++ b/src/obproxy/driver/c/ob_proxy_vc_c.cpp @@ -0,0 +1,231 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#include "ob_proxy_vc_c.h" +#include "proxy/client/ob_driver_client.h" +#include "ob_proxy_init.h" +#include "lib/oblog/ob_log.h" +#include "lib/objectpool/ob_concurrency_objpool.h" + +#include + +using namespace oceanbase::common; +using namespace oceanbase::obproxy; +using namespace oceanbase::obproxy::proxy; + +int ob_proxy_vc_c_init(const char *config, void **p_driver_client) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client = NULL; + + if (OB_ISNULL(config) || OB_ISNULL(p_driver_client)) { + ret = OB_INVALID_ARGUMENT; + MPRINT("invalid argument config=%p, p_driver_client=%p, ret=%d", config, p_driver_client, ret); + } else if (OB_FAIL(init_obproxy_client(config))) { + MPRINT("init obproxy client failed, ret=%d", ret); + } else if (OB_ISNULL(driver_client = new(std::nothrow) ObDriverClient())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client is null unexpected", K(ret)); + } else if (OB_FAIL(driver_client->init())) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client init failed", K(ret)); + } else { + *p_driver_client = static_cast(driver_client); + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "create driver_client success", KP(driver_client)); + } + + if(OB_FAIL(ret) && OB_NOT_NULL(driver_client)) { + delete driver_client; + } + + return ret; +} + +int ob_proxy_vc_c_connect(void *driver_client_handle, int64_t conn_timeout, int64_t sock_timeout) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client; + + if (OB_ISNULL(driver_client_handle) || conn_timeout < 0 || sock_timeout < 0) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(conn_timeout), K(sock_timeout), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + driver_client->set_connect_timeout(conn_timeout); + + if (conn_timeout == 0 && OB_FAIL(driver_client->sync_connect())) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client connect failed", K(ret)); + } else if (conn_timeout > 0 && OB_FAIL(driver_client->sync_connect_with_timeout())) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client connect with timeout failed", K(conn_timeout), K(ret)); + } else { + driver_client->set_send_timeout(sock_timeout); + driver_client->set_recv_timeout(sock_timeout); + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "driver client connect success", K(driver_client)); + } + } + + return ret; +} + +int ob_proxy_vc_c_recv(void *driver_client_handle, char *buffer, int64_t offset, int64_t mlen, int64_t *recv_len, int64_t flag) +{ + int ret = OB_SUCCESS; + int64_t rlen = 0; + ObDriverClient *driver_client; + UNUSED(flag); + + if (OB_ISNULL(driver_client_handle) || OB_ISNULL(buffer) || OB_ISNULL(recv_len)) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(buffer), K(recv_len), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + if (OB_FAIL(driver_client->sync_recv_with_timeout(buffer + offset, mlen, rlen))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "sync recv failed", K(ret)); + } else { + if (rlen < 0) { + switch (errno) { + case ECONNRESET: + case EPIPE: + OBPROXY_DRIVER_CLIENT_LOG(WARN, "Connection reset", "errno", errno); + break; + case EBADF: + OBPROXY_DRIVER_CLIENT_LOG(WARN, "Socket closed", "errno", errno); + break; + case EINTR: + OBPROXY_DRIVER_CLIENT_LOG(WARN, "Operation interrupted", "errno", errno); + break; + default: + OBPROXY_DRIVER_CLIENT_LOG(WARN, "socket read error", "errno", errno); + break; + } + ret = OB_ERR_UNEXPECTED; + } else if (rlen == 0) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "peer close", KP(driver_client), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "read success", K(rlen)); + *recv_len = rlen; + } + } + } + + return ret; +} + +int ob_proxy_vc_c_send(void *driver_client_handle, const char *buffer, int64_t offset, int64_t mlen, int64_t *send_len, int64_t flag) +{ + int ret = OB_SUCCESS; + int64_t wlen = 0; + ObDriverClient *driver_client; + UNUSED(flag); + + if (OB_ISNULL(driver_client_handle) || OB_ISNULL(buffer) || OB_ISNULL(send_len)) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(buffer), K(send_len), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + + if (OB_FAIL(driver_client->sync_send_with_timeout(buffer + offset, mlen, wlen))) { + ret = OB_ERR_UNEXPECTED; //send error; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "sync_send_with_timeout failed", K(wlen), K(ret)); + } else { + if (wlen > 0) { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "sync write success", K(wlen)); + *send_len = wlen; + } else { + ret = ob_get_sys_errno(); + if (errno == ECONNRESET) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "wlen is unexpected, connection reset", K(wlen), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "wlen is unexpected, write failed", K(wlen), K(ret)); + } + } + } + } + + return ret; +} + +int ob_proxy_vc_c_close(void *driver_client_handle) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client; + + if (OB_ISNULL(driver_client_handle)) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "free driver client", KP(driver_client_handle)); + driver_client = static_cast(driver_client_handle); + delete driver_client; + driver_client = NULL; + } + + return ret; +} + +int ob_proxy_vc_set_timeout(void *driver_client_handle, int type, int timeout) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client; + const int C_DRIVER_CONNECT_TIMEOUT = 0; + const int C_DRIVER_READ_TIMEOUT = 1; + const int C_DRIVER_WRITE_TIMEOUT = 2; + const int C_DRIVER_TIMEOUT_MAX = 3; + + if (OB_ISNULL(driver_client_handle) || type < 0 || C_DRIVER_TIMEOUT_MAX <= type) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(type), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + + if (C_DRIVER_CONNECT_TIMEOUT == type) { + driver_client->set_connect_timeout(timeout); + } else if (C_DRIVER_READ_TIMEOUT == type) { + driver_client->set_recv_timeout(timeout); + } else if (C_DRIVER_WRITE_TIMEOUT == type) { + driver_client->set_send_timeout(timeout); + } + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "driver client set timeout succ", K(type), K(timeout)); + } + + return ret; +} + +int ob_proxy_vc_get_timeout(void *driver_client_handle, int type, int *timeout) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client; + const int C_DRIVER_CONNECT_TIMEOUT = 0; + const int C_DRIVER_READ_TIMEOUT = 1; + const int C_DRIVER_WRITE_TIMEOUT = 2; + const int C_DRIVER_TIMEOUT_MAX = 3; + + if (OB_ISNULL(driver_client_handle) || OB_ISNULL(timeout) || type < C_DRIVER_CONNECT_TIMEOUT || C_DRIVER_TIMEOUT_MAX <= type) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), KP(timeout), K(type), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + + if (C_DRIVER_CONNECT_TIMEOUT == type) { + *timeout = static_cast(driver_client->get_connect_timeout()); + } else if (C_DRIVER_READ_TIMEOUT == type) { + *timeout = static_cast(driver_client->get_recv_timeout()); + } else if (C_DRIVER_WRITE_TIMEOUT == type) { + *timeout = static_cast(driver_client->get_send_timeout()); + } + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "driver client get timeout succ", K(type), "timeout", *timeout); + } + + return ret; +} \ No newline at end of file diff --git a/src/obproxy/driver/c/ob_proxy_vc_c.h b/src/obproxy/driver/c/ob_proxy_vc_c.h new file mode 100644 index 00000000..80f37d8a --- /dev/null +++ b/src/obproxy/driver/c/ob_proxy_vc_c.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef _OB_OPROXY_VC_C_H +#define _OB_OPROXY_VC_C_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief + * libobclient calls this function to init obproxy and get driver_client handle + * @param config obproxy config string + * @param driver_client point to driver_client handle + * @return int OB_SUCCESS means success and other means failure + */ +int ob_proxy_vc_c_init(const char *config, void **driver_client); + +/** + * @brief + * libobclient calls this function to connect to obproxy + * @param driver_client driver_client handle + * @param conn_timeout connection timeout + * @param sock_timeout socket timeout + * @return int + */ +int ob_proxy_vc_c_connect(void *driver_client, int64_t conn_timeout, int64_t sock_timeout); + +/** + * @brief + * libobclient calls this function to receive data from obproxy + * @param driver_client driver_client handle + * @param buffer receive buffer + * @param offset buffer offset + * @param mlen max receive length + * @param recv_len point to receive length + * @param flag receive flag + * @return int + */ +int ob_proxy_vc_c_recv(void *driver_client, char *buffer, int64_t offset, int64_t mlen, int64_t *recv_len, int64_t flag); + +/** + * @brief + * libobclient calls this function to send data to obproxy + * @param driver_client driver_client handle + * @param buffer send buffer + * @param offset buffer offset + * @param mlen send buffer len + * @param send_len point to send length + * @param flag send flag + * @return int + */ +int ob_proxy_vc_c_send(void *driver_client, const char *buffer, int64_t offset, int64_t mlen, int64_t *send_len, int64_t flag); + +/** + * @brief + * libobclient calls this function to close driver client, but not stop obproxy service + * @param driver_client driver_client handle + * @return int + */ +int ob_proxy_vc_c_close(void *driver_client); + +/** + * @brief + * libobclient calls this function to set timeout + * @param driver_client driver_client handle + * @param type type for timeout + * @param timeout ms + * @return int + */ +int ob_proxy_vc_set_timeout(void *driver_client, int type, int timeout); + +/** + * @brief + * libobclient calls this function to get timeout + * @param driver_client driver_client handle + * @param type type for timeout + * @param timeout ms + * @return int + */ +int ob_proxy_vc_get_timeout(void *driver_client_handle, int type, int *timeout); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /*_OB_OPROXY_VC_JNI_H */ \ No newline at end of file diff --git a/src/obproxy/engine/Makemodule.am b/src/obproxy/engine/Makemodule.am index 75b4e148..44a328eb 100644 --- a/src/obproxy/engine/Makemodule.am +++ b/src/obproxy/engine/Makemodule.am @@ -11,4 +11,6 @@ obproxy/engine/ob_proxy_operator_agg.cpp\ obproxy/engine/ob_proxy_operator_table_scan.h\ obproxy/engine/ob_proxy_operator_table_scan.cpp\ obproxy/engine/ob_proxy_operator_async_task.h\ -obproxy/engine/ob_proxy_operator_async_task.cpp +obproxy/engine/ob_proxy_operator_async_task.cpp\ +obproxy/engine/ob_proxy_operator_cont.h\ +obproxy/engine/ob_proxy_operator_cont.cpp diff --git a/src/obproxy/engine/ob_proxy_operator_agg.cpp b/src/obproxy/engine/ob_proxy_operator_agg.cpp index 959d9f4f..2f3d9f0f 100644 --- a/src/obproxy/engine/ob_proxy_operator_agg.cpp +++ b/src/obproxy/engine/ob_proxy_operator_agg.cpp @@ -604,7 +604,7 @@ int ObProxyStreamAggOp::handle_response_result(void *data, bool &is_final, ObPro ResultRow *row = NULL; while (OB_SUCC(ret) && OB_SUCC(opres->next(row))) { ObProxyGroupUnit group_unit(allocator_); - if (OB_FAIL(group_unit.init(row, group_exprs))) { + if (OB_FAIL(group_unit.init(row, result_fields_, group_exprs))) { LOG_WARN("fail to init group unit", K(ret)); } else if (NULL == current_group_unit_) { if (OB_FAIL(ObProxyGroupUnit::create_group_unit(allocator_, current_group_unit_, group_unit))) { @@ -732,7 +732,7 @@ int ObProxyMemMergeAggOp::handle_response_result(void *data, bool &is_final, ObP while (OB_SUCC(ret) && OB_SUCC(opres->next(row))) { ObProxyGroupUnit group_unit(allocator_); ObProxyGroupUnit *current_group_unit = NULL; - if (OB_FAIL(group_unit.init(row, group_exprs))) { + if (OB_FAIL(group_unit.init(row, result_fields_, group_exprs))) { LOG_WARN("fail to init group unit", K(ret)); } else if (OB_FAIL(group_unit_map_.get_refactored(group_unit, current_group_unit))) { if (OB_HASH_NOT_EXIST == ret) { @@ -827,7 +827,8 @@ ObProxyGroupUnit::~ObProxyGroupUnit() } } -int ObProxyGroupUnit::init(ResultRow *row, const ObIArray& group_exprs) +int ObProxyGroupUnit::init(ResultRow *row, ResultFields *result_fields, + const ObIArray& group_exprs) { int ret = OB_SUCCESS; @@ -837,11 +838,21 @@ int ObProxyGroupUnit::init(ResultRow *row, const ObIArray& gr for (int64_t i = 0; OB_SUCC(ret) && i < group_exprs.count(); i++) { if (OB_FAIL(group_exprs.at(i)->calc(ctx, calc_item, group_values_))) { LOG_WARN("fail to calc group exprs", K(ret)); + } else { + int64_t index = group_exprs.at(i)->get_expr()->get_index(); + if (-1 != index) { + ObObj &value = group_values_.at(i); + if (OB_FAIL(change_sql_value(value, result_fields->at(index), &allocator_))) { + LOG_WARN("fail to change sql value", K(value), + "filed", result_fields->at(index), K(ret)); + } + } } } if (OB_SUCC(ret)) { row_ = row; + result_fields_ = result_fields; } return ret; @@ -880,6 +891,7 @@ int ObProxyGroupUnit::assign(const ObProxyGroupUnit &group_unit) LOG_WARN("fail to assign group value", K(ret)); } else { row_ = group_unit.get_row(); + result_fields_ = group_unit.get_result_fields(); } return ret; @@ -898,8 +910,19 @@ int ObProxyGroupUnit::do_aggregate(ResultRow *row) agg_values.reuse(); if (OB_FAIL(agg_unit->get_agg_expr()->calc(ctx, calc_item, agg_values))) { LOG_WARN("fail to calc agg expr", K(ret)); - } else if (OB_FAIL(agg_unit->merge(agg_values))) { - LOG_WARN("fail to merge agg value", K(ret)); + } else { + int64_t index = agg_unit->get_agg_expr()->get_index(); + if (-1 != index) { + ObObj &value = agg_values.at(0); + if (OB_FAIL(change_sql_value(value, result_fields_->at(index), &allocator_))) { + LOG_WARN("fail to change sql value", K(value), + "filed", result_fields_->at(index), K(ret)); + } + } + + if (OB_SUCC(ret) && OB_FAIL(agg_unit->merge(agg_values))) { + LOG_WARN("fail to merge agg value", K(ret)); + } } } diff --git a/src/obproxy/engine/ob_proxy_operator_agg.h b/src/obproxy/engine/ob_proxy_operator_agg.h index 223d8496..82792f3f 100644 --- a/src/obproxy/engine/ob_proxy_operator_agg.h +++ b/src/obproxy/engine/ob_proxy_operator_agg.h @@ -350,12 +350,13 @@ class ObProxyGroupUnit { public: ObProxyGroupUnit(common::ObIAllocator &allocator) - : allocator_(allocator), row_(NULL), + : allocator_(allocator), row_(NULL), result_fields_(NULL), group_values_(ObModIds::OB_SE_ARRAY_ENGINE, ENGINE_ARRAY_NEW_ALLOC_SIZE), agg_units_(ObModIds::OB_SE_ARRAY_ENGINE, ENGINE_ARRAY_NEW_ALLOC_SIZE) {} ~ObProxyGroupUnit(); - int init(ResultRow *row, const common::ObIArray& group_by_exprs); + int init(ResultRow *row, ResultFields *result_fields, + const common::ObIArray& group_by_exprs); uint64_t hash() const; bool operator==(const ObProxyGroupUnit &group_unit) const; @@ -366,6 +367,7 @@ class ObProxyGroupUnit int set_agg_value(); ResultRow *get_row() const { return row_; } + ResultFields *get_result_fields() const { return result_fields_; } const common::ObIArray& get_group_values() const { return group_values_; } const common::ObIArray& get_agg_units() { return agg_units_;; } @@ -385,6 +387,7 @@ class ObProxyGroupUnit private: common::ObIAllocator &allocator_; ResultRow *row_; + ResultFields *result_fields_; common::ObSEArray group_values_; common::ObSEArray agg_units_; }; diff --git a/src/obproxy/engine/ob_proxy_operator_cont.cpp b/src/obproxy/engine/ob_proxy_operator_cont.cpp new file mode 100644 index 00000000..edb49005 --- /dev/null +++ b/src/obproxy/engine/ob_proxy_operator_cont.cpp @@ -0,0 +1,301 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX PROXY + +#include "ob_proxy_operator_cont.h" +#include "lib/oblog/ob_log_module.h" + +using namespace oceanbase::common; +using namespace oceanbase::obproxy::event; +using namespace oceanbase::obproxy::obutils; + +namespace oceanbase +{ +namespace obproxy +{ +namespace engine +{ + +int ObProxyOperatorCont::init(ObProxyOperator* operator_root, uint8_t seq, const int64_t timeout_ms) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL != buf_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected buf is not null", K(ret)); + } else if (OB_ISNULL(buf_ = new_empty_miobuffer())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new_empty_miobuffer for buf", K(ret)); + } else if (OB_ISNULL(buf_reader_ = buf_->alloc_reader())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to allocate buffer reader", K(ret)); + } else { + operator_root_ = operator_root; + timeout_ms_ = timeout_ms; + seq_ = seq; + } + + return ret; +} + +int ObProxyOperatorCont::main_handler(int event, void *data) +{ + int ret = OB_SUCCESS; + + if (NULL == execute_thread_) { + execute_thread_ = &self_ethread(); + } + + switch (event) { + case EVENT_INTERVAL: { + timeout_action_ = NULL; + // If it has been canceled, then the underlying operator has been released, + // and here we need to set pending_action_ to NULL + if (action_.cancelled_) { + pending_action_ = NULL; + } + + if (OB_FAIL(handle_timeout())) { + LOG_WARN("fail to handle timeout"); + } + break; + } + case EVENT_IMMEDIATE: { + pending_action_ = NULL; + if (OB_FAIL(cancel_timeout_action())) { + LOG_WARN("fail to cancel_timeout_action", K(ret)); + } else if (OB_FAIL(handle_event_start())) { + LOG_INFO("fail to handle event start", K(ret)); + } else if (OB_FAIL(schedule_timeout())) { + LOG_WARN("fail to schedule timeout action", K(ret)); + } + break; + } + case VC_EVENT_READ_COMPLETE: { + pending_action_ = NULL; + if (OB_FAIL(cancel_timeout_action())) { + LOG_WARN("fail to cancel_timeout_action", K(ret)); + } else if (OB_FAIL(handle_event_complete(data))) { + LOG_WARN("fail to handle event complete", K(ret)); + } + break; + } + case ASYNC_PROCESS_INFORM_OUT_EVENT: { + pending_action_ = NULL; + if (OB_FAIL(cancel_timeout_action())) { + LOG_WARN("fail to cancel_timeout_action", K(ret)); + } else if (OB_FAIL(handle_event_inform_out())) { + LOG_WARN("fail to handle inform out event", K(ret)); + } + break; + } + case VC_EVENT_ACTIVE_TIMEOUT: + case EVENT_ERROR: + default: { + pending_action_ = NULL; + if (OB_FAIL(cancel_timeout_action())) { + LOG_WARN("fail to cancel_timeout_action", K(ret)); + } else if (action_.cancelled_) { + terminate_ = true; + LOG_INFO("async task has been cancelled, will kill itself", K(ret)); + } else if (NULL != cb_cont_) { + need_callback_ = true; + } else { + terminate_ = true; + } + + if (EVENT_ERROR != event || VC_EVENT_ACTIVE_TIMEOUT != event) { + LOG_WARN("error state, nerver run here", K(event), K(ret)); + } else { + LOG_INFO("error state", K(event)); + } + break; + } + } + + if (!terminate_ && (need_callback_ || OB_FAIL(ret))) { + if (execute_thread_ == &self_ethread()) { + execute_thread_->is_need_thread_pool_event_ = true; + } + if (OB_FAIL(handle_callback())) { + LOG_WARN("fail to handle callback", K(ret)); + } + } + + if (terminate_) { + if (execute_thread_ == &self_ethread()) { + execute_thread_->is_need_thread_pool_event_ = true; + } + destroy(); + } + + return EVENT_DONE; +} + +int ObProxyOperatorCont::init_task() +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(operator_root_->open(this, pending_action_, timeout_ms_))) { + LOG_WARN("fail to open operator", K_(timeout_ms), K(ret)); + } else if (OB_FAIL(operator_root_->get_next_row())) { + LOG_WARN("fail to get next row", K(ret)); + } else if (OB_ISNULL(pending_action_)) { + LOG_WARN("pending action should not be null", K(ret)); + } + + return ret; +} + +int ObProxyOperatorCont::finish_task(void *data) +{ + int ret = OB_SUCCESS; + + ObProxyResultResp *result_resp = reinterpret_cast(data); + if (result_resp->is_resultset_resp()) { + if (OB_FAIL(build_executor_resp(buf_, seq_, result_resp))) { + LOG_WARN("fail to build shard scan resp", K(ret)); + } + } else if (OB_FAIL(ObMysqlPacketUtil::encode_err_packet(*buf_, seq_, result_resp->get_err_code(), result_resp->get_err_msg()))) { + LOG_WARN("fail to encode err pacekt buf", K_(seq), "errmsg", result_resp->get_err_msg(), + "errcode", result_resp->get_err_code(), K(ret)); + } + + return ret; +} + +int ObProxyOperatorCont::schedule_timeout() +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL != timeout_action_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("timeout action must be NULL", K_(timeout_action), K(ret)); + } else if (OB_ISNULL(timeout_action_ = execute_thread_->schedule_in(this, HRTIME_MSECONDS(timeout_ms_)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to schedule timeout", K_(timeout_action), K_(timeout_ms), K(ret)); + } + + return ret; +} + +int ObProxyOperatorCont::build_executor_resp(ObMIOBuffer *write_buf, uint8_t &seq, ObProxyResultResp *result_resp) +{ + int ret = OB_SUCCESS; + int64_t column_count = result_resp->get_column_count(); + ObSEArray *fields = NULL; + ObSEArray ob_fields; + + // header , cols , first eof + if (OB_SUCC(ret)) { + if (OB_FAIL(result_resp->get_fields(fields))) { + LOG_WARN("fail to push field", K(fields), K(ret)); + } else if (OB_ISNULL(fields)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fields should not be null", K(ret)); + } else if (OB_UNLIKELY(fields->count() != column_count)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fields count should equal column_count", K(column_count), "fileds count", fields->count(), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::encode_header(*write_buf, seq, *fields))) { + LOG_WARN("fail to encode header", K(fields), K(seq), K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < column_count; i++) { + obmysql::ObMySQLField &mysql_field = fields->at(i); + ObField ob_field; + if (OB_FAIL(ObSMUtils::to_ob_field(mysql_field, ob_field))) { + LOG_WARN("fail to covert to ob field", K(mysql_field), K(ret)); + } else if (OB_FAIL(ob_fields.push_back(ob_field))) { + LOG_WARN("fail to push ob field", K(ob_field), K(ret)); + } + } + } + } + + // rows + if (OB_SUCC(ret)) { + ObObj *objs = NULL; + int64_t buf_len = sizeof(ObObj) * column_count; + + if (OB_ISNULL(objs = static_cast(op_fixed_mem_alloc(buf_len)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to alloc obj array", K(column_count), K(ret)); + } else { + ObNewRow row; + //ObSEArray *row_array; + ObSEArray *row_array; + while ((OB_SUCC(ret)) && (OB_SUCC(result_resp->next(row_array)))) { + if (OB_ISNULL(row_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("row_array should not be null", K(ret)); + } else if (OB_UNLIKELY(row_array->count() != column_count)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("row_array count should equal column_count", K(column_count), "row_array count", row_array->count(), K(ret)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < column_count; i++) { + objs[i] = *(row_array->at(i)); + } + + if (OB_SUCC(ret)) { + row.cells_ = objs; + row.count_ = column_count; + if (OB_FAIL(ObMysqlPacketUtil::encode_row_packet(*write_buf, seq, row, &ob_fields))) { + LOG_WARN("fail to encode row", K(seq), K(row), K(ret)); + } else { + row.reset(); + row_array = NULL; + } + } + } + + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + + if (OB_NOT_NULL(objs)) { + op_fixed_mem_free(objs, buf_len); + objs = NULL; + } + } + + // second eof + if (OB_SUCC(ret)) { + if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*write_buf, seq))) { + LOG_WARN("fail to encode row", K(seq), K(ret)); + } + } + + return ret; +} + +void ObProxyOperatorCont::destroy() +{ + LOG_DEBUG("ObProxyOperatorCont will be destroyed", KP(this)); + + if (OB_LIKELY(NULL != buf_reader_)) { + buf_reader_->dealloc(); + buf_reader_ = NULL; + } + + if (OB_LIKELY(NULL != buf_)) { + free_miobuffer(buf_); + buf_ = NULL; + } + + ObAsyncCommonTask::destroy(); +} + +} // end of namespace engine +} // end of namespace obproxy +} // end of namespace oceanbase diff --git a/src/obproxy/engine/ob_proxy_operator_cont.h b/src/obproxy/engine/ob_proxy_operator_cont.h new file mode 100644 index 00000000..632fc919 --- /dev/null +++ b/src/obproxy/engine/ob_proxy_operator_cont.h @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OBPROXY_OPERATOR_CONT_H +#define OBPROXY_OPERATOR_CONT_H + +#include "obutils/ob_async_common_task.h" +#include "ob_proxy_operator.h" + +namespace oceanbase +{ +namespace obproxy +{ +namespace engine +{ + +class ObProxyOperatorCont : public obutils::ObAsyncCommonTask +{ +public: + ObProxyOperatorCont(event::ObContinuation *cb_cont, event::ObEThread *submit_thread) + : ObAsyncCommonTask(cb_cont->mutex_, "operator cont", cb_cont, submit_thread), + seq_(0), timeout_ms_(0), operator_root_(NULL), execute_thread_(NULL), data_(NULL), + buf_(NULL), buf_reader_(NULL) + { + SET_HANDLER(&ObProxyOperatorCont::main_handler); + } + + ~ObProxyOperatorCont() {} + + int main_handler(int event, void *data); + int init(ObProxyOperator* operator_root, uint8_t seq, const int64_t timeout_ms = 0); + virtual int init_task(); + virtual int finish_task(void *data); + virtual void *get_callback_data() { return buf_reader_; } + virtual int schedule_timeout(); + virtual void destroy(); + +private: + int build_executor_resp(event::ObMIOBuffer *write_buf, uint8_t &seq, ObProxyResultResp *result_resp); + +private: + uint8_t seq_; + int64_t timeout_ms_; + ObProxyOperator* operator_root_; + event::ObEThread *execute_thread_; + void *data_; + event::ObMIOBuffer *buf_; + event::ObIOBufferReader *buf_reader_; + DISALLOW_COPY_AND_ASSIGN(ObProxyOperatorCont); +}; + +} // end of namespace engine +} // end of namespace obproxy +} // end of namespace oceanbase + +#endif // OBPROXY_OPERATOR_CONT_H diff --git a/src/obproxy/engine/ob_proxy_operator_result.h b/src/obproxy/engine/ob_proxy_operator_result.h index 575d7027..05793b7d 100644 --- a/src/obproxy/engine/ob_proxy_operator_result.h +++ b/src/obproxy/engine/ob_proxy_operator_result.h @@ -15,6 +15,7 @@ #include "common/ob_row.h" //#include "common/ob_field.h" #include "common/obsm_utils.h" +#include "common/ob_obj_cast.h" #include "rpc/obmysql/ob_mysql_field.h" #include "proxy/mysqllib/ob_resultset_fetcher.h" #include "lib/container/ob_se_array.h" @@ -123,6 +124,44 @@ int change_sql_field(const ObMysqlField *src_field, obmysql::ObMySQLField *&dst_ return ret; } +int change_sql_value(ObObj &value, obmysql::ObMySQLField &field, ObIAllocator *allocator) +{ + int ret = OB_SUCCESS; + + if (value.is_varchar()) { + ObObjType ob_type; + ObCollationType cs_type = static_cast(field.charsetnr_); + // utf8_general_ci => CS_TYPE_UTF8MB4_GENERAL_CI + if (33 == field.charsetnr_) { + cs_type = CS_TYPE_UTF8MB4_GENERAL_CI; + // utf8_bin => CS_TYPE_UTF8MB4_BIN + } else if (83 == field.charsetnr_) { + cs_type = CS_TYPE_UTF8MB4_BIN; + } + + value.set_collation_type(cs_type); + + if (0 != value.get_string_len()) { + // Convert the column to a specific type, if it cannot be converted, keep varchar + if (OB_FAIL(ObSMUtils::get_ob_type(ob_type, field.type_))) { + COMMON_LOG(INFO, "cast ob type from mysql type failed", K(ob_type), "elem_type", field.type_, K(ret)); + ret = OB_SUCCESS; + } else if (ObTimestampType == ob_type || ObTimeType == ob_type + || ObDateType == ob_type || ObDateTimeType == ob_type) { + //do nothing + } else { + ObCastCtx cast_ctx(allocator, NULL, CM_NULL_ON_WARN, cs_type); + // use src_obj as buf_obj + if (OB_FAIL(ObObjCasterV2::to_type(ob_type, cs_type, cast_ctx, value, value))) { + COMMON_LOG(WARN, "failed to cast obj", "row", value, K(ob_type), K(cs_type), K(ret)); + } + } + } + } + + return ret; +} + class ObProxyResultResp : public executor::ObProxyParallelResp { public: diff --git a/src/obproxy/engine/ob_proxy_operator_sort.cpp b/src/obproxy/engine/ob_proxy_operator_sort.cpp index 8f312225..3ee286fd 100644 --- a/src/obproxy/engine/ob_proxy_operator_sort.cpp +++ b/src/obproxy/engine/ob_proxy_operator_sort.cpp @@ -405,7 +405,7 @@ int ObProxyMemMergeSortOp::handle_response_result(void *data, bool &is_final, Ob } else if (OB_ISNULL(sort_unit = new (tmp_buf) ObProxyMemMergeSortUnit(allocator_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to new merge sort unit", K(ret)); - } else if (OB_FAIL(sort_unit->init(row, input->get_order_exprs()))) { + } else if (OB_FAIL(sort_unit->init(row, result_fields_, input->get_order_exprs()))) { LOG_WARN("fail to init sort unit", K(ret)); } else if (OB_FAIL(sort_units_.push_back(sort_unit))) { LOG_WARN("fail to push back sort unit", K(ret)); @@ -460,7 +460,7 @@ int ObProxyMemMergeSortOp::handle_response_result(void *data, bool &is_final, Ob return ret; } -int ObProxyMemMergeSortUnit::init(ResultRow *row, ObIArray &order_exprs) +int ObProxyMemMergeSortUnit::init(ResultRow *row, ResultFields *result_fields, ObIArray &order_exprs) { int ret = OB_SUCCESS; @@ -468,6 +468,7 @@ int ObProxyMemMergeSortUnit::init(ResultRow *row, ObIArray &o LOG_WARN("fail to assign order exprs", K(ret)); } else { row_ = row; + result_fields_ = result_fields; if (OB_FAIL(calc_order_values())) { LOG_WARN("fail to get order value", K(ret)); } @@ -487,6 +488,15 @@ int ObProxyMemMergeSortUnit::calc_order_values() for (int64_t i = 0; OB_SUCC(ret) && i < order_exprs_.count(); i++) { if (OB_FAIL(order_exprs_.at(i)->calc(ctx, calc_item, order_values_))) { LOG_WARN("fail to calc order exprs", K(ret)); + } else { + int64_t index = order_exprs_.at(i)->get_expr()->get_index(); + if (-1 != index) { + ObObj &value = order_values_.at(i); + if (OB_FAIL(change_sql_value(value, result_fields_->at(index), &allocator_))) { + LOG_WARN("fail to change sql value", K(value), + "filed", result_fields_->at(index), K(ret)); + } + } } } @@ -566,7 +576,7 @@ int ObProxyStreamSortOp::handle_response_result(void *data, bool &is_final, ObPr } else if (OB_ISNULL(sort_unit = new (tmp_buf) ObProxyStreamSortUnit(allocator_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to new merge sort unit", K(ret)); - } else if (OB_FAIL(sort_unit->init(opres, input->get_order_exprs()))) { + } else if (OB_FAIL(sort_unit->init(opres, result_fields_, input->get_order_exprs()))) { LOG_WARN("fail to init sort unit", K(ret)); } else if (OB_FAIL(sort_units_.push_back(sort_unit))) { LOG_WARN("fail to push back sort unit", K(ret)); @@ -638,7 +648,8 @@ int ObProxyStreamSortOp::handle_response_result(void *data, bool &is_final, ObPr return ret; } -int ObProxyStreamSortUnit::init(ObProxyResultResp* result_set, common::ObIArray &order_exprs) +int ObProxyStreamSortUnit::init(ObProxyResultResp* result_set, ResultFields *result_fields, + common::ObIArray &order_exprs) { int ret = OB_SUCCESS; if (OB_FAIL(order_exprs_.assign((order_exprs)))) { @@ -646,6 +657,9 @@ int ObProxyStreamSortUnit::init(ObProxyResultResp* result_set, common::ObIArray< } else if (OB_ISNULL(result_set_ = result_set)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("result set should not NULL", K(ret)); + } else if (OB_ISNULL(result_fields_ = result_fields)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result fields should not NULL", K(ret)); } else if (OB_FAIL(next())) { // The first time, there must be a result, so it must not be OB_ITER_END LOG_WARN("fail to exec next", K(ret)); diff --git a/src/obproxy/engine/ob_proxy_operator_sort.h b/src/obproxy/engine/ob_proxy_operator_sort.h index 033c73d4..a59c55c3 100644 --- a/src/obproxy/engine/ob_proxy_operator_sort.h +++ b/src/obproxy/engine/ob_proxy_operator_sort.h @@ -142,12 +142,13 @@ class ObProxyMemMergeSortUnit { public: ObProxyMemMergeSortUnit(common::ObIAllocator &allocator) - : allocator_(allocator), row_(NULL), + : allocator_(allocator), row_(NULL), result_fields_(NULL), order_values_(ObModIds::OB_SE_ARRAY_ENGINE, ENGINE_ARRAY_NEW_ALLOC_SIZE), order_exprs_(ObModIds::OB_SE_ARRAY_ENGINE, ENGINE_ARRAY_NEW_ALLOC_SIZE) {} ~ObProxyMemMergeSortUnit() {} - int init(ResultRow *row, common::ObIArray &order_exprs); + int init(ResultRow *row, ResultFields *result_fields, + common::ObIArray &order_exprs); virtual bool compare(const ObProxyMemMergeSortUnit* sort_unit) const; int calc_order_values(); @@ -159,6 +160,7 @@ class ObProxyMemMergeSortUnit protected: common::ObIAllocator &allocator_; ResultRow *row_; + ResultFields *result_fields_; common::ObSEArray order_values_; common::ObSEArray order_exprs_; }; @@ -188,7 +190,8 @@ class ObProxyStreamSortUnit : public ObProxyMemMergeSortUnit : ObProxyMemMergeSortUnit(allocator), result_set_(NULL) {} ~ObProxyStreamSortUnit() {} - int init(ObProxyResultResp* result_set, common::ObIArray &order_exprs); + int init(ObProxyResultResp* result_set, ResultFields *result_fields, + common::ObIArray &order_exprs); virtual bool compare(const ObProxyStreamSortUnit* sort_unit) const; int next(); diff --git a/src/obproxy/engine/ob_proxy_operator_table_scan.cpp b/src/obproxy/engine/ob_proxy_operator_table_scan.cpp index eb6fd78f..ddd8de52 100644 --- a/src/obproxy/engine/ob_proxy_operator_table_scan.cpp +++ b/src/obproxy/engine/ob_proxy_operator_table_scan.cpp @@ -20,6 +20,7 @@ #include "executor/ob_proxy_parallel_cont.h" #include "executor/ob_proxy_parallel_execute_cont.h" #include "proxy/shard/obproxy_shard_utils.h" +#include "proxy/mysqllib/ob_proxy_mysql_request.h" using namespace oceanbase::obproxy::executor; using namespace oceanbase::common; @@ -28,6 +29,15 @@ namespace oceanbase { namespace obproxy { namespace engine { +ObProxyTableScanOp::~ObProxyTableScanOp() +{ + for (int64_t i = 0; i < pres_array_.count(); i++) { + executor::ObProxyParallelResp *pres = pres_array_.at(i); + op_free(pres); + pres = NULL; + } +} + int ObProxyTableScanOp::open(event::ObContinuation *cont, event::ObAction *&action, const int64_t timeout_ms) { child_cnt_ = 1; //fake child @@ -77,7 +87,8 @@ int ObProxyTableScanOp::get_next_row() "phy table count", table_name_maps.count(), "shard prop count", shard_props.count(), "dbkey count", db_key_names.count(), K(ret)); - } else if (OB_FAIL(sql_parser.parse_sql_by_obparser(request_sql, NORMAL_PARSE_MODE, parse_result, true))) { + } else if (OB_FAIL(sql_parser.parse_sql_by_obparser(proxy::ObProxyMysqlRequest::get_parse_sql(request_sql), + NORMAL_PARSE_MODE, parse_result, true))) { LOG_WARN("parse_sql_by_obparser failed", K(request_sql), K(ret)); } @@ -88,10 +99,9 @@ int ObProxyTableScanOp::get_next_row() ObSqlString new_sql; char *tmp_buf = NULL; bool is_oracle_mode = db_key_name->server_type_ == common::DB_OB_ORACLE; - if (OB_FAIL(proxy::ObProxyShardUtils::do_rewrite_shard_select_request(request_sql, parse_result, is_oracle_mode, - table_name_map_warraper.get_hash_map(), - db_key_name->database_name_, false, - new_sql))) { + if (OB_FAIL(proxy::ObProxyShardUtils::rewrite_shard_dml_request(request_sql, new_sql, parse_result, + is_oracle_mode, table_name_map_warraper.get_hash_map(), + db_key_name->database_name_, false))) { LOG_WARN("fail to rewrite shard request", K(request_sql), K(is_oracle_mode), K(ret)); } else if (OB_ISNULL(tmp_buf = (char *)allocator_.alloc(new_sql.length()))) { ret = common::OB_ALLOCATE_MEMORY_FAILED; @@ -135,6 +145,8 @@ int ObProxyTableScanOp::handle_result(void *data, bool &is_final, ObProxyResultR } else if (OB_ISNULL(pres = reinterpret_cast(data))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input, pres type is not match", K(ret)); + } else if (OB_FAIL(pres_array_.push_back(pres))) { + LOG_WARN("fail to push result resp to array", K(ret)); } else { if (pres->is_ok_resp()) { // it is the OK packet // For the OK package, it is only necessary to construct an OK package in the case of @@ -156,10 +168,6 @@ int ObProxyTableScanOp::handle_result(void *data, bool &is_final, ObProxyResultR } LOG_DEBUG("handle_result success", K(ret), K(pres)); } - if (OB_NOT_NULL(pres)) { - op_free(pres); - pres = NULL; - } return ret; } diff --git a/src/obproxy/engine/ob_proxy_operator_table_scan.h b/src/obproxy/engine/ob_proxy_operator_table_scan.h index 1c14c926..1571070d 100644 --- a/src/obproxy/engine/ob_proxy_operator_table_scan.h +++ b/src/obproxy/engine/ob_proxy_operator_table_scan.h @@ -32,7 +32,7 @@ class ObProxyTableScanOp : public ObProxyOperator set_op_type(PHY_TABLE_SCAN); } - virtual ~ObProxyTableScanOp() {}; + virtual ~ObProxyTableScanOp(); virtual int open(event::ObContinuation *cont, event::ObAction *&action, const int64_t timeout_ms = 0); virtual int get_next_row(); @@ -53,6 +53,7 @@ class ObProxyTableScanOp : public ObProxyOperator protected: int64_t sub_sql_count_; + common::ObSEArray pres_array_; }; class ObProxyTableScanInput : public ObProxyOpInput diff --git a/src/obproxy/executor/ob_proxy_parallel_execute_cont.cpp b/src/obproxy/executor/ob_proxy_parallel_execute_cont.cpp index 51994759..92884bfc 100644 --- a/src/obproxy/executor/ob_proxy_parallel_execute_cont.cpp +++ b/src/obproxy/executor/ob_proxy_parallel_execute_cont.cpp @@ -27,6 +27,16 @@ namespace obproxy namespace executor { +int64_t ObProxyParallelResp::to_string(char *buf, int64_t buf_len) const +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(column_count), K_(cont_index), + KP_(resp), KP_(rs_fetcher)); + J_OBJ_END(); + return pos; +} + ObProxyParallelResp::~ObProxyParallelResp() { if (OB_NOT_NULL(resp_)) { @@ -66,7 +76,6 @@ int ObProxyParallelResp::next(ObObj *&rows) { int ret = OB_SUCCESS; - ObMysqlField *fields = rs_fetcher_->get_field(); int64_t buf_len = (sizeof(ObObj) * column_count_); char *buf = NULL; @@ -79,50 +88,9 @@ int ObProxyParallelResp::next(ObObj *&rows) LOG_WARN("fail to alloc mem", K(buf_len), K(ret)); } else { rows = new (buf) ObObj[column_count_]; - ObObjType ob_type; for (int64_t i = 0; OB_SUCC(ret) && i < column_count_; i++) { if (OB_FAIL(rs_fetcher_->get_obj(i, rows[i]))) { LOG_WARN("fail to get varchar", K(i), K(ret)); - } else if (rows[i].need_deep_copy()) { - int64_t copy_size = rows[i].get_deep_copy_size(); - int64_t pos = 0; - buf = NULL; - if (OB_ISNULL(buf = static_cast(allocator_->alloc(copy_size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem", K(copy_size), K(ret)); - } else if (OB_FAIL(rows[i].deep_copy(rows[i], buf, copy_size, pos))) { - LOG_WARN("fail to deep coy", "obj", rows[i], K(copy_size), K(ret)); - } - } - - if (OB_SUCC(ret) && rows[i].is_varchar()) { - ObCollationType cs_type = static_cast(fields[i].charsetnr_); - // utf8_general_ci => CS_TYPE_UTF8MB4_GENERAL_CI - if (33 == fields[i].charsetnr_) { - cs_type = CS_TYPE_UTF8MB4_GENERAL_CI; - // utf8_bin => CS_TYPE_UTF8MB4_BIN - } else if (83 == fields[i].charsetnr_) { - cs_type = CS_TYPE_UTF8MB4_BIN; - } - - rows[i].set_collation_type(cs_type); - - if (0 != rows[i].get_string_len()) { - // if can not convert, stay varchar type - if (OB_FAIL(ObSMUtils::get_ob_type(ob_type, fields[i].type_))) { - LOG_INFO("cast ob type from mysql type failed", K(ob_type), "elem_type", fields[i].type_, K(ret)); - ret = OB_SUCCESS; - } else if (ObTimestampType == ob_type || ObTimeType == ob_type - || ObDateType == ob_type || ObDateTimeType == ob_type) { - //do nothing - } else { - ObCastCtx cast_ctx(allocator_, NULL, CM_NULL_ON_WARN, cs_type); - // use src_obj as buf_obj - if (OB_FAIL(ObObjCasterV2::to_type(ob_type, cs_type, cast_ctx, rows[i], rows[i]))) { - COMMON_LOG(WARN, "failed to cast obj", "idx", i, "row", rows[i], K(ob_type), K(cs_type), K(ret)); - } - } - } } } } @@ -201,6 +169,8 @@ int ObProxyParallelExecuteCont::init_task() int ret = OB_SUCCESS; ObMysqlRequestParam request_param; + request_param.ob_client_flags_.client_flags_.OB_CLIENT_SKIP_AUTOCOMMIT = 1; + request_param.ob_client_flags_.client_flags_.OB_CLIENT_SEND_REQUEST_DIRECT = 1; request_param.sql_ = request_sql_; if (OB_FAIL(mysql_proxy_->async_read(this, request_param, pending_action_))) { LOG_WARN("fail to async read", K_(request_sql), K(ret)); diff --git a/src/obproxy/executor/ob_proxy_parallel_execute_cont.h b/src/obproxy/executor/ob_proxy_parallel_execute_cont.h index 98cb30db..ac0ff672 100644 --- a/src/obproxy/executor/ob_proxy_parallel_execute_cont.h +++ b/src/obproxy/executor/ob_proxy_parallel_execute_cont.h @@ -44,6 +44,7 @@ class ObProxyParallelResp ObMysqlField *get_field() const { return rs_fetcher_->get_field(); } int64_t get_column_count() { return column_count_; } int64_t get_cont_index() { return cont_index_; } + int64_t to_string(char *buf, int64_t buf_len) const; private: proxy::ObClientMysqlResp *resp_; diff --git a/src/obproxy/iocore/eventsystem/Makemodule.am b/src/obproxy/iocore/eventsystem/Makemodule.am index be135867..bc8951c9 100644 --- a/src/obproxy/iocore/eventsystem/Makemodule.am +++ b/src/obproxy/iocore/eventsystem/Makemodule.am @@ -19,6 +19,8 @@ obproxy/iocore/eventsystem/ob_priority_event_queue.h\ obproxy/iocore/eventsystem/ob_processor.h\ obproxy/iocore/eventsystem/ob_protected_queue.h\ obproxy/iocore/eventsystem/ob_protected_queue.cpp\ +obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp\ +obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h\ obproxy/iocore/eventsystem/ob_thread.h\ obproxy/iocore/eventsystem/ob_thread.cpp\ obproxy/iocore/eventsystem/ob_vconnection.h\ @@ -32,4 +34,6 @@ obproxy/iocore/eventsystem/ob_grpc_task.h\ obproxy/iocore/eventsystem/ob_grpc_task.cpp\ obproxy/iocore/eventsystem/ob_shard_watch_task.h\ obproxy/iocore/eventsystem/ob_shard_watch_task.cpp\ +obproxy/iocore/eventsystem/ob_shard_scan_all_task.h\ +obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp\ obproxy/iocore/eventsystem/ob_thread_impl.h diff --git a/src/obproxy/iocore/eventsystem/ob_ethread.cpp b/src/obproxy/iocore/eventsystem/ob_ethread.cpp index 24470fef..6ce48ff4 100644 --- a/src/obproxy/iocore/eventsystem/ob_ethread.cpp +++ b/src/obproxy/iocore/eventsystem/ob_ethread.cpp @@ -67,6 +67,8 @@ ObEThread::ObEThread() ps_entry_cache_(NULL), text_ps_entry_cache_(NULL), random_seed_(NULL), + is_need_thread_pool_event_(false), + thread_pool_event_queue_(NULL), warn_log_buf_(NULL), warn_log_buf_start_(NULL), tt_(REGULAR), @@ -105,6 +107,8 @@ ObEThread::ObEThread(const ObThreadType att, const int64_t anid) ps_entry_cache_(NULL), text_ps_entry_cache_(NULL), random_seed_(NULL), + is_need_thread_pool_event_(false), + thread_pool_event_queue_(NULL), warn_log_buf_(NULL), warn_log_buf_start_(NULL), tt_(att), @@ -143,6 +147,8 @@ ObEThread::ObEThread(const ObThreadType att, ObEvent *e) ps_entry_cache_(NULL), text_ps_entry_cache_(NULL), random_seed_(NULL), + is_need_thread_pool_event_(false), + thread_pool_event_queue_(NULL), warn_log_buf_(NULL), warn_log_buf_start_(NULL), tt_(att), @@ -275,6 +281,9 @@ inline void ObEThread::process_event(ObEvent *e, const int calling_code) event_queue_external_.enqueue_local(e); } else { if (e->cancelled_) { + if (e->is_thread_pool_event_) { + is_need_thread_pool_event_ = true; + } free_event(*e); } else { const ObContinuation *c_temp = e->continuation_; @@ -444,7 +453,16 @@ void ObEThread::execute() if (ethreads_to_be_signalled_count_ > 0) { flush_signals(this); } - if (OB_UNLIKELY(OB_SUCCESS != event_queue_external_.dequeue_timed(next_time, true))) { + + if (is_need_thread_pool_event_ && NULL != thread_pool_event_queue_) { + if (OB_UNLIKELY(OB_SUCCESS != thread_pool_event_queue_->dequeue_timed(next_time, e))) { + LOG_WARN("fail to dequeue time in event_queue_external_"); + } else if (NULL != e) { + is_need_thread_pool_event_ = false; + e->ethread_ = this; + process_event(e, e->callback_event_); + } + } else if (OB_UNLIKELY(OB_SUCCESS != event_queue_external_.dequeue_timed(next_time, true))) { LOG_WARN("fail to dequeue time in event_queue_external_"); } } diff --git a/src/obproxy/iocore/eventsystem/ob_ethread.h b/src/obproxy/iocore/eventsystem/ob_ethread.h index f7b36101..ae78a126 100644 --- a/src/obproxy/iocore/eventsystem/ob_ethread.h +++ b/src/obproxy/iocore/eventsystem/ob_ethread.h @@ -34,6 +34,7 @@ #include "iocore/eventsystem/ob_thread.h" #include "iocore/eventsystem/ob_priority_event_queue.h" #include "iocore/eventsystem/ob_protected_queue.h" +#include "iocore/eventsystem/ob_protected_queue_thread_pool.h" #include "lib/container/ob_vector.h" namespace oceanbase @@ -56,7 +57,7 @@ class ObPartitionRefHashMap; class ObRoutineRefHashMap; class ObSqlTableRefHashMap; class ObCacheCleaner; -class ObBasePsEntryCache; +class ObBasePsEntryThreadCache; } namespace net { @@ -324,8 +325,8 @@ class ObEThread : public ObThread proxy::ObSqlTableRefHashMap &get_sql_table_map() { return *sql_table_map_; } proxy::ObPartitionRefHashMap &get_partition_map() { return *partition_map_; } proxy::ObRoutineRefHashMap &get_routine_map() { return *routine_map_; } - proxy::ObBasePsEntryCache &get_ps_entry_cache() { return *ps_entry_cache_; } - proxy::ObBasePsEntryCache &get_text_ps_entry_cache() { return *text_ps_entry_cache_; } + proxy::ObBasePsEntryThreadCache &get_ps_entry_cache() { return *ps_entry_cache_; } + proxy::ObBasePsEntryThreadCache &get_text_ps_entry_cache() { return *text_ps_entry_cache_; } obutils::ObCongestionRefHashMap &get_cgt_map() { return *congestion_map_; } common::ObMysqlRandom &get_random_seed() { return *random_seed_; } @@ -380,10 +381,13 @@ class ObEThread : public ObThread obutils::ObCongestionRefHashMap *congestion_map_; proxy::ObCacheCleaner *cache_cleaner_; proxy::ObSqlTableRefHashMap *sql_table_map_; - proxy::ObBasePsEntryCache *ps_entry_cache_; - proxy::ObBasePsEntryCache *text_ps_entry_cache_; + proxy::ObBasePsEntryThreadCache *ps_entry_cache_; + proxy::ObBasePsEntryThreadCache *text_ps_entry_cache_; common::ObMysqlRandom *random_seed_; + bool is_need_thread_pool_event_; + ObProtectedQueueThreadPool *thread_pool_event_queue_; + char *warn_log_buf_; char *warn_log_buf_start_; diff --git a/src/obproxy/iocore/eventsystem/ob_event.h b/src/obproxy/iocore/eventsystem/ob_event.h index b08d0ddc..ecfa64ac 100644 --- a/src/obproxy/iocore/eventsystem/ob_event.h +++ b/src/obproxy/iocore/eventsystem/ob_event.h @@ -208,6 +208,7 @@ class ObEvent : public ObAction uint32_t in_the_prot_queue_:1; uint32_t in_the_priority_queue_:1; uint32_t in_heap_:4; + uint32_t is_thread_pool_event_; int32_t callback_event_; ObHRTime timeout_at_; @@ -235,6 +236,7 @@ inline ObEvent::ObEvent() in_the_prot_queue_(false), in_the_priority_queue_(false), in_heap_(0), + is_thread_pool_event_(false), callback_event_(EVENT_NONE), timeout_at_(0), period_(0), diff --git a/src/obproxy/iocore/eventsystem/ob_event_processor.cpp b/src/obproxy/iocore/eventsystem/ob_event_processor.cpp index 200d3827..c7587f19 100644 --- a/src/obproxy/iocore/eventsystem/ob_event_processor.cpp +++ b/src/obproxy/iocore/eventsystem/ob_event_processor.cpp @@ -34,6 +34,7 @@ #include "iocore/eventsystem/ob_event_system.h" #include #include "utils/ob_cpu_affinity.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; @@ -45,6 +46,18 @@ namespace event { class ObEventProcessor g_event_processor; +int ObEventProcessor::init_thread(ObEThread *&t) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(t->init())) { + LOG_WARN("fail to init event", K(ret)); + delete t; + t = NULL; + } + + return ret; +} + int ObEventProcessor::spawn_event_threads( const int64_t thread_count, const char *et_name, const int64_t stacksize, ObEventThreadType &etype) @@ -76,10 +89,8 @@ int ObEventProcessor::spawn_event_threads( if (OB_ISNULL(t = new(std::nothrow) ObEThread(REGULAR, MAX_THREADS_IN_EACH_TYPE + event_thread_count_ - net_thread_count + i))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("fail to allocator memory for REGULAR ObEThread", K(i), K(thread_count), K(ret)); - } else if (OB_FAIL(t->init())) { - LOG_WARN("fail to init event", K(i), K(ret)); - delete t; - t = NULL; + } else if (OB_FAIL(init_thread(t))) { + LOG_WARN("fail to init thread", K(i), K(ret)); } else { all_event_threads_[event_thread_count_ + i] = t; event_thread_[new_thread_group_id][i] = t; @@ -134,10 +145,8 @@ int ObEventProcessor::spawn_net_threads(const int64_t thread_count, if (OB_ISNULL(t = new(std::nothrow) ObEThread(REGULAR, net_thread_count + i))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("fail to allocate memory for REGULAR ObEThread", K(i), K(thread_count), K(ret)); - } else if (OB_FAIL(t->init())) { - LOG_WARN("fail to init event", K(i), K(ret)); - delete t; - t = NULL; + } else if (OB_FAIL(init_thread(t))) { + LOG_WARN("fail to init thread", K(i), K(ret)); } else { all_event_threads_[event_thread_count_ + i] = t; event_thread_[ET_CALL][net_thread_count + i] = t; @@ -182,6 +191,7 @@ inline int ObEventProcessor::init_one_event_thread(const int64_t index) delete t; t = NULL; } else { + // It should be noted here that the thread with index 0 in rich client mode will be created if (0 == index) { this_thread() = t; global_mutex = t->mutex_; @@ -235,7 +245,6 @@ int ObEventProcessor::start(const int64_t net_thread_count, const int64_t stacks ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid parameters", K(stacksize), K(ret)); } else { - if (!automatic_match_work_thread || OB_UNLIKELY((cpu_num = get_cpu_count()) <= 0) || cpu_num > net_thread_count) { @@ -297,7 +306,7 @@ int ObEventProcessor::start(const int64_t net_thread_count, const int64_t stacks if (OB_UNLIKELY(length <= 0) || OB_UNLIKELY(length >= static_cast(sizeof(thr_name)))) { ret = OB_SIZE_OVERFLOW; LOG_WARN("fail format thread name", K(length), K(ret)); - } else if ((0 != i) && OB_FAIL(all_event_threads_[i]->start(thr_name, stacksize))) { + } else if ((0 != i || RUN_MODE_CLIENT == g_run_mode) && OB_FAIL(all_event_threads_[i]->start(thr_name, stacksize))) { LOG_WARN("fail to start event thread", K(thr_name), K(ret)); } else { if (bind_cpu) { diff --git a/src/obproxy/iocore/eventsystem/ob_event_processor.h b/src/obproxy/iocore/eventsystem/ob_event_processor.h index df6391d9..cfe8da2a 100644 --- a/src/obproxy/iocore/eventsystem/ob_event_processor.h +++ b/src/obproxy/iocore/eventsystem/ob_event_processor.h @@ -155,6 +155,8 @@ class ObEventProcessor : public ObProcessor int spawn_net_threads(const int64_t thread_count, const char *et_name, const int64_t stacksize); + virtual int init_thread(ObEThread *&t); + /** * Schedules the continuation on a specific ObEThread to receive an event * at the given timeout. Requests the ObEventProcessor to schedule @@ -303,7 +305,7 @@ class ObEventProcessor : public ObProcessor */ int64_t allocate(const int64_t size); - ObEvent *schedule(ObEvent *e, const ObEventThreadType etype, const bool fast_signal = false); + virtual ObEvent *schedule(ObEvent *e, const ObEventThreadType etype, const bool fast_signal = false); ObEThread *assign_thread(const ObEventThreadType etype); @@ -417,7 +419,7 @@ inline ObEThread *ObEventProcessor::assign_thread(const ObEventThreadType etype) return (event_thread_[etype][next]); } -inline ObEvent *ObEventProcessor::schedule( +ObEvent *ObEventProcessor::schedule( ObEvent *event, const ObEventThreadType etype, const bool fast_signal) { event->ethread_ = assign_thread(etype); diff --git a/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp b/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp new file mode 100644 index 00000000..8a6a6420 --- /dev/null +++ b/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX PROXY_EVENT + +#include "iocore/eventsystem/ob_event_system.h" +#include "iocore/net/ob_unix_net.h" + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace obproxy +{ +namespace event +{ + +void ObProtectedQueueThreadPool::enqueue(ObEvent *e) +{ + if (OB_ISNULL(e)) { + LOG_WARN("event NULL, it should not happened"); + } else if (OB_UNLIKELY(e->in_the_prot_queue_) || OB_UNLIKELY(e->in_the_priority_queue_)) { + LOG_WARN("event has already in queue, it should not happened", K(*e)); + } else { + int ret = OB_SUCCESS; + e->in_the_prot_queue_ = 1; + atomic_list_.push(e); + + if (OB_FAIL(signal())) { + LOG_WARN("fail to do signal, it should not happened", K(ret)); + } + } +} + +int ObProtectedQueueThreadPool::dequeue_timed(const ObHRTime timeout, ObEvent *&event) +{ + int ret = OB_SUCCESS; + + if (NULL != (event= (ObEvent *)(atomic_list_.pop()))) { + event->in_the_prot_queue_ = 0; + } else { + if (OB_FAIL(mutex_acquire(&lock_))) { + LOG_ERROR("fail to acquire mutex", K(ret)); + } else { + if (atomic_list_.empty()) { + timespec ts = hrtime_to_timespec(timeout); + cond_timedwait(&might_have_data_, &lock_, &ts); + } + + if (NULL != (event= (ObEvent *)(atomic_list_.pop()))) { + event->in_the_prot_queue_ = 0; + } + + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = mutex_release(&lock_)))) { + LOG_ERROR("fail to release mutex", K(tmp_ret)); + } + } + } + + return ret; +} + +} // end of namespace event +} // end of namespace obproxy +} // end of namespace oceanbase diff --git a/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h b/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h new file mode 100644 index 00000000..668caa6e --- /dev/null +++ b/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OBPROXY_PROTECTED_QUEUE_THREAD_POOL_H +#define OBPROXY_PROTECTED_QUEUE_THREAD_POOL_H + +#include "iocore/eventsystem/ob_event.h" + +namespace oceanbase +{ +namespace obproxy +{ +namespace event +{ + +class ObProtectedQueueThreadPool +{ +public: + ObProtectedQueueThreadPool() : is_inited_(false) {} + ~ObProtectedQueueThreadPool() { } + + int init(); + void enqueue(ObEvent *e); + int dequeue_timed(const ObHRTime timeout, ObEvent *&event); + int signal(); + +public: + bool is_inited_; + common::ObAtomicList atomic_list_; + ObMutex lock_; + ObProxyThreadCond might_have_data_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObProtectedQueueThreadPool); +}; + +inline int ObProtectedQueueThreadPool::init() +{ + int ret = common::OB_SUCCESS; + ObEvent e; + if (OB_FAIL(common::mutex_init(&lock_))) { + PROXY_EVENT_LOG(WARN, "fail to init mutex", K(ret)); + } else if (OB_FAIL(atomic_list_.init("ObProtectedQueueThreadPool", + reinterpret_cast(&e.link_.next_) - reinterpret_cast(&e)))) { + PROXY_EVENT_LOG(WARN, "fail to init atomic_list_", K(ret)); + } else if (OB_FAIL(cond_init(&might_have_data_))) { + PROXY_EVENT_LOG(WARN, "fail to init ObProxyThreadCond", K(ret)); + } else { + is_inited_ = 0; + } + return ret; +} + +inline int ObProtectedQueueThreadPool::signal() +{ + int ret = common::OB_SUCCESS; + // Need to get the lock before you can signal the thread + if (OB_FAIL(common::mutex_acquire(&lock_))) { + PROXY_EVENT_LOG(ERROR, "fail to acquire lock", K(ret)); + } else { + if (OB_FAIL(cond_signal(&might_have_data_))) { + PROXY_EVENT_LOG(WARN, "fail to call cond_signal", K(ret)); + } + + int tmp_ret = common::OB_SUCCESS; + if (OB_UNLIKELY(common::OB_SUCCESS != ( tmp_ret = common::mutex_release(&lock_)))) { + PROXY_EVENT_LOG(WARN, "fail to release mutex", K(tmp_ret)); + } + } + return ret; +} + +} // end of namespace event +} // end of namespace obproxy +} // end of namespace oceanbase + +#endif // OBPROXY_PROTECTED_QUEUE_THREAD_POOL_H diff --git a/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp b/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp new file mode 100644 index 00000000..b1abca64 --- /dev/null +++ b/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX PROXY_EVENT + +#include "iocore/eventsystem/ob_shard_scan_all_task.h" +#include "iocore/eventsystem/ob_event_system.h" + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace obproxy +{ +namespace event +{ +ObEventThreadType ET_SHARD_SCAN_ALL = ET_CALL; +ObShardScanAllTaskProcessor g_shard_scan_all_task_processor; + +// Note that if the number of task_threads is 0, all continuations scheduled for +// ET_SHARD_SCAN_ALL ends up running on ET_CALL (which is the net-threads). +int ObShardScanAllTaskProcessor::start(const int64_t shard_scan_all_threads, const int64_t stacksize) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(thread_pool_event_queue_ = new (std::nothrow) ObProtectedQueueThreadPool())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new ObProtectedQueueThreadPool", K(ret)); + } else if (OB_FAIL(thread_pool_event_queue_->init())) { + LOG_WARN("fail to init thread_pool_event_queue", K(ret)); + } else if (OB_FAIL(spawn_event_threads(shard_scan_all_threads, "ET_SHARD_SCAN_ALL", stacksize, ET_SHARD_SCAN_ALL))) { + LOG_WARN("fail to spawn event threads for ET_SHARD_SCAN_ALL", K(ret)); + } + + return ret; +} + +int ObShardScanAllTaskProcessor::init_thread(ObEThread *&t) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(t->init())) { + LOG_WARN("fail to init event", K(ret)); + delete t; + t = NULL; + } else { + t->thread_pool_event_queue_ = thread_pool_event_queue_; + t->is_need_thread_pool_event_ = true; + } + + return ret; +} + +ObEvent *ObShardScanAllTaskProcessor::schedule(ObEvent *event, const ObEventThreadType etype, const bool fast_signal) +{ + UNUSED(fast_signal); + UNUSED(etype); + + if (NULL != event->continuation_->mutex_) { + event->mutex_ = event->continuation_->mutex_; + } else { + event->continuation_->mutex_ = event->ethread_->mutex_; + event->mutex_ = event->continuation_->mutex_; + } + event->is_thread_pool_event_ = true; + thread_pool_event_queue_->enqueue(event); + return event; +} + +} // end of namespace event +} // end of namespace obproxy +} // end of namespace oceanbase diff --git a/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.h b/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.h new file mode 100644 index 00000000..b2ef2590 --- /dev/null +++ b/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OBPROXY_SHARD_SCAN_ALL_TASK_H +#define OBPROXY_SHARD_SCAN_ALL_TASK_H + +#include "iocore/eventsystem/ob_event_processor.h" +#include "iocore/eventsystem/ob_event.h" +#include "iocore/eventsystem/ob_protected_queue_thread_pool.h" + +namespace oceanbase +{ +namespace obproxy +{ +namespace event +{ +extern ObEventThreadType ET_SHARD_SCAN_ALL; + +class ObShardScanAllTaskProcessor : public ObEventProcessor +{ +public: + ObShardScanAllTaskProcessor() : ObEventProcessor(), thread_pool_event_queue_(NULL) {} + virtual ~ObShardScanAllTaskProcessor() {} + int start(const int64_t shard_scan_all_threads, const int64_t stacksize = DEFAULT_STACKSIZE); + + virtual int init_thread(ObEThread *&t); + virtual ObEvent *schedule(ObEvent *event, const ObEventThreadType etype, const bool fast_signal); + +private: + ObProtectedQueueThreadPool *thread_pool_event_queue_; +}; + +extern ObShardScanAllTaskProcessor g_shard_scan_all_task_processor; +} // end of namespace event +} // end of namespace obproxy +} // end of namespace oceanbase + +#endif // OBPROXY_SHARD_SCAN_ALL_TASK_H diff --git a/src/obproxy/iocore/eventsystem/ob_vconnection.h b/src/obproxy/iocore/eventsystem/ob_vconnection.h index ef3dfe60..d413b7f0 100644 --- a/src/obproxy/iocore/eventsystem/ob_vconnection.h +++ b/src/obproxy/iocore/eventsystem/ob_vconnection.h @@ -98,6 +98,8 @@ class ObProxyMutex; #define VC_EVENT_ACTIVE_TIMEOUT (VC_EVENT_EVENTS_START+6) #define VC_EVENT_HELLO_PKT_READ_READY (VC_EVENT_EVENTS_START+7) +// OBProxy detect server dead, should close connection +#define VC_EVENT_DETECT_SERVER_DEAD (VC_EVENT_EVENTS_START+8) // ObEvent return codes #define VC_EVENT_DONE CONTINUATION_DONE @@ -184,6 +186,8 @@ class ObVConnection : public ObContinuation * No activity was performed for a certain period. * VC_EVENT_ACTIVE_TIMEOUT * Write operation continued beyond a time limit. + * VC_EVENT_DETECT_SERVER_DEAD + * find Server dead, close connection * VC_EVENT_ERROR * An error occurred during the write * @@ -622,6 +626,10 @@ static inline const char *get_vc_event_name(int32_t event) ret = "VC_EVENT_ACTIVE_TIMEOUT"; break; + case VC_EVENT_DETECT_SERVER_DEAD: + ret = "VC_EVENT_DETECT_SERVER_DEAD"; + break; + default: ret = "unknown event"; break; diff --git a/src/obproxy/iocore/net/ob_connection.cpp b/src/obproxy/iocore/net/ob_connection.cpp index 66dee9a9..4ee0c9da 100644 --- a/src/obproxy/iocore/net/ob_connection.cpp +++ b/src/obproxy/iocore/net/ob_connection.cpp @@ -30,6 +30,8 @@ #include "iocore/net/ob_connection.h" #include "utils/ob_proxy_hot_upgrader.h" +#include "utils/ob_layout.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -390,6 +392,50 @@ int ObServerConnection::setup_fd_for_listen( const int32_t send_bufsize) { int ret = OB_SUCCESS; + if (RUN_MODE_PROXY == g_run_mode) { + if (OB_FAIL(setup_fd_for_listen_proxy_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "setup_fd_for_listen_proxy_mode failed", K(ret)); + } + } else if (RUN_MODE_CLIENT == g_run_mode) { + if (OB_FAIL(setup_fd_for_listen_client_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "setup_fd_for_listen_client_mode failed", K(ret)); + } + } + + return ret; +} + +int ObServerConnection::setup_fd_for_listen_client_mode( + const bool non_blocking, + const int32_t recv_bufsize, + const int32_t send_bufsize) +{ + UNUSED(recv_bufsize); + UNUSED(send_bufsize); + int ret = OB_SUCCESS; + + if (non_blocking && OB_FAIL(ObSocketManager::nonblocking(fd_))) { + PROXY_SOCK_LOG(WARN, "fail to set fd nonblocking", K(fd_), K(ret)); + } + + if (OB_FAIL(ret)) { + // make coverity happy + int tmp_ret = ret; + if (OB_FAIL(close())) { + PROXY_SOCK_LOG(WARN, "fail to close server connection", K(ret)); + } + ret = tmp_ret; + } + return ret; +} + + +int ObServerConnection::setup_fd_for_listen_proxy_mode( + const bool non_blocking, + const int32_t recv_bufsize, + const int32_t send_bufsize) +{ + int ret = OB_SUCCESS; if (OB_FAIL(ObSocketManager::set_sndbuf_and_rcvbuf_size(fd_, send_bufsize, recv_bufsize, SNDBUF_AND_RCVBUF_PREC))) { @@ -458,7 +504,7 @@ int ObServerConnection::setup_fd_for_listen( // make coverity happy int tmp_ret = ret; if (OB_FAIL(close())) { - PROXY_SOCK_LOG(WARN, "fail to close server connection", K(tmp_ret)); + PROXY_SOCK_LOG(WARN, "fail to close server connection", K(ret)); } ret = tmp_ret; } @@ -467,6 +513,55 @@ int ObServerConnection::setup_fd_for_listen( int ObServerConnection::listen(const bool non_blocking, const int32_t recv_bufsize, const int32_t send_bufsize) +{ + int ret = OB_SUCCESS; + if (RUN_MODE_PROXY == g_run_mode) { + if (OB_FAIL(listen_proxy_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "listen proxy mode failed", K(ret)); + } + } else if (RUN_MODE_CLIENT == g_run_mode) { + if (OB_FAIL(listen_client_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "listen client mode failed", K(ret)); + } + } + + return ret; +} + +int ObServerConnection::listen_client_mode(const bool non_blocking, const int32_t recv_bufsize, + const int32_t send_bufsize) +{ + int ret = OB_SUCCESS; + struct sockaddr_un *addr = (struct sockaddr_un*)&addr_.unix_domain_; + addr->sun_family = AF_UNIX; + memset(addr->sun_path, 0, sizeof(addr->sun_path)); + strncpy(addr->sun_path, get_global_layout().get_unix_domain_path(), sizeof(addr->sun_path) - 1); + if (OB_FAIL(ObSocketManager::socket(AF_UNIX, SOCK_STREAM, 0, fd_))) { + PROXY_SOCK_LOG(WARN, "fail to create socket", K(ret), KERRMSGS); + } else if (OB_FAIL(setup_fd_for_listen_client_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "fail to setup_fd_for_listen", K(ret)); + } else if (OB_FAIL(ObSocketManager::bind(fd_, &addr_.sa_, sizeof(*addr)))) { + PROXY_SOCK_LOG(WARN, "fail to bind", K(ret)); + } else if (OB_FAIL(ObSocketManager::listen(fd_, LISTEN_BACKLOG))) { + PROXY_SOCK_LOG(WARN, "fail to listen", KERRMSGS, K(ret)); + } else { + ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); + info.ipv4_fd_ = fd_; + } + + if (OB_FAIL(ret)) { + // make coverity happy + int tmp_ret = ret; + if (OB_FAIL(close())) { + PROXY_SOCK_LOG(WARN, "fail to close server connection", K(ret)); + } + ret = tmp_ret; + } + return ret; +} + +int ObServerConnection::listen_proxy_mode(const bool non_blocking, const int32_t recv_bufsize, + const int32_t send_bufsize) { int ret = OB_SUCCESS; if (!ops_is_ip(accept_addr_)) { @@ -478,21 +573,23 @@ int ObServerConnection::listen(const bool non_blocking, const int32_t recv_bufsi ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); if (OB_FAIL(ObSocketManager::socket(addr_.sa_.sa_family, SOCK_STREAM, IPPROTO_TCP, fd_))) { - PROXY_SOCK_LOG(WARN, "failed to create socket", K(addr_), KERRMSGS, K(ret)); + PROXY_SOCK_LOG(WARN, "fail to create socket", K(addr_), KERRMSGS, K(ret)); } else if (OB_FAIL(setup_fd_for_listen(non_blocking, recv_bufsize, send_bufsize))) { - PROXY_SOCK_LOG(WARN, "failed to setup_fd_for_listen", K(addr_), K(ret)); + PROXY_SOCK_LOG(WARN, "fail to setup_fd_for_listen", K(addr_), K(ret)); } else if (OB_FAIL(ObSocketManager::bind(fd_, &addr_.sa_, static_cast(ops_ip_size(addr_.sa_))))) { - PROXY_SOCK_LOG(WARN, "failed to bind", K(addr_), KERRMSGS, K(ret)); + PROXY_SOCK_LOG(WARN, "fail to bind", K(addr_), KERRMSGS, K(ret)); } else if (OB_FAIL(ObSocketManager::listen(fd_, LISTEN_BACKLOG))) { - PROXY_SOCK_LOG(WARN, "failed to listen", K(addr_), KERRMSGS, K(ret)); + PROXY_SOCK_LOG(WARN, "fail to listen", K(addr_), KERRMSGS, K(ret)); } else { // Original just did this on port == 0. int64_t namelen = sizeof(addr_); if (OB_FAIL(ObSocketManager::getsockname(fd_, &addr_.sa_, &namelen))) { PROXY_SOCK_LOG(WARN, "failed to getsockname", K(addr_), KERRMSGS, K(ret)); - } else { - info.fd_ = fd_; + } else if (addr_.is_ip4()) { + info.ipv4_fd_ = fd_; + } else if (addr_.is_ip6()) { + info.ipv6_fd_ = fd_; } } @@ -500,7 +597,7 @@ int ObServerConnection::listen(const bool non_blocking, const int32_t recv_bufsi // make coverity happy int tmp_ret = ret; if (OB_FAIL(close())) { - PROXY_SOCK_LOG(WARN, "fail to close server connection", K(tmp_ret)); + PROXY_SOCK_LOG(WARN, "fail to close server connection", K(ret)); } ret = tmp_ret; } diff --git a/src/obproxy/iocore/net/ob_connection.h b/src/obproxy/iocore/net/ob_connection.h index 31cf184e..bc87bc03 100644 --- a/src/obproxy/iocore/net/ob_connection.h +++ b/src/obproxy/iocore/net/ob_connection.h @@ -159,6 +159,22 @@ class ObServerConnection : public ObConnection // Client side (inbound) local IP address. ObIpEndpoint accept_addr_; +private: + int setup_fd_for_listen_proxy_mode( + const bool non_blocking = false, + const int32_t recv_bufsize = 0, + const int32_t send_bufsize = 0); + int setup_fd_for_listen_client_mode( + const bool non_blocking = false, + const int32_t recv_bufsize = 0, + const int32_t send_bufsize = 0); + int listen_proxy_mode(const bool non_blocking = false, + const int32_t recv_bufsize = 0, + const int32_t send_bufsize = 0); + int listen_client_mode(const bool non_blocking = false, + const int32_t recv_bufsize = 0, + const int32_t send_bufsize = 0); + private: static const int32_t LISTEN_BACKLOG; }; diff --git a/src/obproxy/iocore/net/ob_inet.cpp b/src/obproxy/iocore/net/ob_inet.cpp index 3cfe40a1..f37e0e42 100644 --- a/src/obproxy/iocore/net/ob_inet.cpp +++ b/src/obproxy/iocore/net/ob_inet.cpp @@ -41,14 +41,27 @@ namespace obproxy namespace net { +uint64_t ObIpEndpoint::hash(const uint64_t hash) const +{ + char buf[MAX_IP_ADDR_LENGTH]; + int64_t pos = to_string(buf, MAX_IP_ADDR_LENGTH); + return murmurhash(buf, static_cast(pos), hash); +} + int64_t ObIpEndpoint::to_string(char *buf, const int64_t buf_len) const { - char ip_buff[INET6_ADDRSTRLEN]; + char ip_buff[MAX_IP_ADDR_LENGTH]; int64_t pos = 0; J_OBJ_START(); - databuff_printf(buf, buf_len, pos, "%s:%u", - ops_ip_ntop(*this, ip_buff, sizeof(ip_buff)), - ops_ip_port_host_order(*this)); + if (is_ip6()) { + databuff_printf(buf, buf_len, pos, "[%s]:%u", + ops_ip_ntop(*this, ip_buff, sizeof(ip_buff)), + ops_ip_port_host_order(*this)); + } else { + databuff_printf(buf, buf_len, pos, "%s:%u", + ops_ip_ntop(*this, ip_buff, sizeof(ip_buff)), + ops_ip_port_host_order(*this)); + } J_OBJ_END(); return pos; } diff --git a/src/obproxy/iocore/net/ob_inet.h b/src/obproxy/iocore/net/ob_inet.h index 369d8ce3..6321c6e5 100644 --- a/src/obproxy/iocore/net/ob_inet.h +++ b/src/obproxy/iocore/net/ob_inet.h @@ -92,10 +92,15 @@ union ObIpEndpoint memset(this, 0, sizeof(ObIpEndpoint)); assign(addr); } + explicit ObIpEndpoint(const sockaddr_storage &addr) { + memset(this, 0, sizeof(ObIpEndpoint)); + assign(addr); + } ObIpEndpoint (const ObIpEndpoint &point) { MEMCPY(this, &point, sizeof(ObIpEndpoint)); } void operator= (const ObIpEndpoint &point) { MEMCPY(this, &point, sizeof(ObIpEndpoint)); } ObIpEndpoint &assign(const sockaddr &ip); + ObIpEndpoint &assign(const sockaddr_storage &ip); ObIpEndpoint &assign(const ObIpAddr &addr, const in_port_t port = 0); // Test for valid IP address. @@ -107,6 +112,8 @@ union ObIpEndpoint // Test for IPv6. bool is_ip6() const; + bool is_unix_domain() const; + uint16_t family() const; // Set to be any address for family family. // family must be AF_INET or AF_INET6. @@ -129,13 +136,14 @@ union ObIpEndpoint int64_t get_port_host_order() const; uint32_t get_ip4_host_order() const; - uint64_t hash(const uint64_t hash = 0) const { return common::murmurhash(&sa_, sizeof(sockaddr), hash); } + uint64_t hash(const uint64_t hash = 0) const; int64_t to_string(char *buffer, const int64_t size) const; struct sockaddr sa_; // Generic address. struct sockaddr_in sin_; // IPv4 struct sockaddr_in6 sin6_; // IPv6 + struct sockaddr_un unix_domain_; // unix_domain }; // Reset an address to invalid. @@ -485,8 +493,17 @@ inline const uint8_t *ops_ip_addr8_cast(const ObIpEndpoint &ip) // @return true if this is an IP loopback address, false otherwise. inline bool ops_is_ip_loopback(const sockaddr &ip) { - return (AF_INET == ip.sa_family && 0x7F == ops_ip_addr8_cast(ip)[0]) - || (AF_INET6 == ip.sa_family && IN6_IS_ADDR_LOOPBACK(&ops_ip6_addr_cast(ip))); + bool zret = false; + if (ops_is_ip4(ip)) { + in_addr_t a = ops_ip4_addr_cast(ip); + zret = (a == 0x100007F); + } else if (ops_is_ip6(ip)) { + in6_addr a = ops_ip6_addr_cast(ip); + zret = ((a.s6_addr32[0] == 0 && a.s6_addr32[1] == 0 && a.s6_addr32[2] == 0 + && a.s6_addr[12] == 0 && a.s6_addr[13] == 0 && a.s6_addr[14] == 0 + && a.s6_addr[15] == 1)); + } + return zret; } inline bool ops_is_ip_loopback(const ObIpEndpoint &ip) @@ -556,6 +573,8 @@ inline bool ops_ip_copy(sockaddr &dst, const sockaddr &src) case AF_INET6: n = sizeof(sockaddr_in6); break; + case AF_UNIX: + break; } switch (dst.sa_family) { case AF_INET: @@ -1034,6 +1053,12 @@ inline ObIpEndpoint& ObIpEndpoint::assign(const sockaddr &ip) return *this; } +inline ObIpEndpoint& ObIpEndpoint::assign(const sockaddr_storage &ip) +{ + ops_ip_copy(sa_, ops_ip_sa_cast(ip)); + return *this; +} + inline in_port_t& ObIpEndpoint::port() { return ops_ip_port_cast(sa_); @@ -1061,6 +1086,7 @@ inline bool ObIpEndpoint::is_valid() const inline bool ObIpEndpoint::is_ip4() const { return AF_INET == sa_.sa_family; } inline bool ObIpEndpoint::is_ip6() const { return AF_INET6 == sa_.sa_family; } +inline bool ObIpEndpoint::is_unix_domain() const { return AF_UNIX == sa_.sa_family; } inline uint16_t ObIpEndpoint::family() const { return sa_.sa_family; } inline ObIpEndpoint& ObIpEndpoint::set_to_any_addr(const int family) diff --git a/src/obproxy/iocore/net/ob_net_accept.cpp b/src/obproxy/iocore/net/ob_net_accept.cpp index 3827565c..c43c0ee5 100644 --- a/src/obproxy/iocore/net/ob_net_accept.cpp +++ b/src/obproxy/iocore/net/ob_net_accept.cpp @@ -32,6 +32,7 @@ #include "iocore/net/ob_net_accept.h" #include "iocore/net/ob_net.h" #include "iocore/net/ob_event_io.h" +#include "ob_proxy_init.h" #include "omt/ob_resource_unit_table_processor.h" #include "proxy/mysql/ob_mysql_client_session.h" #include "proxy/route/ob_table_cache.h" @@ -264,7 +265,6 @@ int ObNetAccept::init_accept_per_thread() int ObNetAccept::do_listen(const bool non_blocking) { - int ret = OB_SUCCESS; PROXY_NET_LOG(DEBUG, "ObNetAccept::do_listen", K(server_.fd_), K(non_blocking)); const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); @@ -323,22 +323,34 @@ int ObNetAccept::do_listen(const bool non_blocking) int ObNetAccept::fetch_vip_tenant(ObUnixNetVConnection* vc, ObVipTenant& vip_tenant, bool& lookup_success) { int ret = OB_SUCCESS; - int32_t ip; - int32_t port; int64_t vid; + bool found = false; + ObConfigItem tenant_item; + ObConfigItem cluster_item; if (OB_ISNULL(vc)) { ret = OB_ERR_UNEXPECTED; PROXY_NET_LOG(WARN, "vc pointer is null", K(ret)); } else { - ip = ntohl(vc->get_virtual_ip()); - port = static_cast(vc->get_virtual_port()); vid = static_cast(vc->get_virtual_vid()); - vip_tenant.vip_addr_.set(ip, port, vid); - if (OB_FAIL(get_global_vip_tenant_processor().get_vip_tenant(vip_tenant))) { - PROXY_NET_LOG(DEBUG, "fail to get vip tenant", K(ret)); - ret = OB_SUCCESS; - } else { - lookup_success = true; + vip_tenant.vip_addr_.set(vc->get_virtual_addr(), vid); + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + vip_tenant.vip_addr_, "", "", "proxy_tenant_name", tenant_item, "LEVEL_VIP", found))) { + PROXY_NET_LOG(WARN, "get proxy tenant name config failed", K(vip_tenant.vip_addr_), K(ret)); + } + + if (OB_SUCC(ret) && found) { + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + vip_tenant.vip_addr_, "", "", "rootservice_cluster_name", cluster_item, "LEVEL_VIP", found))) { + PROXY_NET_LOG(WARN, "get cluster name config failed", K(vip_tenant.vip_addr_), K(ret)); + } + } + + if (OB_SUCC(ret) && found) { + if (OB_FAIL(vip_tenant.set_tenant_cluster(tenant_item.str(), cluster_item.str()))) { + PROXY_CS_LOG(WARN, "set tenant and cluster name failed", K(tenant_item), K(cluster_item), K(ret)); + } else { + lookup_success = true; + } } } return ret; @@ -348,8 +360,8 @@ int ObNetAccept::fetch_tenant_cpu(ObVipTenant& vip_tenant, ObTenantCpu*& tenant_ { int ret = OB_SUCCESS; ObString key_name; - char vip_name[OB_IP_STR_BUFF]; - common::ObFixedLengthString key_string; + char vip_name[MAX_IP_ADDR_LENGTH]; + common::ObFixedLengthString key_string; if (OB_UNLIKELY(!vip_tenant.vip_addr_.addr_.ip_to_string(vip_name, static_cast(sizeof(vip_name))))) { ret = OB_ERR_UNEXPECTED; PROXY_NET_LOG(WARN, "fail to covert ip to string", K(vip_name), K(ret)); diff --git a/src/obproxy/iocore/net/ob_net_vconnection.h b/src/obproxy/iocore/net/ob_net_vconnection.h index 6ab615ea..6fa43201 100644 --- a/src/obproxy/iocore/net/ob_net_vconnection.h +++ b/src/obproxy/iocore/net/ob_net_vconnection.h @@ -419,35 +419,23 @@ class ObNetVConnection : public event::ObVConnection virtual int get_socket() = 0; public: - // Returns local ip. - // @deprecated get_local_addr() should be used instead for AF_INET6 compatibility. - in_addr_t get_local_ip(); // Returns local port uint16_t get_local_port(); // Returns local sockaddr storage const sockaddr &get_local_addr(); - // Returns remote ip. - // @deprecated get_remote_addr() should be used instead for AF_INET6 compatibility. - in_addr_t get_remote_ip(); // Returns remote port uint16_t get_remote_port(); // Returns remote sockaddr storage const sockaddr &get_remote_addr(); - // Returns virual ip. - // @deprecated get_virtual_addr() should be used instead for AF_INET6 compatibility. - in_addr_t get_virtual_ip(); // Returns virtual port uint16_t get_virtual_port(); // Returns virtual vid(vpc id) uint32_t get_virtual_vid(); // Returns virtual sockaddr storage const sockaddr &get_virtual_addr(); - const sockaddr &get_real_client_addr(); - in_addr_t get_real_client_ip(); - uint16_t get_real_client_port(); // Force an event if a write operation empties the write buffer. // @@ -476,7 +464,7 @@ class ObNetVConnection : public event::ObVConnection ObIpEndpoint local_addr_; // it is local proxy addr ObIpEndpoint remote_addr_; // if from accept, it is client addr, otherwise it is server addr ObIpEndpoint real_client_addr_; - ObIpEndpoint virtual_addr_; + ObIpEndpoint virtual_addr_; // vip addr uint32_t virtual_vid_; bool got_local_addr_; @@ -504,13 +492,6 @@ inline ObNetVConnection::ObNetVConnection() ob_zero(real_client_addr_); } -// local -inline in_addr_t ObNetVConnection::get_local_ip() -{ - const sockaddr addr = get_local_addr(); - return ops_is_ip4(addr) ? ops_ip4_addr_cast(addr) : 0; -} - //@return The local port in host order. inline uint16_t ObNetVConnection::get_local_port() { @@ -530,13 +511,6 @@ inline const sockaddr &ObNetVConnection::get_local_addr() return local_addr_.sa_; } -// remote -inline in_addr_t ObNetVConnection::get_remote_ip() -{ - const sockaddr &addr = get_remote_addr(); - return ops_is_ip4(addr) ? ops_ip4_addr_cast(addr) : 0; -} - // @return The remote port in host order. inline uint16_t ObNetVConnection::get_remote_port() { @@ -561,17 +535,6 @@ inline const sockaddr &ObNetVConnection::get_real_client_addr() return real_client_addr_.sa_; } -inline in_addr_t ObNetVConnection::get_real_client_ip() -{ - const sockaddr addr = get_real_client_addr(); - return ops_is_ip4(addr) ? ops_ip4_addr_cast(addr) : 0; -} - -inline uint16_t ObNetVConnection::get_real_client_port() -{ - return ops_ip_port_host_order(get_real_client_addr()); -} - // virtual inline const sockaddr &ObNetVConnection::get_virtual_addr() { @@ -582,12 +545,6 @@ inline const sockaddr &ObNetVConnection::get_virtual_addr() return virtual_addr_.sa_; } -inline in_addr_t ObNetVConnection::get_virtual_ip() -{ - const sockaddr addr = get_virtual_addr(); - return ops_is_ip4(addr) ? ops_ip4_addr_cast(addr) : 0; -} - inline uint16_t ObNetVConnection::get_virtual_port() { return ops_ip_port_host_order(get_virtual_addr()); @@ -595,6 +552,10 @@ inline uint16_t ObNetVConnection::get_virtual_port() inline uint32_t ObNetVConnection::get_virtual_vid() { + if (!got_virtual_addr_) { + set_virtual_addr(); + got_virtual_addr_ = true; + } return virtual_vid_; } diff --git a/src/obproxy/iocore/net/ob_unix_net.cpp b/src/obproxy/iocore/net/ob_unix_net.cpp index a2410a82..37d4a289 100644 --- a/src/obproxy/iocore/net/ob_unix_net.cpp +++ b/src/obproxy/iocore/net/ob_unix_net.cpp @@ -82,6 +82,17 @@ static inline int net_signal_hook_function(ObEThread &thread) return ret; } +void send_signal_when_exit_normally() +{ + if (g_proxy_fatal_errcode == OB_SUCCESS) { + pid_t parent_pid= getppid(); + if (parent_pid != 1) { + PROXY_NET_LOG(INFO, "obproxy child will send SIGUSR2 to parent", K(parent_pid)); + kill(parent_pid, SIGUSR2); + } + } +} + void proxy_exit_once() { // no connection opened, graceful exit flag is true, graceful exit timeout, exit!! @@ -100,7 +111,7 @@ void proxy_exit_once() } ret = OB_SUCCESS;//ignore error } - OB_LOGGER.destory_async_log_thread(); + OB_LOGGER.destroy_async_log_thread(); _exit(1); } @@ -309,6 +320,7 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) if (global_connections > 0) { if (info.graceful_exit_end_time_ >= info.graceful_exit_start_time_ && info.graceful_exit_end_time_ <= now) { + send_signal_when_exit_normally(); pthread_once(&g_exit_once, proxy_exit_once); } else { int64_t thread_local_client_connections = 0; @@ -317,6 +329,7 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) K(global_connections), K(thread_local_client_connections), K(g_proxy_fatal_errcode)); } } else { + send_signal_when_exit_normally(); pthread_once(&g_exit_once, proxy_exit_once); } } else { @@ -349,7 +362,7 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) PROXY_NET_LOG(WARN, "fail to close unix net vconnection", K(vc), K(close_ret)); } } else { - + int32_t event = EVENT_NONE; if (vc->get_is_force_timeout() || (info.graceful_exit_end_time_ >= info.graceful_exit_start_time_ && info.graceful_exit_end_time_ > 0 @@ -358,13 +371,12 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) } if (now != vc->next_inactivity_timeout_at_) { - ObIpEndpoint ip; - ip.sa_ = vc->get_remote_addr(); + ObIpEndpoint ip(vc->get_remote_addr()); if (0 < get_global_proxy_config().server_detect_mode && vc->source_type_ == ObUnixNetVConnection::VC_CONNECT && OB_HASH_EXIST == get_global_resource_pool_processor().ip_set_.exist_refactored(ip)) { - PROXY_NET_LOG(WARN, "server dead, close connection", K(ip)); - vc->next_inactivity_timeout_at_ = now; + PROXY_NET_LOG(WARN, "detect server dead, close connection", K(ip)); + event = EVENT_ERROR; } } @@ -391,6 +403,8 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) "next_inactivity_timeout_at", hrtime_to_sec(vc->next_inactivity_timeout_at_), "inactivity_timeout_in", hrtime_to_sec(vc->inactivity_timeout_in_)); vc->handle_event(EVENT_IMMEDIATE, e); + } else if (EVENT_NONE != event) { + vc->handle_event(event, e); } } } diff --git a/src/obproxy/iocore/net/ob_unix_net_processor.cpp b/src/obproxy/iocore/net/ob_unix_net_processor.cpp index d6ad29d2..27f409d1 100644 --- a/src/obproxy/iocore/net/ob_unix_net_processor.cpp +++ b/src/obproxy/iocore/net/ob_unix_net_processor.cpp @@ -459,6 +459,15 @@ class ObCheckConnect : public ObContinuation } break; + case VC_EVENT_DETECT_SERVER_DEAD: + PROXY_NET_LOG(WARN, "detect server addr dead", "addr", vc_->con_.addr_, K(this)); + vc_->do_io_close(); + if (!action_.cancelled_) { + action_.continuation_->handle_event(NET_EVENT_OPEN_FAILED, + reinterpret_cast(-ENET_CONNECT_FAILED)); + } + break; + default: PROXY_NET_LOG(WARN, "unknown connect event"); if (!action_.cancelled_) { diff --git a/src/obproxy/iocore/net/ob_unix_net_vconnection.cpp b/src/obproxy/iocore/net/ob_unix_net_vconnection.cpp index b865ce7d..764248eb 100644 --- a/src/obproxy/iocore/net/ob_unix_net_vconnection.cpp +++ b/src/obproxy/iocore/net/ob_unix_net_vconnection.cpp @@ -117,6 +117,7 @@ inline int ObUnixNetVConnection::read_signal_and_update(const int event) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: PROXY_NET_LOG(DEBUG, "null read.vio cont, closing vc", K(event), K(this)); closed_ = 1; break; @@ -151,6 +152,7 @@ inline int ObUnixNetVConnection::write_signal_and_update(const int event) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: PROXY_NET_LOG(DEBUG, "null write.vio cont, closing vc", K(event), K(this)); closed_ = 1; break; @@ -1192,6 +1194,32 @@ void ObUnixNetVConnection::remove_from_keep_alive_lru() } } +int ObUnixNetVConnection::set_virtual_addr() +{ + int ret = OB_SUCCESS; + get_remote_addr(); + + if (OB_UNLIKELY(get_global_proxy_config().enable_qa_mode)) { + // Simulate public cloud SLB to assign IP addresses + // Get the real client address first, then modify the virutal address + do_set_virtual_addr(); + if (OB_FAIL(ops_ip_pton(get_global_proxy_config().qa_mode_mock_public_cloud_slb_addr, virtual_addr_))) { + PROXY_CS_LOG(WARN, "fail to ops ip pton", "qa_mode_mock_public_cloud_slb_addr", + get_global_proxy_config().qa_mode_mock_public_cloud_slb_addr, K(ret)); + } else { + virtual_vid_ = static_cast(get_global_proxy_config().qa_mode_mock_public_cloud_vid); + } + } else if (remote_addr_.is_ip4()) { + ret = do_set_virtual_addr(); + } else { + real_client_addr_ = remote_addr_; + virtual_addr_ = remote_addr_; + virtual_addr_.sin6_.sin6_port = htons(2883); + } + + return ret; +} + int ObUnixNetVConnection::do_set_virtual_addr() { int ret = OB_SUCCESS; @@ -1234,27 +1262,6 @@ int ObUnixNetVConnection::do_set_virtual_addr() return ret; } -int ObUnixNetVConnection::set_virtual_addr() -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(get_global_proxy_config().enable_qa_mode)) { - // SLB to simulate public cloud allocation of IP addresses - // First obtain the real client address, and then modify the virutal address - do_set_virtual_addr(); - if (OB_FAIL(ops_ip_pton(get_global_proxy_config().qa_mode_mock_public_cloud_slb_addr, virtual_addr_))) { - PROXY_CS_LOG(WARN, "fail to ops ip pton", "qa_mode_mock_public_cloud_slb_addr", - get_global_proxy_config().qa_mode_mock_public_cloud_slb_addr, K(ret)); - } else { - virtual_vid_ = static_cast(get_global_proxy_config().qa_mode_mock_public_cloud_vid); - } - } else { - ret = do_set_virtual_addr(); - } - - return ret; -} - int ObUnixNetVConnection::apply_options() { int ret = OB_SUCCESS; @@ -1465,7 +1472,7 @@ int ObUnixNetVConnection::main_event(int event, ObEvent *e) if (OB_ISNULL(e)) { ret = OB_ERR_UNEXPECTED; PROXY_NET_LOG(WARN, "occur fatal error", K(event), K(e), K(ret)); - } else if (OB_UNLIKELY(EVENT_IMMEDIATE != event && EVENT_INTERVAL != event)) { + } else if (OB_UNLIKELY(EVENT_IMMEDIATE != event && EVENT_INTERVAL != event && EVENT_ERROR != event)) { ret = OB_ERR_UNEXPECTED; PROXY_NET_LOG(WARN, "occur fatal error", K(event), K(e), K(ret)); } else if (thread_ != this_ethread()) { @@ -1506,6 +1513,8 @@ int ObUnixNetVConnection::main_event(int event, ObEvent *e) signal_event = VC_EVENT_INACTIVITY_TIMEOUT; signal_timeout_at = &next_inactivity_timeout_at_; } + } else if (EVENT_ERROR == event) { + signal_event = VC_EVENT_DETECT_SERVER_DEAD; } else { signal_event = VC_EVENT_ACTIVE_TIMEOUT; signal_timeout = &active_timeout_action_; diff --git a/src/obproxy/ob_proxy.cpp b/src/obproxy/ob_proxy.cpp index b94a9f15..cc8444a7 100644 --- a/src/obproxy/ob_proxy.cpp +++ b/src/obproxy/ob_proxy.cpp @@ -75,6 +75,7 @@ #include "obutils/ob_session_pool_processor.h" #include "obutils/ob_config_processor.h" #include "iocore/net/ob_ssl_processor.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::share; @@ -194,9 +195,11 @@ int ObProxy::init(ObProxyOptions &opts, ObAppVersionInfo &proxy_version) } else if (OB_FAIL(app_config_processor.init())) { LOG_ERROR("fail to init app config processor", K(ret)); } else { - // if fail to init prometheus, do not stop the startup of obproxy - if (g_ob_prometheus_processor.init()) { - LOG_WARN("fail to init prometheus processor"); + if (RUN_MODE_PROXY == g_run_mode) { + // if fail to init prometheus, do not stop the startup of obproxy + if (OB_FAIL(g_ob_prometheus_processor.init())) { + LOG_WARN("fail to init prometheus processor", K(ret)); + } } #if OB_HAS_TESTS @@ -247,9 +250,33 @@ void ObProxy::destroy() if (OB_FAIL(ObAsyncCommonTask::destroy_repeat_task(mmp_init_cont_))) { LOG_WARN("fail to destroy meta proxy init task", K(ret)); } + ObThreadId tid = 0; + for (int64_t i = 0; i < g_event_processor.dedicate_thread_count_ && OB_SUCC(ret); ++i) { + tid = g_event_processor.all_dedicate_threads_[i]->tid_; + if (OB_FAIL(thread_cancel(tid))) { + PROXY_NET_LOG(WARN, "fail to do thread_cancel", K(tid), K(ret)); + } else if (OB_FAIL(thread_join(tid))) { + PROXY_NET_LOG(WARN, "fail to do thread_join", K(tid), K(ret)); + } else { + PROXY_NET_LOG(INFO, "graceful exit, dedicated thread exited", K(tid)); + } + ret = OB_SUCCESS;//ignore error + } + + for (int64_t i = 0; i < g_event_processor.event_thread_count_ && OB_SUCC(ret); ++i) { + tid = g_event_processor.all_event_threads_[i]->tid_; + if (OB_FAIL(thread_cancel(tid))) { + PROXY_NET_LOG(WARN, "fail to do thread_cancel", K(tid), K(ret)); + } else if (OB_FAIL(thread_join(tid))) { + PROXY_NET_LOG(WARN, "fail to do thread_join", K(tid), K(ret)); + } else { + PROXY_NET_LOG(INFO, "graceful exit, event thread exited", K(tid)); + } + ret = OB_SUCCESS;//ignore error + } - proxy_opts_ = NULL; - mysql_config_params_ = NULL; + OB_LOGGER.destroy_async_log_thread(); + _exit(0); } } @@ -347,9 +374,11 @@ int ObProxy::start() } else if (OB_FAIL(ObMysqlProxyServerMain::start_mysql_proxy_acceptor())) { LOG_ERROR("fail to start accept server", K(ret)); } else { - // if fail to init prometheus, do not stop the startup of obproxy - if (g_ob_prometheus_processor.start_prometheus()) { - LOG_WARN("fail to start prometheus"); + if (RUN_MODE_PROXY == g_run_mode) { + // if fail to init prometheus, do not stop the startup of obproxy + if (OB_FAIL(g_ob_prometheus_processor.start_prometheus())) { + LOG_WARN("fail to start prometheus", K(ret)); + } } mysql_config_params_ = NULL; @@ -373,7 +402,9 @@ int ObProxy::start() } info.is_parent_ = true; } - this_ethread()->execute(); + if (RUN_MODE_PROXY == g_run_mode) { + this_ethread()->execute(); + } } } return ret; @@ -411,7 +442,7 @@ int ObProxy::init_user_specified_config() { int ret = OB_SUCCESS; //1. set config from cmd -o name=value - if (NULL != proxy_opts_->optstr_ && OB_FAIL(config_->add_extra_config(proxy_opts_->optstr_))) { + if (NULL != proxy_opts_->optstr_ && OB_FAIL(config_->add_extra_config_from_opt(proxy_opts_->optstr_))) { LOG_WARN("fail to add extra config", K(ret)); //2. set config from cmd other opts @@ -958,7 +989,7 @@ int ObProxy::get_meta_table_server(ObIArray &replicas, O if (rs_list.count() <= 0) { ret = OB_ERR_UNEXPECTED; LOG_WARN("rs_list count must > 0", K(ret)); - } else if (OB_FAIL(raw_client.init(user_name, password, database, password1))) { + } else if (OB_FAIL(raw_client.init(user_name, password, database, cluster_name, password1))) { LOG_WARN("fail to init raw mysql client", K(ret)); } else if (OB_FAIL(raw_client.set_server_addr(rs_list))) { LOG_WARN("fail to set server addr", K(ret)); diff --git a/src/obproxy/ob_proxy_init.cpp b/src/obproxy/ob_proxy_init.cpp new file mode 100644 index 00000000..4300cfe6 --- /dev/null +++ b/src/obproxy/ob_proxy_init.cpp @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + * + * ************************************************************* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ob_proxy_main.h" +#include "lib/oblog/ob_warning_buffer.h" +#include "ob_proxy_init.h" +#include "lib/json/ob_json.h" +#include "obutils/ob_proxy_json_config_info.h" + +using namespace oceanbase::common; +using namespace oceanbase::json; +using namespace oceanbase::obproxy::obutils; + +namespace oceanbase +{ +namespace obproxy +{ + +OBPROXY_RUN_MODE g_run_mode = RUN_MODE_PROXY; +static bool is_obproxy_inited = false; +DRWLock local_init_lock; + +int init_obproxy_client(const ObString &config) +{ + int ret = OB_SUCCESS; + if (!is_obproxy_inited) { + DRWLock::WRLockGuard lock(local_init_lock); + if (!is_obproxy_inited) { + static const int DEFAULT_MMAP_MAX_VAL = 1024 * 1024 * 1024; // 1G + mallopt(M_MMAP_MAX, DEFAULT_MMAP_MAX_VAL); + mallopt(M_ARENA_MAX, 1); // disable malloc multiple arena pool + + setlocale(LC_ALL, ""); + + // turn warn log on so that there's a obproxy.log.wf file which records + // all WARN and ERROR logs in log directory. + ObWarningBuffer::set_warn_log_on(true); + // DISABLE_DIA(); disable di_cache stat + + g_run_mode = RUN_MODE_CLIENT; + int argc = 0; + char argv[10][4096]; + memset(argv, 0, sizeof(argv)); + MEMCPY(argv[0], "./bin/obproxy", strlen("./bin/obproxy")); + argc++; + if (!config.empty()) { + Parser parser; + json::Value *json_value = NULL; + ObArenaAllocator json_allocator(ObModIds::OB_JSON_PARSER); + if (OB_FAIL(parser.init(&json_allocator))) { + MPRINT("json parser init failed, ret =%d", ret); + } else if (OB_FAIL(parser.parse(config.ptr(), config.length(), json_value))) { + MPRINT("json parse failed, ret =%d", ret); + } else if (OB_FAIL(ObProxyJsonUtils::check_config_info_type(json_value, json::JT_OBJECT))) { + MPRINT("check config info type failed, ret=%d", ret); + } else { + DLIST_FOREACH(p, json_value->get_object()) { + if (0 == p->name_.case_compare("proxy_config")) { + if (OB_FAIL(ObProxyJsonUtils::check_config_info_type(p->value_, json::JT_STRING))) { + MPRINT("check config info type failed, ret=%d", ret); + } else { + MEMCPY(argv[argc++], "-o", strlen("-o")); + MEMCPY(argv[argc++], p->value_->get_string().ptr(), p->value_->get_string().length()); + } + } + } + } + } + + if (OB_SUCC(ret)) { + char *tmp_argv[10]; + for (int i = 0; i < argc; i++) { + tmp_argv[i] = argv[i]; + } + ObProxyMain *proxy_main = ObProxyMain::get_instance(); + if (OB_ISNULL(proxy_main)) { + ret = OB_ERR_UNEXPECTED; + MPRINT("fail to get obproxy main instance, ret=%d", ret); + } else if (OB_FAIL(proxy_main->start(argc, tmp_argv))) { + MPRINT("fail to start obproxy, ret=%d", ret); + } else { + is_obproxy_inited = true; + atexit(destroy_obproxy_client); + } + } + } + } + + return ret; +} + +void destroy_obproxy_client() +{ + ObProxyMain *proxy_main = ObProxyMain::get_instance(); + if (OB_NOT_NULL(proxy_main)) { + proxy_main->destroy(); + } +} + +} +} + diff --git a/src/obproxy/ob_proxy_init.h b/src/obproxy/ob_proxy_init.h new file mode 100644 index 00000000..4c76fc2b --- /dev/null +++ b/src/obproxy/ob_proxy_init.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + * + * ************************************************************* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBPROXY_INIT_H_ +#define OBPROXY_INIT_H_ + +namespace oceanbase +{ +namespace common +{ +class ObString; +} +namespace obproxy +{ +enum OBPROXY_RUN_MODE { + RUN_MODE_PROXY, + RUN_MODE_CLIENT, + RUN_MODE_INVALID, +}; + +extern OBPROXY_RUN_MODE g_run_mode; + +int init_obproxy_client(const common::ObString& config); + +void destroy_obproxy_client(); + +} // end of obproxy +} // end of oceanbase + + +#endif diff --git a/src/obproxy/ob_proxy_main.cpp b/src/obproxy/ob_proxy_main.cpp index 9a38e14c..3a5161b3 100644 --- a/src/obproxy/ob_proxy_main.cpp +++ b/src/obproxy/ob_proxy_main.cpp @@ -28,6 +28,7 @@ #include "obutils/ob_async_common_task.h" #include "cmd/ob_show_sqlaudit_handler.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::lib; @@ -400,6 +401,8 @@ int ObProxyMain::get_log_file_name(const ObLogFDType type, char *file_name, cons ret_len = snprintf(log_file_name, OB_MAX_LOG_FILE_NAME_LEN, "obproxy_pool_stat.log"); } else if (FD_TRACE_FILE == type) { ret_len = snprintf(log_file_name, OB_MAX_LOG_FILE_NAME_LEN, "obproxy_trace.log"); + } else if (FD_DRIVER_CLIENT_FILE == type) { + ret_len = snprintf(log_file_name, OB_MAX_LOG_FILE_NAME_LEN, "obproxy_client.log"); } else { ret_len = snprintf(log_file_name, OB_MAX_LOG_FILE_NAME_LEN, "obproxy.log"); } @@ -436,7 +439,7 @@ int ObProxyMain::start(const int argc, char *const argv[]) ObProxyOptions opts; memset(&opts, 0, sizeof(opts)); - if (OB_FAIL(print_args(argc, argv))) { + if (RUN_MODE_PROXY == g_run_mode && OB_FAIL(print_args(argc, argv))) { MPRINT("fail to print args, ret=%d", ret); } else if (OB_FAIL(parse_cmd_line(argc, argv, opts))) { if (OB_NOT_RUNNING != ret) { @@ -448,7 +451,7 @@ int ObProxyMain::start(const int argc, char *const argv[]) const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); // if inherited, don not use daemon - if (OB_SUCC(ret)) { + if (RUN_MODE_PROXY == g_run_mode && OB_SUCC(ret)) { if (!opts.nodaemon_ && !info.is_inherited_) { if (OB_FAIL(use_daemon())) { MPRINT("fail to use deamon, ret=%d", ret); @@ -456,16 +459,16 @@ int ObProxyMain::start(const int argc, char *const argv[]) } } - if (OB_SUCC(ret)) { + if (RUN_MODE_PROXY == g_run_mode && OB_SUCC(ret)) { if (info.is_inherited_) { - if (OB_FAIL(close_all_fd(info.fd_))) { + if (OB_FAIL(close_all_fd(info.ipv4_fd_, info.ipv6_fd_))) { MPRINT("fail to close all fd, ret=%d", ret); } } } if (OB_SUCC(ret)) { - if (OB_FAIL(get_global_layout().init(info.argv_[0]))) { + if (OB_FAIL(get_global_layout().init(argv[0]))) { MPRINT("fail to init global layout, ret=%d", ret); } else if (OB_FAIL(init_log())) { MPRINT("fail to init log, ret=%d", ret); @@ -477,7 +480,8 @@ int ObProxyMain::start(const int argc, char *const argv[]) app_info_.setup(PACKAGE_STRING, APP_NAME, RELEASEID); _LOG_INFO("%s-%s", app_info_.full_version_info_str_, build_version()); if (info.is_inherited_) { - LOG_INFO("obproxy will start by hot upgrade", " listen fd", info.fd_, K(info)); + LOG_INFO("obproxy will start by hot upgrade", " listen ipv4 fd", info.ipv4_fd_, + "listen ipv6 fd", info.ipv6_fd_, K(info)); } else { LOG_INFO("has no inherited sockets, start new obproxy", K(info)); } @@ -495,18 +499,28 @@ int ObProxyMain::handle_inherited_sockets(const int argc, char *const argv[]) int ret = OB_SUCCESS; ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); - if (OB_UNLIKELY(argc <= 0) || OB_ISNULL(argv) || OB_ISNULL(argv[0])) { + if (RUN_MODE_CLIENT == g_run_mode) { + // do nothing + } else if (OB_UNLIKELY(argc <= 0) || OB_ISNULL(argv) || OB_ISNULL(argv[0])) { ret = OB_INVALID_ARGUMENT; MPRINT("invalid argument, argc=%d, argv=%p, ret=%d", argc, argv, ret); } else { info.set_main_arg(argc, argv); - char *inherited = NULL; + char *inherited_ipv4 = NULL; + char *inherited_ipv6 = NULL; - if (NULL == (inherited = getenv(OBPROXY_INHERITED_FD))) { + inherited_ipv4 = getenv(OBPROXY_INHERITED_IPV4_FD); + inherited_ipv6 = getenv(OBPROXY_INHERITED_IPV6_FD); + if (NULL == inherited_ipv4 && NULL == inherited_ipv6) { // has no inherited sockets, will start new obproxy, // and set it HU_STATE_WAIT_HU_CMD state info.update_state(HU_STATE_WAIT_HU_CMD); info.is_parent_ = true; + } else if (NULL == inherited_ipv4) { + // Allow IPv6 to be empty + // because it may be a hot upgrade from a lower version to a higher version + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ipv4 should not be NULL", K(ret)); } else if (info.is_inherited_) { ret = OB_ERR_UNEXPECTED; MPRINT("hot upgrade info is_inherited can't be true, ret=%d", ret); @@ -514,11 +528,18 @@ int ObProxyMain::handle_inherited_sockets(const int argc, char *const argv[]) // obproxy will start by hot upgrade // we will set it HU_STATE_WAIT_CR_CMD state and HU_STATUS_NEW_PROXY_CREATED_SUCC status info.is_inherited_ = true; - info.fd_ = atoi(inherited); + info.ipv4_fd_ = atoi(inherited_ipv4); + + if (NULL != inherited_ipv6) { + info.ipv6_fd_ = atoi(inherited_ipv6); + } + info.update_state(HU_STATE_WAIT_HU_CMD); info.is_parent_ = false; - if (OB_FAIL(unsetenv(OBPROXY_INHERITED_FD))) { - MPRINT("fail to unsetenv OBPROXY_INHERITED_FD, ret=%d", ret); + if (OB_FAIL(unsetenv(OBPROXY_INHERITED_IPV4_FD))) { + MPRINT("fail to unsetenv OBPROXY_INHERITED_IPV4_FD, ret=%d", ret); + } else if (OB_FAIL(unsetenv(OBPROXY_INHERITED_IPV6_FD))) { + MPRINT("fail to unsetenv OBPROXY_INHERITED_IPV6_FD, ret=%d", ret); } } } @@ -536,7 +557,13 @@ int ObProxyMain::init_log() LOG_ERROR("fail to get log file name", K(type), K(ret)); } else { if (FD_DEFAULT_FILE == type) { - OB_LOGGER.set_file_name(type, log_file_name, true, true); + if (RUN_MODE_PROXY == g_run_mode) { + OB_LOGGER.set_file_name(type, log_file_name, true, true); + } else if (RUN_MODE_CLIENT == g_run_mode) { + OB_LOGGER.set_file_name(type, log_file_name, false, true); + } else { + MPRINT("invalid g_run_mode, mode=%d", g_run_mode); + } } else { OB_LOGGER.set_file_name(type, log_file_name); } @@ -578,6 +605,8 @@ int ObProxyMain::init_signal() LOG_WARN("fail to add_sig_direct_catched", K(ret)); } else if (OB_FAIL(add_sig_direct_catched(action, SIGUSR1))) { LOG_WARN("fail to add_sig_direct_catched", K(ret)); + } else if (OB_FAIL(add_sig_direct_catched(action, SIGUSR2))) { + LOG_WARN("fail to add_sig_direct_catched", K(ret)); } else if (OB_FAIL(add_sig_direct_catched(action, 43))) { LOG_WARN("fail to add_sig_direct_catched", K(ret)); @@ -738,16 +767,17 @@ int ObProxyMain::do_detect_sig() // -1 : wait for any sub process while((pid = waitpid(-1, &stat, WNOHANG)) > 0) { LOG_INFO("sub process exit", K(info), K(pid), "status", stat, KERRMSGS); - if (info.sub_pid_ == pid) { - info.reset_sub_pid(); - // after sub was exited, we need passing this status - if (OB_LIKELY(common::OB_SUCCESS == lib::mutex_acquire(&info.hot_upgrade_mutex_))) { + if (OB_LIKELY(common::OB_SUCCESS == lib::mutex_acquire(&info.hot_upgrade_mutex_))) { + if (info.sub_pid_ == pid) { + info.reset_sub_pid(); + // after sub was exited, we need passing this status info.update_sub_status(HU_STATUS_EXITED); info.parent_hot_upgrade_flag_ = false; lib::mutex_release(&info.hot_upgrade_mutex_); + } else { + LOG_WARN("sub process exit, but recv it late"); } - } else { - LOG_WARN("sub process exit, but recv it late"); + lib::mutex_release(&info.hot_upgrade_mutex_); } } break; @@ -826,6 +856,17 @@ void ObProxyMain::sig_direct_handler(const int sig) } break; } + case SIGUSR2: { + ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); + if (OB_LIKELY(common::OB_SUCCESS == lib::mutex_acquire(&info.hot_upgrade_mutex_))) { + // If the SIGUSR2 signal is received, + // the child process is considered to exit normally, + // and the child process is ignored + info.reset_sub_pid(); + lib::mutex_release(&info.hot_upgrade_mutex_); + } + break; + } case SIGTERM: case SIGINT: { ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); @@ -945,7 +986,7 @@ int ObProxyMain::do_monitor_mem() } } - if (is_out_of_mem_limit) { + if (is_out_of_mem_limit && RUN_MODE_PROXY == g_run_mode) { LOG_ERROR("obproxy's memroy is out of limit, will be going to commit suicide", K(mem_limited), "OTHER_MEMORY_SIZE", static_cast(OTHER_MEMORY_SIZE), K(is_out_of_mem_limit), K(cur_pos)); @@ -1033,7 +1074,7 @@ int ObProxyMain::do_detect_sqlaudit() return ret; } -int ObProxyMain::close_all_fd(const int32_t listen_fd) +int ObProxyMain::close_all_fd(const int32_t listen_ipv4_fd, const int32_t listen_ipv6_fd) { //this func can't print log, because log isn't initialized int ret = OB_SUCCESS; @@ -1042,7 +1083,7 @@ int ObProxyMain::close_all_fd(const int32_t listen_fd) DIR *fd_dir = NULL; char fd_dir_path [OB_MAX_FILE_NAME_LENGTH]; - if (OB_UNLIKELY(listen_fd < 3)) { + if (OB_UNLIKELY(listen_ipv4_fd < 3 && listen_ipv6_fd < 3)) { ret = OB_INVALID_ARGUMENT; } else { int n = snprintf(fd_dir_path, OB_MAX_FILE_NAME_LENGTH, "/proc/%d/fd", pid); @@ -1062,7 +1103,8 @@ int ObProxyMain::close_all_fd(const int32_t listen_fd) fd = static_cast(strtol(de->d_name, NULL, 10)); if (fd < 0) { continue; - } else if (fd < 3 || fd == dirfd(fd_dir) || fd == listen_fd) { + } else if (fd < 3 || fd == dirfd(fd_dir) || fd == listen_ipv4_fd + || fd == listen_ipv6_fd) { continue; } else { if (OB_UNLIKELY(0 != close(fd))) { diff --git a/src/obproxy/ob_proxy_main.h b/src/obproxy/ob_proxy_main.h index e2985781..35a5d8a4 100644 --- a/src/obproxy/ob_proxy_main.h +++ b/src/obproxy/ob_proxy_main.h @@ -86,7 +86,7 @@ class ObProxyMain int init_log(); int init_signal(); - int close_all_fd(const int32_t listen_fd); + int close_all_fd(const int32_t listen_ipv4_fd, const int32_t listen_ipv6_fd); class ObLogLevel { diff --git a/src/obproxy/obutils/ob_async_common_task.cpp b/src/obproxy/obutils/ob_async_common_task.cpp index 501541f0..cb05e6f1 100644 --- a/src/obproxy/obutils/ob_async_common_task.cpp +++ b/src/obproxy/obutils/ob_async_common_task.cpp @@ -117,7 +117,7 @@ int ObAsyncCommonTask::main_handler(int event, void *data) return EVENT_DONE; } -inline int ObAsyncCommonTask::handle_event_start() +int ObAsyncCommonTask::handle_event_start() { int ret = OB_SUCCESS; if (action_.cancelled_) { @@ -134,7 +134,7 @@ inline int ObAsyncCommonTask::handle_event_start() return ret; } -inline int ObAsyncCommonTask::handle_event_complete(void *data) +int ObAsyncCommonTask::handle_event_complete(void *data) { int ret = OB_SUCCESS; if (action_.cancelled_) { diff --git a/src/obproxy/obutils/ob_config_processor.cpp b/src/obproxy/obutils/ob_config_processor.cpp index 08ae8b37..19dd9004 100644 --- a/src/obproxy/obutils/ob_config_processor.cpp +++ b/src/obproxy/obutils/ob_config_processor.cpp @@ -60,7 +60,7 @@ namespace obutils //the table name need to be lower case, or func'handle_dml_stmt' will get error #define MAX_INIT_SQL_LEN 1024 -static const char* sqlite3_db_name = "etc/proxyconfig.db"; +static const char* sqlite3_db_name = "proxyconfig.db"; static const char* all_table_version_table_name = "all_table_version"; static const char* white_list_table_name = "white_list"; static const char* resource_unit_table_name = "resource_unit"; @@ -124,12 +124,28 @@ ObConfigProcessor::~ObConfigProcessor() int ObConfigProcessor::init() { int ret = OB_SUCCESS; + const char *dir = NULL; if (OB_FAIL(table_handler_map_.create(32, ObModIds::OB_HASH_BUCKET))) { LOG_WARN("create hash map failed", K(ret)); - } else if (SQLITE_OK != sqlite3_open_v2( - sqlite3_db_name, &proxy_config_db_, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) { + } else if (OB_ISNULL(dir = get_global_layout().get_etc_dir())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("sqlite3 open failed", K(ret), "err_msg", sqlite3_errmsg(proxy_config_db_)); + LOG_WARN("get etc dir failed", K(ret)); + } else { + char *path = NULL; + ObFixedArenaAllocator allocator; + if (OB_FAIL(ObLayout::merge_file_path(dir, sqlite3_db_name, allocator, path))) { + LOG_WARN("fail to merge file path", K(sqlite3_db_name), K(ret)); + } else if (OB_ISNULL(path)) { + ret = OB_ERR_UNEXPECTED; + } else if (SQLITE_OK != sqlite3_open_v2( + path, &proxy_config_db_, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sqlite3 open failed", K(ret), "path", path, "err_msg", sqlite3_errmsg(proxy_config_db_)); + } + } + + if (OB_FAIL(ret)) { + // do nothing } else if (OB_FAIL(check_and_create_table())) { LOG_WARN("check create table failed", K(ret)); } else { @@ -175,14 +191,20 @@ int ObConfigProcessor::init_callback(void *data, int argc, char **argv, char **c if (NULL == argv[i]) { continue; } else { - SqlField sql_field; - sql_field.column_name_.set_string(column_name[i], static_cast(strlen(column_name[i]))); - sql_field.value_type_ = TOKEN_STR_VAL; - sql_field.column_value_.set_value(static_cast(strlen(argv[i])), argv[i]); - if (OB_FAIL(field_result.fields_.push_back(sql_field))) { - LOG_WARN("push back failed", K(ret)); + SqlField *sql_field = NULL; + if (OB_FAIL(SqlField::alloc_sql_field(sql_field))) { + LOG_WARN("fail to alloc sql field", K(ret)); } else { - field_result.field_num_++; + sql_field->column_name_.set_value(static_cast(strlen(column_name[i])), column_name[i]); + sql_field->value_type_ = TOKEN_STR_VAL; + sql_field->column_value_.set_value(static_cast(strlen(argv[i])), argv[i]); + if (OB_FAIL(field_result.fields_.push_back(sql_field))) { + sql_field->reset(); + sql_field = NULL; + LOG_WARN("push back failed", K(ret)); + } else { + field_result.field_num_++; + } } } } @@ -192,11 +214,11 @@ int ObConfigProcessor::init_callback(void *data, int argc, char **argv, char **c const char* cluster_name_str = "cluster_name"; const char* tenant_name_str = "tenant_name"; for (int64_t i = 0; i < field_result.field_num_; i++) { - SqlField &field = field_result.fields_.at(i); - if (field.column_name_.string_ == cluster_name_str) { - params.cluster_name_ = field.column_value_.config_string_; - } else if (field.column_name_.string_ == tenant_name_str) { - params.tenant_name_ = field.column_value_.config_string_; + SqlField* field = field_result.fields_.at(i); + if (field->column_name_.config_string_ == cluster_name_str) { + params.cluster_name_ = field->column_value_.config_string_; + } else if (field->column_name_.config_string_ == tenant_name_str) { + params.tenant_name_ = field->column_value_.config_string_; } } @@ -370,11 +392,11 @@ int ObConfigProcessor::handle_dml_stmt(ObString &sql, ParseResult& parse_result, const char* cluster_name_str = "cluster_name"; const char* tenant_name_str = "tenant_name"; for (int64_t i = 0; i < params.fields_->field_num_; i++) { - SqlField &field = params.fields_->fields_.at(i); - if (field.column_name_.string_ == cluster_name_str) { - params.cluster_name_ = field.column_value_.config_string_; - } else if (field.column_name_.string_ == tenant_name_str) { - params.tenant_name_ = field.column_value_.config_string_; + SqlField* field = params.fields_->fields_.at(i); + if (field->column_name_.config_string_ == cluster_name_str) { + params.cluster_name_ = field->column_value_.config_string_; + } else if (field->column_name_.config_string_ == tenant_name_str) { + params.tenant_name_ = field->column_value_.config_string_; } } //table name is UPPER CASE in stmt, need convert to lower case as origin @@ -404,12 +426,31 @@ int ObConfigProcessor::handle_dml_stmt(ObString &sql, ParseResult& parse_result, } else { memcpy(sql_buf, sql.ptr(), sql.length()); sql_buf[sql.length()] = '\0'; - if (SQLITE_OK != sqlite3_exec(proxy_config_db_, sql_buf, NULL, 0, &err_msg)) { + if (SQLITE_OK != sqlite3_exec(proxy_config_db_, "begin;", NULL, 0, &err_msg)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sqlite3 exec failed", K(sql), "err_msg", err_msg); + sqlite3_free(err_msg); + } + + if (OB_SUCC(ret) && SQLITE_OK != sqlite3_exec(proxy_config_db_, sql_buf, NULL, 0, &err_msg)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sqlite3 exec failed", K(sql), "err_msg", err_msg); sqlite3_free(err_msg); } ob_free(sql_buf); + + if (OB_SUCC(ret) && NULL != handler.before_commit_func_) { + if (OB_FAIL(handler.before_commit_func_(proxy_config_db_))) { + LOG_WARN("before commit func failed", K_(params.table_name), K(ret)); + } + } + + const char *end_sql = OB_SUCCESS == ret ? "commit;" : "rollback;"; + if (SQLITE_OK != sqlite3_exec(proxy_config_db_, end_sql, NULL, 0, &err_msg)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sqlite3 exec failed", K(sql), "err_msg", err_msg); + sqlite3_free(err_msg); + } } tmp_ret = ret; } @@ -523,6 +564,18 @@ bool ObConfigProcessor::is_table_in_service(const ObString &table_name) return is_in_service; } +int ObConfigProcessor::execute(const char* sql, int (*callback)(void*, int, char**, char**), void* handler) +{ + int ret = OB_SUCCESS; + char *err_msg = NULL; + if (SQLITE_OK != sqlite3_exec(proxy_config_db_, sql, callback, handler, &err_msg)) { + ret = OB_ERR_UNEXPECTED; + WARN_ICMD("exec sql failed", K(ret), "err_msg", err_msg); + sqlite3_free(err_msg); + } + return ret; +} + int ObConfigProcessor::store_global_ssl_config(const ObString &name, const ObString &value) { int ret = OB_SUCCESS; @@ -559,27 +612,42 @@ int ObConfigProcessor::store_global_ssl_config(const ObString &name, const ObStr return ret; } -int ObConfigProcessor::store_global_proxy_config(const ObString &name, const ObString &value) +int ObConfigProcessor::store_proxy_config_with_level(int64_t vid, const ObString &vip, int64_t vport, + const ObString &tenant_name, const ObString &cluster_name, + const ObString &name, const ObString& value, const ObString &level) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(name.empty())) { + if (OB_UNLIKELY(name.empty() || level.empty())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(name), K(value)); + LOG_WARN("invalid argument", K(name), K(level)); } else { - const char *sql = "replace into proxy_config(name, value, config_level) values('%.*s', '%.*s', 'LEVEL_GLOBAL')"; - int64_t buf_len = name.length() + value.length() + strlen(sql); + const char *sql = + "replace into proxy_config(vid, vip, vport, cluster_name, tenant_name, name, value, config_level) " + "values(%ld, '%.*s', %ld, '%.*s', '%.*s', '%.*s', '%.*s', '%.*s')"; + char vid_buf[64]; + char vport_buf[64]; + int32_t vid_len = snprintf(vid_buf, sizeof(vid_buf), "%ld", vid); + int32_t vport_len = snprintf(vport_buf, sizeof(vport_buf), "%ld", vport); + int64_t buf_len = vid_len + vport_len + vip.length() + tenant_name.length() + cluster_name.length() + name.length() + value.length() + level.length() + strlen(sql); char *sql_buf = (char*)ob_malloc(buf_len + 1, ObModIds::OB_PROXY_CONFIG_TABLE); if (OB_ISNULL(sql_buf)) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("allocate memory failed", K(ret), K(buf_len)); } else { ObString sql_string; - int64_t len = 0; + int32_t len = 0; get_global_proxy_config_table_processor().set_need_sync_to_file(false); - len = static_cast(snprintf(sql_buf, buf_len, sql, + len = static_cast(snprintf(sql_buf, buf_len, sql, + vid, + vip.length(), vip.ptr(), + vport, + cluster_name.length(), cluster_name.ptr(), + tenant_name.length(), tenant_name.ptr(), name.length(), name.ptr(), - value.length(), value.ptr())); - sql_string.assign_ptr(sql_buf, static_cast(len)); + value.length(), value.ptr(), + level.length(), level.ptr())); + sql_string.assign_ptr(sql_buf, len); + LOG_DEBUG("execute sql", K(sql_string)); if (OB_UNLIKELY(len <= 0)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to fill sql", K(len), K(ret)); @@ -597,6 +665,15 @@ int ObConfigProcessor::store_global_proxy_config(const ObString &name, const ObS return ret; } +int ObConfigProcessor::store_global_proxy_config(const ObString &name, const ObString &value) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(store_proxy_config_with_level(-1, "", 0, "", "", name, value, "LEVEL_GLOBAL"))) { + LOG_WARN("store_proxy_config_with_level failed", K(ret)); + } + return ret; +} + int ObConfigProcessor::get_proxy_config_with_level(const ObVipAddr &addr, const common::ObString &cluster_name, const common::ObString &tenant_name, const common::ObString& name, common::ObConfigItem &ret_item, const ObString level, bool &found) @@ -612,7 +689,7 @@ int ObConfigProcessor::get_proxy_config_with_level(const ObVipAddr &addr, const } } else if (0 != strcasecmp(proxy_item.config_level_.ptr(), level.ptr())) { ret = OB_SUCCESS; - LOG_DEBUG("vip config level not match", K(proxy_item)); + LOG_TRACE("vip config level not match", K(proxy_item), K(level)); } else { found = true; ret_item = proxy_item.config_item_; @@ -675,6 +752,22 @@ int ObConfigProcessor::get_proxy_config_bool_item(const ObVipAddr &addr, const O return ret; } +int ObConfigProcessor::get_proxy_config_int_item(const ObVipAddr &addr, const ObString &cluster_name, + const ObString &tenant_name, const ObString& name, + ObConfigIntItem &ret_item) +{ + int ret = OB_SUCCESS; + ObConfigItem item; + if (OB_FAIL(get_proxy_config(addr, cluster_name, tenant_name, name, item))) { + LOG_WARN("get proxy config failed", K(addr), K(cluster_name), K(tenant_name), K(name), K(ret)); + } else { + ret_item.set(item.str()); + LOG_DEBUG("get int item succ", K(ret_item)); + } + + return ret; +} + } // end of obutils } // end of obproxy } // end of oceanbase diff --git a/src/obproxy/obutils/ob_config_processor.h b/src/obproxy/obutils/ob_config_processor.h index ef0224e9..156789a8 100644 --- a/src/obproxy/obutils/ob_config_processor.h +++ b/src/obproxy/obutils/ob_config_processor.h @@ -54,11 +54,14 @@ struct ObVipAddr; typedef int (*config_processor_execute) (void *); typedef int (*config_processor_commit) (void*, bool is_success); +typedef int (*config_processor_before_commit) (void *); struct ObConfigHandler { + ObConfigHandler() : execute_func_(NULL), commit_func_(NULL), before_commit_func_(NULL) {} config_processor_execute execute_func_; config_processor_commit commit_func_; + config_processor_before_commit before_commit_func_; }; typedef common::hash::ObHashMap, ObConfigHandler> ConfigHandlerHashMap; @@ -98,6 +101,11 @@ class ObConfigProcessor bool is_table_in_service(const common::ObString &table_name); int store_global_ssl_config(const common::ObString& name, const common::ObString &value); int store_global_proxy_config(const common::ObString &name, const common::ObString &value); + int store_vip_tenant_cluster_config(int64_t vid, const ObString &vip, int64_t vport, + const ObString &name, const ObString &value); + int store_proxy_config_with_level(int64_t vid, const ObString &vip, int64_t vport, + const ObString &cluster_name, const ObString &tenant_name, + const ObString &name, const ObString &value, const ObString &level); int get_proxy_config(const ObVipAddr &addr, const common::ObString &cluster_name, const common::ObString &tenant_name, const common::ObString& name, @@ -105,15 +113,19 @@ class ObConfigProcessor int get_proxy_config_bool_item(const ObVipAddr &addr, const common::ObString &cluster_name, const common::ObString &tenant_name, const common::ObString& name, common::ObConfigBoolItem &ret_item); + int get_proxy_config_int_item(const ObVipAddr &addr, const common::ObString &cluster_name, + const common::ObString &tenant_name, const common::ObString& name, + common::ObConfigIntItem &ret_item); + int get_proxy_config_with_level(const ObVipAddr &addr, const common::ObString &cluster_name, + const common::ObString &tenant_name, const common::ObString& name, + common::ObConfigItem &ret_item, const ObString level, bool &found); + int execute(const char* sql, int (*callback)(void*, int, char**, char**), void* handler); private: int init_config_from_disk(); int check_and_create_table(); int handle_dml_stmt(common::ObString &sql, ParseResult& parse_result, ObArenaAllocator&allocator); int handle_select_stmt(common::ObString &sql, obproxy::ObConfigV2Handler *v2_handler); - int get_proxy_config_with_level(const ObVipAddr &addr, const common::ObString &cluster_name, - const common::ObString &tenant_name, const common::ObString& name, - common::ObConfigItem &ret_item, const ObString level, bool &found); static int init_callback(void *data, int argc, char **argv, char **column_name); static int sqlite3_callback(void *data, int argc, char **argv, char **column_name); diff --git a/src/obproxy/obutils/ob_congestion_entry.cpp b/src/obproxy/obutils/ob_congestion_entry.cpp index 54859add..ec3cbf7b 100644 --- a/src/obproxy/obutils/ob_congestion_entry.cpp +++ b/src/obproxy/obutils/ob_congestion_entry.cpp @@ -91,6 +91,7 @@ ObCongestionEntry::ObCongestionEntry(const ObIpEndpoint &ip) last_dead_congested_(0), dead_congested_(0), last_alive_congested_(0),alive_congested_(0), last_detect_congested_(0), detect_congested_(0), + last_client_feedback_congested_(0), stat_client_feedback_failures_(0), client_feedback_congested_(0), stat_conn_failures_(0), stat_alive_failures_(0), last_revalidate_time_us_(0), cr_version_(-1) { @@ -380,7 +381,7 @@ void ObCongestionEntry::set_alive_failed_at(const ObHRTime t) (void)ATOMIC_FAA(&stat_alive_failures_, 1); if (control_config_->alive_failure_threshold_ >= 0) { int64_t time = hrtime_to_sec(t); - LOG_INFO("alive failed at", K(t)); + LOG_INFO("alive failed at", K(t), KPC(this)); MUTEX_TRY_LOCK(lock, fail_hist_lock_, this_ethread()); if (lock.is_locked()) { alive_fail_history_.regist_event(time); @@ -390,7 +391,32 @@ void ObCongestionEntry::set_alive_failed_at(const ObHRTime t) if (new_congested && !ATOMIC_TAS(&alive_congested_, 1)) { last_alive_congested_ = alive_fail_history_.last_event_; // action congested ? - LOG_INFO("set_alive_congested", KPC(this)); + LOG_INFO("set alive congested", KPC(this)); + } + } + } else { + LOG_DEBUG("failure info lost due to lock contention", + KPC(this), K(time)); + } + } +} + +void ObCongestionEntry::set_client_feedback_failed_at(const ObHRTime t) +{ + (void)ATOMIC_FAA(&stat_client_feedback_failures_, 1); + if (control_config_->alive_failure_threshold_ >= 0) { + int64_t time = hrtime_to_sec(t); + LOG_INFO("client feedback failed at", K(t)); + MUTEX_TRY_LOCK(lock, fail_hist_lock_, this_ethread()); + if (lock.is_locked()) { + client_feedback_fail_history_.regist_event(time); + if (!client_feedback_congested_) { + bool new_congested = check_client_feedback_congested(); + // TODO: This used to signal via SNMP + if (new_congested && !ATOMIC_TAS(&client_feedback_congested_, 1)) { + last_client_feedback_congested_ = client_feedback_fail_history_.last_event_; + // action congested ? + LOG_INFO("set_client_feedback_congested", KPC(this)); } } } else { @@ -435,7 +461,7 @@ void ObCongestionEntry::set_alive_congested() // action congested ? } else { last_alive_congested_ = ObTimeUtility::extract_second(ObTimeUtility::current_time()); - LOG_INFO("set_alive_congested", KPC(this)); + LOG_INFO("set alive congested", KPC(this)); } } @@ -473,7 +499,6 @@ void ObCongestionEntry::set_detect_congested() } else { last_detect_congested_ = ObTimeUtility::extract_second(ObTimeUtility::current_time()); LOG_INFO("set detect congested", KPC(this)); - get_global_resource_pool_processor().ip_set_.set_refactored(server_ip_); } } @@ -483,7 +508,6 @@ void ObCongestionEntry::set_detect_congested_free() // action not congested ? LOG_INFO("set detect congested free", KPC(this)); } - get_global_resource_pool_processor().ip_set_.erase_refactored(server_ip_); } diff --git a/src/obproxy/obutils/ob_congestion_entry.h b/src/obproxy/obutils/ob_congestion_entry.h index d0c4c82e..0c9f04f1 100644 --- a/src/obproxy/obutils/ob_congestion_entry.h +++ b/src/obproxy/obutils/ob_congestion_entry.h @@ -290,6 +290,7 @@ struct ObCongestionEntry : public ObCongestionRefCnt void set_detect_congested_free(); void set_dead_failed_at(const ObHRTime t); void set_alive_failed_at(const ObHRTime t); + void set_client_feedback_failed_at(const ObHRTime t); // Connection controls bool alive_need_retry(const ObHRTime t); @@ -300,6 +301,7 @@ struct ObCongestionEntry : public ObCongestionRefCnt void reset_fail_history(); bool check_dead_congested(); bool check_alive_congested(); + bool check_client_feedback_congested(); // ObCongestionEntry and ObCongestionControl config interaction helper functions int validate_config(ObCongestionControlConfig *config); @@ -338,6 +340,11 @@ struct ObCongestionEntry : public ObCongestionRefCnt ObHRTime last_detect_congested_; volatile int64_t detect_congested_; + ObFailHistory client_feedback_fail_history_; + ObHRTime last_client_feedback_congested_; + volatile int64_t stat_client_feedback_failures_; + int64_t client_feedback_congested_; + volatile int64_t stat_conn_failures_; volatile int64_t stat_alive_failures_; int64_t last_revalidate_time_us_; // unit us @@ -437,12 +444,27 @@ inline bool ObCongestionEntry::check_alive_congested() return bret; } +inline bool ObCongestionEntry::check_client_feedback_congested() +{ + bool bret = false; + if (1 == client_feedback_congested_) { + bret = true; + } else if (control_config_->alive_failure_threshold_ < 0) { + bret = false; + } else { + bret = control_config_->alive_failure_threshold_ <= client_feedback_fail_history_.events_; + } + + return bret; +} + inline void ObCongestionEntry::reset_fail_history() { conn_fail_history_.init(control_config_->fail_window_sec_); dead_congested_ = 0; alive_fail_history_.init(control_config_->fail_window_sec_); alive_congested_ = 0; + client_feedback_fail_history_.init(control_config_->fail_window_sec_); } void ObCongestionEntry::free() diff --git a/src/obproxy/obutils/ob_congestion_manager.cpp b/src/obproxy/obutils/ob_congestion_manager.cpp index 3d18b4c2..1be3253b 100644 --- a/src/obproxy/obutils/ob_congestion_manager.cpp +++ b/src/obproxy/obutils/ob_congestion_manager.cpp @@ -382,6 +382,7 @@ int ObCongestionManager::add_new_server(const net::ObIpEndpoint &ip, break; case ObCongestionEntry::DETECT_ALIVE: entry->set_detect_congested_free(); + entry->set_alive_congested_free(); break; case ObCongestionEntry::DETECT_DEAD: entry->set_detect_congested(); @@ -607,6 +608,7 @@ int ObCongestionManager::process(const int64_t buck_id, ObCongestRequestParam *p break; case ObCongestionEntry::DETECT_ALIVE: entry->set_detect_congested_free(); + entry->set_alive_congested_free(); break; case ObCongestionEntry::DETECT_DEAD: entry->set_detect_congested(); @@ -985,6 +987,7 @@ int ObCongestionManager::revalidate_server(const ObIpEndpoint &ip, break; case ObCongestionEntry::DETECT_ALIVE: entry->set_detect_congested_free(); + entry->set_alive_congested_free(); break; case ObCongestionEntry::DETECT_DEAD: entry->set_detect_congested(); @@ -1014,7 +1017,7 @@ int ObCongestionManager::revalidate_server(const ObIpEndpoint &ip, } } else { LOG_DEBUG("failed to lock_bucket, add to todo_list", "server_state", - ObCongestionEntry::get_server_state_name(server_state), K(*entry)); + ObCongestionEntry::get_server_state_name(server_state)); ObCongestRequestParam *param = op_alloc(ObCongestRequestParam); if (OB_ISNULL(param)) { ret = OB_ALLOCATE_MEMORY_FAILED; diff --git a/src/obproxy/obutils/ob_hot_upgrade_processor.cpp b/src/obproxy/obutils/ob_hot_upgrade_processor.cpp index 5ddfbc27..bedfce3e 100644 --- a/src/obproxy/obutils/ob_hot_upgrade_processor.cpp +++ b/src/obproxy/obutils/ob_hot_upgrade_processor.cpp @@ -110,7 +110,7 @@ int ObProxyHotUpgrader::get_envp(char **&envp) { static const int64_t OBPROXY_ENVP_MAX_SIZE = 128; int ret = OB_SUCCESS; - int64_t count = 1; // envp's valid items count + int64_t count = 2; // envp's valid items count bool is_obproxy_root_set = false; char *obproxy_root = NULL; if (NULL != (obproxy_root = getenv("OBPROXY_ROOT"))) { @@ -128,7 +128,8 @@ int ObProxyHotUpgrader::get_envp(char **&envp) memset(var, 0, size); envp = reinterpret_cast(var); envp[0] = reinterpret_cast(malloc(OBPROXY_ENVP_MAX_SIZE)); - if (OB_ISNULL(envp[0])) { + envp[1] = reinterpret_cast(malloc(OBPROXY_ENVP_MAX_SIZE)); + if (OB_ISNULL(envp[0]) || OB_ISNULL(envp[1])) { ret = OB_ALLOCATE_MEMORY_FAILED; free(var); var = NULL; @@ -137,16 +138,23 @@ int ObProxyHotUpgrader::get_envp(char **&envp) } else { const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); int64_t length = snprintf(envp[0], static_cast(OBPROXY_ENVP_MAX_SIZE), - OBPROXY_INHERITED_FD"=%d", info.fd_); + OBPROXY_INHERITED_IPV4_FD"=%d", info.ipv4_fd_); if (OB_UNLIKELY(length <= 0) || OB_UNLIKELY(length >= OBPROXY_ENVP_MAX_SIZE)) { ret = OB_BUF_NOT_ENOUGH; LOG_WARN("buf not enought", K(length), "envp[0]_length", OBPROXY_ENVP_MAX_SIZE, K(envp[0]), K(ret)); + } else { + int64_t length = snprintf(envp[1], static_cast(OBPROXY_ENVP_MAX_SIZE), + OBPROXY_INHERITED_IPV6_FD"=%d", info.ipv6_fd_); + if (OB_UNLIKELY(length <= 0) || OB_UNLIKELY(length >= OBPROXY_ENVP_MAX_SIZE)) { + ret = OB_BUF_NOT_ENOUGH; + LOG_WARN("buf not enought", K(length), "envp[0]_length", OBPROXY_ENVP_MAX_SIZE, K(envp[1]), K(ret)); + } } } //set OBPROXY_ROOT if (OB_SUCC(ret) && is_obproxy_root_set) { - envp[1] = reinterpret_cast(malloc(OBPROXY_ENVP_MAX_SIZE)); - if (OB_ISNULL(envp[1])) { + envp[2] = reinterpret_cast(malloc(OBPROXY_ENVP_MAX_SIZE)); + if (OB_ISNULL(envp[2])) { ret = OB_ALLOCATE_MEMORY_FAILED; free(envp[0]); free(var); @@ -154,11 +162,11 @@ int ObProxyHotUpgrader::get_envp(char **&envp) envp = NULL; LOG_ERROR("fail to malloc", K(ret)); } else { - int64_t length = snprintf(envp[1], static_cast(OBPROXY_ENVP_MAX_SIZE), + int64_t length = snprintf(envp[2], static_cast(OBPROXY_ENVP_MAX_SIZE), "OBPROXY_ROOT=%s", obproxy_root); if (OB_UNLIKELY(length <= 0) || OB_UNLIKELY(length >= OBPROXY_ENVP_MAX_SIZE)) { ret = OB_BUF_NOT_ENOUGH; - LOG_WARN("buf not enought", K(length), "envp[1]_length", OBPROXY_ENVP_MAX_SIZE, K(envp[1]), K(ret)); + LOG_WARN("buf not enought", K(length), "envp[2]_length", OBPROXY_ENVP_MAX_SIZE, K(envp[2]), K(ret)); } } } @@ -1289,6 +1297,8 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O char passwd_staged1_buf[ENC_STRING_BUF_LEN] = {0}; // 1B '*' + 40B octal num ObProxyLoginInfo login_info; int64_t pos = 0; + char cluster_name_buf[OB_PROXY_FULL_USER_NAME_MAX_LEN + 1]; + ObString cluster_name; switch (type) { case USER_TYPE_METADB: { @@ -1311,14 +1321,13 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O break; } case USER_TYPE_PROXYRO: { - char cluster_name[OB_PROXY_FULL_USER_NAME_MAX_LEN + 1]; - cluster_name[0] = '\0'; - if (OB_FAIL(get_global_config_server_processor().get_default_cluster_name(cluster_name, OB_PROXY_FULL_USER_NAME_MAX_LEN + 1))) { + cluster_name_buf[0] = '\0'; + if (OB_FAIL(get_global_config_server_processor().get_default_cluster_name(cluster_name_buf, OB_PROXY_FULL_USER_NAME_MAX_LEN + 1))) { LOG_WARN("fail to get default cluster name", K(ret)); } else { - ObString default_cname = '\0' == cluster_name[0] + ObString default_cname = '\0' == cluster_name_buf[0] ? ObString::make_string(OB_PROXY_DEFAULT_CLUSTER_NAME) - : ObString::make_string(cluster_name); + : ObString::make_string(cluster_name_buf); if (OB_FAIL(databuff_printf(full_user_name, OB_PROXY_FULL_USER_NAME_MAX_LEN + 1, pos, "%s#%.*s", ObProxyTableInfo::READ_ONLY_USERNAME, default_cname.length(), default_cname.ptr()))) { LOG_WARN("fail to databuff_printf", "username", ObProxyTableInfo::READ_ONLY_USERNAME, K(default_cname), K(ret)); @@ -1330,6 +1339,7 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O static_cast(strlen(get_global_proxy_config().observer_sys_password1.str()))); string_db.assign_ptr(ObProxyTableInfo::READ_ONLY_DATABASE, static_cast(STRLEN(ObProxyTableInfo::READ_ONLY_DATABASE))); + cluster_name.assign_ptr(cluster_name_buf, static_cast(strlen(cluster_name_buf))); } } break; @@ -1357,12 +1367,12 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O if (OB_SUCC(ret)) { ObSEArray local_addrs; ObAddr addr; - if (OB_UNLIKELY(!addr.set_ipv4_addr(proxy_ip_, proxy_port_))) { + if (OB_UNLIKELY(!addr.set_ip_addr(proxy_ip_, proxy_port_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to set addr", K(proxy_ip_), K(proxy_port_), K(ret)); } else if (OB_FAIL(local_addrs.push_back(addr))) { LOG_WARN("fail to push addr to local_addrs", K(addr), K(ret)); - } else if (OB_FAIL(raw_client.init(string_username, string_passwd, string_db, string_passwd1))) { + } else if (OB_FAIL(raw_client.init(string_username, string_passwd, string_db, cluster_name, string_passwd1))) { LOG_WARN("fail to init raw mysql client", K(string_username), K(string_db), K(ret)); } else if (OB_FAIL(raw_client.set_server_addr(local_addrs))) { LOG_WARN("fail to set server addr", K(ret)); diff --git a/src/obproxy/obutils/ob_hot_upgrade_processor.h b/src/obproxy/obutils/ob_hot_upgrade_processor.h index 86798808..51824001 100644 --- a/src/obproxy/obutils/ob_hot_upgrade_processor.h +++ b/src/obproxy/obutils/ob_hot_upgrade_processor.h @@ -133,7 +133,7 @@ class ObHotUpgradeProcessor ObAsyncCommonTask *hu_cont_; ObAsyncCommonTask *hot_upgrade_cont_; ObHotUpgraderInfo &info_; - char proxy_ip_[common::OB_IP_STR_BUFF]; // ip primary key + char proxy_ip_[common::MAX_IP_ADDR_LENGTH]; // ip primary key char proxy_self_md5_[OB_DEFAULT_PROXY_MD5_LEN + 1]; int32_t proxy_port_; // port primary key int64_t upgrade_failures_; // upgrade failures when handling 'hot_upgrade' cmd diff --git a/src/obproxy/obutils/ob_proxy_config.h b/src/obproxy/obutils/ob_proxy_config.h index 92c7465a..906eefdb 100644 --- a/src/obproxy/obutils/ob_proxy_config.h +++ b/src/obproxy/obutils/ob_proxy_config.h @@ -148,6 +148,8 @@ class ObProxyConfig : public common::ObCommonConfig public: // FIXME: DEF_INT can not compare with 0(<, >, >=, <=) mutable obsys::CRWLock rwlock_; + // xa transaction + DEF_BOOL(enable_xa_route, "true", "whether to enable hold XA_START and route to the partition that the next dml will visit",CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); // refresh local config DEF_BOOL(refresh_json_config, "false", "force update json info if refresh_json_config is true", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_MEMORY); DEF_BOOL(refresh_rslist, "false", "when refresh config server, update all rslist if refresh_rslist is true", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_MEMORY); @@ -218,7 +220,7 @@ class ObProxyConfig : public common::ObCommonConfig DEF_INT(server_tcp_keepcnt, "5", "[0,9]", "tcp keepalive probe count, 0 means use default value by kernel", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(server_tcp_user_timeout, "0", "[0,20]", "tcp user timeout, unit is s, 0 means no user timeout", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_INT(client_sock_option_flag_out, "2", "[0,]","client sock param, option flag out, bit 1: NO_DELAY, bit 2: KEEP_ALIVE", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_INT(client_sock_option_flag_out, "3", "[0,]","client sock param, option flag out, bit 1: NO_DELAY, bit 2: KEEP_ALIVE", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(client_tcp_keepidle, "5", "[0,7200]", "client tcp keepalive idle time, unit is second, 0 means use default value by kernel", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(client_tcp_keepintvl, "5", "[0,75]", "client tcp keepalive interval time, unit is second, 0 means use default value by kernel", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(client_tcp_keepcnt, "5", "[0,9]", "client tcp keepalive probe count, 0 means use default value by kernel", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); @@ -233,6 +235,7 @@ class ObProxyConfig : public common::ObCommonConfig DEF_INT(block_thread_num, "1", "[1,4]", "proxy block thread num, [1, 4]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(grpc_thread_num, "8", "[8,16]", "proxy grpc thread num, [8, 16]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(grpc_client_num, "9", "[9,16]", "proxy grpc client num, [9, 16]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_INT(shard_scan_thread_num, "0", "[0,128]", "proxy shard scan thread num, if 0, use (real work thread num/2), [0, 128]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(automatic_match_work_thread, "true", "ignore work_thread_num configuration item, use the count of cpu for current proxy work thread num", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_strict_kernel_release, "true", "If is true, proxy only support 5u/6u/7u redhat. Otherwise no care kernel release, and proxy maybe unstable", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_CAP(max_log_file_size, "256MB", "[1MB,1G]", "max size of log file, [1MB, 1G]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); @@ -264,6 +267,8 @@ class ObProxyConfig : public common::ObCommonConfig DEF_BOOL(ignore_local_config, "true", "ignore all local cached files, start proxy with remote json", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_IP(local_bound_ip, "0.0.0.0", "local bound ip(any)", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_INT(listen_port, "6688", "(1024,65536)", "obproxy listen port", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_INT(ip_listen_mode, "1", "[1, 3]", "1 means ipv4 listen mode, 2 means ipv6 listen mode, 3 means ipv4 and ipv6 listen mode", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_IP(local_bound_ipv6_ip, "::", "local bound ipv6 ip(any)", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_STR(obproxy_config_server_url, "", "url of config info(rs list and so on)", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_STR(proxy_service_mode, "client", "proxy deploy and service mode: 1.client(default); 2.server", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_INT(proxy_id, "0", "[0, 255]", "used to identify each obproxy, it can not be zero if proxy_service_mode is server", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); @@ -284,15 +289,17 @@ class ObProxyConfig : public common::ObCommonConfig DEF_TIME(congestion_retry_interval, "20s", "[1s,1h]", "congestion retry interval, [1s, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_TIME(min_congested_connect_timeout, "100ms", "[1ms,1h]", "if client connect timeout after the time, proxy set target server alive congested, [1ms, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_congestion, "true", "enable congestion feature or not", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_INT(server_detect_mode, "0", "[0,1]", "0 means no detect, 1 means target detect", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_INT(server_detect_mode, "1", "[0,2]", "0 means no detect, 1 means target server detect, 2 means all server detect", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(server_detect_fail_threshold, "3", "[1,10000]", "server detect try times", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); - DEF_TIME(server_detect_refresh_interval, "10s", "[1ms, 1h]", "the interval to refresh server state for getting zone or server newest state, [10ms, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_TIME(server_detect_refresh_interval, "1s", "[1ms, 1h]", "the interval to refresh server state for getting zone or server newest state, [10ms, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_TIME(detect_server_timeout, "5s", "[1s,1h]", "detect server sql timeout, [1s, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_bad_route_reject, "false", "if enabled, bad route request will be rejected, e.g. first statement of transaction opened by BEGIN(or START TRANSACTION) without table name", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_partition_table_route, "true", "if enabled, partition table will be accurate routing", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_compression_protocol, "true", "if enabled, proxy will use compression protocol with server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_ob_protocol_v2, "true", "if enabled, proxy will use oceanbase protocol 2.0 with server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_BOOL(enable_ob_protocol_v2_with_client, "true", "if enabled, proxy will use oceanbase protocol 2.0 with client", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_BOOL(enable_transaction_internal_routing, "true", "if enabled, proxy will route the dml statement in a transaction to different servers", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_reroute, "false", "if this and protocol_v2 enabled, proxy will reroute when routing error", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_pl_route, "true", "if enabled, pl will be accurate routing", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); @@ -306,6 +313,9 @@ class ObProxyConfig : public common::ObCommonConfig DEF_CAP(sqlaudit_mem_limited, "0", "[0,1G]", "sqlaudit memory limited, [0, 1GB]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_CAP(internal_cmd_mem_limited, "16M", "[0,64MB]", "internal cmd response memory limited, [0, 64MB], 0 means unlimited", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + // target db servers + DEF_STR(target_db_server, "", "proxy will choose to route target db server addr forcibly, format ip0:port0,ip1:port1,ip2:port2;ip3:port3;ip4:port4", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + //debug DEF_STR(test_server_addr, "", "proxy will choose this addr(if not empty) as observer addr forcibly, format ip1:sql_port1;ip2:sql_port2", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_STR(server_routing_mode, "oceanbase", "server routing mode: 1.oceanbase(default mode); 2.random; 3.mock; 4.mysql", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); @@ -449,14 +459,10 @@ class ObProxyConfig : public common::ObCommonConfig // beyond trust sdk DEF_STR(domain_name, "", "app domain name", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_BOOL(bt_use_antvip, "true", "if enabled, will use ant vip for bt sdk", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_STR(bt_server_addr, "", "beyond trust server address or hostname", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_STR(bt_antvip_server_addr, "", "beyond trust antvip server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_STR(bt_server_antvip, "", "beyond trust server antvip", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_BOOL(bt_local_work_mode, "false", "true means LOCAL_CERT_MODE and false means CITADEL_CERT_MODE", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_STR(bt_env_mode, "TENANT_MODE", "beyond trust env mode", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_STR(bt_instance_id, "", "beyond trust instance id for INSTANCEID env mode", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(bt_retry_times, "3", "[0,100]", "beyond trust sdk retry times", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_STR(bt_mode, "", "beyond trust mode", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_STR(citadel_agent_ip, "", "bkmi citadel agent ip", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); // proxyro@sys and root@proxysys passwd DEF_STR(inspector_password, "", "password for inspector user", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); @@ -471,6 +477,18 @@ class ObProxyConfig : public common::ObCommonConfig DEF_BOOL(enable_stat, "true", "if enabled, will collect stat info", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_INT(digest_sql_length, "1024", "0 means use default print sql len, otherwise is digest_sql_length", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + + DEF_INT(obproxy_read_only, "1", "[0,1]", "read write type: 0 means ReadOnly, 1 means ReadWrite", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_INT(obproxy_read_consistency, "0", "[0,1]", "request target: 0 means leader; 1 means follower", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + + DEF_BOOL(enable_global_ps_cache, "true", "if enabled, use global ps cache", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + + DEF_BOOL(enable_read_write_split, "false", "if enabled, use read write split mode", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_BOOL(enable_transaction_split, "false", "if enabled, support transaction split", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + + // binlog service + DEF_STR(binlog_service_ip, "", "binlog service ip, format ip1:sql_port1", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_BOOL(enable_binlog_service, "false", "if enabled, obproxy will send binlog request to OBLogProxy", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); }; ObProxyConfig &get_global_proxy_config(); diff --git a/src/obproxy/obutils/ob_proxy_config_utils.cpp b/src/obproxy/obutils/ob_proxy_config_utils.cpp index 892594a0..e97774d3 100644 --- a/src/obproxy/obutils/ob_proxy_config_utils.cpp +++ b/src/obproxy/obutils/ob_proxy_config_utils.cpp @@ -18,8 +18,10 @@ #include "utils/ob_layout.h" #include "obutils/ob_proxy_config.h" #include "proxy/client/ob_mysql_proxy.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; +using namespace oceanbase::obproxy; using namespace oceanbase::obproxy::event; using namespace oceanbase::obproxy::proxy; @@ -569,7 +571,9 @@ int ObProxyConfigUtils::load_config_from_file(ObProxyConfig &proxy_config) if (OB_ISNULL(buf = static_cast(ob_malloc(OB_PROXY_CONFIG_BUFFER_SIZE, mem_attr)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("ob tc malloc memory for buf fail", K(ret)); - } else if (OB_FAIL(ObProxyFileUtils::read(CFG_DUMP_NAME, buf, OB_PROXY_CONFIG_BUFFER_SIZE, read_len))) { + // If it is a rich client mode, the configuration will not be read from the local file + } else if (RUN_MODE_PROXY == g_run_mode + && OB_FAIL(ObProxyFileUtils::read(CFG_DUMP_NAME, buf, OB_PROXY_CONFIG_BUFFER_SIZE, read_len))) { // no need to print warn log, the caller will do it } else { obsys::CWLockGuard guard(proxy_config.rwlock_); diff --git a/src/obproxy/obutils/ob_proxy_json_config_info.cpp b/src/obproxy/obutils/ob_proxy_json_config_info.cpp index 092d05d6..2aa9b2f6 100644 --- a/src/obproxy/obutils/ob_proxy_json_config_info.cpp +++ b/src/obproxy/obutils/ob_proxy_json_config_info.cpp @@ -2103,7 +2103,7 @@ int ObProxyJsonUtils::rslist_to_json(const LocationList &addr_list, const char * } } if (OB_SUCC(ret)) { - char ip_buf[OB_IP_STR_BUFF]; + char ip_buf[MAX_IP_ADDR_LENGTH]; for (int64_t i = 0; OB_SUCC(ret) && i < addr_list.count(); ++i) { ip_buf[0] = '\0'; if (i > 0) { diff --git a/src/obproxy/obutils/ob_proxy_sql_parser.cpp b/src/obproxy/obutils/ob_proxy_sql_parser.cpp index 7a4fc5d0..d8bd2905 100644 --- a/src/obproxy/obutils/ob_proxy_sql_parser.cpp +++ b/src/obproxy/obutils/ob_proxy_sql_parser.cpp @@ -28,6 +28,7 @@ namespace obproxy { namespace obutils { +#define ISSPACE(c) ((c) == ' ' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\f' || (c) == '\v') void ObSqlParseResult::clear_proxy_stmt() { @@ -55,7 +56,7 @@ int ObSqlParseResult::set_real_table_name(const char *table_name, int64_t len) return ret; } -inline int ObSqlParseResult::set_db_name(const ObProxyParseString &database_name, +int ObSqlParseResult::set_db_name(const ObProxyParseString &database_name, const bool use_lower_case_name/*false*/, const bool drop_origin_db_table_name /*false*/) { @@ -200,24 +201,33 @@ inline int ObSqlParseResult::set_call_prarms(const ObProxyCallParseInfo &call_pa } else if (call_parse_info.node_count_ >= 0) { call_info_.is_param_valid_ = true; call_info_.param_count_ = call_parse_info.node_count_; - ObProxyCallParam tmp_param; + ObProxyCallParam* tmp_param = NULL; ObProxyCallParseNode *tmp_node = call_parse_info.head_; - while(tmp_node && OB_SUCC(ret)) { - tmp_param.reset(); - tmp_param.type_ = tmp_node->type_; - if (CALL_TOKEN_INT_VAL == tmp_node->type_) { - tmp_param.str_value_.set_integer(tmp_node->int_value_); - } else if (CALL_TOKEN_PLACE_HOLDER == tmp_node->type_) { - // for place holder, store its pos - tmp_param.str_value_.set_integer(tmp_node->placeholder_idx_); + while(OB_SUCC(ret) && tmp_node) { + tmp_param = NULL; + if (OB_FAIL(ObProxyCallParam::alloc_call_param(tmp_param))) { + LOG_WARN("fail to alloc call param", K(ret)); } else { - const ObString tmp_string(tmp_node->str_value_.str_len_, tmp_node->str_value_.str_); - tmp_param.str_value_.set(tmp_string); - } // end node_type - if (OB_FAIL(call_info_.params_.push_back(tmp_param))) { - LOG_WARN("fail to push back call param", K(tmp_param), K(ret)); + tmp_param->type_ = tmp_node->type_; + if (CALL_TOKEN_INT_VAL == tmp_node->type_) { + tmp_param->str_value_.set_integer(tmp_node->int_value_); + } else if (CALL_TOKEN_PLACE_HOLDER == tmp_node->type_) { + // for place holder, store its pos + tmp_param->str_value_.set_integer(tmp_node->placeholder_idx_); + } else { + tmp_param->str_value_.set_value(tmp_node->str_value_.str_len_, tmp_node->str_value_.str_); + } // end node_type + if (OB_FAIL(call_info_.params_.push_back(tmp_param))) { + LOG_WARN("fail to push back call param", K(tmp_param), K(ret)); + } + + if (OB_FAIL(ret) && NULL != tmp_param) { + tmp_param->reset(); + tmp_param = NULL; + } + + tmp_node = tmp_node->next_; } - tmp_node = tmp_node->next_; } } return ret; @@ -375,26 +385,35 @@ int ObSqlParseResult::set_dbmesh_route_info(const ObProxyParseResult &parse_resu ObShardColumnNode *tmp_node = route_info.head_; fileds_result_.field_num_ = 0; fileds_result_.fields_.reuse(); - SqlField field; + SqlField* field = NULL; while(tmp_node) { - field.reset(); + field = NULL; tmp_str.assign_ptr(tmp_node->tb_name_.str_, tmp_node->tb_name_.str_len_); const ObString table_name = tmp_str.trim(); if (is_dual_request_ || table_name.case_compare(table_name_) == 0) { tmp_str.assign_ptr(tmp_node->col_name_.str_, tmp_node->col_name_.str_len_); - field.column_name_.set(tmp_str); - SqlColumnValue column_value; - if (DBMESH_TOKEN_STR_VAL == tmp_node->type_) { - column_value.value_type_ = TOKEN_STR_VAL; - tmp_str.assign_ptr(tmp_node->col_str_value_.str_, tmp_node->col_str_value_.str_len_); - column_value.column_value_.set(tmp_str); - field.column_values_.push_back(column_value); + if (OB_FAIL(SqlField::alloc_sql_field(field))) { + LOG_WARN("fail to alloc sql field", K(ret)); } else { - LOG_INFO("unknown column value type", "token type", - get_obproxy_dbmesh_token_type(tmp_node->type_)); - } - if (field.is_valid() && OB_SUCCESS == fileds_result_.fields_.push_back(field)) { - ++fileds_result_.field_num_; + field->column_name_.set_value(tmp_str); + SqlColumnValue column_value; + if (DBMESH_TOKEN_STR_VAL == tmp_node->type_) { + column_value.value_type_ = TOKEN_STR_VAL; + tmp_str.assign_ptr(tmp_node->col_str_value_.str_, tmp_node->col_str_value_.str_len_); + column_value.column_value_.set_value(tmp_str); + if (OB_FAIL(field->column_values_.push_back(column_value))) { + LOG_WARN("field push back column values failed", K(column_value), K(ret)); + } + } else { + LOG_INFO("unknown column value type", "token type", + get_obproxy_dbmesh_token_type(tmp_node->type_)); + } + if (OB_SUCC(ret) && field->is_valid() && OB_SUCCESS == fileds_result_.fields_.push_back(field)) { + ++fileds_result_.field_num_; + } else if (NULL != field) { + field->reset(); + field = NULL; + } } } tmp_node = tmp_node->next_; @@ -431,23 +450,38 @@ int ObSqlParseResult::set_dbmesh_route_info(const ObProxyParseResult &parse_resu use_dbp_hint_ = true; dbp_route_info_.scan_all_ = dbp_route_info.scan_all_; } + + if (OB_SUCC(ret) && dbp_route_info.sticky_session_) { + use_dbp_hint_ = true; + dbp_route_info_.sticky_session_ = dbp_route_info.sticky_session_; + } + if (OB_SUCC(ret) && dbp_route_info.has_shard_key_) { use_dbp_hint_ = true; fileds_result_.field_num_ = 0; fileds_result_.fields_.reuse(); dbp_route_info_.has_shard_key_ = dbp_route_info.has_shard_key_; - SqlField field; for (int i = 0; OB_SUCC(ret) && i < dbp_route_info.shard_key_count_;i++) { + SqlField* field = NULL; SqlColumnValue column_value; - field.reset(); - field.column_name_.set_string(dbp_route_info.shard_key_infos_[i].left_str_.str_, - dbp_route_info.shard_key_infos_[i].left_str_.str_len_); - column_value.column_value_.set_string(dbp_route_info.shard_key_infos_[i].right_str_.str_, - dbp_route_info.shard_key_infos_[i].right_str_.str_len_); - column_value.value_type_ = TOKEN_STR_VAL; - field.column_values_.push_back(column_value); - if (field.is_valid() && OB_SUCC(fileds_result_.fields_.push_back(field))) { - ++fileds_result_.field_num_; + if (OB_FAIL(SqlField::alloc_sql_field(field))) { + LOG_WARN("fail to alloc sql field", K(ret)); + } else { + field->column_name_.set_value(dbp_route_info.shard_key_infos_[i].left_str_.str_len_, + dbp_route_info.shard_key_infos_[i].left_str_.str_); + column_value.column_value_.set_value(dbp_route_info.shard_key_infos_[i].right_str_.str_len_, + dbp_route_info.shard_key_infos_[i].right_str_.str_); + column_value.value_type_ = TOKEN_STR_VAL; + if (OB_FAIL(field->column_values_.push_back(column_value))) { + LOG_WARN("fail to push back to column_values", K(ret)); + } else if (field->is_valid() && OB_SUCC(fileds_result_.fields_.push_back(field))) { + ++fileds_result_.field_num_; + } + + if (OB_FAIL(ret) || !field->is_valid()) { + field->reset(); + field = NULL; + } } } } @@ -474,47 +508,52 @@ int ObSqlParseResult::set_var_info(const ObProxyParseResult &parse_result) ObString tmp_str; ObProxySetVarNode *tmp_node = set_parse_info.head_; - SetVarNode var_node; - while(tmp_node) { - var_node.reset(); - - var_node.var_type_ = tmp_node->type_; - - tmp_str.assign_ptr(tmp_node->name_.str_, tmp_node->name_.str_len_); - var_node.var_name_.set(tmp_str); - - var_node.value_type_ = tmp_node->value_type_; - if (SET_VALUE_TYPE_INT == tmp_node->value_type_) { - var_node.int_value_ = tmp_node->int_value_; - // float will be coverted to double - } else if (SET_VALUE_TYPE_NUMBER == tmp_node->value_type_) { - tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); - var_node.str_value_.set(tmp_str); + SetVarNode* var_node = NULL; + while(OB_SUCC(ret) && tmp_node) { + var_node = NULL; + if (OB_FAIL(SetVarNode::alloc_var_node(var_node))) { + LOG_WARN("fail to alloc var node", K(ret)); } else { - // compatible observer: - // for user var: the var will be returned from observer by OK packet: - // 1. if varchar is digital, observer return value not with ' - // 2. if varchar is string, observer return vaue with ' - // so, varchar type, do not add ' when format SQL - // for sys var: varchar type will add ' on format SQL - if (SET_VAR_USER == tmp_node->type_) { + var_node->var_type_ = tmp_node->type_; + tmp_str.assign_ptr(tmp_node->name_.str_, tmp_node->name_.str_len_); + var_node->var_name_.set_value(tmp_str); + + var_node->value_type_ = tmp_node->value_type_; + if (SET_VALUE_TYPE_INT == tmp_node->value_type_) { + var_node->int_value_ = tmp_node->int_value_; + //Floating point numbers will be converted to double type when saving + } else if (SET_VALUE_TYPE_NUMBER == tmp_node->value_type_) { tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); - if (OBPROXY_QUOTE_T_SINGLE == tmp_node->str_value_.quote_type_) { - var_node.str_value_.set_with_squote(tmp_str); - } else if (OBPROXY_QUOTE_T_DOUBLE == tmp_node->str_value_.quote_type_) { - var_node.str_value_.set_with_dquote(tmp_str); + var_node->str_value_.set_value(tmp_str); + } else { + // compatible observer: + // for user var: the var will be returned from observer by OK packet: + // 1. if varchar is digital, observer return value not with ' + // 2. if varchar is string, observer return vaue with ' + // so, varchar type, do not add ' when format SQL + // for sys var: varchar type will add ' on format SQL + if (SET_VAR_USER == tmp_node->type_) { + tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); + if (OBPROXY_QUOTE_T_SINGLE == tmp_node->str_value_.quote_type_) { + var_node->str_value_.set_value_with_quote(tmp_str, '\''); + } else if (OBPROXY_QUOTE_T_DOUBLE == tmp_node->str_value_.quote_type_) { + var_node->str_value_.set_value_with_quote(tmp_str, '"'); + } + } else { + tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); + var_node->str_value_.set_value(tmp_str); } + } + + if (OB_SUCCESS == set_info_.var_nodes_.push_back(var_node)) { + ++set_info_.node_count_; } else { - tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); - var_node.str_value_.set(tmp_str); + var_node->reset(); + var_node = NULL; } - } - if (OB_SUCCESS == set_info_.var_nodes_.push_back(var_node)) { - ++set_info_.node_count_; + tmp_node = tmp_node->next_; } - - tmp_node = tmp_node->next_; } } @@ -534,15 +573,20 @@ int ObSqlParseResult::set_text_ps_info(ObProxyTextPsInfo& text_ps_info, } else if (parse_info.node_count_ > 0) { text_ps_info.is_param_valid_ = true; text_ps_info.param_count_ = parse_info.node_count_; - ObProxyTextPsParam tmp_param; + ObProxyTextPsParam* tmp_param = NULL; ObProxyTextPsParseNode *tmp_node = parse_info.head_; while (OB_SUCC(ret) && OB_NOT_NULL(tmp_node)) { - tmp_param.reset(); - const ObString tmp_string(tmp_node->str_value_.str_len_, tmp_node->str_value_.str_); - tmp_param.str_value_.set(tmp_string); - - if (OB_FAIL(text_ps_info.params_.push_back(tmp_param))) { - LOG_WARN("fail to push back text ps execute info", K(tmp_param), K(ret)); + tmp_param = NULL; + if (OB_FAIL(ObProxyTextPsParam::alloc_text_ps_param(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_, tmp_param))) { + LOG_WARN("fail to alloc text ps param", K(ret)); + } else { + const ObString tmp_string(tmp_node->str_value_.str_len_, tmp_node->str_value_.str_); + tmp_param->str_value_.set_value(tmp_string); + if (OB_FAIL(text_ps_info.params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_WARN("fail to push back text ps execute info", KPC(tmp_param), K(ret)); + } } tmp_node = tmp_node->next_; } @@ -597,6 +641,18 @@ int ObSqlParseResult::load_result(const ObProxyParseResult &parse_result, rpc_id_.assign_ptr(rpc_id_buf_, parse_result.rpc_id_.str_len_); } + if (OB_UNLIKELY(NULL != parse_result.target_db_server_.str_ + && 0 < parse_result.target_db_server_.str_len_)) { + if (OB_ISNULL(target_db_server_) && OB_ISNULL(target_db_server_ = op_alloc(ObTargetDbServer))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc memory for target db server", K(ret)); + } else if (OB_FAIL(target_db_server_->init(parse_result.target_db_server_.str_, parse_result.target_db_server_.str_len_))) { + LOG_WARN("fail to init target db server from sql comment", K(ret)); + } else { + LOG_DEBUG("succ to init target db server from sql comment", K(ret)); + } + } + // if is dml stmt, then set db/table name if (OB_LIKELY(is_dml_stmt() || is_call_stmt() || (is_text_ps_stmt() && is_text_ps_inner_dml_stmt()) || is_show_stmt() || is_desc_table_stmt())) { @@ -637,7 +693,7 @@ int ObSqlParseResult::load_result(const ObProxyParseResult &parse_result, if (OB_FAIL(set_var_info(parse_result))) { LOG_WARN("fail to set var info", K(ret)); } - } else if (is_show_topology_stmt()) { + } else if (is_show_elastic_id_stmt()) { ObString tmp_string(parse_result.cmd_info_.string_[0].str_len_, parse_result.cmd_info_.string_[0].str_); if (!tmp_string.empty()) { cmd_info_.string_[0].set(tmp_string); @@ -750,8 +806,7 @@ int64_t ObProxyCallParam::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; J_OBJ_START(); - J_KV("type", get_obproxy_call_token_type(type_), - K_(str_value)); + J_KV("type", get_obproxy_call_token_type(type_), K_(str_value), K_(is_alloc)); J_OBJ_END(); return pos; } @@ -765,11 +820,56 @@ int64_t ObProxyCallInfo::to_string(char *buf, const int64_t buf_len) const return pos; } +ObProxyCallInfo::ObProxyCallInfo(const ObProxyCallInfo &other) +{ + int ret = OB_SUCCESS; + is_param_valid_ = other.is_param_valid_; + param_count_ = other.param_count_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_count_; i++) { + ObProxyCallParam *param = other.params_.at(i); + ObProxyCallParam *tmp_param = NULL; + if (OB_FAIL(ObProxyCallParam::alloc_call_param(tmp_param))) { + LOG_WARN("fail to alloc call param", K(ret)); + } else { + *tmp_param = *param; + if (OB_FAIL(params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_ERROR("fail to assign param", K(ret)); + } + } + } +} + +ObProxyCallInfo& ObProxyCallInfo::operator=(const ObProxyCallInfo &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + is_param_valid_ = other.is_param_valid_; + param_count_ = other.param_count_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_count_; i++) { + ObProxyCallParam *param = other.params_.at(i); + ObProxyCallParam *tmp_param = NULL; + if (OB_FAIL(ObProxyCallParam::alloc_call_param(tmp_param))) { + LOG_WARN("fail to alloc call param", K(ret)); + } else { + *tmp_param = *param; + if (OB_FAIL(params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_ERROR("fail to assign param", K(ret)); + } + } + } + } + return *this; +} + int64_t ObProxyTextPsParam::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; J_OBJ_START(); - J_KV(K_(str_value)); + J_KV(K_(str_value), K_(is_alloc)); J_OBJ_END(); return pos; } @@ -783,6 +883,52 @@ int64_t ObProxyTextPsInfo::to_string(char *buf, const int64_t buf_len) const return pos; } +ObProxyTextPsInfo::ObProxyTextPsInfo(const ObProxyTextPsInfo &other) +{ + + int ret = OB_SUCCESS; + is_param_valid_ = other.is_param_valid_; + param_count_ = other.param_count_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_count_; i++) { + ObProxyTextPsParam *param = other.params_.at(i); + ObProxyTextPsParam *tmp_param = NULL; + if (OB_FAIL(ObProxyTextPsParam::alloc_text_ps_param(param->str_value_.ptr(), param->str_value_.length(), tmp_param))) { + LOG_WARN("fai lto alloc text ps param", K(ret)); + } else { + *tmp_param = *param; + if (OB_FAIL(params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_WARN("fail to push back text ps param", K(ret)); + } + } + } +} + +ObProxyTextPsInfo& ObProxyTextPsInfo::operator=(const ObProxyTextPsInfo &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + is_param_valid_ = other.is_param_valid_; + param_count_ = other.param_count_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_count_; i++) { + ObProxyTextPsParam *param = other.params_.at(i); + ObProxyTextPsParam *tmp_param = NULL; + if (OB_FAIL(ObProxyTextPsParam::alloc_text_ps_param(param->str_value_.ptr(), param->str_value_.length(), tmp_param))) { + LOG_WARN("fai lto alloc text ps param", K(ret)); + } else { + *tmp_param = *param; + if (OB_FAIL(params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_WARN("fail to push back text ps param", K(ret)); + } + } + } + } + return *this; +} + int64_t ObProxySimpleRouteInfo::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; @@ -840,7 +986,8 @@ int64_t SetVarNode::to_string(char* buf, const int64_t buf_len) const int64_t pos = 0; J_OBJ_START(); J_KV(K_(var_type), - K_(var_name)); + K_(var_name), + K_(is_alloc)); if (SET_VALUE_TYPE_INT == value_type_) { J_COMMA(); J_KV(K_(int_value)); @@ -920,6 +1067,7 @@ int ObProxySqlParser::parse_sql(const ObString &sql, drop_origin_db_table_name, is_sharding_request))) { LOG_INFO("fail to load result, will go on anyway", K(sql), K(use_lower_case_name), K(tmp_ret)); } else { + sql_parse_result.set_multi_semicolon_in_stmt(ObProxySqlParser::is_multi_semicolon_in_stmt(sql)); LOG_DEBUG("success to do proxy parse", K(sql_parse_result)); } @@ -1360,6 +1508,182 @@ int ObProxySqlParser::parse_sql_by_obparser(const ObString &sql, return ret; } +// A simplified version from observer +int ObProxySqlParser::split_multiple_stmt(const ObString &stmt, + ObIArray &queries) +{ + int ret = OB_SUCCESS; + + int64_t offset = 0; + int64_t remain = stmt.length(); + + trim_multi_stmt(stmt, remain); + + // Special handling for empty statements + if (OB_UNLIKELY(0 >= remain)) { + ObString part; + ret = queries.push_back(part); + } + + while (remain > 0 && OB_SUCC(ret)) { + int64_t str_len = 0; + + //calc the end position of a single sql. + get_single_sql(stmt, offset, remain, str_len); + str_len = str_len == remain ? str_len : str_len + 1; + ObString query(static_cast(str_len), stmt.ptr() + offset); + + remain -= str_len; + offset += str_len; + + if (remain < 0 || offset > stmt.length()) { + LOG_ERROR("split_multiple_stmt data error", + K(remain), K(offset), K(stmt.length()), K(ret)); + } else if(OB_FAIL(queries.push_back(query))){ + LOG_WARN("fail to push back part of multi stmt", K(stmt), K(ret)); + } + } + + return ret; +} + +// avoid separeting sql by semicolons in quotes or comment. +void ObProxySqlParser::get_single_sql(const common::ObString &stmt, int64_t offset, int64_t remain, int64_t &str_len) { + /* following two flags are used to mark wether we are in comment, if in comment, ';' can't be used to split sql*/ + // in -- comment + bool comment_flag = false; + // in /*! comment */ or /* comment */ + bool c_comment_flag = false; + /* follwing three flags are used to mark wether we are in quotes.*/ + // in '', single quotes + bool sq_flag = false; + // in "", double quotes + bool dq_flag = false; + // in ``, backticks. + bool bt_flag = false; + //bool is_escape = false; + + bool in_comment = false; + bool in_string = false; + while (str_len < remain && (in_comment || in_string || (stmt[str_len + offset] != ';'))) { + if (!in_comment && !in_string) { + if (str_len + 1 >= remain) { + } else if ((stmt[str_len + offset] == '-' && stmt[str_len + offset + 1] == '-') || stmt[str_len + offset + 1] == '#') { + comment_flag = true; + } else if (stmt[str_len + offset] == '/' && stmt[str_len + offset + 1] == '*') { + c_comment_flag = true; + } else if (stmt[str_len + offset] == '\'') { + sq_flag = true; + } else if (stmt[str_len + offset] == '"') { + dq_flag = true; + } else if (stmt[str_len + offset] == '`') { + bt_flag = true; + } + } else if (in_comment) { + if (comment_flag) { + if (stmt[str_len + offset] == '\r' || stmt[str_len + offset] == '\n') { + comment_flag = false; + } + } else if (c_comment_flag) { + if (str_len + 1 >= remain) { + + } else if (stmt[str_len + offset] == '*' && (str_len + 1 < remain) && stmt[str_len + offset + 1] == '/') { + c_comment_flag = false; + } + } + } else if (in_string) { + if (str_len + 1 >= remain) { + } else if (!bt_flag && stmt[str_len + offset] == '\\') { + // in mysql mode, handle the escape char in '' and "" + ++ str_len; + } else if (sq_flag) { + if (stmt[str_len + offset] == '\'') { + sq_flag = false; + } + } else if (dq_flag) { + if (stmt[str_len + offset] == '"') { + dq_flag = false; + } + } else if (bt_flag) { + if (stmt[str_len + offset] == '`') { + bt_flag = false; + } + } + } + ++ str_len; + + // update states. + in_comment = comment_flag || c_comment_flag; + in_string = sq_flag || bt_flag || dq_flag; + } +} + +int ObProxySqlParser::preprocess_multi_stmt(ObArenaAllocator &allocator, + char* &multi_sql_buf, + const int64_t origin_sql_length, + ObSEArray &sql_array) +{ + int ret = OB_SUCCESS; + + const int64_t PARSE_EXTRA_CHAR_NUM = 2; + const int64_t total_sql_length = origin_sql_length + + (sql_array.count() * PARSE_EXTRA_CHAR_NUM); + + if (OB_ISNULL(multi_sql_buf = static_cast(allocator.alloc(total_sql_length)))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("fail to alloc memory for multi_sql_buf", K(ret), K(total_sql_length)); + } else { + MEMSET(multi_sql_buf, '\0', total_sql_length); + int64_t pos = 0; + for (int64_t i = 0; i < sql_array.count(); ++i) { + ObString& sql = sql_array.at(i); + MEMCPY(multi_sql_buf + pos ,sql.ptr(), sql.length()); + sql.assign_ptr(multi_sql_buf + pos, sql.length()); + pos += sql.length() + PARSE_EXTRA_CHAR_NUM; + } + } + + return ret; +} + +void ObProxySqlParser::trim_multi_stmt(const common::ObString &stmt, int64_t &remain) +{ + // Bypass parser's unfriendly approach to empty query processing: remove the trailing spaces by yourself + while (remain > 0 && ISSPACE(stmt[remain - 1])) { + --remain; + } + //Remove the last '\0' to be compatible with mysql + if (remain > 0 && '\0' == stmt[remain - 1]) { + --remain; + } + //remove trailing spaces + while (remain > 0 && ISSPACE(stmt[remain - 1])) { + --remain; + } +} + +bool ObProxySqlParser::is_multi_semicolon_in_stmt(const common::ObString &stmt) +{ + bool is_multi = false; + int64_t offset = 0; + int64_t remain = stmt.length(); + int64_t str_len = 0; + trim_multi_stmt(stmt, remain); + + // Special handling for empty statements + if (OB_UNLIKELY(0 >= remain)) { + } else { + get_single_sql(stmt, offset, remain, str_len); + remain -= str_len; + // 2: remain space for `;` and `\0` + if (remain > 2) { + is_multi = true; + } + } + return is_multi; +} + + int64_t ObParseNode::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; @@ -1380,6 +1704,135 @@ int64_t ObParseNode::to_string(char *buf, const int64_t buf_len) const return pos; } +void ObProxyCallParam::reset() +{ + type_ = CALL_TOKEN_NONE; + str_value_.reset(); + if (is_alloc_) { + is_alloc_ = false; + ob_free(this); + } +} + +int ObProxyCallParam::alloc_call_param(ObProxyCallParam*& param) +{ + int ret = OB_SUCCESS; + char* buf = NULL; + int64_t alloc_size = sizeof(ObProxyCallParam); + ObMemAttr mem_attr; + mem_attr.mod_id_ = common::ObModIds::OB_PROXY_SQL_PARSE; + if (OB_ISNULL(buf = static_cast(ob_malloc(alloc_size, mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for call param", K(alloc_size), K(ret)); + } else { + param = new (buf) ObProxyCallParam(); + param->is_alloc_ = true; + } + return ret; +} + +void ObProxyTextPsParam::reset() +{ + str_value_.reset(); + if (is_alloc_) { + is_alloc_ = false; + ob_free(this); + } +} + +int ObProxyTextPsParam::alloc_text_ps_param(const char* str, const int str_len, ObProxyTextPsParam*& param) +{ + int ret = OB_SUCCESS; + char* buf = NULL; + int64_t alloc_size = sizeof(ObProxyTextPsParam); + param = NULL; + ObMemAttr mem_attr; + mem_attr.mod_id_ = ObModIds::OB_PROXY_SQL_PARSE; + if (OB_UNLIKELY(NULL == str || str_len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(str), K(str_len), K(ret)); + } else if (OB_ISNULL(buf = static_cast(ob_malloc(alloc_size, mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for param", K(alloc_size), K(ret)); + } else { + param = new (buf) ObProxyTextPsParam(); + param->is_alloc_ = true; + } + + if (OB_SUCC(ret)) { + param->str_value_.set_value(str_len, str); + } + + if (OB_FAIL(ret) && NULL != param) { + param->reset(); + } + return ret; +} + +void SetVarNode::reset() +{ + value_type_ = SET_VALUE_TYPE_NONE; + var_type_ = SET_VAR_TYPE_NONE; + var_name_.reset(); + int_value_ = 0; + str_value_.reset(); + if (is_alloc_) { + is_alloc_ = false; + ob_free(this); + } +} + +int SetVarNode::alloc_var_node(SetVarNode*& node) +{ + int ret = OB_SUCCESS; + char* buf = NULL; + int64_t alloc_size = sizeof(SetVarNode); + ObMemAttr mem_attr; + mem_attr.mod_id_ = ObModIds::OB_PROXY_SQL_PARSE; + if (OB_ISNULL(buf = static_cast(ob_malloc(alloc_size, mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for var node", K(alloc_size), K(ret)); + } else { + node = new (buf) SetVarNode(); + node->is_alloc_ = true; + } + return ret; +} + +int SqlField::alloc_sql_field(SqlField*& field) +{ + int ret = OB_SUCCESS; + char* buf = NULL; + int64_t alloc_size = sizeof(SqlField); + ObMemAttr mem_attr; + mem_attr.mod_id_ = ObModIds::OB_PROXY_SQL_PARSE; + if (OB_ISNULL(buf = static_cast(ob_malloc(alloc_size, mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for call param", K(alloc_size), K(ret)); + } else { + field = new (buf) SqlField(); + field->is_alloc_ = true; + } + return ret; +} + +SqlField& SqlField::operator=(const SqlField& other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + column_name_ = other.column_name_; + value_type_ = other.value_type_; + column_int_value_ = other.column_int_value_; + column_value_ = other.column_value_; + for (int i = 0; OB_SUCC(ret) && i < other.column_values_.count(); i++) { + if (OB_FAIL(column_values_.push_back(other.column_values_.at(i)))) { + LOG_WARN("fail to push back column values", K(ret)); + } + } + } + return *this; +} + } // end of namespace obutils } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/obutils/ob_proxy_sql_parser.h b/src/obproxy/obutils/ob_proxy_sql_parser.h index 6fc7274d..54bf0e87 100644 --- a/src/obproxy/obutils/ob_proxy_sql_parser.h +++ b/src/obproxy/obutils/ob_proxy_sql_parser.h @@ -23,6 +23,8 @@ #include "common/ob_hint.h" #include "lib/utility/ob_print_utils.h" #include "utils/ob_proxy_lib.h" +#include "utils/ob_proxy_utils.h" +#include "utils/ob_target_db_server.h" #include "obutils/ob_proxy_string_utils.h" #include #include @@ -30,8 +32,8 @@ #define OBPROXY_MAX_STRING_VALUE_LENGTH 512 -#define OBPROXY_CALL_NODE_COUNT 20 -#define OBPROXY_TEXT_PS_EXECUTE_NODE_COUNT 20 +#define OBPROXY_CALL_NODE_COUNT 3 +#define OBPROXY_TEXT_PS_EXECUTE_NODE_COUNT 3 using namespace oceanbase::obproxy::opsql; @@ -179,84 +181,72 @@ struct ObProxyCmdInfo struct ObProxyCallParam { - ObProxyCallParam() { reset(); } + ObProxyCallParam() : type_(CALL_TOKEN_NONE), str_value_(), is_alloc_(false) {} ~ObProxyCallParam() { reset(); } DECLARE_TO_STRING; - void reset() - { - type_ = CALL_TOKEN_NONE; - str_value_.reset(); - } - static int32_t get_fix_buf_size() { return OBPROXY_MAX_STRING_VALUE_LENGTH; } + void reset(); + static int alloc_call_param(ObProxyCallParam*& param); ObProxyCallTokenType type_; - ObFixSizeString str_value_; + ObProxyVariantString str_value_; + bool is_alloc_; }; struct ObProxyCallInfo { - ObProxyCallInfo() { reset(); } + ObProxyCallInfo() : params_(), param_count_(0), is_param_valid_(false) {} ~ObProxyCallInfo() { reset(); } + ObProxyCallInfo(const ObProxyCallInfo &other); DECLARE_TO_STRING; - ObProxyCallInfo& operator=(const ObProxyCallInfo &other) - { - if (this != &other) { - is_param_valid_ = other.is_param_valid_; - param_count_ = other.param_count_; - params_.assign(other.params_); - } - return *this; - } + ObProxyCallInfo& operator=(const ObProxyCallInfo &other); void reset() { + for (int64_t i = 0; i < param_count_; i++) { + ObProxyCallParam *param = params_.at(i); + param->reset(); + } param_count_ = 0; is_param_valid_ = false; params_.reset(); } bool is_valid() const { return is_param_valid_ && 0 <= param_count_; } - common::ObSEArray params_; + common::ObSEArray params_; int32_t param_count_; bool is_param_valid_;//whether size is valid }; struct ObProxyTextPsParam { - ObProxyTextPsParam() { reset(); } + ObProxyTextPsParam() : str_value_(), is_alloc_(false) { } ~ObProxyTextPsParam() { reset(); } DECLARE_TO_STRING; - void reset() - { - str_value_.reset(); - } - static int32_t get_fix_buf_size() { return OBPROXY_MAX_STRING_VALUE_LENGTH; } - - ObFixSizeString str_value_; + void reset(); + static int alloc_text_ps_param(const char* str, const int str_len, ObProxyTextPsParam*& param); + ObProxyVariantString str_value_; + bool is_alloc_; }; struct ObProxyTextPsInfo { - ObProxyTextPsInfo() { reset(); } + ObProxyTextPsInfo() : params_(), param_count_(0), is_param_valid_(false) {} ~ObProxyTextPsInfo() { reset(); } + ObProxyTextPsInfo(const ObProxyTextPsInfo &other); DECLARE_TO_STRING; - ObProxyTextPsInfo& operator=(const ObProxyTextPsInfo &other) - { - if (this != &other) { - is_param_valid_ = other.is_param_valid_; - param_count_ = other.param_count_; - params_.assign(other.params_); - } - return *this; - } + ObProxyTextPsInfo& operator=(const ObProxyTextPsInfo &other); void reset() { + for (int64_t i = 0; i < param_count_; i++) { + ObProxyTextPsParam *param = params_.at(i); + param->reset(); + } param_count_ = 0; is_param_valid_ = false; params_.reset(); } bool is_valid() const { return is_param_valid_ && 0 <= param_count_; } - common::ObSEArray params_; + common::ObSEArray params_; int32_t param_count_; bool is_param_valid_;//whether size is valid }; @@ -301,14 +291,16 @@ struct SqlColumnValue column_int_value_ = 0; column_value_.reset(); } - TO_STRING_KV(K_(value_type), K(column_int_value_), K(column_value_)); + TO_STRING_KV(K_(value_type), K_(column_int_value), K_(column_value)); ObProxyTokenType value_type_; int64_t column_int_value_; - ObFixSizeString column_value_; + ObProxyVariantString column_value_; }; struct SqlField { - SqlField() { reset(); } + SqlField() : column_name_(), column_values_(), value_type_(TOKEN_NONE), + column_int_value_(0), column_value_(), is_alloc_(false) {} + ~SqlField() { reset(); } void reset() { @@ -317,31 +309,26 @@ struct SqlField { column_int_value_ = 0; column_value_.reset(); column_values_.reset(); + if (is_alloc_) { + is_alloc_ = false; + ob_free(this); + } } DECLARE_TO_STRING; bool is_valid() const { return column_values_.count() > 0; } - SqlField& operator=(const SqlField& other) - { - if (this != &other) { - column_name_ = other.column_name_; - value_type_ = other.value_type_; - column_int_value_ = other.column_int_value_; - column_value_ = other.column_value_; - for (int i = 0; i < other.column_values_.count(); i++) { - column_values_.push_back(other.column_values_.at(i)); - } - } - return *this; - } + SqlField& operator=(const SqlField& other); + + static int alloc_sql_field(SqlField*& field); + ObProxyVariantString column_name_; - ObFixSizeString column_name_; common::ObSEArray column_values_; // TODO: erase deprecated ObProxyTokenType value_type_; int64_t column_int_value_; - obutils::ObProxyVariantString column_value_; + ObProxyVariantString column_value_; + bool is_alloc_; }; struct SqlFieldResult { @@ -350,13 +337,17 @@ struct SqlFieldResult { void reset() { + for (int64_t i = 0; i < field_num_; i++) { + SqlField* field = fields_.at(i); + field->reset(); + } field_num_ = 0; fields_.reset(); } DECLARE_TO_STRING; int field_num_; - common::ObSEArray fields_; + common::ObSEArray fields_; }; struct DbMeshRouteInfo { @@ -406,40 +397,44 @@ struct DbMeshRouteInfo { }; struct SetVarNode { - SetVarNode() { reset(); } + SetVarNode() : var_name_(), int_value_(0), str_value_(), + value_type_(SET_VALUE_TYPE_NONE), + var_type_(SET_VAR_TYPE_NONE), is_alloc_(false) {} ~SetVarNode() { reset(); } - void reset() { - var_name_.reset(); - str_value_.reset(); - int_value_ = 0; - value_type_ = SET_VALUE_TYPE_ONE; - var_type_ = SET_VAR_TYPE_NONE; - } + void reset(); + static int alloc_var_node(SetVarNode*& node); DECLARE_TO_STRING; - ObFixSizeString var_name_; + ObProxyVariantString var_name_; int64_t int_value_; - ObFixSizeString str_value_; - + obutils::ObProxyVariantString str_value_; ObProxySetValueType value_type_; ObProxySetVarType var_type_; + bool is_alloc_; }; struct ObProxySetInfo { - ObProxySetInfo() { reset(); } + ObProxySetInfo() : node_count_(0), var_nodes_() {} ~ObProxySetInfo() { reset(); } void reset() { + for (int64_t i = 0; i < node_count_; i++) { + SetVarNode *node = var_nodes_.at(i); + node->reset(); + } node_count_ = 0; var_nodes_.reset(); } DECLARE_TO_STRING; int node_count_; - common::ObSEArray var_nodes_; + common::ObSEArray var_nodes_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObProxySetInfo); }; struct DbpRouteInfo { @@ -451,6 +446,7 @@ struct DbpRouteInfo { has_group_info_ = false; group_idx_ = OBPROXY_MAX_DBMESH_ID; scan_all_ = false; + sticky_session_ = false; table_name_.reset(); has_shard_key_ = false; } @@ -463,11 +459,11 @@ struct DbpRouteInfo { bool is_group_info_valid() const { // table_name can be empty - return OBPROXY_MAX_DBMESH_ID != group_idx_ && group_idx_ >= 0 && !scan_all_; + return OBPROXY_MAX_DBMESH_ID != group_idx_ && group_idx_ >= 0 && !scan_all_ && !sticky_session_; } bool is_shard_key_valid() const { - return !scan_all_; + return !scan_all_ && !sticky_session_; } bool is_error_info() const @@ -486,6 +482,7 @@ struct DbpRouteInfo { bool has_group_info_; int64_t group_idx_; bool scan_all_; + bool sticky_session_; common::ObString table_name_; char table_name_str_[common::OB_MAX_TABLE_NAME_LENGTH]; bool has_shard_key_; @@ -519,7 +516,7 @@ typedef struct _ObProxyDualParseResult struct ObSqlParseResult { ObSqlParseResult() : allocator_(common::ObModIds::OB_PROXY_SHARDING_PARSE), - text_ps_buf_(NULL), text_ps_buf_len_(0), ob_parser_result_(NULL), proxy_stmt_(NULL) { reset(); } + text_ps_buf_(NULL), text_ps_buf_len_(0), target_db_server_(NULL), ob_parser_result_(NULL), proxy_stmt_(NULL) { reset(); } ~ObSqlParseResult() { reset(); } void clear_proxy_stmt(); void reset(bool is_reset_origin_db_table = true); @@ -549,7 +546,6 @@ struct ObSqlParseResult bool is_show_session_stmt() const { return OBPROXY_T_ICMD_SHOW_SESSION == stmt_type_; } bool is_select_tx_ro() const { return OBPROXY_T_SELECT_TX_RO == stmt_type_; } bool is_select_proxy_version() const { return OBPROXY_T_SELECT_PROXY_VERSION == stmt_type_; } - bool is_set_autocommit_0() const { return OBPROXY_T_SET_AC_0 == stmt_type_; } bool is_select_route_addr() const { return OBPROXY_T_SELECT_ROUTE_ADDR == stmt_type_; } bool is_set_route_addr() const { return OBPROXY_T_SET_ROUTE_ADDR == stmt_type_; } bool is_set_ob_read_consistency() const { return OBPROXY_T_SET_OB_READ_CONSISTENCY == stmt_type_; } @@ -567,6 +563,7 @@ struct ObSqlParseResult bool is_show_tables_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_TABLES == cmd_sub_type_; } bool is_show_full_tables_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_FULL_TABLES == cmd_sub_type_; } bool is_show_table_status_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_TABLE_STATUS == cmd_sub_type_; } + bool is_show_elastic_id_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_ELASTIC_ID == cmd_sub_type_; } bool is_show_topology_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_TOPOLOGY == cmd_sub_type_; } bool is_show_db_version_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_DB_VERSION == cmd_sub_type_; } bool is_desc_table_stmt() const { return OBPROXY_T_DESC == stmt_type_ && OBPROXY_T_SUB_DESC_TABLE == cmd_sub_type_; } @@ -606,6 +603,16 @@ struct ObSqlParseResult bool is_text_ps_execute_stmt() const { return OBPROXY_T_TEXT_PS_EXECUTE == stmt_type_; } bool is_text_ps_drop_stmt() const { return OBPROXY_T_TEXT_PS_DROP == stmt_type_; } + bool is_binlog_stmt() const + { + return OBPROXY_T_SHOW_MASTER_STATUS == stmt_type_ + || OBPROXY_T_SHOW_BINARY_LOGS == stmt_type_ + || OBPROXY_T_SHOW_BINLOG_EVENTS == stmt_type_ + || OBPROXY_T_PURGE_BINARY_LOGS == stmt_type_ + || OBPROXY_T_RESET_MASTER == stmt_type_ + || OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT == stmt_type_; + } + bool is_internal_select() const { return is_select_tx_ro() || is_select_proxy_version(); } bool is_dual_request() const {return is_dual_request_;} bool is_internal_request() const; @@ -629,6 +636,7 @@ struct ObSqlParseResult bool is_shard_special_cmd() const; + bool is_multi_semicolon_in_stmt() const { return is_multi_semicolon_in_stmt_; } bool has_last_insert_id() const { return has_last_insert_id_; } bool has_found_rows() const { return has_found_rows_; } bool has_row_count() const { return has_row_count_; } @@ -644,6 +652,7 @@ struct ObSqlParseResult bool has_show_warnings() const { return is_show_warnings_stmt(); } bool need_hold_start_trans() const { return is_start_trans_stmt(); } + bool need_hold_xa_start() const { return is_xa_start_stmt_; } // has a function depend on the sql last executed, such as found_rows , row_count, etc. bool has_dependent_func() const; // whether a sql is not supported by PROXY (BUT it is supported by observer) @@ -669,6 +678,9 @@ struct ObSqlParseResult const common::ObString get_trace_id() const { return trace_id_; } const common::ObString get_rpc_id() const { return rpc_id_; } + // route server addrs in sql comment + ObTargetDbServer* get_target_db_server() const { return target_db_server_; } + char *get_table_name_str() { return table_name_.ptr(); } int64_t get_table_name_length() const { return table_name_.length(); } char *get_package_name_str() { return package_name_.ptr(); } @@ -686,6 +698,7 @@ struct ObSqlParseResult void set_stmt_type(const ObProxyBasicStmtType type) { stmt_type_ = type; } void set_err_stmt_type(const ObProxyErrorStmtType type) { cmd_err_type_ = type; } + void set_xa_start_stmt(bool is_xa_start) { is_xa_start_stmt_ = is_xa_start; } int set_db_name(const ObProxyParseString &database_name, const bool use_lower_case_name = false, const bool drop_origin_db_table_name = false); @@ -700,6 +713,7 @@ struct ObSqlParseResult int set_dbmesh_route_info(const ObProxyParseResult &obproxy_parse_result); int set_var_info(const ObProxyParseResult &parse_result); int set_text_ps_info(ObProxyTextPsInfo& text_ps_info, const ObProxyTextPsParseInfo &execute_parse_info); + void set_multi_semicolon_in_stmt(bool is_multi_semicolon_in_stmt) {is_multi_semicolon_in_stmt_ = is_multi_semicolon_in_stmt;} int load_result(const ObProxyParseResult &obproxy_parse_result, const bool use_lower_case_name = false, const bool save_origin_db_table_name = false, @@ -737,6 +751,7 @@ struct ObSqlParseResult has_simple_route_info_ = other.has_simple_route_info_; has_anonymous_block_ = other.has_anonymous_block_; has_for_update_ = other.has_for_update_; + is_xa_start_stmt_ = other.is_xa_start_stmt_; stmt_type_ = other.stmt_type_; hint_query_timeout_ = other.hint_query_timeout_; parsed_length_ = other.parsed_length_; @@ -752,6 +767,7 @@ struct ObSqlParseResult alias_name_quote_ = other.alias_name_quote_; col_name_quote_ = other.col_name_quote_; text_ps_inner_stmt_type_ = other.text_ps_inner_stmt_type_; + is_multi_semicolon_in_stmt_ = other.is_multi_semicolon_in_stmt_; table_name_.assign_ptr(dml_buf_.table_name_buf_, other.table_name_.length()); package_name_.assign_ptr(dml_buf_.package_name_buf_, other.package_name_.length()); database_name_.assign_ptr(dml_buf_.database_name_buf_, other.database_name_.length()); @@ -783,6 +799,18 @@ struct ObSqlParseResult trace_id_.assign_ptr(trace_id_buf_, other.trace_id_.length()); MEMCPY(rpc_id_buf_, other.rpc_id_buf_, other.rpc_id_.length()); rpc_id_.assign_ptr(rpc_id_buf_, other.rpc_id_.length()); + + // copy target db server in sql comment + if (OB_ISNULL(other.target_db_server_)) { + if (OB_NOT_NULL(target_db_server_)) { + op_free(target_db_server_); + target_db_server_ = NULL; + } + } else if (OB_ISNULL(target_db_server_) && OB_ISNULL(target_db_server_ = op_alloc(ObTargetDbServer))) { + PROXY_LOG(WARN, "fail to alloc memory for target db server"); + } else { + *target_db_server_ = *other.target_db_server_; + } } return *this; } @@ -807,6 +835,7 @@ struct ObSqlParseResult database_name_quote_ = other.database_name_quote_; alias_name_quote_ = other.alias_name_quote_; col_name_quote_ = other.col_name_quote_; + is_multi_semicolon_in_stmt_ = other.is_multi_semicolon_in_stmt_; table_name_.assign_ptr(dml_buf_.table_name_buf_, other.table_name_.length()); package_name_.assign_ptr(dml_buf_.package_name_buf_, other.package_name_.length()); database_name_.assign_ptr(dml_buf_.database_name_buf_, other.database_name_.length()); @@ -824,6 +853,18 @@ struct ObSqlParseResult trace_id_.assign_ptr(trace_id_buf_, other.trace_id_.length()); MEMCPY(rpc_id_buf_, other.rpc_id_buf_, other.rpc_id_.length()); rpc_id_.assign_ptr(rpc_id_buf_, other.rpc_id_.length()); + + // copy target db server addr in sql comment + if (OB_ISNULL(other.target_db_server_)) { + if (OB_NOT_NULL(target_db_server_)) { + op_free(target_db_server_); + target_db_server_ = NULL; + } + } else if (OB_ISNULL(target_db_server_) && OB_ISNULL(target_db_server_ = op_alloc(ObTargetDbServer))) { + PROXY_LOG(WARN, "fail to alloc memory target db server"); + } else { + *target_db_server_ = *other.target_db_server_; + } } ObProxyCmdInfo cmd_info_; @@ -841,6 +882,7 @@ struct ObSqlParseResult bool is_dual_request_; bool has_anonymous_block_; bool has_for_update_; + bool is_xa_start_stmt_; ObProxyBasicStmtType stmt_type_; int64_t hint_query_timeout_; int64_t parsed_length_; // next parser can starts with (orig_sql + parsed_length_) @@ -878,6 +920,8 @@ struct ObSqlParseResult common::ObString rpc_id_; char rpc_id_buf_[common::OB_MAX_OBPROXY_TRACE_ID_LENGTH]; + ObTargetDbServer *target_db_server_; + SqlFieldResult fileds_result_; int64_t batch_insert_values_count_; DbMeshRouteInfo dbmesh_route_info_; @@ -886,6 +930,7 @@ struct ObSqlParseResult bool use_dbp_hint_; ObProxyDualParseResult dual_result_; ObDmlBuf origin_dml_buf_; + bool is_multi_semicolon_in_stmt_; // buffer holder union { @@ -931,6 +976,15 @@ class ObProxySqlParser oceanbase::common::ObArenaAllocator &allocator); static int init_ob_parser_node(oceanbase::common::ObArenaAllocator &allocator, ObParseNode *&ob_node); static int get_parse_allocator(common::ObArenaAllocator *&allocator); + static int split_multiple_stmt(const common::ObString &stmt, + common::ObIArray &queries); + static void get_single_sql(const common::ObString &stmt, int64_t offset, int64_t remain, int64_t &str_len); + static int preprocess_multi_stmt(common::ObArenaAllocator &allocator, + char* &multi_sql_buf, + const int64_t origin_sql_length, + common::ObSEArray &sql_array); + static void trim_multi_stmt(const common::ObString &stmt, int64_t &remain); + static bool is_multi_semicolon_in_stmt(const common::ObString &stmt); }; inline void ObSqlParseResult::reset(bool is_reset_origin_db_table /* true */) @@ -944,6 +998,7 @@ inline void ObSqlParseResult::reset(bool is_reset_origin_db_table /* true */) is_dual_request_ = false; has_anonymous_block_ = false; has_for_update_ = false; + is_xa_start_stmt_ = false; stmt_type_ = OBPROXY_T_INVALID; cmd_sub_type_ = OBPROXY_T_SUB_INVALID; cmd_err_type_ = OBPROXY_T_ERR_INVALID; @@ -958,6 +1013,11 @@ inline void ObSqlParseResult::reset(bool is_reset_origin_db_table /* true */) part_name_.reset(); trace_id_.reset(); rpc_id_.reset(); + + if (OB_NOT_NULL(target_db_server_)) { + op_free(target_db_server_); + target_db_server_ = NULL; + } if (is_reset_origin_db_table) { origin_table_name_.reset(); @@ -991,6 +1051,7 @@ inline void ObSqlParseResult::reset(bool is_reset_origin_db_table /* true */) col_name_quote_ = OBPROXY_QUOTE_T_INVALID; dbp_route_info_.reset(); use_dbp_hint_ = false; + is_multi_semicolon_in_stmt_ = false; ob_parser_result_ = NULL; //TODO check delete it } @@ -1084,7 +1145,6 @@ inline bool ObSqlParseResult::is_internal_request() const { return (is_not_supported() || is_internal_select() - || is_set_autocommit_0() || is_set_route_addr() || is_select_route_addr() || is_ping_proxy_cmd()); @@ -1101,6 +1161,7 @@ inline bool ObSqlParseResult::is_shard_special_cmd() const || is_use_db_stmt() || is_show_databases_stmt() || is_show_db_version_stmt() + || is_show_elastic_id_stmt() || is_show_topology_stmt()); } @@ -1123,7 +1184,6 @@ inline bool ObSqlParseResult::is_need_resp_ok_cmd() const { return (is_set_stmt() || is_start_trans_stmt() - || is_set_autocommit_0() || is_commit_stmt() || is_rollback_stmt()); } diff --git a/src/obproxy/obutils/ob_proxy_stmt.cpp b/src/obproxy/obutils/ob_proxy_stmt.cpp index c6e92a20..b61a7152 100644 --- a/src/obproxy/obutils/ob_proxy_stmt.cpp +++ b/src/obproxy/obutils/ob_proxy_stmt.cpp @@ -23,8 +23,8 @@ namespace obproxy namespace obutils { -ObProxyDMLStmt::ObProxyDMLStmt(common::ObIAllocator& allocator): ObProxyStmt(allocator), limit_offset_(0), limit_size_(-1), limit_token_off_(-1),dml_field_results_(),comments_(), - column_name_array_(), table_name_(), is_inited_(false), has_unsupport_expr_type_(false),table_pos_array_() +ObProxyDMLStmt::ObProxyDMLStmt(common::ObIAllocator& allocator): ObProxyStmt(allocator), limit_offset_(0), limit_size_(-1), limit_token_off_(-1), dml_field_results_(), comments_(), + column_name_array_(), table_name_(), is_inited_(false), has_unsupport_expr_type_(false), table_pos_array_(), has_rollup_(false), has_for_update_(false), from_token_off_(-1), t_case_level_(0) { field_results_ = &dml_field_results_; } @@ -38,6 +38,21 @@ ObProxyDMLStmt::~ObProxyDMLStmt() expr->~ObProxyExpr(); } + for (int64_t i = 0; i < select_exprs_.count(); i++) { + ObProxyExpr *expr = select_exprs_.at(i); + expr->~ObProxyExpr(); + } + + for (int64_t i = 0; i < group_by_exprs_.count(); i++) { + ObProxyGroupItem *group_expr = group_by_exprs_.at(i); + group_expr->~ObProxyGroupItem(); + } + + for (int64_t i = 0; i < order_by_exprs_.count(); i++) { + ObProxyOrderItem *order_expr = order_by_exprs_.at(i); + order_expr->~ObProxyOrderItem(); + } + table_exprs_map_.destroy(); alias_table_map_.destroy(); } @@ -176,7 +191,7 @@ int ObProxyDMLStmt::handle_from_list(ParseNode* node) tmp_node = node->children_[i]; if (NULL == tmp_node) { // do nothing - } else { + } else { switch(tmp_node->type_) { case T_ORG: case T_ALIAS: @@ -217,6 +232,7 @@ int ObProxyDMLStmt::handle_table_node_to_expr(ParseNode* node) int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; ObProxyExprTable* expr_table = NULL; + bool is_sub_query = false; for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { tmp_node = node->children_[i]; if (NULL == tmp_node) { @@ -229,20 +245,28 @@ int ObProxyDMLStmt::handle_table_node_to_expr(ParseNode* node) } break; case T_IDENT: - if (OB_ISNULL(expr_table)) { + if (is_sub_query) { + // skip alias + } else if (OB_ISNULL(expr_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to get expr table", K(ret)); - } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->token_len_)) { + } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->str_len_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("alias token meet some wrong", "token len", tmp_node->token_len_, K(ret)); + LOG_WARN("alias token meet some wrong", "str len", tmp_node->str_len_, K(ret)); } else { - ObString alias_table = ObString::make_string(tmp_node->str_value_); + ObString alias_table(static_cast(tmp_node->str_len_), tmp_node->str_value_); if (OB_FAIL(alias_table_map_.set_refactored(alias_table, expr_table))) { LOG_WARN("fail to add alias table set", K(alias_table), K(ret)); } } break; - case T_SELECT: //sub query in "table node" not support in DML sql except select + case T_SELECT: + if (OB_FAIL(do_handle_parse_result(tmp_node))) { + LOG_WARN("fail to do handle parse result", "node_type", get_type_name(tmp_node->type_), K(ret)); + } else { + is_sub_query = true; + } + break; default: has_unsupport_expr_type_ = true; LOG_WARN("unsupport type", "node_type", get_type_name(node->type_), K(node->str_value_)); @@ -268,19 +292,19 @@ int ObProxyDMLStmt::get_table_and_db_expr(ParseNode* node, ObProxyExprTable* &ex LOG_WARN("T_RELATION_FACTOR children node is not 2", K(node->num_child_), K(ret)); } else if (FALSE_IT(db_node = node->children_[0])) { } else if (NULL != db_node - && OB_UNLIKELY(T_IDENT != db_node->type_ || NULL == db_node->str_value_ || 0 >= db_node->token_len_)) { + && OB_UNLIKELY(T_IDENT != db_node->type_ || NULL == db_node->str_value_ || 0 >= db_node->str_len_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("T_RELATION_FACTOR unexpected table entry", "node type", db_node->type_, - "token len", db_node->token_len_, K(ret)); + "str len", db_node->str_len_, K(ret)); } else if (OB_ISNULL(table_node = node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret)); - } else if (OB_UNLIKELY(T_IDENT != table_node->type_ || NULL == table_node->str_value_ || 0 >= table_node->token_len_)) { + } else if (OB_UNLIKELY(T_IDENT != table_node->type_ || NULL == table_node->str_value_ || 0 >= table_node->str_len_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("T_RELATION_FACTOR unexpected table entry", "node type", table_node->type_, - "token len", table_node->token_len_, K(ret)); + "str len", table_node->str_len_, K(ret)); } else { - ObString table_name(table_node->token_len_, table_node->str_value_); + ObString table_name(static_cast(table_node->str_len_), table_node->str_value_); string_to_upper_case(table_name.ptr(), table_name.length()); // change all to upper to store if (OB_FAIL(table_exprs_map_.get_refactored(table_name, expr))) { /* same table keep last one. */ if (OB_HASH_NOT_EXIST == ret) { @@ -293,11 +317,11 @@ int ObProxyDMLStmt::get_table_and_db_expr(ParseNode* node, ObProxyExprTable* &ex LOG_WARN("dynamic_cast failed", K(ret)); } else { if (NULL != db_node) { - ObString database_name(db_node->token_len_, db_node->str_value_); + ObString database_name(static_cast(db_node->str_len_), db_node->str_value_); string_to_upper_case(database_name.ptr(), database_name.length()); // change all to upper to store - expr_table->set_database_name(db_node->str_value_, db_node->token_len_); + expr_table->set_database_name(db_node->str_value_, static_cast(db_node->str_len_)); } - expr_table->set_table_name(table_node->str_value_, table_node->token_len_); + expr_table->set_table_name(table_node->str_value_, static_cast(table_node->str_len_)); if (OB_FAIL(table_exprs_map_.set_refactored(table_name, expr_table))) { /* same table keep last one. */ LOG_WARN("fail to add table expr", K(table_name), K(ret)); @@ -311,9 +335,9 @@ int ObProxyDMLStmt::get_table_and_db_expr(ParseNode* node, ObProxyExprTable* &ex ret = OB_ERR_UNEXPECTED; LOG_WARN("dynamic_cast failed", K(ret)); } else if (NULL != db_node && expr_table->get_database_name().empty()) { - ObString database_name(db_node->token_len_, db_node->str_value_); + ObString database_name(static_cast(db_node->str_len_), db_node->str_value_); string_to_upper_case(database_name.ptr(), database_name.length()); // change all to upper to store - expr_table->set_database_name(db_node->str_value_, db_node->token_len_); + expr_table->set_database_name(db_node->str_value_, static_cast(db_node->str_len_)); } } } @@ -342,13 +366,13 @@ int ObProxyDMLStmt::handle_table_and_db_node(ParseNode* node, ObProxyExprTable* ParseNode* table_node = node->children_[1]; if (OB_ISNULL(table_node)) { // do nothing - } else if (OB_UNLIKELY(T_IDENT != table_node->type_ || NULL == table_node->str_value_ || 0 >= table_node->token_len_)) { + } else if (OB_UNLIKELY(T_IDENT != table_node->type_ || NULL == table_node->str_value_ || 0 >= table_node->str_len_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected table node", "node type", table_node->type_, "token len", table_node->token_len_, K(ret)); + LOG_WARN("unexpected table node", "node type", table_node->type_, "str len", table_node->str_len_, K(ret)); } else if (NULL != db_node - && OB_UNLIKELY(T_IDENT != db_node->type_ || NULL == db_node->str_value_ || 0 >= db_node->token_len_)) { + && OB_UNLIKELY(T_IDENT != db_node->type_ || NULL == db_node->str_value_ || 0 >= db_node->str_len_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected db node", "node type", db_node->type_, "token len", db_node->token_len_, K(ret)); + LOG_WARN("unexpected db node", "node type", db_node->type_, "str len", db_node->str_len_, K(ret)); } else { ObProxyExpr* expr = NULL; ObString table_name = ObString::make_string(table_node->str_value_); @@ -388,22 +412,23 @@ int ObProxyDMLStmt::handle_table_references(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_ORG: - case T_ALIAS: - if (OB_FAIL(handle_table_node_to_expr(tmp_node))) { - LOG_WARN("fail to handle table node to expr", K(sql_string_), K(ret)); - } - break; - //sql: delete tbl_name1,tbl_name2 ... - //MULTI DELETE STMT is not support now - case T_RELATION_FACTOR: - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + //do nothing + } else { + switch (tmp_node->type_) { + case T_ORG: + case T_ALIAS: + if (OB_FAIL(handle_table_node_to_expr(tmp_node))) { + LOG_WARN("fail to handle table node to expr", K(sql_string_), K(ret)); + } + break; + //sql: delete tbl_name1,tbl_name2 ... + //MULTI DELETE STMT is not support now + case T_RELATION_FACTOR: + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + } } } return ret; @@ -440,6 +465,13 @@ int ObProxyDMLStmt::handle_where_clause(ParseNode* node) } break; } + case T_CASE: + t_case_level_++; + if (OB_FAIL(handle_where_clause(tmp_node))) { + LOG_WARN("handle_where_nodes failed", K(sql_string_), K(ret)); + } + t_case_level_--; + break; default: if (OB_FAIL(handle_where_clause(tmp_node))) { LOG_WARN("handle_where_nodes failed", K(sql_string_), K(ret)); @@ -461,6 +493,9 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) SqlField sql_field; SqlColumnValue column_value; bool is_skip_field = false; + if (t_case_level_ > 0) { + is_skip_field = true; + } if (OB_ISNULL(field_results_)) { LOG_WARN("unexpected null"); ret = OB_ERR_UNEXPECTED; @@ -485,7 +520,7 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) } else { if (NULL == expr_table || 0 == expr_table->get_table_name().case_compare(table_name_)) { - sql_field.column_name_.set(expr_column->get_column_name()); + sql_field.column_name_.set_value(expr_column->get_column_name()); } else { is_skip_field = true; } @@ -504,8 +539,8 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) sql_field.column_int_value_ = tmp_node->value_; } column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(tmp_node->str_value_); - sql_field.column_values_.push_back(column_value); + column_value.column_value_.set_value(tmp_node->str_value_); + ret = sql_field.column_values_.push_back(column_value); break; case T_VARCHAR: ret = handle_varchar_node_in_column_value(tmp_node, sql_field); @@ -526,7 +561,7 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) if (OB_SUCC(ret) && !is_skip_field) { int duplicate_column_idx = -1; for (int i = 0; i < field_results_->fields_.count(); i++) { - if (0 == sql_field.column_name_.get_string().case_compare(field_results_->fields_[i].column_name_.get_string())) { + if (0 == sql_field.column_name_.config_string_.case_compare(field_results_->fields_[i]->column_name_.config_string_)) { duplicate_column_idx = i; break; } @@ -534,15 +569,26 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) if (-1 != duplicate_column_idx) { for (int i = 0; OB_SUCC(ret) && i < sql_field.column_values_.count(); i++) { SqlColumnValue tmp_column_value = sql_field.column_values_[i]; - if (OB_FAIL(field_results_->fields_.at(duplicate_column_idx).column_values_.push_back(tmp_column_value))) { + if (OB_FAIL(field_results_->fields_.at(duplicate_column_idx)->column_values_.push_back(tmp_column_value))) { LOG_WARN("push_back failed", K(ret), K(sql_string_)); } } - } else if (OB_FAIL(field_results_->fields_.push_back(sql_field))) { - LOG_WARN("push_back failed", K(ret), K(sql_string_)); } else { - ++field_results_->field_num_; - LOG_DEBUG("add sql_field", K(sql_field), K(field_results_->field_num_)); + SqlField *tmp_field = NULL; + if (OB_ISNULL(tmp_field = op_alloc(SqlField))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sqlfield", K(ret)); + } else { + *tmp_field = sql_field; + if (OB_FAIL(field_results_->fields_.push_back(tmp_field))) { + tmp_field->reset(); + tmp_field = NULL; + LOG_WARN("push_back failed", K(ret), K(sql_string_)); + } else { + ++field_results_->field_num_; + LOG_DEBUG("add sql_field", KPC(tmp_field), K(field_results_->field_num_)); + } + } } } } @@ -562,18 +608,16 @@ int ObProxyDMLStmt::handle_varchar_node_in_column_value(ParseNode* node, SqlFiel //there is implicit type conversion: const char* -> ObString sql_field.column_value_.set_value(node->str_value_); column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(node->str_value_); - sql_field.column_values_.push_back(column_value); + column_value.column_value_.set_value(node->str_value_); + ret = sql_field.column_values_.push_back(column_value); } else { tmp_varchar_node = NULL; for (i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { - if (node->children_[i] == NULL) { + if ((node->children_[i] == NULL) || (node->children_[i]->type_ != T_VARCHAR)) { //do nothing - } else if (tmp_varchar_node != NULL) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("should null here", K(ret), K(node->str_value_), K(sql_string_)); } else { tmp_varchar_node = node->children_[i]; + break; } } if (tmp_varchar_node == NULL) { @@ -584,8 +628,31 @@ int ObProxyDMLStmt::handle_varchar_node_in_column_value(ParseNode* node, SqlFiel sql_field.column_value_.set_value(tmp_varchar_node->str_value_); sql_field.value_type_ = TOKEN_STR_VAL; column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(tmp_varchar_node->str_value_); - sql_field.column_values_.push_back(column_value); + column_value.column_value_.set_value(tmp_varchar_node->str_value_); + if (OB_FAIL(sql_field.column_values_.push_back(column_value))) { + LOG_WARN("fail to push column_value", K(ret)); + } + + bool need_save = false; + ShardingPosType type = SHARDING_POS_NONE; + if (0 == sql_field.column_name_.config_string_.case_compare("SCHEMA_NAME") + || 0 == sql_field.column_name_.config_string_.case_compare("TABLE_SCHEMA")) { + need_save = true; + type = SHARDING_POS_DB; + } else if (0 == sql_field.column_name_.config_string_.case_compare("TABLE_NAME")) { + need_save = true; + type = SHARDING_POS_TABLE; + } + + if (need_save) { + ObProxyDbTablePos db_table_pos; + db_table_pos.set_pos(tmp_varchar_node->token_off_); + db_table_pos.set_name(tmp_varchar_node->str_value_); + db_table_pos.set_type(type); + if (OB_FAIL(db_table_pos_array_.push_back(db_table_pos))) { + LOG_WARN("fail to push expr table pos", K(ret)); + } + } } } return ret; @@ -608,7 +675,7 @@ int ObProxyDMLStmt::handle_expr_list_node_in_column_value(ParseNode* node, SqlFi case T_INT: default: column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(tmp_node->str_value_); + column_value.column_value_.set_value(tmp_node->str_value_); if (OB_FAIL(sql_field.column_values_.push_back(column_value))) { LOG_WARN("push_back failed", K(i), K(sql_string_), K(ret)); } @@ -625,18 +692,19 @@ int ObProxyDMLStmt::handle_assign_list(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_ASSIGN_ITEM: - if (OB_FAIL(handle_column_and_value(tmp_node))) { - LOG_WARN("handle op and failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_ASSIGN_ITEM: + if (OB_FAIL(handle_column_and_value(tmp_node))) { + LOG_WARN("handle op and failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } return ret; @@ -686,11 +754,11 @@ int ObProxyDMLStmt::column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObPr if (OB_ISNULL(column_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("T_COLUMN_REF unexpected column entry", K(ret)); - } else if (T_IDENT != column_node->type_) { + } else if (T_IDENT != column_node->type_ && T_STAR != column_node->type_) { // now column_ref child should be T_IDENT has_unsupport_expr_type_ = true; LOG_WARN("T_COLUMN_REF unexpected column entry", "node_type", get_type_name(column_node->type_), K(ret)); - } else { + } else if (T_IDENT == column_node->type_) { ObProxyExprColumn* expr_column = NULL; if (OB_FAIL(get_expr_by_type(expr, OB_PROXY_EXPR_TYPE_COLUMN))) { LOG_WARN("get_expr_by_type failed", K(ret), K(sql_string_)); @@ -698,14 +766,26 @@ int ObProxyDMLStmt::column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObPr ret = OB_ERR_UNEXPECTED; LOG_WARN("dynamic_cast failed", K(ret)); } else { - expr_column->set_column_name(column_node->str_value_, column_node->token_len_); + expr_column->set_column_name(column_node->str_value_, static_cast(column_node->str_len_)); if (OB_NOT_NULL(table_node)) { - expr_column->set_table_name(table_node->str_value_, table_node->token_len_); + expr_column->set_table_name(table_node->str_value_, static_cast(table_node->str_len_)); if (NULL != expr_table) { expr_column->set_real_table_name(expr_table->get_table_name()); } } } + } else if (T_STAR == column_node->type_) { + ObProxyExprStar* expr_star = NULL; + if (OB_FAIL(get_expr_by_type(expr, OB_PROXY_EXPR_TYPE_STAR))) { + LOG_WARN("get_expr_by_type failed", K(ret), K(sql_string_)); + } else if (OB_ISNULL(expr_star = dynamic_cast(expr))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dynamic_cast failed", K(ret)); + } else { + if (OB_NOT_NULL(table_node)) { + expr_star->set_table_name(table_node->str_value_, static_cast(table_node->str_len_)); + } + } } } @@ -729,47 +809,8 @@ int ObProxyDMLStmt::limit_to_sql_string(common::ObSqlString& sql_string) } return ret; } -ObProxySelectStmt::ObProxySelectStmt(common::ObIAllocator& allocator) : ObProxyDMLStmt(allocator), - has_rollup_(false), - has_for_update_(false), - from_token_off_(-1) -{ - -} -ObProxySelectStmt::~ObProxySelectStmt() -{ - for (int64_t i = 0; i < select_exprs_.count(); i++) { - ObProxyExpr *expr = select_exprs_.at(i); - expr->~ObProxyExpr(); - } - - for (int64_t i = 0; i < group_by_exprs_.count(); i++) { - ObProxyGroupItem *group_expr = group_by_exprs_.at(i); - group_expr->~ObProxyGroupItem(); - } - - for (int64_t i = 0; i < order_by_exprs_.count(); i++) { - ObProxyOrderItem *order_expr = order_by_exprs_.at(i); - order_expr->~ObProxyOrderItem(); - } -} - -int ObProxySelectStmt::handle_parse_result(const ParseResult &parse_result) -{ - int ret = OB_SUCCESS; - ParseNode* node = parse_result.result_tree_->children_[0]; - - if (OB_FAIL(do_handle_parse_result(node))) { - LOG_WARN("fail to do handle parse result", K(sql_string_), "node_type", get_type_name(node->type_), K(ret)); - } else if (OB_FAIL(handle_comment_list(parse_result))) { - LOG_WARN("handle_comment_list failed", K(ret), K(sql_string_)); - } - - return ret; -} - -int ObProxySelectStmt::do_handle_parse_result(ParseNode* node) +int ObProxyDMLStmt::do_handle_parse_result(ParseNode* node) { int ret = OB_SUCCESS; @@ -843,7 +884,7 @@ int ObProxySelectStmt::do_handle_parse_result(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_comment_list(const ParseResult &parse_result) +int ObProxyDMLStmt::handle_comment_list(const ParseResult &parse_result) { int ret = OB_SUCCESS; for (int i = 0; OB_SUCC(ret) && i < parse_result.comment_cnt_; i++) { @@ -857,7 +898,8 @@ int ObProxySelectStmt::handle_comment_list(const ParseResult &parse_result) } return ret; } -int ObProxySelectStmt::comments_to_sql_string(common::ObSqlString& sql_string) + +int ObProxyDMLStmt::comments_to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; for (int i = 0; OB_SUCC(ret) && i < comments_.count(); i++) { @@ -868,13 +910,13 @@ int ObProxySelectStmt::comments_to_sql_string(common::ObSqlString& sql_string) return ret; } -int ObProxySelectStmt::hint_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::hint_exprs_to_sql_string(common::ObSqlString& sql_string) { UNUSED(sql_string); int ret = OB_SUCCESS; return ret; } -int ObProxySelectStmt::select_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::select_exprs_to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; if (select_exprs_.count() < 1) { @@ -894,14 +936,14 @@ int ObProxySelectStmt::select_exprs_to_sql_string(common::ObSqlString& sql_strin return ret; } -int ObProxySelectStmt::table_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::table_exprs_to_sql_string(common::ObSqlString& sql_string) { UNUSED(sql_string); int ret = OB_SUCCESS; return ret; } -int ObProxySelectStmt::group_by_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::group_by_exprs_to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; if (group_by_exprs_.count() <= 0) { @@ -927,7 +969,7 @@ int ObProxySelectStmt::group_by_exprs_to_sql_string(common::ObSqlString& sql_str return ret; } -int ObProxySelectStmt::order_by_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::order_by_exprs_to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; if (order_by_exprs_.count() <= 0) { @@ -949,7 +991,7 @@ int ObProxySelectStmt::order_by_exprs_to_sql_string(common::ObSqlString& sql_str } //REFER:https://dev.mysql.com/doc/refman/8.0/en/select.html -int ObProxySelectStmt::to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; if (OB_FAIL(comments_to_sql_string(sql_string))) { @@ -976,7 +1018,7 @@ int ObProxySelectStmt::to_sql_string(common::ObSqlString& sql_string) return ret; } -int ObProxySelectStmt::handle_union_clause(ParseNode* node) +int ObProxyDMLStmt::handle_union_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1005,7 +1047,7 @@ int ObProxySelectStmt::handle_union_clause(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_hint_clause(ParseNode* node) +int ObProxyDMLStmt::handle_hint_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1031,7 +1073,7 @@ int ObProxySelectStmt::handle_hint_clause(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_limit_clause(ParseNode* node) +int ObProxyDMLStmt::handle_limit_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1066,7 +1108,7 @@ int ObProxySelectStmt::handle_limit_clause(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_project_list(ParseNode* node) +int ObProxyDMLStmt::handle_project_list(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1098,7 +1140,7 @@ int ObProxySelectStmt::handle_project_list(ParseNode* node) return ret; } -int ObProxySelectStmt::get_const_expr(ParseNode* node, ObProxyExpr* &expr) +int ObProxyDMLStmt::get_const_expr(ParseNode* node, ObProxyExpr* &expr) { int ret = OB_SUCCESS; ObProxyExprConst* expr_const = NULL; @@ -1122,7 +1164,7 @@ int ObProxySelectStmt::get_const_expr(ParseNode* node, ObProxyExpr* &expr) LOG_DEBUG("add int value", K(obj)); } } else { - ObString var(node->token_len_, node->str_value_); + ObString var(static_cast(node->str_len_), node->str_value_); obj.set_varchar(var); expr_const->set_object(obj); LOG_DEBUG("add varchar value", K(obj)); @@ -1131,7 +1173,7 @@ int ObProxySelectStmt::get_const_expr(ParseNode* node, ObProxyExpr* &expr) return ret; } -int ObProxySelectStmt::get_sharding_const_expr(ParseNode* node, ObProxyExpr* &expr) +int ObProxyDMLStmt::get_sharding_const_expr(ParseNode* node, ObProxyExpr* &expr) { int ret = OB_SUCCESS; ObProxyExprShardingConst* expr_const = NULL; @@ -1144,12 +1186,12 @@ int ObProxySelectStmt::get_sharding_const_expr(ParseNode* node, ObProxyExpr* &ex ret = OB_ERR_UNEXPECTED; LOG_WARN("dynamic_cast failed", K(ret)); } else { - expr_const->set_expr_name(node->str_value_, node->token_len_); + expr_const->set_expr_name(node->str_value_, static_cast(node->str_len_)); } return ret; } -int ObProxySelectStmt::handle_table_and_db_in_hint(ParseNode* node) +int ObProxyDMLStmt::handle_table_and_db_in_hint(ParseNode* node) { int ret = OB_SUCCESS; @@ -1165,62 +1207,8 @@ int ObProxySelectStmt::handle_table_and_db_in_hint(ParseNode* node) return ret; } -int ObProxySelectStmt::column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObProxyExprTable* &expr_table) -{ - int ret = OB_SUCCESS; - - if (OB_T_COLUMN_REF_NUM_CHILD /* 3 */ != node->num_child_) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("T_COLUMN_REF children node is not 3", "child num", node->num_child_, K(ret)); - } else if (OB_FAIL(handle_table_and_db_node(node, expr_table))) { - LOG_WARN("fail to handle table and db node", K(ret)); - } - - if (OB_SUCC(ret)) { - ParseNode* table_node = node->children_[1]; - ParseNode* column_node = node->children_[2]; - if (OB_ISNULL(column_node)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("T_COLUMN_REF unexpected column entry", K(ret)); - } else if (T_IDENT != column_node->type_ && T_STAR != column_node->type_) { - // now column_ref child should be T_IDENT - has_unsupport_expr_type_ = true; - LOG_WARN("T_COLUMN_REF unexpected column entry", "node_type", get_type_name(column_node->type_), K(ret)); - } else if (T_IDENT == column_node->type_) { - ObProxyExprColumn* expr_column = NULL; - if (OB_FAIL(get_expr_by_type(expr, OB_PROXY_EXPR_TYPE_COLUMN))) { - LOG_WARN("get_expr_by_type failed", K(ret), K(sql_string_)); - } else if (OB_ISNULL(expr_column = dynamic_cast(expr))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("dynamic_cast failed", K(ret)); - } else { - expr_column->set_column_name(column_node->str_value_, column_node->token_len_); - if (OB_NOT_NULL(table_node)) { - expr_column->set_table_name(table_node->str_value_, table_node->token_len_); - if (NULL != expr_table) { - expr_column->set_real_table_name(expr_table->get_table_name()); - } - } - } - } else if (T_STAR == column_node->type_) { - ObProxyExprStar* expr_star = NULL; - if (OB_FAIL(get_expr_by_type(expr, OB_PROXY_EXPR_TYPE_STAR))) { - LOG_WARN("get_expr_by_type failed", K(ret), K(sql_string_)); - } else if (OB_ISNULL(expr_star = dynamic_cast(expr))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("dynamic_cast failed", K(ret)); - } else { - if (OB_NOT_NULL(table_node)) { - expr_star->set_table_name(table_node->str_value_, table_node->token_len_); - } - } - } - } - - return ret; -} -int ObProxySelectStmt::alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) +int ObProxyDMLStmt::alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1235,11 +1223,11 @@ int ObProxySelectStmt::alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, P if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to get expr table", K(ret)); - } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->token_len_)) { + } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->str_len_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("alias token meet some wrong", "token len", tmp_node->token_len_, K(ret)); + LOG_WARN("alias token meet some wrong", "str len", tmp_node->str_len_, K(ret)); } else { - expr->set_alias_name(tmp_node->str_value_, tmp_node->token_len_); + expr->set_alias_name(tmp_node->str_value_, static_cast(tmp_node->str_len_)); } break; default: @@ -1252,7 +1240,7 @@ int ObProxySelectStmt::alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, P return ret; } -int ObProxySelectStmt::func_node_to_expr(ParseNode* node, ObProxyExpr* &expr) +int ObProxyDMLStmt::func_node_to_expr(ParseNode* node, ObProxyExpr* &expr) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1300,12 +1288,12 @@ int ObProxySelectStmt::func_node_to_expr(ParseNode* node, ObProxyExpr* &expr) } if (OB_SUCC(ret)) { - func_expr->set_expr_name(node->str_value_, node->token_len_); + func_expr->set_expr_name(node->str_value_, static_cast(node->str_len_)); } return ret; } -int ObProxySelectStmt::check_node_has_agg(ParseNode* node) +int ObProxyDMLStmt::check_node_has_agg(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1338,7 +1326,7 @@ int ObProxySelectStmt::check_node_has_agg(ParseNode* node) return ret; } //we do not cover all sys func. if sys func do not have agg func, pass it to server as string -int ObProxySelectStmt::func_sys_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) +int ObProxyDMLStmt::func_sys_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) { int ret = OB_SUCCESS; if (OB_FAIL(check_node_has_agg(node))) { @@ -1353,7 +1341,7 @@ int ObProxySelectStmt::func_sys_node_to_expr(ParseNode* node, ObProxyExpr* &expr return ret; } -int ObProxySelectStmt::string_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) +int ObProxyDMLStmt::string_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) { int ret = OB_SUCCESS; int i = 0; @@ -1434,7 +1422,7 @@ int ObProxySelectStmt::string_node_to_expr(ParseNode* node, ObProxyExpr* &expr, } return ret; } -int ObProxySelectStmt::project_string_to_expr(ParseNode* node, ObProxyExpr* &expr) +int ObProxyDMLStmt::project_string_to_expr(ParseNode* node, ObProxyExpr* &expr) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1452,56 +1440,8 @@ int ObProxySelectStmt::project_string_to_expr(ParseNode* node, ObProxyExpr* &exp return ret; } -int ObProxySelectStmt::handle_table_node_to_expr(ParseNode* node) -{ - int ret = OB_SUCCESS; - ParseNode* tmp_node = NULL; - ObProxyExprTable* expr_table = NULL; - bool is_sub_query = false; - for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { - tmp_node = node->children_[i]; - if (NULL == tmp_node) { - //do nothing - } else { - switch(tmp_node->type_) { - case T_RELATION_FACTOR: - if (OB_FAIL(get_table_and_db_expr(tmp_node, expr_table))) { - LOG_WARN("fail to get table expr", K(ret)); - } - break; - case T_IDENT: - if (is_sub_query) { - // skip alias - } else if (OB_ISNULL(expr_table)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fail to get expr table", K(ret)); - } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->token_len_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("alias token meet some wrong", "token len", tmp_node->token_len_, K(ret)); - } else { - ObString alias_table = ObString::make_string(tmp_node->str_value_); - if (OB_FAIL(alias_table_map_.set_refactored(alias_table, expr_table))) { - LOG_WARN("fail to add alias table set", K(alias_table), K(ret)); - } - } - break; - case T_SELECT: - if (OB_FAIL(do_handle_parse_result(tmp_node))) { - LOG_WARN("fail to do handle parse result", "node_type", get_type_name(tmp_node->type_), K(ret)); - } else { - is_sub_query = true; - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unsupport type", "node_type", get_type_name(node->type_), K(node->str_value_)); - } - } - } - return ret; -} -int ObProxySelectStmt::handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, const SortListType& sort_list_type) +int ObProxyDMLStmt::handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, const SortListType& sort_list_type) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1520,7 +1460,7 @@ int ObProxySelectStmt::handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, order_direction = NULLS_LAST_DESC; break; default: - if (OB_FAIL(string_node_to_expr(tmp_node, tmp_expr))) { + if (OB_FAIL(string_node_to_expr(tmp_node, tmp_expr, tmp_node))) { LOG_WARN("string_node_to_expr failed", K(ret), K(sql_string_)); } else if (T_INT == tmp_node->type_) { ObProxyExprConst* expr_const = NULL; @@ -1569,7 +1509,7 @@ int ObProxySelectStmt::handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, } return ret; } -int ObProxySelectStmt::handle_sort_list_node(ParseNode* node, const SortListType& sort_list_type) +int ObProxyDMLStmt::handle_sort_list_node(ParseNode* node, const SortListType& sort_list_type) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1622,7 +1562,7 @@ int ObProxySelectStmt::handle_sort_list_node(ParseNode* node, const SortListType } return ret; } -int ObProxySelectStmt::handle_with_rollup_in_groupby(ParseNode* node) +int ObProxyDMLStmt::handle_with_rollup_in_groupby(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1649,7 +1589,7 @@ int ObProxySelectStmt::handle_with_rollup_in_groupby(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_groupby_clause(ParseNode* node) +int ObProxyDMLStmt::handle_groupby_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1668,7 +1608,7 @@ int ObProxySelectStmt::handle_groupby_clause(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_orderby_clause(ParseNode* node) +int ObProxyDMLStmt::handle_orderby_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1687,6 +1627,20 @@ int ObProxySelectStmt::handle_orderby_clause(ParseNode* node) return ret; } +int ObProxySelectStmt::handle_parse_result(const ParseResult &parse_result) +{ + int ret = OB_SUCCESS; + ParseNode* node = parse_result.result_tree_->children_[0]; + + if (OB_FAIL(do_handle_parse_result(node))) { + LOG_WARN("fail to do handle parse result", K(sql_string_), "node_type", get_type_name(node->type_), K(ret)); + } else if (OB_FAIL(handle_comment_list(parse_result))) { + LOG_WARN("handle_comment_list failed", K(ret), K(sql_string_)); + } + + return ret; +} + int ObProxyInsertStmt::handle_parse_result(const ParseResult &parse_result) { int ret = OB_SUCCESS; @@ -1698,28 +1652,37 @@ int ObProxyInsertStmt::handle_parse_result(const ParseResult &parse_result) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_REPLACE: - stmt_type_ = OBPROXY_T_REPLACE; - break; - case T_SINGLE_TABLE_INSERT: - if (OB_FAIL(handle_single_table_insert(tmp_node))) { - LOG_WARN("handle single table insert failed", K(ret)); - } - break; - case T_INSERT: - //nothing - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_REPLACE: + stmt_type_ = OBPROXY_T_REPLACE; + break; + case T_HINT_OPTION_LIST: + ret = handle_hint_clause(tmp_node); + break; + case T_SINGLE_TABLE_INSERT: + if (OB_FAIL(handle_single_table_insert(tmp_node))) { + LOG_WARN("handle single table insert failed", K(ret)); + } + break; + case T_INSERT: + //nothing + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } } + if(OB_SUCC(ret)) { + if (OB_FAIL(handle_comment_list(parse_result))) { + LOG_WARN("handle_comment_list failed", K(ret), K(sql_string_)); + } + } return ret; } @@ -1729,27 +1692,33 @@ int ObProxyInsertStmt::handle_single_table_insert(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_INSERT_INTO_CLAUSE: - if (OB_FAIL(handle_insert_into(tmp_node))) { - LOG_WARN("fail to handle insert into", K(ret)); - } - break; - case T_VALUE_LIST: - if (OB_FAIL(handle_value_list(tmp_node))) { - LOG_WARN("fail to handle value list", K(ret)); - } - break; - case T_ASSIGN_LIST: - if (OB_FAIL(handle_assign_list(tmp_node))) { - LOG_WARN("fail to handle assign list", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + ///do nothing + } else { + switch (tmp_node->type_) { + case T_INSERT_INTO_CLAUSE: + if (OB_FAIL(handle_insert_into(tmp_node))) { + LOG_WARN("fail to handle insert into", K(ret)); + } + break; + case T_VALUE_LIST: + if (OB_FAIL(handle_value_list(tmp_node))) { + LOG_WARN("fail to handle value list", K(ret)); + } + break; + case T_ASSIGN_LIST: + if (OB_FAIL(handle_assign_list(tmp_node))) { + LOG_WARN("fail to handle assign list", K(ret)); + } + break; + case T_SELECT: + if (OB_FAIL(do_handle_parse_result(tmp_node))) { + LOG_WARN("fail to do handle parse result", "node_type", get_type_name(tmp_node->type_), K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + } } } @@ -1762,23 +1731,24 @@ int ObProxyInsertStmt::handle_insert_into(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_ORG: - if (OB_FAIL(handle_table_node_to_expr(tmp_node))) { - LOG_WARN("handle org failed", K(ret)); - } - break; - case T_COLUMN_LIST: - if (OB_FAIL(handle_column_list(tmp_node))) { - LOG_WARN("handle column list failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_ORG: + if (OB_FAIL(handle_table_node_to_expr(tmp_node))) { + LOG_WARN("handle org failed", K(ret)); + } + break; + case T_COLUMN_LIST: + if (OB_FAIL(handle_column_list(tmp_node))) { + LOG_WARN("handle column list failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } @@ -1791,13 +1761,7 @@ int ObProxyInsertStmt::handle_value_list(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - - // The writing method of insert inserting multiple rows is not supported - if (node->num_child_ > 1) { - ret = OB_ERR_BATCH_INSERT_FOUND; - LOG_WARN("replace more than one row", K(ret)); + //do nothing } else { switch (tmp_node->type_) { case T_VALUE_VECTOR: @@ -1822,17 +1786,18 @@ int ObProxyInsertStmt::handle_column_list(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_COLUMN_REF: - if (OB_FAIL(handle_column_ref_in_list(tmp_node))) { - LOG_WARN("handle column ref failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown ndoe type", K_(tmp_node->type), K(ret)); + //do nothing + } else { + switch (tmp_node->type_) { + case T_COLUMN_REF: + if (OB_FAIL(handle_column_ref_in_list(tmp_node))) { + LOG_WARN("handle column ref failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown ndoe type", K_(tmp_node->type), K(ret)); + } } } return ret; @@ -1842,64 +1807,85 @@ int ObProxyInsertStmt::handle_value_vector(ParseNode *node) { int ret = OB_SUCCESS; if (OB_UNLIKELY(column_name_array_.empty())) { - ret = OB_ERR_UNEXPECTED; + ret = OB_EXPR_CALC_ERROR; LOG_WARN("need column name in value vector", K(ret)); } else if (OB_UNLIKELY(node->num_child_ != column_name_array_.count())){ - ret = OB_ERR_PARSE_SQL; + ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("the num of column name do not match value vector", K(ret)); } else { bool is_skip_field = false; SqlColumnValue column_value; for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { - column_value.reset(); - is_skip_field = false; ParseNode *tmp_node = node->children_[i]; + SqlField *sql_field = NULL; if (NULL == tmp_node) { - continue; - } - SqlField sql_field; - sql_field.column_name_.set(column_name_array_.at(i)); - switch (tmp_node->type_) { - case T_INT: - { - sql_field.value_type_ = TOKEN_INT_VAL; - sql_field.column_int_value_ = tmp_node->value_; - column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(tmp_node->str_value_); - sql_field.column_values_.push_back(column_value); - break; - } - case T_VARCHAR: - { - ret = handle_varchar_node_in_column_value(tmp_node, sql_field); - break; - } - default: - has_unsupport_expr_type_ = true; - is_skip_field = true; - LOG_WARN("unknown node type", "node type", tmp_node->type_, K(ret)); - break; - } - if (OB_SUCC(ret) && !is_skip_field) { - int duplicate_column_idx = -1; - for (int i = 0; i < field_results_->fields_.count(); i++) { - if (0 == sql_field.column_name_.get_string().case_compare(field_results_->fields_[i].column_name_.get_string())) { - duplicate_column_idx = i; + // do nothing + } else if (OB_ISNULL(sql_field = op_alloc(SqlField))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sqlfield", K(ret)); + } else { + is_skip_field = false; + column_value.reset(); + sql_field->column_name_.set_value(column_name_array_.at(i)); + switch (tmp_node->type_) { + case T_INT: + { + sql_field->value_type_ = TOKEN_INT_VAL; + sql_field->column_int_value_ = tmp_node->value_; + column_value.value_type_ = TOKEN_STR_VAL; + column_value.column_value_.set_value(tmp_node->str_value_); + ret = sql_field->column_values_.push_back(column_value); + break; + } + case T_VARCHAR: + { + ret = handle_varchar_node_in_column_value(tmp_node, *sql_field); + break; + } + case T_OP_NEG: + { + ParseNode *child_node = tmp_node->children_[0]; + if (child_node->type_ == T_INT) { + sql_field->value_type_ = TOKEN_INT_VAL; + sql_field->column_int_value_ = -1 * (child_node->value_); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unknown node type", K_(child_node->type), K(ret)); + } + break; + } + default: + column_value.value_type_ = TOKEN_NONE; + ret = sql_field->column_values_.push_back(column_value); + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", "node type", tmp_node->type_, K(ret)); break; - } } - if (OB_UNLIKELY(-1 != duplicate_column_idx)) { - for (int i = 0; OB_SUCC(ret) && i < sql_field.column_values_.count(); i++) { - SqlColumnValue tmp_column_value = sql_field.column_values_[i]; - if (OB_FAIL(field_results_->fields_.at(duplicate_column_idx).column_values_.push_back(tmp_column_value))) { - LOG_WARN("push_back failed", K(ret), K(sql_string_)); + if (OB_SUCC(ret) && !is_skip_field) { + int duplicate_column_idx = -1; + for (int i = 0; i < field_results_->fields_.count(); i++) { + if (0 == sql_field->column_name_.config_string_.case_compare(field_results_->fields_[i]->column_name_.config_string_)) { + duplicate_column_idx = i; + break; } } - } else if (OB_FAIL(field_results_->fields_.push_back(sql_field))) { - LOG_WARN("push_back failed", K(ret), K(sql_string_)); - } else { - ++field_results_->field_num_; - LOG_DEBUG("add sql_field", K(sql_field), K(field_results_->field_num_)); + if (OB_UNLIKELY(-1 != duplicate_column_idx)) { + for (int i = 0; OB_SUCC(ret) && i < sql_field->column_values_.count(); i++) { + SqlColumnValue tmp_column_value = sql_field->column_values_[i]; + if (OB_FAIL(field_results_->fields_.at(duplicate_column_idx)->column_values_.push_back(tmp_column_value))) { + LOG_WARN("push_back failed", K(ret), K(sql_string_)); + } + } + } else if (OB_FAIL(field_results_->fields_.push_back(sql_field))) { + LOG_WARN("push_back failed", K(ret), K(sql_string_)); + } else { + ++field_results_->field_num_; + LOG_DEBUG("add sql_field", KPC(sql_field), K(field_results_->field_num_)); + } + } + if (OB_FAIL(ret) && NULL != sql_field) { + sql_field->reset(); + sql_field = NULL; } } } @@ -1926,23 +1912,27 @@ int ObProxyDeleteStmt::handle_parse_result(const ParseResult &parse_result) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_DELETE_TABLE_NODE: - if (OB_FAIL(handle_delete_table_node(tmp_node))) { - LOG_WARN("handle delete table node failed", K(ret)); - } - break; - case T_WHERE_CLAUSE: - if (OB_FAIL(handle_where_clause(tmp_node))) { - LOG_WARN("handle where clause failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_DELETE_TABLE_NODE: + if (OB_FAIL(handle_delete_table_node(tmp_node))) { + LOG_WARN("handle delete table node failed", K(ret)); + } + break; + case T_HINT_OPTION_LIST: + ret = handle_hint_clause(tmp_node); + break; + case T_WHERE_CLAUSE: + if (OB_FAIL(handle_where_clause(tmp_node))) { + LOG_WARN("handle where clause failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } } @@ -1956,17 +1946,18 @@ int ObProxyDeleteStmt::handle_delete_table_node(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_TABLE_REFERENCES: - if (OB_FAIL(handle_table_references(tmp_node))) { - LOG_WARN("handle table references failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + //do nothing + } else { + switch (tmp_node->type_) { + case T_TABLE_REFERENCES: + if (OB_FAIL(handle_table_references(tmp_node))) { + LOG_WARN("handle table references failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + } } } return ret; @@ -1984,28 +1975,32 @@ int ObProxyUpdateStmt::handle_parse_result(const ParseResult &parse_result) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_TABLE_REFERENCES: - if (OB_FAIL(handle_table_references(tmp_node))) { - LOG_WARN("handle where clause failed", K(ret)); - } - break; - case T_ASSIGN_LIST: - if (OB_FAIL(handle_assign_list(tmp_node))) { - LOG_WARN("handle where clause failed", K(ret)); - } - break; - case T_WHERE_CLAUSE: - if (OB_FAIL(handle_where_clause(tmp_node))) { - LOG_WARN("handle where clause failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_TABLE_REFERENCES: + if (OB_FAIL(handle_table_references(tmp_node))) { + LOG_WARN("handle where clause failed", K(ret)); + } + break; + case T_HINT_OPTION_LIST: + ret = handle_hint_clause(tmp_node); + break; + case T_ASSIGN_LIST: + if (OB_FAIL(handle_assign_list(tmp_node))) { + LOG_WARN("handle where clause failed", K(ret)); + } + break; + case T_WHERE_CLAUSE: + if (OB_FAIL(handle_where_clause(tmp_node))) { + LOG_WARN("handle where clause failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } } diff --git a/src/obproxy/obutils/ob_proxy_stmt.h b/src/obproxy/obutils/ob_proxy_stmt.h index 7065401f..39942588 100644 --- a/src/obproxy/obutils/ob_proxy_stmt.h +++ b/src/obproxy/obutils/ob_proxy_stmt.h @@ -56,6 +56,39 @@ class ObProxyExprTablePos { ObProxyExprTable* table_expr_; }; +enum ShardingPosType { + SHARDING_POS_NONE = 0, + SHARDING_POS_DB, + SHARDING_POS_TABLE, +}; + +class ObProxyDbTablePos { +public: + ObProxyDbTablePos() : pos_(-1), name_(), type_(SHARDING_POS_NONE) {} + virtual ~ObProxyDbTablePos() {} + + void set_pos(const int32_t pos) { pos_ = pos; } + int32_t get_pos() { return pos_; } + + void set_type(const ShardingPosType type) { type_ = type; } + ShardingPosType get_type() { return type_; } + + void set_name(const ObString &name) { name_ = name; } + ObString &get_name() { return name_; } + + bool operator<(ObProxyDbTablePos &db_table_pos) + { + return pos_ < db_table_pos.get_pos(); + } + + TO_STRING_KV(K_(pos), K_(name), K_(type)); + +private: + int32_t pos_; + ObString name_; + ShardingPosType type_; +}; + class ObProxyStmt { public: ObProxyStmt(common::ObIAllocator& allocator) : stmt_type_(OBPROXY_T_INVALID), allocator_(allocator) {} @@ -71,11 +104,19 @@ class ObProxyStmt { common::ObString sql_string_; }; +enum SortListType { + SORT_LIST_NONE = 0, + SORT_LIST_IN_GROUP_BY, + SORT_LSIT_IN_ORDER_BY, + SORT_LIST_TYPE_MAX, +}; + class ObProxyDMLStmt : public ObProxyStmt { public: typedef common::hash::ObHashMap ExprMap; typedef common::ObSEArray TablePosArray; + typedef common::ObSEArray DbTablePosArray; public: ObProxyDMLStmt(common::ObIAllocator& allocator); @@ -96,6 +137,7 @@ class ObProxyDMLStmt : public ObProxyStmt bool has_unsupport_expr_type() const { return has_unsupport_expr_type_; } ExprMap& get_table_exprs_map() { return table_exprs_map_; } TablePosArray& get_table_pos_array() { return table_pos_array_; } + DbTablePosArray& get_db_table_pos_array() { return db_table_pos_array_; } protected: ObProxyExprType get_expr_type_by_node_type(const ObItemType& item_type); @@ -103,7 +145,7 @@ class ObProxyDMLStmt : public ObProxyStmt //for from int handle_from_list(ParseNode* node); - virtual int handle_table_node_to_expr(ParseNode* node); + int handle_table_node_to_expr(ParseNode* node); int get_table_and_db_expr(ParseNode* node, ObProxyExprTable* &expr_table); int handle_table_and_db_node(ParseNode* node, ObProxyExprTable* &expr_table); //for from in delete and update @@ -120,7 +162,7 @@ class ObProxyDMLStmt : public ObProxyStmt int handle_varchar_node_in_column_value(ParseNode* node, SqlField& sql_field); int handle_expr_list_node_in_column_value(ParseNode* node, SqlField& sql_field); int handle_column_ref_in_list(ParseNode *node); - virtual int column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObProxyExprTable* &expr_table); + int column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObProxyExprTable* &expr_table); int condition_exprs_to_sql_string(common::ObSqlString& sql_string); int limit_to_sql_string(common::ObSqlString& sql_string); @@ -146,21 +188,10 @@ class ObProxyDMLStmt : public ObProxyStmt ExprMap table_exprs_map_; ExprMap alias_table_map_; common::ObSEArray table_pos_array_; -}; - -enum SortListType { - SORT_LIST_NONE = 0, - SORT_LIST_IN_GROUP_BY, - SORT_LSIT_IN_ORDER_BY, - SORT_LIST_TYPE_MAX, -}; + common::ObSEArray db_table_pos_array_; -class ObProxySelectStmt : public ObProxyDMLStmt -{ +/*for sub select*/ public: - ObProxySelectStmt(common::ObIAllocator& allocator); - virtual ~ObProxySelectStmt(); - virtual int handle_parse_result(const ParseResult &parse_result); int handle_project_list(ParseNode* node); int handle_project_string(ParseNode* node); int handle_hint_clause(ParseNode* node); @@ -173,7 +204,7 @@ class ObProxySelectStmt : public ObProxyDMLStmt bool has_for_update() const { return has_for_update_; } int64_t get_from_token_off() { return from_token_off_; } -private: +protected: int project_string_to_expr(ParseNode* node, ObProxyExpr* &expr); int string_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node = NULL); int alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node = NULL); @@ -186,11 +217,9 @@ class ObProxySelectStmt : public ObProxyDMLStmt int max_node_to_expr(ParseNode* node, ObProxyExpr* &expr); int min_node_to_expr(ParseNode* node, ObProxyExpr* &expr); - int column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObProxyExprTable* &expr_table); int get_const_expr(ParseNode* node, ObProxyExpr* &expr); int get_sharding_const_expr(ParseNode* node, ObProxyExpr* &expr); - int handle_table_node_to_expr(ParseNode* node); int handle_table_and_db_in_hint(ParseNode* node); //for group by @@ -198,7 +227,7 @@ class ObProxySelectStmt : public ObProxyDMLStmt int handle_sort_list_node(ParseNode* node, const SortListType& sort_list_type); int handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, const SortListType& sort_list_type); -private: +protected: int do_handle_parse_result(ParseNode* node); int comments_to_sql_string(common::ObSqlString& sql_string); int hint_exprs_to_sql_string(common::ObSqlString& sql_string); @@ -206,16 +235,25 @@ class ObProxySelectStmt : public ObProxyDMLStmt int table_exprs_to_sql_string(common::ObSqlString& sql_string); int group_by_exprs_to_sql_string(common::ObSqlString& sql_string); int order_by_exprs_to_sql_string(common::ObSqlString& sql_string); -private: + int check_node_has_agg(ParseNode* node); public: common::ObSEArray select_exprs_; common::ObSEArray group_by_exprs_; //select groupby expression common::ObSEArray order_by_exprs_; -private: +protected: bool has_rollup_; bool has_for_update_; int64_t from_token_off_; + int64_t t_case_level_; +}; + +class ObProxySelectStmt : public ObProxyDMLStmt +{ +public: + ObProxySelectStmt(common::ObIAllocator& allocator) : ObProxyDMLStmt(allocator) {} + virtual ~ObProxySelectStmt() {} + virtual int handle_parse_result(const ParseResult &parse_result); }; class ObProxyInsertStmt : public ObProxyDMLStmt diff --git a/src/obproxy/obutils/ob_proxy_string_utils.cpp b/src/obproxy/obutils/ob_proxy_string_utils.cpp index 802876b9..c32caeb5 100644 --- a/src/obproxy/obutils/ob_proxy_string_utils.cpp +++ b/src/obproxy/obutils/ob_proxy_string_utils.cpp @@ -23,7 +23,7 @@ namespace obproxy { namespace obutils { -ObProxyVariantString::ObProxyVariantString():data_(NULL), data_size_(0) +ObProxyVariantString::ObProxyVariantString(): config_string_(), data_(NULL), data_size_(0) { } @@ -47,7 +47,7 @@ ObProxyVariantString& ObProxyVariantString::operator=(const ObProxyVariantString { if (&vstr != this) { reset(); - set_value(vstr.data_size_, vstr.data_); + set_value(vstr.config_string_.length(), vstr.config_string_.ptr()); } return *this; } @@ -92,6 +92,41 @@ bool ObProxyVariantString::set_value(const int32_t len, const char *value) return true; } +bool ObProxyVariantString::set_value_with_quote(const common::ObString &value, const char quote) +{ + return set_value_with_quote(value.length(), value.ptr(), quote); +} + +bool ObProxyVariantString::set_value_with_quote(const int32_t len, const char *value, const char quote) +{ + reset(); + data_size_ = len + 3; + data_ = (char*)ob_malloc(data_size_); + if (OB_ISNULL(data_)) { + LOG_WARN("ob_malloc failed", K_(data_size)); + return false; + } else { + data_[0] = quote; + MEMCPY(data_ + 1, value, len); + data_[len + 1] = quote; + data_[len + 2] = '\0'; + config_string_.assign_ptr(data_, len + 2); + } + + return true; +} + +void ObProxyVariantString::set_integer(const int64_t other) +{ + char buf[1024]; + const int32_t len = snprintf(buf, 1024, "%ld", other); + if (len <= 0 || len >= 1024) { + LOG_ERROR("snprintf failed", K(other)); + } else { + set_value(len, buf); + } +} + } // end of namespace obutils } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/obutils/ob_proxy_string_utils.h b/src/obproxy/obutils/ob_proxy_string_utils.h index 1e5ce7bd..8bd00432 100644 --- a/src/obproxy/obutils/ob_proxy_string_utils.h +++ b/src/obproxy/obutils/ob_proxy_string_utils.h @@ -44,7 +44,10 @@ class ObProxyVariantString bool init(common::ObMalloc* allocator, const int64_t mod_id); bool set_value(const common::ObString &value); bool set_value(const int32_t len, const char *value); + bool set_value_with_quote(const common::ObString &value, const char quote); + bool set_value_with_quote(const int32_t len, const char *value, const char quote); uint64_t hash(uint64_t seed = 0) const { return config_string_.hash(seed); } + void set_integer(const int64_t other); common::ObString config_string_; DECLARE_TO_STRING; private: diff --git a/src/obproxy/obutils/ob_proxy_table_processor.h b/src/obproxy/obutils/ob_proxy_table_processor.h index 84424575..f847b000 100644 --- a/src/obproxy/obutils/ob_proxy_table_processor.h +++ b/src/obproxy/obutils/ob_proxy_table_processor.h @@ -68,7 +68,7 @@ class ObProxyServerInfo DECLARE_TO_STRING; public: - char proxy_ip_[common::OB_IP_STR_BUFF]; // ip primary key + char proxy_ip_[common::MAX_IP_ADDR_LENGTH]; // ip primary key char regist_time_str_[common::OB_MAX_TIME_STR_LENGTH + 1]; // the time when one obproxy register to observer char app_name_[common::OB_MAX_APP_NAME_LENGTH + 1]; // application proxy used for char binary_version_[OB_MAX_PROXY_BINARY_VERSION_LEN + 1]; // man readable version diff --git a/src/obproxy/obutils/ob_proxy_table_processor_utils.cpp b/src/obproxy/obutils/ob_proxy_table_processor_utils.cpp index e1fdc15f..7e8600dc 100644 --- a/src/obproxy/obutils/ob_proxy_table_processor_utils.cpp +++ b/src/obproxy/obutils/ob_proxy_table_processor_utils.cpp @@ -453,7 +453,7 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result int64_t tmp_real_str_len = 0; int64_t vid = 0; int64_t vport = 0; - char vip[OB_IP_STR_BUFF]; + char vip[MAX_IP_ADDR_LENGTH]; vip[0] = '\0'; ObString tenant_name; ObString cluster_name; @@ -472,7 +472,7 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result while (OB_SUCC(ret) && OB_SUCC(result_handler.next())) { PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "vid", vid, int64_t); - PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "vip", vip, OB_IP_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "vip", vip, MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "vport", vport, int64_t); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(result_handler, "tenant_name", tenant_name); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(result_handler, "cluster_name", cluster_name); @@ -506,8 +506,7 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result if (OB_ISNULL(vip_tenant = op_alloc(ObVipTenant))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory for ObVipTenant", K(ret)); - } else if (FALSE_IT(vip_tenant->vip_addr_.set(ObAddr::convert_ipv4_addr(vip), - static_cast(vport), vid))) { + } else if (FALSE_IT(vip_tenant->vip_addr_.set(vip, static_cast(vport), vid))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to set vip_addr", K(vip), K(vport), K(vid), K(ret)); } else if (OB_FAIL(vip_tenant->set_tenant_cluster(tenant_name, cluster_name))) { @@ -522,16 +521,47 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result } else if (OB_FAIL(cache_map.unique_set(vip_tenant))) { LOG_WARN("fail to insert one vip_tenant into cache_map", K(*vip_tenant), K(ret)); } else { - LOG_DEBUG("succ to insert one vip_tenant into cache_map", K(*vip_tenant)); - vip_tenant = NULL; - vid = 0; - vip[0] = '\0'; - vport = 0; - tenant_name.reset(); - cluster_name.reset(); - info_config = NULL; - request_target_type = -1; - rw_type = -1; + char request_target_buf[32]; + char rw_buf[32]; + ObString request_target_string; + ObString rw_string; + int32_t request_len = snprintf(request_target_buf, sizeof(request_target_buf), "%ld", request_target_type); + int32_t rw_len = snprintf(rw_buf, sizeof(rw_buf), "%ld", rw_type); + request_target_string.assign_ptr(request_target_buf, request_len); + rw_string.assign_ptr(rw_buf, rw_len); + if (OB_FAIL(get_global_config_processor().store_proxy_config_with_level( + vid, vip, vport, "", "", "proxy_tenant_name", tenant_name, "LEVEL_VIP"))) { + LOG_WARN("store proxy_tenant_name failed", K(vid), K(vip), K(vport), K(tenant_name), K(cluster_name), K(ret)); + } else if (OB_FAIL(get_global_config_processor().store_proxy_config_with_level( + vid, vip, vport, "", "", "rootservice_cluster_name", cluster_name, "LEVEL_VIP"))) { + LOG_WARN("store rootservice_cluster_name failed", K(vid), K(vip), K(vport), K(tenant_name), K(cluster_name), K(ret)); + } + if (OB_SUCC(ret) && -1 != rw_type) { + if (OB_FAIL(get_global_config_processor().store_proxy_config_with_level( + vid, vip, vport, tenant_name, cluster_name, "obproxy_read_only", rw_string, "LEVEL_VIP"))) { + LOG_WARN("store obporxy_read_only failed", K(vid), K(vip), K(vport), K(tenant_name), K(cluster_name), K(rw_type), K(ret)); + } + } + if (OB_SUCC(ret) && -1 != request_target_type) { + if (OB_FAIL(get_global_config_processor().store_proxy_config_with_level( + vid, vip, vport, tenant_name, cluster_name, "obproxy_read_consistency", request_target_string, "LEVEL_VIP"))) { + LOG_WARN("store obproxy_read_consistency failed", K(vid), K(vip), K(vport), K(tenant_name), K(cluster_name), K(request_target_type), K(ret)); + } + } + if (OB_SUCC(ret)) { + LOG_DEBUG("succ to insert one vip_tenant into cache_map", K(*vip_tenant)); + vip_tenant = NULL; + vid = 0; + vip[0] = '\0'; + vport = 0; + tenant_name.reset(); + cluster_name.reset(); + info_config = NULL; + request_target_type = -1; + rw_type = -1; + request_target_string.reset(); + rw_string.reset(); + } } }//end if OB_SUCCESS }//end of while @@ -554,23 +584,24 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result int ObProxyTableProcessorUtils::get_proxy_local_addr(ObAddr &addr) { int ret = OB_SUCCESS; - char ip_str[OB_IP_STR_BUFF] = {'\0'}; + char ip_str[MAX_IP_ADDR_LENGTH] = {'\0'}; const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); in_port_t port = 0; ObIpAddr inbound_ip; // get inbound ip and port if (OB_LIKELY(info.is_inherited_)) { - if (OB_UNLIKELY(NO_FD == info.fd_)) { + // Does not support ipv6 yet + if (OB_UNLIKELY(NO_FD == info.ipv4_fd_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("this process is inherited born, but listen fd is invalid", - "is_inherited", info.is_inherited_, "fd", info.fd_, K(ret)); + "is_inherited", info.is_inherited_, "fd", info.ipv4_fd_, K(ret)); } else { struct sockaddr sock_addr; int64_t namelen = sizeof(sock_addr); memset(&sock_addr, 0, namelen); - if (OB_FAIL(ObSocketManager::getsockname(info.fd_, &sock_addr , &namelen))) { - LOG_WARN("fail to get sock name", K(info.fd_), K(ret)); + if (OB_FAIL(ObSocketManager::getsockname(info.ipv4_fd_, &sock_addr , &namelen))) { + LOG_WARN("fail to get sock name", K(info.ipv4_fd_), K(ret)); } else { struct sockaddr_in *ain = (sockaddr_in *)&sock_addr; inbound_ip.assign(sock_addr); @@ -590,7 +621,7 @@ int ObProxyTableProcessorUtils::get_proxy_local_addr(ObAddr &addr) // check valid if (OB_SUCC(ret)) { - inbound_ip.get_ip_str(ip_str, OB_IP_STR_BUFF); + inbound_ip.get_ip_str(ip_str, MAX_IP_ADDR_LENGTH); ObAddr any_addr(ObAddr::IPV4, INADDR_ANY_IP, port); ObAddr local_addr(ObAddr::IPV4, INADDR_LOOPBACK_IP, port); ObAddr inbound_addr(ObAddr::IPV4, ip_str, port); @@ -600,15 +631,15 @@ int ObProxyTableProcessorUtils::get_proxy_local_addr(ObAddr &addr) // if inbound_addr == 0.0.0.0 or 127.0.0.1, we treat it as not user specified ip, // and in this case, we get one local net addr; if (inbound_addr == any_addr || inbound_addr == local_addr) { - memset(ip_str, 0, OB_IP_STR_BUFF); - if (OB_FAIL(get_one_local_addr(ip_str, OB_IP_STR_BUFF))) { + memset(ip_str, 0, MAX_IP_ADDR_LENGTH); + if (OB_FAIL(get_one_local_addr(ip_str, MAX_IP_ADDR_LENGTH))) { LOG_WARN("fail to get one local addr", K(ret)); } } } if (OB_SUCC(ret)) { - addr.set_ipv4_addr(ip_str, port); + addr.set_ip_addr(ip_str, port); if (OB_UNLIKELY(!addr.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid addr", K(addr), K(ret)); diff --git a/src/obproxy/obutils/ob_resource_pool_processor.cpp b/src/obproxy/obutils/ob_resource_pool_processor.cpp index c83f71b6..7a343bfd 100644 --- a/src/obproxy/obutils/ob_resource_pool_processor.cpp +++ b/src/obproxy/obutils/ob_resource_pool_processor.cpp @@ -27,6 +27,7 @@ #include "obutils/ob_async_common_task.h" #include "lib/container/ob_array_iterator.h" #include "lib/container/ob_se_array_iterator.h" +#include "lib/encrypt/ob_encrypted_helper.h" using namespace obsys; using namespace oceanbase::common; @@ -511,7 +512,7 @@ int ObServerStateInfoInitCont::finish_task(void *data) const int64_t MAX_DISPLAY_STATUS_LEN = 64; char display_status_str[MAX_DISPLAY_STATUS_LEN]; ObServerStatus::DisplayStatus server_status = ObServerStatus::OB_DISPLAY_MAX; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; int64_t port = 0; int64_t tmp_real_str_len = 0; int64_t start_service_time = 0; @@ -548,7 +549,7 @@ int ObServerStateInfoInitCont::finish_task(void *data) PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(result_handler, "zone", zone_name); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(result_handler, "zone_status", zone_status); - PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "svr_ip", ip_str, OB_IP_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "svr_ip", ip_str, MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "svr_port", port, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "start_service_time", start_service_time, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "stop_time", stop_time, int64_t); @@ -1591,6 +1592,8 @@ int ObClusterResource::init(const common::ObString &cluster_name, int64_t cluste } else if (OB_FAIL(pending_list_.init("cr init pending list", reinterpret_cast(&(reinterpret_cast (0))->link_)))) { LOG_WARN("fail to init pending list", K(ret)); + } else if (OB_FAIL(alive_addr_set_.create(4))) { + LOG_WARN("alive_addr_set create failed", K(ret)); } else { is_inited_ = true; version_ = version; @@ -1619,10 +1622,34 @@ int ObClusterResource::init_local_config(const ObResourcePoolConfig &config) int64_t timeout_ms = usec_to_msec(config.short_async_task_timeout_); const ObString user_name(ObProxyTableInfo::READ_ONLY_USERNAME); const ObString database(ObProxyTableInfo::READ_ONLY_DATABASE); - ObString password(get_global_proxy_config().observer_sys_password.str()); - ObString password1(get_global_proxy_config().observer_sys_password1.str()); + ObString cluster_name = cluster_info_key_.cluster_name_.config_string_; + ObConfigItem item; + char password[ENC_STRING_BUF_LEN]; + char password1[ENC_STRING_BUF_LEN]; + memset(password, 0, sizeof (password)); + memset(password1, 0, sizeof (password1)); + + ObVipAddr addr; + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name, "", ObProxyTableInfo::OBSERVER_SYS_PASSWORD, item))) { + LOG_WARN("get observer_sys_password config failed", K(cluster_name), K(ret)); + } else { + MEMCPY(password, item.str(), strlen(item.str())); + } - if (OB_FAIL(mysql_proxy_.init(timeout_ms, user_name, password, database, password1))) { + if (OB_SUCC(ret)) { + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name, "", ObProxyTableInfo::OBSERVER_SYS_PASSWORD1, item))) { + LOG_WARN("get observer_sys_password1 config failed", K(cluster_name), K(ret)); + } else { + MEMCPY(password1, item.str(), strlen(item.str())); + } + } + + + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(mysql_proxy_.init(timeout_ms, user_name, password, database, cluster_name, password1))) { LOG_WARN("fail to init mysql proxy", K(ret)); } else if (OB_FAIL(rebuild_mysql_client_pool( get_global_resource_pool_processor().get_default_cluster_resource()))) { @@ -1956,7 +1983,7 @@ int ObClusterResource::update_location_tenant_info(ObSEArray &tenan } } // for } // if in wlock - + return ret; } @@ -2017,7 +2044,7 @@ uint64_t ObClusterResource::get_location_tenant_version(const ObString &tenant_n int ObClusterResource::get_location_tenant_info(const ObString &tenant_name, ObLocationTenantInfo *&info_out) { int ret = OB_SUCCESS; - + if (!tenant_name.empty() && tenant_name != OB_SYS_TENANT_NAME) { ObLocationTenantInfo *info = NULL; DRWLock::RDLockGuard lock(location_tenant_info_lock_); @@ -2057,52 +2084,16 @@ int ObLocationTenantInfo::resolve_location_tenant_info_primary_zone(ObString &pr // resolve to zone priority array // resolve to zone weight priority array - int i = 0; - int j = i; - int total_len = primary_zone_.length(); - const char *ptr = primary_zone_.ptr(); - ObSEArray tmp_pz_prio_array; - int8_t weight = 1; - - while (i < total_len && j < total_len) { - j++; - if (j >= total_len || ptr[j] == ';') { - if (j > i) { - ObString each_zone(j - i, ptr + i); - tmp_pz_prio_array.push_back(each_zone); - } - - if (tmp_pz_prio_array.count() > 0) { - for (int64_t k = 0; k < tmp_pz_prio_array.count(); k++) { - primary_zone_prio_array_.push_back(tmp_pz_prio_array.at(k)); - primary_zone_prio_weight_array_.push_back(weight); - } - tmp_pz_prio_array.reset(); - weight++; - } - i = j + 1; - j = i; - } else if (ptr[j] == ',') { - if (j > i) { - ObString each_zone(j - i, ptr + i); - tmp_pz_prio_array.push_back(each_zone); - } - i = j + 1; - j = i; - } else { - // nothing - } - } // while - - - if (primary_zone_prio_array_.count() != primary_zone_prio_weight_array_.count()) { + if (OB_FAIL(split_weight_group(primary_zone_, primary_zone_prio_array_, primary_zone_prio_weight_array_))) { + LOG_WARN("fail to resolve primary zone", K(ret), K(primary_zone_)); + } else if (primary_zone_prio_array_.count() != primary_zone_prio_weight_array_.count()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected array count check", K(tenant_name_), K(version_), K(primary_zone_prio_array_.count()), + LOG_WARN("unexpected array count check", K(tenant_name_), K(version_), K(primary_zone_prio_array_.count()), K(primary_zone_prio_weight_array_.count())); } else { LOG_DEBUG("succ to resolve primary zone", KPC(this)); } - } + } return ret; } @@ -2202,11 +2193,12 @@ int ObResourcePoolProcessor::init(ObProxyConfig &config, proxy::ObMysqlProxy &me // impossible } else if (OB_FAIL(default_cr_->init_local_config(config_))) { LOG_WARN("fail to build local default cluster resource", K(ret)); + } else if (OB_FAIL(ip_set_.create(8))) { + LOG_WARN("ip_set create failed", K(ret)); } else { default_cr_->inc_ref(); default_sysvar_set_->inc_ref(); meta_client_proxy_ = &meta_client_proxy; - ip_set_.create(8); is_inited_ = true; } diff --git a/src/obproxy/obutils/ob_resource_pool_processor.h b/src/obproxy/obutils/ob_resource_pool_processor.h index 6777e03f..b4847957 100644 --- a/src/obproxy/obutils/ob_resource_pool_processor.h +++ b/src/obproxy/obutils/ob_resource_pool_processor.h @@ -228,7 +228,7 @@ class ObClusterResource : public common::ObSharedRefCount cluster_info_key_(), last_access_time_ns_(0), deleting_completed_thread_num_(0), version_(0), fetch_rslist_task_count_(0), fetch_idc_list_task_count_(0), last_idc_list_refresh_time_ns_(0), last_rslist_refresh_time_ns_(0), - pending_list_(), cluster_version_(0), is_inited_(false), cr_state_(CR_BORN), sys_ldg_info_map_(), + pending_list_(), cluster_version_(0), alive_addr_set_(), is_inited_(false), cr_state_(CR_BORN), sys_ldg_info_map_(), sys_ldg_info_lock_(), location_tenant_info_lock_(), location_tenant_info_map_() {} virtual ~ObClusterResource() {} virtual void free(); @@ -358,6 +358,7 @@ class ObClusterResource : public common::ObSharedRefCount int64_t last_rslist_refresh_time_ns_; common::ObAtomicList pending_list_; int64_t cluster_version_; + common::hash::ObHashSet alive_addr_set_; LINK(ObClusterResource, cr_link_); private: diff --git a/src/obproxy/obutils/ob_server_state_processor.cpp b/src/obproxy/obutils/ob_server_state_processor.cpp index d08665b6..346ade5f 100644 --- a/src/obproxy/obutils/ob_server_state_processor.cpp +++ b/src/obproxy/obutils/ob_server_state_processor.cpp @@ -91,6 +91,8 @@ class ObDetectOneServerStateCont : public obutils::ObAsyncCommonTask private: ObClusterResource *cluster_resource_; ObAddr addr_; + ObMysqlClient *mysql_client_; + ObMysqlProxy mysql_proxy_; private: DISALLOW_COPY_AND_ASSIGN(ObDetectOneServerStateCont); @@ -606,7 +608,7 @@ int ObServerStateRefreshCont::handle_all_tenant(void *data) } } } - + if (ret != OB_ITER_END) { // handle case of fail to access __all_tenant on alipay main site: do not exec error handling process if (ER_TABLEACCESS_DENIED_ERROR == resp->get_err_code()) { @@ -623,7 +625,7 @@ int ObServerStateRefreshCont::handle_all_tenant(void *data) } ret = OB_SUCCESS; } - + if (OB_SUCC(ret) && OB_FAIL(schedule_refresh_server_state())) { LOG_WARN("fail to schedule refresh server state", K(ret)); } @@ -1236,8 +1238,7 @@ int ObServerStateRefreshCont::do_update_server(const ObServerStateInfo &ss_info) } } - ObIpEndpoint ip; - ops_ip_copy(ip.sa_, ss_info.replica_.server_.get_ipv4(), static_cast(ss_info.replica_.server_.get_port())); + ObIpEndpoint ip(ss_info.replica_.server_.get_sockaddr()); if (!need_update && ObCongestionEntry::ACTIVE == ss_info.cgt_server_state_) { if (OB_HASH_EXIST == get_global_resource_pool_processor().ip_set_.exist_refactored(ip)) { need_update = true; @@ -1504,8 +1505,7 @@ int ObServerStateRefreshCont::handle_deleted_server(ObIArray } if (!found) { LOG_INFO("deleted server", "ss_info", last_ss_info); - ops_ip_copy(ip.sa_, last_ss_info.replica_.server_.get_ipv4(), - static_cast(last_ss_info.replica_.server_.get_port())); + ip.assign(last_ss_info.replica_.server_.get_sockaddr()); int64_t cr_version = cluster_resource_->version_; if (OB_FAIL(congestion_manager_->update_server(ip, cr_version, ObCongestionEntry::DELETED, last_ss_info.zone_state_->zone_name_, @@ -1666,7 +1666,7 @@ int ObServerStateRefreshUtils::get_server_state_info( { int ret = OB_SUCCESS; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; int64_t port = 0; ObServerStateInfo server_state; const int64_t MAX_DISPLAY_STATUS_LEN = 64; @@ -1682,7 +1682,7 @@ int ObServerStateRefreshUtils::get_server_state_info( display_status_str[0] = '\0'; zone_name[0] = '\0'; PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "svr_ip", ip_str, - OB_IP_STR_BUFF, tmp_real_str_len); + MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "svr_port", port, int64_t); PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "zone", zone_name, MAX_ZONE_LENGTH + 1, zone_name_len); @@ -1921,7 +1921,7 @@ DEF_TO_STRING(ObDetectServerStateCont) int ObDetectServerStateCont::schedule_detect_server_state() { int ret = OB_SUCCESS; - bool enable_server_detect = (0 < get_global_proxy_config().server_detect_mode); + const int64_t server_detect_mode = get_global_proxy_config().server_detect_mode; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", K_(is_inited), K(ret)); @@ -1931,7 +1931,7 @@ int ObDetectServerStateCont::schedule_detect_server_state() } else if (OB_UNLIKELY(!self_ethread().is_event_thread_type(ET_CALL))) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("server state refresh cont must be scheduled in work thread", K(ret)); - } else if (enable_server_detect) { + } else if (server_detect_mode > 0) { int64_t ss_version = cluster_resource_->server_state_version_; common::DRWLock &server_state_lock = cluster_resource_->get_server_state_lock(ss_version); server_state_lock.rdlock(); @@ -1942,11 +1942,14 @@ int ObDetectServerStateCont::schedule_detect_server_state() for (int i = 0; i < server_state_info.count(); i++) { ObServerStateSimpleInfo &info = server_state_info.at(i); - bool need_check = common::ObTimeUtility::current_time() - info.last_response_time_ >= 5 * 1000 * 1000; - int64_t cnt = info.request_sql_cnt_; + bool check_pass = true; + // Accurate detection method + if (1 == server_detect_mode) { + check_pass = (info.request_sql_cnt_ > 0); + LOG_DEBUG("check detect one server", K(server_detect_mode), K_(info.request_sql_cnt), K(check_pass)); + } - LOG_DEBUG("check need schedule one server", K(info), K(need_check), K(cnt)); - if ((cnt > 0 && need_check) || info.detect_fail_cnt_ > 0) { + if (check_pass || info.detect_fail_cnt_ > 0) { // There is no need to judge whether the push_back is successful here ObDetectOneServerStateCont *cont = NULL; if (OB_ISNULL(cont = op_alloc(ObDetectOneServerStateCont))) { @@ -1960,13 +1963,11 @@ int ObDetectServerStateCont::schedule_detect_server_state() } LOG_DEBUG("schedule detect one server state", K(info), K(ss_version)); } else { - struct sockaddr_in in; - in.sin_family = AF_INET; - in.sin_port = (htons)(static_cast(info.addr_.get_port())); - in.sin_addr.s_addr = htonl(info.addr_.ip_.v4_); - ObIpEndpoint point(*reinterpret_cast(&in)); + ObIpEndpoint point(info.addr_.get_sockaddr()); if (OB_HASH_EXIST == get_global_resource_pool_processor().ip_set_.exist_refactored(point)) { addr_set.set_refactored(info.addr_); + } else if (OB_HASH_EXIST == cluster_resource_->alive_addr_set_.exist_refactored(point)) { + addr_set.set_refactored(info.addr_); } } } @@ -1997,11 +1998,11 @@ int ObDetectServerStateCont::schedule_detect_server_state() HRTIME_USECONDS(server_detect_state_interval_us_), DETECT_SERVER_STATE_EVENT))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to schedule refresh server state", K_(server_detect_state_interval_us), - K(enable_server_detect), KPC_(cluster_resource), K(ret)); + K(server_detect_mode), KPC_(cluster_resource), K(ret)); } LOG_DEBUG("schedule detect server state", K_(server_detect_state_interval_us), - K(enable_server_detect), KPC_(cluster_resource), K(ret)); + K(server_detect_mode), KPC_(cluster_resource), K(ret)); return ret; } @@ -2096,7 +2097,8 @@ int ObDetectServerStateCont::set_detect_server_state_interval(const int64_t refr ObDetectOneServerStateCont::ObDetectOneServerStateCont() : ObAsyncCommonTask(NULL, "detect_server_state_task"), - cluster_resource_(NULL), addr_() + cluster_resource_(NULL), addr_(), mysql_client_(NULL), + mysql_proxy_() { SET_HANDLER(&ObDetectOneServerStateCont::main_handler); } @@ -2104,13 +2106,33 @@ ObDetectOneServerStateCont::ObDetectOneServerStateCont() int ObDetectOneServerStateCont::init(ObClusterResource *cluster_resource, ObAddr addr) { int ret = OB_SUCCESS; + const int64_t timeout_ms = usec_to_msec(get_global_proxy_config().detect_server_timeout); if (OB_UNLIKELY(NULL == cluster_resource || !addr.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("init obdetectserverstate cont failed", K(cluster_resource), K(ret)); + // The detection only depends on whether OBServer returns OB_MYSQL_COM_HANDSHAKE, + // and will not log in. The following parameters will not be actually used, + // only for the initialization of class objects + // user_name : detect_username + // password : detect_password + // database : detect_database + } else if (OB_FAIL(mysql_proxy_.init(timeout_ms, ObProxyTableInfo::DETECT_USERNAME_USER, "detect_password", "detect_database"))) { + LOG_WARN("fail to init mysql proxy", K(ret)); } else { cluster_resource->inc_ref(); cluster_resource_ = cluster_resource; addr_ = addr; + if (OB_ISNULL(mysql_client_ = op_alloc(ObMysqlClient))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate ObMysqlClient", K(ret)); + } else if (OB_FAIL(mysql_client_->init_detect_client(cluster_resource_))) { + LOG_WARN("fail to init detect client", K(ret)); + } + + if (OB_FAIL(ret) && (NULL != mysql_client_)) { + mysql_client_->kill_this(); + mysql_client_ = NULL; + } } return ret; @@ -2124,6 +2146,10 @@ void ObDetectOneServerStateCont::kill_this() cluster_resource_->dec_ref(); cluster_resource_ = NULL; } + if (OB_LIKELY(NULL != mysql_client_)) { + mysql_client_->kill_this(); + mysql_client_ = NULL; + } if (OB_FAIL(cancel_timeout_action())) { LOG_WARN("fail to cancel timeout action", K(ret)); } @@ -2174,14 +2200,15 @@ int ObDetectOneServerStateCont::main_handler(int event, void *data) int ObDetectOneServerStateCont::detect_server_state_by_sql() { int ret = OB_SUCCESS; - ObMysqlProxy *mysql_proxy = &cluster_resource_->mysql_proxy_; - char sql[] = "select 'detect server alive' from dual"; + char sql[] = "select 'detect server' from dual"; LOG_DEBUG("begin to detect server", K_(addr)); ObMysqlRequestParam request_param(sql); request_param.set_target_addr(addr_); + request_param.set_mysql_client(mysql_client_); + request_param.set_is_detect_client(true); const int64_t timeout_ms = usec_to_msec(get_global_proxy_config().detect_server_timeout); - if (OB_FAIL(mysql_proxy->async_read(this, request_param, pending_action_, timeout_ms))) { - LOG_WARN("fail to nonblock read", K(sql), K(ret)); + if (OB_FAIL(mysql_proxy_.async_read(this, request_param, pending_action_, timeout_ms))) { + LOG_WARN("fail to async read", K(ret)); } return ret; @@ -2199,24 +2226,26 @@ int ObDetectOneServerStateCont::handle_client_resp(void *data) bool found = false; for (int i = 0; !found && i < server_state_info.count(); i++) { ObServerStateSimpleInfo &info = server_state_info.at(i); - ObIpEndpoint ip; + ObIpEndpoint ip(info.addr_.get_sockaddr()); ObCongestionEntry::ObServerState state = ObCongestionEntry::ObServerState::ACTIVE; - ops_ip_copy(ip.sa_, info.addr_.get_ipv4(), static_cast(info.addr_.get_port())); if (addr_ == info.addr_) { if (NULL != data) { (void)ATOMIC_SET(&info.detect_fail_cnt_, 0); state = ObCongestionEntry::ObServerState::DETECT_ALIVE; - LOG_DEBUG("succe to get resp from server", K(info)); + cluster_resource_->alive_addr_set_.erase_refactored(ip); + get_global_resource_pool_processor().ip_set_.erase_refactored(ip); + LOG_DEBUG("detect server alive", K(info)); } else { int64_t fail_cnt = ATOMIC_AAF(&info.detect_fail_cnt_, 1); - LOG_WARN("detect server alive failed", K(info)); + LOG_WARN("detect server dead", K(info)); if (fail_cnt >= get_global_proxy_config().server_detect_fail_threshold) { // If the detection failure exceeds the number of retries, the server needs to be added to the blacklist (void)ATOMIC_SET(&info.detect_fail_cnt_, 0); state = ObCongestionEntry::ObServerState::DETECT_DEAD; + get_global_resource_pool_processor().ip_set_.set_refactored(ip); } } - + if (ObCongestionEntry::ObServerState::DETECT_DEAD == state || ObCongestionEntry::ObServerState::DETECT_ALIVE == state) { ObCongestionManager &congestion_manager = cluster_resource_->congestion_manager_; @@ -2232,9 +2261,9 @@ int ObDetectOneServerStateCont::handle_client_resp(void *data) } if (!found) { - ObIpEndpoint ip; - ops_ip_copy(ip.sa_, addr_.get_ipv4(), static_cast(addr_.get_port())); + ObIpEndpoint ip(addr_.get_sockaddr()); get_global_resource_pool_processor().ip_set_.erase_refactored(ip); + cluster_resource_->alive_addr_set_.erase_refactored(ip); LOG_WARN("server not in cluster", K(ip), KPC_(cluster_resource)); } server_state_lock2.rdunlock(); diff --git a/src/obproxy/obutils/ob_state_info.h b/src/obproxy/obutils/ob_state_info.h index f6d450e8..f039bd8d 100644 --- a/src/obproxy/obutils/ob_state_info.h +++ b/src/obproxy/obutils/ob_state_info.h @@ -286,7 +286,7 @@ inline int ObServerStateInfo::add_addr(const char *ip, const int64_t port) inline ObServerStateSimpleInfo &ObServerStateSimpleInfo::operator=(const ObServerStateSimpleInfo &other) { if (this != &other) { - addr_.set_ipv4_addr(other.addr_.get_ipv4(), other.addr_.get_port()); + addr_ = other.addr_; is_merging_ = other.is_merging_; is_force_congested_ = other.is_force_congested_; zone_type_ = other.zone_type_; @@ -329,8 +329,8 @@ inline int ObServerStateSimpleInfo::set_addr(const common::ObAddr &addr) if (OB_UNLIKELY(!addr.is_valid())) { ret = common::OB_INVALID_ARGUMENT; PROXY_LOG(WARN, "invalid argument", K(addr), K(ret)); - } else if (OB_UNLIKELY(!addr_.set_ipv4_addr(addr.get_ipv4(), addr.get_port()))) { - ret = common::OB_INVALID_ARGUMENT; + } else { + addr_ = addr; } return ret; } @@ -338,7 +338,7 @@ inline int ObServerStateSimpleInfo::set_addr(const common::ObAddr &addr) inline int ObServerStateSimpleInfo::set_addr(const char *ip, const int64_t port) { int ret = common::OB_SUCCESS; - if (OB_UNLIKELY(!addr_.set_ipv4_addr(ip, static_cast(port)))) { + if (OB_UNLIKELY(!addr_.set_ip_addr(ip, static_cast(port)))) { ret = common::OB_INVALID_ARGUMENT; } return ret; diff --git a/src/obproxy/obutils/ob_vip_tenant_cache.cpp b/src/obproxy/obutils/ob_vip_tenant_cache.cpp index 0d3a41d5..51b27f90 100644 --- a/src/obproxy/obutils/ob_vip_tenant_cache.cpp +++ b/src/obproxy/obutils/ob_vip_tenant_cache.cpp @@ -23,7 +23,19 @@ namespace obproxy namespace obutils { -void ObVipAddr::set(const int32_t ip, const int32_t port, const int64_t vid) +void ObVipAddr::set(const char* ip, const int32_t port, const int64_t vid) +{ + if (NULL == ip || 0 == strcasecmp(ip, "") || port <= 0) { + addr_.reset(); + } else if (OB_UNLIKELY(!addr_.set_ip_addr(ip, port))) { + LOG_WARN("fail to set_ip_addr", K(ip), K(port), K(addr_)); + addr_.reset(); + } else { + vid_ = vid; + } +} + +void ObVipAddr::set_ipv4(int32_t ip, const int32_t port, const int64_t vid) { if (OB_UNLIKELY(!addr_.set_ipv4_addr(ip, port))) { LOG_WARN("fail to set_ipv4_addr", K(ip), K(port), K(addr_)); @@ -33,6 +45,12 @@ void ObVipAddr::set(const int32_t ip, const int32_t port, const int64_t vid) } } +void ObVipAddr::set(const struct sockaddr &addr, const int64_t vid) +{ + addr_.set_sockaddr(addr); + vid_ = vid; +} + int ObVipTenant::set_tenant_cluster(const ObString &tenant_name, const ObString &cluster_name) { int ret = OB_SUCCESS; diff --git a/src/obproxy/obutils/ob_vip_tenant_cache.h b/src/obproxy/obutils/ob_vip_tenant_cache.h index 487c6b0a..95c2aefa 100644 --- a/src/obproxy/obutils/ob_vip_tenant_cache.h +++ b/src/obproxy/obutils/ob_vip_tenant_cache.h @@ -24,6 +24,19 @@ namespace obproxy namespace obutils { +enum ObVipTenantRequestType +{ + InvalidRequestType = -1, + RequestLeader, + RequestFollower, +}; +enum ObVipTenantRWType +{ + InvalidRWType = -1, + ReadOnly, + ReadWrite, +}; + struct ObVipAddr { public: @@ -33,7 +46,9 @@ struct ObVipAddr bool is_valid() const { return (addr_.is_valid() && vid_ >= 0); } void reset() { vid_ = -1; addr_.reset(); } bool operator==(const ObVipAddr &vip_addr) const { return (vip_addr.vid_ == vid_ && vip_addr.addr_ == addr_); } - void set(const int32_t ip, const int32_t port, const int64_t vid); + void set(const char* ip, const int32_t port, const int64_t vid); + void set_ipv4(int32_t ip, const int32_t port, const int64_t vid); + void set(const struct sockaddr &addr, const int64_t vid); TO_STRING_KV(K_(addr), K_(vid)); public: @@ -43,20 +58,6 @@ struct ObVipAddr struct ObVipTenant { -private: - enum ObVipTenantRequestType - { - InvalidRequestType = -1, - RequestLeader, - RequestFollower, - }; - enum ObVipTenantRWType - { - InvalidRWType = -1, - ReadOnly, - ReadWrite, - }; - public: ObVipTenant() : vip_addr_(), tenant_name_(), cluster_name_(), request_target_type_(InvalidRequestType), rw_type_(InvalidRWType) diff --git a/src/obproxy/omt/ob_conn_table_processor.cpp b/src/obproxy/omt/ob_conn_table_processor.cpp index bf49a325..73bb19ee 100644 --- a/src/obproxy/omt/ob_conn_table_processor.cpp +++ b/src/obproxy/omt/ob_conn_table_processor.cpp @@ -49,7 +49,7 @@ using namespace oceanbase::obproxy::obutils; using namespace oceanbase::json; extern int build_tenant_cluster_vip_name(const ObString &tenant_name, const ObString &cluster_name, const ObString &vip_name, - ObFixedLengthString &key_string); + ObFixedLengthString &key_string); int ObConnTableProcessor::commit(bool is_success) { @@ -111,7 +111,7 @@ int ObConnTableProcessor::inc_conn(ObString& cluster_name, ObString& tenant_name int ret = OB_SUCCESS; ObString key_name; ObUsedConn* used_conn = NULL; - common::ObFixedLengthString key_string; + common::ObFixedLengthString key_string; if (OB_FAIL(build_tenant_cluster_vip_name(tenant_name, cluster_name, ip_name, key_string))) { LOG_WARN("build tenant cluser vip name failed", K(tenant_name), K(cluster_name), K(ip_name), K(ret)); } else { @@ -131,7 +131,7 @@ void ObConnTableProcessor::dec_conn( int ret = OB_SUCCESS; ObUsedConn* used_conn = NULL; int64_t cur_used_connections = 0; - common::ObFixedLengthString key_string; + common::ObFixedLengthString key_string; if (OB_FAIL(build_tenant_cluster_vip_name(tenant_name, cluster_name, ip_name, key_string))) { LOG_WARN("build tenant cluster vip name failed", K(ret), K(tenant_name), K(cluster_name), K(ip_name)); @@ -161,7 +161,7 @@ int ObConnTableProcessor::get_vt_conn_object( { int ret = OB_SUCCESS; - common::ObFixedLengthString key_string; + common::ObFixedLengthString key_string; if (OB_FAIL(build_tenant_cluster_vip_name(tenant_name, cluster_name, vip_name, key_string))) { LOG_WARN("build tenant cluser vip name failed", K(ret), K(tenant_name), K(cluster_name), K(vip_name)); } else { @@ -193,7 +193,7 @@ int ObConnTableProcessor::alloc_and_init_vt_conn( } else if (OB_ISNULL(tmp_vt_conn = op_alloc(ObVipTenantConn))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory for ObVipTenantConn", K(ret)); - } else if (OB_FAIL(tmp_vt_conn->set(cluster_name, tenant_name, vip_name, max_connections))) { + } else if (OB_FAIL(tmp_vt_conn->set(cluster_name, tenant_name, vip_name, max_connections))) { LOG_WARN("fail to set vip tenant connect info", K(ret)); } else { vt_conn = tmp_vt_conn; @@ -211,11 +211,11 @@ int ObConnTableProcessor::alloc_and_init_vt_conn( // local vip json format: //[ // { -// "vip" : "127.0.0.1", +// "vip" : "127.0.0.1", // "value" : "1000" // }, // { -// "vip" : "0.0.0.1", +// "vip" : "0.0.0.1", // "value" : "2000" // } //] @@ -328,7 +328,7 @@ int ObConnTableProcessor::conn_handle_replace_config( return ret; } -int ObConnTableProcessor::conn_handle_delete_config(ObString& cluster_name, ObString& tenant_name) +int ObConnTableProcessor::conn_handle_delete_config(ObString& cluster_name, ObString& tenant_name) { int ret = OB_SUCCESS; diff --git a/src/obproxy/omt/ob_cpu_table_processor.cpp b/src/obproxy/omt/ob_cpu_table_processor.cpp index 2e018203..dc9638e0 100644 --- a/src/obproxy/omt/ob_cpu_table_processor.cpp +++ b/src/obproxy/omt/ob_cpu_table_processor.cpp @@ -51,7 +51,7 @@ using namespace oceanbase::obproxy::obutils; using namespace oceanbase::json; extern int build_tenant_cluster_vip_name(const ObString &tenant_name, const ObString &cluster_name, const ObString &vip_name, - ObFixedLengthString &key_string); + ObFixedLengthString &key_string); void ObCpuTableProcessor::commit(bool is_success) { @@ -214,7 +214,7 @@ int ObCpuTableProcessor::handle_cpu_config( int ret = OB_SUCCESS; ObString key_name; ObTenantCpu* tenant_cpu = NULL; - common::ObFixedLengthString key_string; + common::ObFixedLengthString key_string; if (max_cpu_usage <= 0) { ret = OB_ERR_UNEXPECTED; LOG_WARN("max cpu usage error", K(max_cpu_usage), K(ret)); diff --git a/src/obproxy/omt/ob_proxy_config_table_processor.cpp b/src/obproxy/omt/ob_proxy_config_table_processor.cpp index f07e9b83..f3a1966a 100644 --- a/src/obproxy/omt/ob_proxy_config_table_processor.cpp +++ b/src/obproxy/omt/ob_proxy_config_table_processor.cpp @@ -38,7 +38,17 @@ #include "cmd/ob_internal_cmd_processor.h" static const char *config_name_array[] = {"proxy_route_policy", "proxy_idc_name", "enable_cloud_full_username", - "enable_client_ssl", "enable_server_ssl"}; + "enable_client_ssl", "enable_server_ssl", + "obproxy_read_consistency", "obproxy_read_only", + "proxy_tenant_name", "rootservice_cluster_name", + "enable_read_write_split", "enable_transaction_split", + "target_db_server", "observer_sys_password", + "observer_sys_password1"}; + +static const char *EXECUTE_SQL = + "replace into proxy_config(vip, vid, vport, cluster_name, tenant_name, name, value, config_level) values(" + "'%.*s', %ld, %ld, '%.*s', '%.*s', '%s', '%s', '%.*s')"; + using namespace oceanbase::common; using namespace oceanbase::obproxy::obutils; namespace oceanbase @@ -143,12 +153,19 @@ int ObProxyConfigTableProcessor::commit(void *arg, bool is_success) LOG_WARN("proxy config commit failed", K(is_success)); } + get_global_proxy_config_table_processor().clear_execute_sql(); get_global_proxy_config_table_processor().clean_hashmap( get_global_proxy_config_table_processor().get_backup_hashmap()); return OB_SUCCESS; } +int ObProxyConfigTableProcessor::before_commit(void *arg) +{ + sqlite3 *db = (sqlite3*)arg; + return get_global_proxy_config_table_processor().commit_execute_sql(db); +} + void ObProxyConfigTableProcessor::inc_index() { DRWLock::WRLockGuard guard(proxy_config_lock_); @@ -167,6 +184,7 @@ int ObProxyConfigTableProcessor::init() ObConfigHandler handler; handler.execute_func_ = &ObProxyConfigTableProcessor::execute; handler.commit_func_ = &ObProxyConfigTableProcessor::commit; + handler.before_commit_func_ = &ObProxyConfigTableProcessor::before_commit; if (OB_FAIL(get_global_config_processor().register_callback("proxy_config", handler))) { LOG_WARN("register proxy config table callback failed", K(ret)); } @@ -237,15 +255,15 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) ObString name; SqlFieldResult *sql_fields = static_cast(arg); for (int i = 0; OB_SUCC(ret) && i < sql_fields->field_num_; i++) { - SqlField &sql_field = sql_fields->fields_.at(i); - if (0 == sql_field.column_name_.string_.case_compare("vip")) { + SqlField &sql_field = *(sql_fields->fields_.at(i)); + if (0 == sql_field.column_name_.config_string_.case_compare("vip")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); } else { vip = sql_field.column_value_.config_string_; } - } else if (0 == sql_field.column_name_.string_.case_compare("vport")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("vport")) { if (TOKEN_STR_VAL == sql_field.value_type_) { vport = atoi(sql_field.column_value_.config_string_.ptr()); } else if (TOKEN_INT_VAL == sql_field.value_type_) { @@ -254,7 +272,7 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid value type", K(sql_field.value_type_), K(ret)); } - } else if (0 == sql_field.column_name_.string_.case_compare("vid")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("vid")) { if (TOKEN_STR_VAL == sql_field.value_type_) { vid = atoi(sql_field.column_value_.config_string_.ptr()); } else if (TOKEN_INT_VAL == sql_field.value_type_) { @@ -263,28 +281,28 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid value type", K(sql_field.value_type_), K(ret)); } - } else if (0 == sql_field.column_name_.string_.case_compare("config_level")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("config_level")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); } else { item->config_level_.assign(sql_field.column_value_.config_string_.ptr()); } - } else if (0 == sql_field.column_name_.string_.case_compare("tenant_name")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("tenant_name")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); } else { item->tenant_name_.assign(sql_field.column_value_.config_string_.ptr()); } - } else if (0 == sql_field.column_name_.string_.case_compare("cluster_name")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("cluster_name")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); } else { item->cluster_name_.assign(sql_field.column_value_.config_string_.ptr()); } - } else if (0 == sql_field.column_name_.string_.case_compare("name")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("name")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); @@ -292,7 +310,7 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) ObString &name = sql_field.column_value_.config_string_; item->config_item_.set_name(name.ptr()); } - } else if (0 == sql_field.column_name_.string_.case_compare("value")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("value")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); @@ -301,12 +319,12 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) } } else { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected column name", K(sql_field.column_name_.string_)); + LOG_WARN("unexpected column name", K(sql_field.column_name_.config_string_)); } } if (OB_SUCC(ret)) { - item->vip_addr_.set(ObAddr::convert_ipv4_addr(vip.ptr()), static_cast(vport), vid); + item->vip_addr_.set(vip.ptr(), static_cast(vport), vid); if (0 != strcasecmp("LEVEL_GLOBAL", item->config_level_.ptr()) && !is_config_in_service(item->config_item_.name())) { ret = OB_NOT_SUPPORTED; @@ -321,7 +339,45 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) tmp_item = NULL; } - if (need_sync_to_file_ && 0 == strcasecmp("LEVEL_GLOBAL", item->config_level_.ptr()) && + // need_sync_to_file_ indicates that it is not a command set by alter proxyconfig, + // but a configuration item set by proxy_config + if (need_sync_to_file_) { + if ((0 == strcasecmp("obproxy_sys_password", item->config_item_.name()) + || 0 == strcasecmp("observer_sys_password", item->config_item_.name()) + || 0 == strcasecmp("observer_sys_password1", item->config_item_.name())) + && (NULL != item->config_item_.str() && '\0' != *item->config_item_.str())) { + char value_str[common::OB_MAX_CONFIG_VALUE_LEN + 1]; + char passwd_staged1_buf[ENC_STRING_BUF_LEN]; + ObString tmp_value_string; + ObString passwd_string(ENC_STRING_BUF_LEN, passwd_staged1_buf); + if (OB_FAIL(ObEncryptedHelper::encrypt_passwd_to_stage1(item->config_item_.str(), passwd_string))) { + LOG_WARN("encrypt_passwd_to_stage1 failed", K(ret)); + } else { + MEMCPY(value_str, passwd_staged1_buf + 1, 40); + value_str[40] = '\0'; + tmp_value_string.assign(value_str, 40); + item->config_item_.set_value(tmp_value_string); + char sql[1024]; + int64_t len = static_cast(snprintf(sql, 1024, EXECUTE_SQL, vip.length(), vip.ptr(), vid, vport, + item->cluster_name_.size(), item->cluster_name_.ptr(), + item->tenant_name_.size(), item->tenant_name_.ptr(), + item->config_item_.name(), item->config_item_.str(), + item->config_level_.size(), item->config_level_.ptr())); + if (OB_UNLIKELY(len <= 0 || len >= 1024)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get execute sql failed", K(len), K(ret)); + } else { + ObProxyVariantString buf_string; + buf_string.set_value(sql); + if (OB_FAIL(execute_sql_array_.push_back(buf_string))) { + LOG_WARN("execute_sql_array push back failed", K(ret)); + } + } + } + } + } + + if (OB_SUCC(ret) && need_sync_to_file_ && 0 == strcasecmp("LEVEL_GLOBAL", item->config_level_.ptr()) && OB_FAIL(alter_proxy_config(item->config_item_.name(), item->config_item_.str()))) { LOG_WARN("alter proxyconfig failed", K(ret)); } else if (OB_FAIL(backup_map.unique_set(item))) { @@ -359,22 +415,22 @@ int ObProxyConfigTableProcessor::delete_proxy_config(void *arg) bool need_delete = true; ++it; for (int i = 0; OB_SUCC(ret) && need_delete && i < fields->field_num_; i++) { - SqlField &sql_field = fields->fields_.at(i); - if (0 == sql_field.column_name_.string_.case_compare("vip")) { + SqlField* sql_field = fields->fields_.at(i); + if (0 == sql_field->column_name_.config_string_.case_compare("vip")) { char ip_buf[256]; item.vip_addr_.addr_.ip_to_string(ip_buf, 256); - if (TOKEN_STR_VAL != sql_field.value_type_) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(ip_buf, sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(ip_buf, sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("vport")) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("vport")) { int64_t vport = 0; - if (TOKEN_STR_VAL == sql_field.value_type_) { - vport = atoi(sql_field.column_value_.config_string_.ptr()); - } else if (TOKEN_INT_VAL == sql_field.value_type_) { - vport = sql_field.column_int_value_; + if (TOKEN_STR_VAL == sql_field->value_type_) { + vport = atoi(sql_field->column_value_.config_string_.ptr()); + } else if (TOKEN_INT_VAL == sql_field->value_type_) { + vport = sql_field->column_int_value_; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid value type", K(ret)); @@ -384,12 +440,12 @@ int ObProxyConfigTableProcessor::delete_proxy_config(void *arg) need_delete = false; } } - } else if (0 == sql_field.column_name_.string_.case_compare("vid")) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("vid")) { int64_t vid = 0; - if (TOKEN_STR_VAL == sql_field.value_type_) { - vid = atoi(sql_field.column_value_.config_string_.ptr()); - } else if (TOKEN_INT_VAL == sql_field.value_type_) { - vid = sql_field.column_int_value_; + if (TOKEN_STR_VAL == sql_field->value_type_) { + vid = atoi(sql_field->column_value_.config_string_.ptr()); + } else if (TOKEN_INT_VAL == sql_field->value_type_) { + vid = sql_field->column_int_value_; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid value type", K(ret)); @@ -399,44 +455,44 @@ int ObProxyConfigTableProcessor::delete_proxy_config(void *arg) need_delete = false; } } - } else if (0 == sql_field.column_name_.string_.case_compare("config_level")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("config_level")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.config_level_.ptr(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.config_level_.ptr(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("tenant_name")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("tenant_name")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.tenant_name_.ptr(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.tenant_name_.ptr(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("cluster_name")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("cluster_name")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.cluster_name_.ptr(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.cluster_name_.ptr(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("name")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("name")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.config_item_.name(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.config_item_.name(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("value")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("value")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.config_item_.str(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.config_item_.str(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } } else { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected column name", K(sql_field.column_name_.string_)); + LOG_WARN("unexpected column name", K(sql_field->column_name_)); } } @@ -482,7 +538,7 @@ int ObProxyConfigTableProcessor::get_config_item(const obutils::ObVipAddr &addr, LOG_WARN("proxy config item is null unexpected", K(ret)); } else { item = *proxy_config_item; - LOG_DEBUG("get config item succ", K(addr), K(cluster_name), K(tenant_name), K(item)); + LOG_TRACE("get config item succ", K(addr), K(cluster_name), K(tenant_name), K(item)); } return ret; @@ -501,22 +557,6 @@ int ObProxyConfigTableProcessor::alter_proxy_config(const common::ObString &key_ ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(key_string), K(value_string), K(ret)); } else { - char value_str[common::OB_MAX_CONFIG_VALUE_LEN + 1]; - if ((0 == key_string.case_compare("observer_sys_password") - || 0 == key_string.case_compare("obproxy_sys_password") - || 0 == key_string.case_compare("observer_sys_password1")) - && !value_string.empty()) { - char passwd_staged1_buf[ENC_STRING_BUF_LEN]; - ObString passwd_string(ENC_STRING_BUF_LEN, passwd_staged1_buf); - if (OB_FAIL(ObEncryptedHelper::encrypt_passwd_to_stage1(value_string, passwd_string))) { - LOG_WARN("encrypt_passwd_to_stage1 failed", K(ret)); - } else { - MEMCPY(value_str, passwd_staged1_buf + 1, 40); - value_str[40] = '\0'; - tmp_value_string.assign(value_str, 40); - LOG_DEBUG("alter password", K(key_string), K(value_string)); - } - } if (OB_ISNULL(reload_config = get_global_internal_cmd_processor().get_reload_config())) { ret = OB_ERR_NULL_VALUE; LOG_WARN("fail to get reload config", K(ret)); @@ -586,6 +626,36 @@ bool ObProxyConfigTableProcessor::is_config_in_service(const ObString &config_na return is_in_service; } +int ObProxyConfigTableProcessor::commit_execute_sql(sqlite3 *db) +{ + int ret = OB_SUCCESS; + if (execute_sql_array_.count() > 0) { + if (OB_UNLIKELY(NULL == db)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sqlite db is null unexpected", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < execute_sql_array_.count(); i++) { + char *err_msg = NULL; + ObString sql = execute_sql_array_.at(i).config_string_; + if (SQLITE_OK != sqlite3_exec(db, sql.ptr(), NULL, 0, &err_msg)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("exec failed", K(ret), "err_msg", err_msg); + } + + if (NULL != err_msg) { + sqlite3_free(err_msg); + } + } + } + + return ret; +} + +void ObProxyConfigTableProcessor::clear_execute_sql() +{ + execute_sql_array_.reset(); +} + } // end of omt } // end of obprxy } // end of oceanbase diff --git a/src/obproxy/omt/ob_proxy_config_table_processor.h b/src/obproxy/omt/ob_proxy_config_table_processor.h index eae6ade5..ef172825 100644 --- a/src/obproxy/omt/ob_proxy_config_table_processor.h +++ b/src/obproxy/omt/ob_proxy_config_table_processor.h @@ -31,10 +31,13 @@ #ifndef OB_PROXY_CONFIG_TABLE_PROCESSOR_H_ #define OB_PROXY_CONFIG_TABLE_PROCESSOR_H_ +#include + #include "lib/lock/ob_drw_lock.h" #include "obutils/ob_vip_tenant_cache.h" #include "lib/string/ob_fixed_length_string.h" #include "share/config/ob_config.h" +#include "obutils/ob_proxy_string_utils.h" namespace oceanbase { @@ -98,7 +101,8 @@ class ObProxyConfigTableProcessor public: ObProxyConfigTableProcessor() : index_(0), proxy_config_lock_(obsys::WRITE_PRIORITY), - config_version_(0), need_sync_to_file_(false) {} + config_version_(0), need_sync_to_file_(false), + execute_sql_array_() {} ~ObProxyConfigTableProcessor() {} int init(); @@ -113,6 +117,8 @@ class ObProxyConfigTableProcessor void inc_config_version() { config_version_++; } void set_need_sync_to_file(const bool bvalue) { need_sync_to_file_ = bvalue; } ProxyConfigHashMap& get_backup_hashmap() { return proxy_config_map_array_[(index_ + 1) % 2]; } + int commit_execute_sql(sqlite3 *db); + void clear_execute_sql(); private: void clean_hashmap_with_lock(ProxyConfigHashMap &map); int backup_hashmap_with_lock(); @@ -120,6 +126,7 @@ class ObProxyConfigTableProcessor bool is_config_in_service(const common::ObString &config_name); static int execute(void *arg); static int commit(void* arg, bool is_success); + static int before_commit(void * arg); private: ProxyConfigHashMap proxy_config_map_array_[2]; @@ -127,6 +134,7 @@ class ObProxyConfigTableProcessor common::DRWLock proxy_config_lock_; uint64_t config_version_; bool need_sync_to_file_; + common::ObSEArray execute_sql_array_; private: DISALLOW_COPY_AND_ASSIGN(ObProxyConfigTableProcessor); }; diff --git a/src/obproxy/omt/ob_resource_unit_table_processor.cpp b/src/obproxy/omt/ob_resource_unit_table_processor.cpp index c216670e..6311e3b7 100644 --- a/src/obproxy/omt/ob_resource_unit_table_processor.cpp +++ b/src/obproxy/omt/ob_resource_unit_table_processor.cpp @@ -69,11 +69,11 @@ int ObResourceUnitTableProcessor::get_config_params(void* args, } else { // The storage format is:[cluster|tenant|name|value] for (int64_t i = 0; i < fields->field_num_; i++) { - SqlField& sql_field = fields->fields_.at(i); - if (0 == sql_field.column_name_.string_.case_compare("name")) { - name_str = sql_field.column_value_.config_string_; - } else if (0 == sql_field.column_name_.string_.case_compare("value")) { - value_str = sql_field.column_value_.config_string_; + SqlField* sql_field = fields->fields_.at(i); + if (0 == sql_field->column_name_.config_string_.case_compare("name")) { + name_str = sql_field->column_value_.config_string_; + } else if (0 == sql_field->column_name_.config_string_.case_compare("value")) { + value_str = sql_field->column_value_.config_string_; } } } @@ -216,16 +216,16 @@ int ObResourceUnitTableProcessor::handle_delete_config( } int build_tenant_cluster_vip_name(const ObString &tenant_name, const ObString &cluster_name, - const ObString &vip_name, ObFixedLengthString &key_string) + const ObString &vip_name, ObFixedLengthString &key_string) { int ret = OB_SUCCESS; - char buf[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF]; + char buf[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH]; int64_t len = 0; - len = static_cast(snprintf(buf, OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF, "%.*s#%.*s|%.*s", + len = static_cast(snprintf(buf, OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH, "%.*s#%.*s|%.*s", tenant_name.length(), tenant_name.ptr(), cluster_name.length(), cluster_name.ptr(), vip_name.length(), vip_name.ptr())); - if (OB_UNLIKELY(len <= 0) || OB_UNLIKELY(len >= OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF)) { + if (OB_UNLIKELY(len <= 0) || OB_UNLIKELY(len >= OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to fill buf", K(ret), K(tenant_name), K(cluster_name), K(vip_name)); } else if (OB_FAIL(key_string.assign(buf))) { diff --git a/src/obproxy/omt/ob_resource_unit_table_processor.h b/src/obproxy/omt/ob_resource_unit_table_processor.h index cc5967b2..f8f90838 100644 --- a/src/obproxy/omt/ob_resource_unit_table_processor.h +++ b/src/obproxy/omt/ob_resource_unit_table_processor.h @@ -62,7 +62,7 @@ class ObResourceUnitTableProcessor ObResourceUnitTableProcessor &get_global_resource_unit_table_processor(); int build_tenant_cluster_vip_name(const common::ObString &tenant_name, const common::ObString &cluster_name, const common::ObString &vip_name, - common::ObFixedLengthString& key_string); + common::ObFixedLengthString& key_string); } // end of namespace omt } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/omt/ob_ssl_config_table_processor.cpp b/src/obproxy/omt/ob_ssl_config_table_processor.cpp index e7a42d3e..7f05b740 100644 --- a/src/obproxy/omt/ob_ssl_config_table_processor.cpp +++ b/src/obproxy/omt/ob_ssl_config_table_processor.cpp @@ -72,11 +72,11 @@ int ObSSLConfigTableProcessor::execute(void *arg) LOG_WARN("execute failed, tenant_name or cluster_name is null", K(ret), K(cluster_name), K(tenant_name)); } else { for (int64_t i = 0; i < params->fields_->field_num_; i++) { - SqlField &sql_field = params->fields_->fields_.at(i); - if (sql_field.column_name_.string_ == "value") { - value = sql_field.column_value_.config_string_; - } else if (sql_field.column_name_.string_ == "name") { - name = sql_field.column_value_.config_string_; + SqlField *sql_field = params->fields_->fields_.at(i); + if (0 == sql_field->column_name_.config_string_.case_compare("value")) { + value = sql_field->column_value_.config_string_; + } else if (0 == sql_field->column_name_.config_string_.case_compare("name")) { + name = sql_field->column_value_.config_string_; } } diff --git a/src/obproxy/omt/ob_vip_tenant_conn.cpp b/src/obproxy/omt/ob_vip_tenant_conn.cpp index 6286c285..86f3480b 100644 --- a/src/obproxy/omt/ob_vip_tenant_conn.cpp +++ b/src/obproxy/omt/ob_vip_tenant_conn.cpp @@ -45,7 +45,7 @@ using namespace obsys; using namespace oceanbase::common; extern int build_tenant_cluster_vip_name(const ObString &tenant_name, const ObString &cluster_name, const ObString &vip_name, - ObFixedLengthString &key_string); + ObFixedLengthString &key_string); int ObVipTenantConn::set_tenant_cluster(const ObString &tenant_name, const ObString &cluster_name) { @@ -66,7 +66,7 @@ int ObVipTenantConn::set_tenant_cluster(const ObString &tenant_name, const ObStr int ObVipTenantConn::set_addr(const common::ObString addr) { int ret = OB_SUCCESS; - if (addr.empty() || addr.length() > OB_IP_STR_BUFF) { + if (addr.empty() || addr.length() > MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(addr), K(ret)); } else { @@ -80,7 +80,7 @@ int ObVipTenantConn::set_full_name() { int ret = OB_SUCCESS; - ObFixedLengthString full_name; + ObFixedLengthString full_name; if (OB_FAIL(build_tenant_cluster_vip_name(tenant_name_, cluster_name_, vip_name_, full_name))) { LOG_WARN("build tenant cluser and vip name failed", K(ret), K_(tenant_name), K_(cluster_name), K_(vip_name)); } else { @@ -149,7 +149,7 @@ int ObVipTenantConnCache::get(ObString& key_name, ObVipTenantConn*& vt_conn) int ret = OB_SUCCESS; ObVipTenantConn *tmp_vt_conn = NULL; - if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(key_name), K(ret)); } else { @@ -231,19 +231,19 @@ int ObVipTenantConnCache::backup() //CWLockGuard guard(rwlock_); // Initialization state: - // vt_conn_map_ = vt_conn_map_array[0]; + // vt_conn_map_ = vt_conn_map_array[0]; // replica_vt_conn_map = vt_conn_map_array[1]; VTHashMap& replica_vt_conn_map = get_conn_map_replica(); clear_conn_map(replica_vt_conn_map); // Even if an error occurs in the backup process and an error is returned to the cloud platform, vt_conn_map_ is still the previous configuration information VTHashMap::iterator last = vt_conn_map_->end(); for (VTHashMap::iterator it = vt_conn_map_->begin(); it != last; ++it) { - ObVipTenantConn* tmp_vt_conn = NULL; + ObVipTenantConn* tmp_vt_conn = NULL; if (OB_ISNULL(tmp_vt_conn = op_alloc(ObVipTenantConn))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory for ObVipTenantConn", K(ret)); } else if (OB_FAIL(tmp_vt_conn->set( - it->cluster_name_, it->tenant_name_, it->vip_name_, it->max_connections_))) { + it->cluster_name_, it->tenant_name_, it->vip_name_, it->max_connections_))) { LOG_WARN("fail to set vip tenant connect info", K(ret)); } else if (OB_FAIL(replica_vt_conn_map.unique_set(tmp_vt_conn))) { LOG_WARN("insert vip tenant connection failed", K(ret)); @@ -302,7 +302,7 @@ void ObVipTenantConnCache::dump_conn_map(VTHashMap &cache_map) int ObUsedConnCache::get(ObString& key_name, ObUsedConn*& used_conn) { int ret = OB_SUCCESS; - if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(key_name), K(ret)); } else if (OB_FAIL(used_conn_map_.get_refactored(key_name, used_conn))) { @@ -326,7 +326,7 @@ int ObUsedConnCache::set(ObUsedConn* used_conn) int ObUsedConnCache::erase(ObString& key_name) { int ret = OB_SUCCESS; - if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(key_name), K(ret)); } else if (OB_FAIL(used_conn_map_.erase_refactored(key_name))) { diff --git a/src/obproxy/omt/ob_vip_tenant_conn.h b/src/obproxy/omt/ob_vip_tenant_conn.h index b767c0ea..ea3de354 100644 --- a/src/obproxy/omt/ob_vip_tenant_conn.h +++ b/src/obproxy/omt/ob_vip_tenant_conn.h @@ -78,10 +78,10 @@ class ObVipTenantConn { LINK(ObVipTenantConn, vt_link_); private: - char tenant_name_str_[common::OB_MAX_TENANT_NAME_LENGTH]; + char tenant_name_str_[common::OB_MAX_TENANT_NAME_LENGTH]; char cluster_name_str_[OB_PROXY_MAX_CLUSTER_NAME_LENGTH]; - char vip_name_str_[common::OB_IP_STR_BUFF]; - char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::OB_IP_STR_BUFF]; + char vip_name_str_[common::MAX_IP_ADDR_LENGTH]; + char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::MAX_IP_ADDR_LENGTH]; DISALLOW_COPY_AND_ASSIGN(ObVipTenantConn); }; @@ -109,7 +109,7 @@ class ObVipTenantConnCache typedef common::hash::ObBuildInHashMap VTHashMap; public: - + int set(ObVipTenantConn* vt); int get(common::ObString& key_name, ObVipTenantConn*& vt_conn); int erase(common::ObString& cluster_name, common::ObString& tenant_name); @@ -132,7 +132,7 @@ class ObVipTenantConnCache class ObUsedConn : public common::ObSharedRefCount { public: ObUsedConn(common::ObString& full_name) : max_used_connections_(0), is_in_map_(false) { - if (full_name.length() < OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::OB_IP_STR_BUFF) { + if (full_name.length() < OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::MAX_IP_ADDR_LENGTH) { MEMCPY(full_name_str_, full_name.ptr(), full_name.length()); full_name_.assign_ptr(full_name_str_, (int32_t)full_name.length()); } @@ -158,7 +158,7 @@ class ObUsedConn : public common::ObSharedRefCount { bool is_in_map_; private: - char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::OB_IP_STR_BUFF]; + char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::MAX_IP_ADDR_LENGTH]; DISALLOW_COPY_AND_ASSIGN(ObUsedConn); }; diff --git a/src/obproxy/omt/ob_vip_tenant_cpu.cpp b/src/obproxy/omt/ob_vip_tenant_cpu.cpp index 55c18bc2..5260ec22 100644 --- a/src/obproxy/omt/ob_vip_tenant_cpu.cpp +++ b/src/obproxy/omt/ob_vip_tenant_cpu.cpp @@ -57,11 +57,11 @@ ObTenantCpu::ObTenantCpu(ObString& cluster_name, ObString& tenant_name, MEMCPY(tenant_name_str_, tenant_name.ptr(), tenant_name.length()); tenant_name_.assign_ptr(tenant_name_str_, tenant_name.length()); } - if (vip_name.length() < OB_IP_STR_BUFF) { + if (vip_name.length() < MAX_IP_ADDR_LENGTH) { MEMCPY(vip_name_str_, vip_name.ptr(), vip_name.length()); vip_name_.assign_ptr(vip_name_str_, vip_name.length()); } - if (full_name.length() < OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (full_name.length() < OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { MEMCPY(full_name_str_, full_name.ptr(), full_name.length()); full_name_.assign_ptr(full_name_str_, full_name.length()); } @@ -176,7 +176,7 @@ int64_t ObTenantCpuCache::get_cpu_map_count() int ObTenantCpuCache::get(ObString& key_name, ObTenantCpu*& tenant_cpu) { int ret = OB_SUCCESS; - if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(key_name), K(ret)); } else if (OB_FAIL(vt_cpu_map_.get_refactored(key_name, tenant_cpu))) { diff --git a/src/obproxy/omt/ob_vip_tenant_cpu.h b/src/obproxy/omt/ob_vip_tenant_cpu.h index 8b598ae4..d0ee29ae 100644 --- a/src/obproxy/omt/ob_vip_tenant_cpu.h +++ b/src/obproxy/omt/ob_vip_tenant_cpu.h @@ -73,7 +73,7 @@ class ObTenantCpu : public common::ObSharedRefCount { int set_unit_max_cpu(double cpu); int acquire_more_worker(const int64_t tid); - + TO_STRING_KV(K_(tenant_name), K_(cluster_name), K_(vip_name), K_(full_name), K_(max_thread_num), K_(backup_max_thread_num), K_(max_cpu_usage), K_(backup_max_cpu_usage), K_(index), K_(is_inited), K_(instance_status)); @@ -92,14 +92,14 @@ class ObTenantCpu : public common::ObSharedRefCount { bool is_inited_; ObTenantCpuStatus instance_status_; common::ObSEArray thread_array_; - + LINK(ObTenantCpu, cpu_link_); private: - char tenant_name_str_[common::OB_MAX_TENANT_NAME_LENGTH]; + char tenant_name_str_[common::OB_MAX_TENANT_NAME_LENGTH]; char cluster_name_str_[OB_PROXY_MAX_CLUSTER_NAME_LENGTH]; - char vip_name_str_[common::OB_IP_STR_BUFF]; - char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::OB_IP_STR_BUFF]; + char vip_name_str_[common::MAX_IP_ADDR_LENGTH]; + char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::MAX_IP_ADDR_LENGTH]; DISALLOW_COPY_AND_ASSIGN(ObTenantCpu); }; @@ -148,4 +148,4 @@ class ObTenantCpuCache } // namespace obproxy } // namespace oceanbase -#endif // OB_VIP_TENANT_CPU_H \ No newline at end of file +#endif // OB_VIP_TENANT_CPU_H diff --git a/src/obproxy/omt/ob_white_list_table_processor.cpp b/src/obproxy/omt/ob_white_list_table_processor.cpp index 384c8ff7..b332c216 100644 --- a/src/obproxy/omt/ob_white_list_table_processor.cpp +++ b/src/obproxy/omt/ob_white_list_table_processor.cpp @@ -63,9 +63,9 @@ int ObWhiteListTableProcessor::execute(void *arg) LOG_WARN("execute failed, tenant_name or cluster_name is null", K(ret), K(cluster_name), K(tenant_name)); } else { for (int64_t i = 0; i < params->fields_->field_num_; i++) { - SqlField &sql_field = params->fields_->fields_.at(i); - if (sql_field.column_name_.string_ == "value") { - ip_list = sql_field.column_value_.config_string_; + SqlField *sql_field = params->fields_->fields_.at(i); + if (0 == sql_field->column_name_.config_string_.case_compare("value")) { + ip_list = sql_field->column_value_.config_string_; } } @@ -154,6 +154,7 @@ int ObWhiteListTableProcessor::set_ip_list(ObString &cluster_name, ObString &ten int pos = 0; AddrStruct ip_addr; memset(&ip_addr, 0, sizeof(AddrStruct)); + bool set_ip = false; while (OB_SUCC(ret) && pos < ip_list.length()) { if (ip_list[pos] == ',' || pos == ip_list.length() - 1 || ip_list[pos] == '/') { char buf[64]; @@ -164,10 +165,16 @@ int ObWhiteListTableProcessor::set_ip_list(ObString &cluster_name, ObString &ten } memcpy(buf, start, len); buf[len] = '\0'; - if (ip_addr.ip_ == 0) { - if (OB_FAIL(ip_to_int(buf, ip_addr.ip_))) { - LOG_WARN("ip to int failed", K(ret)); + if (!set_ip) { + if (false == ip_addr.addr_.set_ip_addr(buf, 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("set ip addr failed", K(buf), K(ret)); break; + } else { + if (ObAddr::VER::IPV4 == ip_addr.addr_.version_) { + ip_addr.v4_ = to_little_endian(htonl(ip_addr.addr_.ip_.v4_)); + } + set_ip = true; } } else { ip_addr.net_ = atoi(buf); @@ -183,6 +190,7 @@ int ObWhiteListTableProcessor::set_ip_list(ObString &cluster_name, ObString &ten LOG_WARN("ip addr push back failed", K(ret)); } else { memset(&ip_addr, 0, sizeof(AddrStruct)); + set_ip = false; } } pos++; @@ -234,26 +242,26 @@ int ObWhiteListTableProcessor::delete_ip_list(ObString &cluster_name, ObString & return ret; } -bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &tenant_name, ObString &user_name, char* ip) +bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &tenant_name, + ObString &user_name, const struct sockaddr& addr) { - uint32_t ip_value = 0; - int ret = OB_SUCCESS; bool can_pass = false; - if (OB_FAIL(ip_to_int(ip, ip_value))) { - LOG_WARN("ip to in failed", K(ret)); - } else { - can_pass = can_ip_pass(cluster_name, tenant_name, user_name, ip_value, false); + if (net::ops_is_ip4(addr)) { + can_pass = can_ipv4_pass(cluster_name, tenant_name, user_name, addr); + } else if (net::ops_is_ip6(addr)) { + can_pass = can_ipv6_pass(cluster_name, tenant_name, user_name, addr); } return can_pass; } -bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &tenant_name, - ObString &user_name, uint32_t src_ip, bool is_big_endian) +bool ObWhiteListTableProcessor::can_ipv4_pass(ObString &cluster_name, ObString &tenant_name, + ObString &user_name, const struct sockaddr& in_addr) { int ret = OB_SUCCESS; bool can_pass = false; - uint32_t ip = is_big_endian ? to_little_endian(src_ip) : src_ip; - LOG_DEBUG("check can ip pass", K(cluster_name), K(tenant_name), K(ip)); + ObIpEndpoint endpoint(in_addr); + uint32_t ip = to_little_endian(endpoint.sin_.sin_addr.s_addr); + LOG_DEBUG("check can ip pass", K(cluster_name), K(tenant_name), K(endpoint)); if (!cluster_name.empty() && !tenant_name.empty()) { ObFixedLengthString key_string; if (OB_FAIL(paste_tenant_and_cluster_name(tenant_name, cluster_name, key_string))) { @@ -265,22 +273,71 @@ bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &te if (OB_SUCC(current_map.get_refactored(key_string, ip_array))) { for (int64_t i = 0; !can_pass && i < ip_array.count(); i++) { AddrStruct addr = ip_array.at(i); - if (0 == addr.ip_) { + if (0 == addr.v4_) { can_pass = true; } else if (0 == addr.net_) { - can_pass = (addr.ip_ == ip); + can_pass = (addr.v4_ == ip); } else { uint32_t mask = 0xffffffff; - can_pass = (addr.ip_ == (ip & (mask << (32 - addr.net_)))); + can_pass = (addr.v4_ == (ip & (mask << (32 - addr.net_)))); } - if (OB_UNLIKELY(IS_DEBUG_ENABLED())) { - ObIpEndpoint client_info; - ObIpEndpoint white_list_info; - client_info.sin_.sin_addr.s_addr = __bswap_32(ip); - client_info.sin_.sin_family = AF_INET; - white_list_info.sin_.sin_addr.s_addr = __bswap_32(addr.ip_); - white_list_info.sin_.sin_family = AF_INET; - LOG_DEBUG("ip check can pass", K(client_info), K(white_list_info), "mask", addr.net_, K(can_pass)); + } + } else if (OB_HASH_NOT_EXIST == ret) { + can_pass = true; + } else { + LOG_WARN("unexpected error", K(ret)); + } + } + } else { + LOG_WARN("cluster_name or tenant_name is empty", K(cluster_name), K(tenant_name), K(endpoint)); + } + + if (!can_pass) { + LOG_WARN("can not pass white_list", K(cluster_name), K(tenant_name), K(user_name), K(endpoint)); + } + + return can_pass; +} + +bool ObWhiteListTableProcessor::can_ipv6_pass(ObString &cluster_name, ObString &tenant_name, + ObString &user_name, const struct sockaddr& in6_addr) +{ + int ret = OB_SUCCESS; + bool can_pass =false; + ObIpEndpoint endpoint(in6_addr); + LOG_DEBUG("check can ip pass", K(cluster_name), K(tenant_name), K(endpoint)); + if (!cluster_name.empty() && !tenant_name.empty()) { + ObFixedLengthString key_string; + if (OB_FAIL(paste_tenant_and_cluster_name(tenant_name, cluster_name, key_string))) { + LOG_WARN("paste tenant and cluster name failed", K(ret), K(tenant_name), K(cluster_name)); + } else { + ObSEArray ip_array; + DRWLock::RDLockGuard guard(white_list_lock_); + WhiteListHashMap ¤t_map = addr_hash_map_array_[index_]; + if (OB_SUCC(current_map.get_refactored(key_string, ip_array))) { + for (int64_t i = 0; !can_pass && i < ip_array.count(); i++) { + AddrStruct addr = ip_array.at(i); + if (addr.addr_.ip_.v6_[0] == 0 && addr.addr_.ip_.v6_[1] == 0 + && addr.addr_.ip_.v6_[2] == 0 && addr.addr_.ip_.v6_[3] == 0) { + can_pass = true; + } else { + int64_t net = addr.net_; + int64_t index = 0; + can_pass = true; + sockaddr_storage ss = addr.addr_.get_sockaddr(); + sockaddr_in6 &in6 = *(sockaddr_in6*)(&ss); + while ((net - 8) >= 0 && can_pass) { + if (in6.sin6_addr.s6_addr[index] != endpoint.sin6_.sin6_addr.s6_addr[index]) { + can_pass = false; + } + index++; + net -= 8; + } + + if (net && can_pass) { + can_pass = in6.sin6_addr.s6_addr[index] == + (endpoint.sin6_.sin6_addr.s6_addr[index] & (0xff << (8 - net))); + } } } } else if (OB_HASH_NOT_EXIST == ret) { @@ -290,13 +347,11 @@ bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &te } } } else { - LOG_WARN("cluster_name or tenant_name is empty", K(cluster_name), K(tenant_name), K(ip)); + LOG_WARN("cluster_name or tenant_name is empty", K(cluster_name), K(tenant_name), K(endpoint)); } if (!can_pass) { - struct sockaddr_in address; - address.sin_addr.s_addr = __bswap_32(ip); - LOG_WARN("can not pass white_list", K(cluster_name), K(tenant_name), K(user_name), "client_ip", inet_ntoa(address.sin_addr)); + LOG_WARN("can not pass white_list", K(cluster_name), K(tenant_name), K(user_name), K(endpoint)); } return can_pass; @@ -305,10 +360,8 @@ bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &te int64_t AddrStruct::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; - in_addr addr; - addr.s_addr = static_cast(ip_); J_OBJ_START(); - J_KV("ip", inet_ntoa(addr), K_(net)); + J_KV(K_(addr), K_(net)); J_OBJ_END(); return pos; } @@ -353,9 +406,7 @@ void ObWhiteListTableProcessor::print_config() LOG_DEBUG("white list map info", K(iter->first)); for (int64_t i = 0; i < iter->second.count(); i++) { AddrStruct addr_info = iter->second.at(i); - struct sockaddr_in address; - address.sin_addr.s_addr = __bswap_32(addr_info.ip_); - LOG_DEBUG("ip/net info", "ip", inet_ntoa(address.sin_addr), "mask", addr_info.net_); + LOG_DEBUG("ip/net info", K(addr_info)); } } } diff --git a/src/obproxy/omt/ob_white_list_table_processor.h b/src/obproxy/omt/ob_white_list_table_processor.h index 8c9a5ca2..cbfc2d6f 100644 --- a/src/obproxy/omt/ob_white_list_table_processor.h +++ b/src/obproxy/omt/ob_white_list_table_processor.h @@ -35,6 +35,7 @@ #include "lib/container/ob_se_array.h" #include "lib/lock/ob_drw_lock.h" #include "utils/ob_proxy_lib.h" +#include "lib/net/ob_addr.h" namespace oceanbase { @@ -45,7 +46,8 @@ namespace omt struct AddrStruct { - uint32_t ip_; + common::ObAddr addr_; + uint32_t v4_; uint32_t net_; int64_t to_string(char *buf, const int64_t buf_len) const; @@ -60,8 +62,7 @@ typedef common::hash::ObHashMapexpr_result_; - expr_result.target_mask_ = FIRST_PART_MASK; // set for init success if (OB_FAIL(ObProxySqlParser::get_parse_allocator(allocator_))) { } else if (OB_ISNULL(allocator_)) { ret = OB_ERR_UNEXPECTED; diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parse_result.h b/src/obproxy/opsql/expr_parser/ob_expr_parse_result.h index c27ea471..4dfee39d 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parse_result.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parse_result.h @@ -124,9 +124,18 @@ typedef struct _ObProxyTokenList ObProxyTokenNode *tail_; } ObProxyTokenList; +/** + * @brief If level_ == PART_KEY_LEVEL_ONE, first_part_column_idx_ will be set. + * If level_ == PART_KEY_LEVEL_TWO, second_part_column_idx_ will be set. + * If level_ == PART_KEY_LEVEL_BOTH, both of them will be set. + * first_part_column_idx_: the column's idx in partition expression + * second_part_column_idx_: the column's idx in subpartition expression + */ typedef struct _ObProxyRelationExpr { int64_t column_idx_; + int64_t first_part_column_idx_; + int64_t second_part_column_idx_; ObProxyTokenList *left_value_; ObProxyTokenList *right_value_; ObProxyFunctionType type_; @@ -150,17 +159,21 @@ typedef struct _ObProxyPartKeyAccuracy { typedef struct _ObProxyPartKey { ObProxyParseString name_; + ObProxyParseString default_value_; // serialized value ObProxyPartKeyLevel level_; - int64_t idx_; // column position + int64_t idx_; // pos in schema columns int64_t obj_type_; // ObObjType int64_t cs_type_; // ObCollationType + bool is_exist_in_sql_; // is part key exist in sql bool is_generated_; int64_t generated_col_idx_; int64_t param_num_; ObProxyExprType func_type_; ObProxyParamNode *params_[OBPROXY_MAX_PARAM_NUM]; // used to store generated func param - int64_t idx_in_rowid_; + int64_t real_source_idx_; // the real source idx of generated key, have no params_ + int64_t idx_in_rowid_; // pos in rowid + int64_t idx_in_part_columns_; // pos in part expr columns ObProxyPartKeyAccuracy accuracy_; } ObProxyPartKey; @@ -185,7 +198,6 @@ typedef struct _ObExprParseResult ObExprParseMode parse_mode_; ObProxyTableInfo table_info_; ObProxyPartKeyInfo part_key_info_; - int64_t target_mask_; // scanner buffer void *yyscan_info_; // yy_scan_t @@ -195,7 +207,6 @@ typedef struct _ObExprParseResult jmp_buf jmp_buf_; // handle fatal error const char *start_pos_; const char *end_pos_; - int64_t cur_mask_; // if cur_flag_ == target_flag_ means we will finish parse int64_t column_idx_; int64_t values_list_idx_; int64_t multi_param_values_; @@ -208,7 +219,6 @@ typedef struct _ObExprParseResult // hash rowid or not bool has_rowid_; - } ObExprParseResult; static const char *g_ROWID = "ROWID"; diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser.h b/src/obproxy/opsql/expr_parser/ob_expr_parser.h index 0e21e2ca..e39db222 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser.h @@ -76,7 +76,6 @@ inline int ObExprParser::init_result(ObExprParseResult &parse_result, const char parse_result.tmp_buf_ = NULL; parse_result.tmp_len_ = 0; parse_result.end_pos_ = NULL; - parse_result.cur_mask_ = 0; parse_result.column_idx_ = 0; parse_result.values_list_idx_ = 0; parse_result.multi_param_values_ = 0; @@ -87,12 +86,13 @@ inline int ObExprParser::init_result(ObExprParseResult &parse_result, const char parse_result.relation_info_.relation_num_ = 0; parse_result.all_relation_info_.relation_num_ = 0; parse_result.all_relation_info_.right_value_num_ = 0; + for (int64_t i = 0; i < parse_result.part_key_info_.key_num_; ++i) { + parse_result.part_key_info_.part_keys_[i].is_exist_in_sql_ = false; + } - if (0 == parse_result.target_mask_ - || INVALID_PARSE_MODE == parse_result.parse_mode_) { + if (INVALID_PARSE_MODE == parse_result.parse_mode_) { ret = common::OB_INVALID_ARGUMENT; PROXY_LOG(DEBUG, "failed to initialized parser, maybe parse sql for shard user", - K(parse_result.target_mask_), K(parse_result.parse_mode_), K(ret)); } diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser.l b/src/obproxy/opsql/expr_parser/ob_expr_parser.l index fca7116b..ff498367 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser.l +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser.l @@ -45,6 +45,10 @@ do {\ #define RETURN_ROW_ID() \ { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return ROW_ID; } + +#define RETURN_REVERSED_EXPR_FUNC() \ + { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return REVERSED_EXPR_FUNC; } + %} %x in_c_comment @@ -59,8 +63,10 @@ multi_byte_left_parenthesis [\uff08] multi_byte_right_parenthesis [\uff09] space [ \t\n\r\f] identifer ([A-Za-z0-9$_]*) -int_num [\-\+]?[0-9]+ -number ([\-]?[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*E[-+]?[0-9]+)|([\-]?"."[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*)|([\-]?"."[0-9]+) + +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +int_num [\-\+]?[0-9]{1,17} +number ([\-]?[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*E[-+]?[0-9]+)|([\-]?"."[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*)|([\-]?"."[0-9]+)|([\-\+]?[0-9]{18,}) non_newline [^\n\r] sql_comment ("--"{space}+{non_newline}*)|(#{non_newline}*) @@ -113,6 +119,9 @@ AND { return AND_OP; } OR { return OR_OP; } "||" { return OR_OP; } IN { return IN; } +IS { return IS; } +NULL { return TOKEN_NULL; } +NOT { return NOT; } "=" { return COMP_EQ; } "<=>" { return COMP_NSEQ; } ">=" { return COMP_GE; } @@ -122,6 +131,7 @@ IN { return IN; } "!="|"<>" { return COMP_NE; } "?" { return PLACE_HOLDER; } ":"{int_num} { store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } +"SYSDATE" { RETURN_REVERSED_EXPR_FUNC();} {int_num} { RETURN_INT_VAL(); } {number} { RETURN_NUMBER_VAL(); } diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser.y b/src/obproxy/opsql/expr_parser/ob_expr_parser.y index 06489e71..e190314c 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser.y +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser.y @@ -55,8 +55,8 @@ static inline void add_token_list(ObProxyTokenList *list, ObProxyTokenList *next if (OB_ISNULL(list) || OB_ISNULL(next_list)) { } else if (NULL != list->tail_ && NULL != next_list->head_ - && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_) - && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_)) { + && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_ || TOKEN_FUNC == list->tail_->type_) + && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_ || TOKEN_FUNC == next_list->head_->type_)) { list->tail_->next_ = next_list->head_; list->tail_ = next_list->head_; list->tail_->next_ = NULL; @@ -128,11 +128,18 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar for (i = 0; i < result->part_key_info_.key_num_; ++i) { if (is_equal(column_name, &result->part_key_info_.part_keys_[i].name_)) { result->part_key_info_.part_keys_[i].idx_ = result->column_idx_; - break; + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; } } } +static inline void init_part_key_all_match(ObExprParseResult *result) +{ + for (int64_t i = 0; i < result->part_key_info_.key_num_; ++i) { + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; + } +} + #define malloc_node(node, result, type) \ do { \ if (OB_ISNULL(node = ((ObProxyTokenNode *)obproxy_parse_malloc(sizeof(ObProxyTokenNode), \ @@ -167,21 +174,13 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar do { \ if (NULL == relation) { \ } else { \ - int64_t new_mask = get_mask(relation->type_, relation->level_); \ - bool has_rowid = result->has_rowid_; \ - if (((result->cur_mask_ | new_mask) != result->cur_mask_) \ - || (has_rowid \ - && is_equal_to_rowid(&relation->left_value_->column_node_->column_name_))) { \ + if (relation->level_ != PART_KEY_LEVEL_ZERO) { \ if (result->relation_info_.relation_num_ < OBPROXY_MAX_RELATION_NUM) { \ result->relation_info_.relations_[result->relation_info_.relation_num_++] = relation; \ - result->cur_mask_ = (result->cur_mask_ | new_mask); \ } else { \ /* YYACCEPT; */ \ } \ } \ - if ((result->cur_mask_ & result->target_mask_) == result->target_mask_) { \ - /* YYACCEPT; */ \ - } \ } \ } while(0) \ @@ -251,6 +250,92 @@ static inline void add_relation(ObExprParseResult *result, } } +static inline void set_relation_part_with_column_idx(int64_t idx_in_schema_columns, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(level) && OB_ISNULL(first_part_column_idx) && + OB_ISNULL(second_part_column_idx) && OB_ISNULL(result)) { + // do nothing + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (idx_in_schema_columns == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + +static inline void set_relation_part_with_column_name(ObProxyParseString *column, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(column) + || OB_ISNULL(result) + || OB_ISNULL(level) + || OB_ISNULL(first_part_column_idx) + || OB_ISNULL(second_part_column_idx)) { + // do nothing + } else if (result->has_rowid_ + && is_equal_to_rowid(column)) { + // handle rowid + *level = PART_KEY_LEVEL_ONE; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + if (is_equal(&result->part_key_info_.part_keys_[i].name_, column)) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *left_value, @@ -261,25 +346,25 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *tmp_left = NULL; ObProxyTokenList *tmp_right = NULL; ObProxyFunctionType tmp_type = F_NONE; - ObProxyPartKeyLevel tmp_level = PART_KEY_LEVEL_ZERO; int64_t tmp_column_idx_ = -1; + ObProxyParseString *tmp_column = NULL; if (NULL != left_value->column_node_ && TOKEN_COLUMN == left_value->column_node_->type_ && left_value->column_node_->part_key_idx_ >= 0) { tmp_left = left_value; - tmp_level = result->part_key_info_.part_keys_[left_value->column_node_->part_key_idx_].level_; tmp_right = right_value; tmp_type = type; tmp_column_idx_ = left_value->column_node_->part_key_idx_; + tmp_column = &left_value->column_node_->column_name_; } else if (NULL != right_value->column_node_ && TOKEN_COLUMN == right_value->column_node_->type_ && right_value->column_node_->part_key_idx_ >= 0) { tmp_left = right_value; - tmp_level = result->part_key_info_.part_keys_[right_value->column_node_->part_key_idx_].level_; tmp_right = left_value; tmp_type = get_reverse_func(type); tmp_column_idx_ = right_value->column_node_->part_key_idx_; + tmp_column = &right_value->column_node_->column_name_; } if (NULL == tmp_left || NULL == tmp_right || F_COMP_NE == tmp_type) { @@ -292,7 +377,11 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, relation->left_value_ = tmp_left; relation->type_ = tmp_type; relation->right_value_ = tmp_right; - relation->level_ = tmp_level; + set_relation_part_with_column_name(tmp_column, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } return relation; } @@ -306,14 +395,20 @@ static inline ObProxyRelationExpr *get_values_relation(ObExprParseResult *result } else { int64_t i = 0; for (i = 0; i < result->part_key_info_.key_num_; ++i) { - if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { if (OB_ISNULL(relation = ((ObProxyRelationExpr *)obproxy_parse_malloc( sizeof(ObProxyRelationExpr), result->malloc_pool_)))) { } else { relation->column_idx_ = i; relation->type_ = F_COMP_EQ; relation->right_value_ = right_value; - relation->level_ = result->part_key_info_.part_keys_[i].level_; + relation->left_value_ = NULL; + set_relation_part_with_column_idx(result->values_list_idx_, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } break; } @@ -363,12 +458,12 @@ static inline void add_right_relation_value(ObExprParseResult *result, %token DUMMY_SELECT_CLAUSE DUMMY_INSERT_CLAUSE /* reserved keyword */ %token WHERE AS VALUES SET END_WHERE JOIN -%token AND_OP OR_OP IN ON BETWEEN +%token AND_OP OR_OP IN ON BETWEEN IS TOKEN_NULL NOT %token COMP_EQ COMP_NSEQ COMP_GE COMP_GT COMP_LE COMP_LT COMP_NE %token PLACE_HOLDER %token END_P ERROR IGNORED_WORD /* type token */ -%token NAME_OB STR_VAL ROW_ID +%token NAME_OB STR_VAL ROW_ID REVERSED_EXPR_FUNC %token INT_VAL POS_PLACE_HOLDER %type comp %type token opt_column @@ -422,6 +517,8 @@ bool_pri: expr comp expr { add_relation(result, $1, $2,$3); $$ = get_relation(re add_relation(result, $1, F_COMP_LE, $5); $$ = NULL; } + | expr IS TOKEN_NULL { $$ = NULL; } + | expr IS NOT TOKEN_NULL { $$ = NULL; } comp: COMP_EQ { $$ = F_COMP_EQ; } | COMP_NSEQ { $$ = F_COMP_NSEQ; } @@ -469,6 +566,11 @@ token: $$->part_key_idx_ = get_part_key_idx(&$1, &$3, &$5, result); $$->column_name_ = $5; } + | REVERSED_EXPR_FUNC + { + malloc_node($$, result, TOKEN_FUNC); + $$->str_value_ = $1; + } | NAME_OB '(' token_list ')' { malloc_node($$, result, TOKEN_FUNC); @@ -518,7 +620,7 @@ values_expr_lists: '(' values_expr_list ')' result->multi_param_values_++; } -opt_column_list: /* empty */ +opt_column_list: /* empty */ { init_part_key_all_match(result);} | '(' column_list ')' /* column_list: NAME_OB { result->column_idx_ = 0; set_part_key_column_idx(result, &$1); } diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.c b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.c index e5532cd5..4be99343 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.c +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 57 -#define YY_END_OF_BUFFER 58 +#define YY_NUM_RULES 61 +#define YY_END_OF_BUFFER 62 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,28 +357,37 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[187] = +static yyconst flex_int16_t yy_accept[269] = { 0, - 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, - 58, 56, 31, 31, 35, 46, 31, 30, 35, 35, - 40, 33, 34, 35, 32, 35, 35, 35, 28, 35, - 24, 19, 22, 26, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 52, 35, 56, - 56, 39, 38, 39, 41, 42, 57, 47, 48, 57, - 54, 55, 31, 0, 25, 31, 30, 15, 28, 0, - 0, 28, 29, 36, 29, 28, 30, 0, 27, 23, - 21, 30, 2, 30, 30, 30, 30, 18, 30, 30, - 12, 16, 30, 30, 30, 30, 17, 33, 34, 32, - - 0, 37, 41, 0, 0, 43, 0, 0, 44, 47, - 0, 49, 0, 0, 0, 50, 54, 53, 31, 0, - 0, 0, 29, 0, 0, 29, 20, 14, 30, 6, - 30, 30, 30, 30, 30, 5, 30, 30, 45, 0, - 45, 0, 51, 0, 51, 0, 31, 31, 31, 29, - 0, 29, 0, 29, 30, 30, 30, 11, 30, 30, - 30, 30, 0, 0, 0, 0, 30, 8, 30, 7, - 10, 4, 1, 0, 0, 45, 0, 0, 0, 51, - 0, 30, 9, 3, 13, 0 + 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 60, 35, 35, 39, 50, 35, 34, 39, 39, + 44, 37, 38, 39, 36, 39, 39, 39, 32, 39, + 27, 22, 25, 29, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 56, 39, + 60, 60, 43, 42, 43, 45, 46, 61, 51, 52, + 61, 58, 59, 35, 0, 28, 35, 34, 15, 32, + 0, 0, 32, 33, 40, 33, 32, 34, 0, 30, + 26, 24, 34, 2, 34, 34, 34, 34, 18, 19, + 34, 34, 34, 34, 12, 16, 34, 34, 34, 34, + + 34, 17, 37, 38, 36, 0, 41, 45, 0, 0, + 47, 0, 0, 48, 51, 0, 53, 0, 0, 0, + 54, 58, 57, 32, 35, 0, 32, 0, 0, 33, + 0, 32, 0, 33, 30, 23, 14, 34, 6, 34, + 34, 34, 34, 21, 34, 34, 5, 34, 34, 34, + 49, 0, 49, 0, 55, 0, 55, 0, 32, 35, + 35, 35, 32, 33, 0, 33, 0, 33, 32, 30, + 34, 34, 34, 11, 34, 20, 34, 34, 34, 34, + 0, 0, 0, 0, 32, 32, 32, 30, 34, 8, + 34, 7, 10, 34, 4, 1, 0, 0, 49, 0, + + 0, 0, 55, 0, 32, 32, 32, 30, 34, 9, + 34, 3, 32, 32, 32, 30, 13, 31, 32, 32, + 32, 30, 32, 32, 32, 30, 32, 32, 32, 30, + 32, 32, 32, 30, 32, 32, 32, 30, 32, 32, + 32, 30, 32, 32, 32, 30, 32, 32, 32, 30, + 32, 32, 32, 30, 32, 32, 32, 30, 32, 32, + 33, 30, 33, 33, 33, 33, 33, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -391,17 +400,17 @@ static yyconst flex_int32_t yy_ec[256] = 20, 20, 20, 20, 20, 20, 20, 21, 9, 22, 23, 24, 25, 9, 26, 27, 8, 28, 29, 30, 31, 32, 33, 34, 8, 35, 36, 37, 38, 39, - 8, 40, 41, 42, 43, 44, 45, 8, 8, 8, - 1, 46, 1, 9, 8, 47, 48, 49, 8, 50, + 8, 40, 41, 42, 43, 44, 45, 8, 46, 8, + 1, 47, 1, 9, 8, 48, 49, 50, 8, 51, - 51, 52, 53, 54, 55, 56, 8, 57, 58, 59, - 60, 61, 8, 62, 63, 64, 65, 66, 67, 8, - 8, 8, 1, 68, 1, 9, 1, 1, 1, 1, + 52, 53, 54, 55, 56, 57, 8, 58, 59, 60, + 61, 62, 8, 63, 64, 65, 66, 67, 68, 8, + 69, 8, 1, 70, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 69, 1, 70, 1, 1, 1, 1, 71, 72, 1, - 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, + 71, 1, 72, 1, 1, 1, 1, 73, 74, 1, + 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -413,140 +422,174 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[74] = +static yyconst flex_int32_t yy_meta[76] = { 0, 1, 1, 2, 2, 1, 3, 1, 4, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 6, 7, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, - 1, 1, 1 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, + 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[203] = +static yyconst flex_int16_t yy_base[285] = { 0, - 0, 0, 71, 72, 65, 66, 72, 73, 312, 311, - 357, 500, 78, 85, 333, 500, 0, 0, 500, 345, - 500, 500, 500, 334, 500, 73, 333, 338, 74, 80, - 60, 500, 328, 500, 61, 70, 63, 64, 79, 69, - 69, 75, 73, 71, 85, 89, 84, 500, 282, 280, - 68, 500, 500, 103, 0, 141, 0, 0, 153, 0, - 0, 301, 147, 278, 500, 0, 0, 500, 326, 159, - 325, 146, 145, 500, 147, 151, 162, 324, 323, 317, - 500, 118, 0, 130, 133, 140, 137, 0, 150, 148, - 0, 0, 140, 144, 152, 160, 500, 500, 500, 500, - - 174, 500, 0, 188, 329, 500, 321, 268, 500, 0, - 211, 500, 330, 318, 265, 500, 0, 500, 216, 264, - 206, 210, 204, 214, 307, 303, 500, 0, 187, 0, - 193, 204, 201, 206, 207, 0, 198, 202, 500, 296, - 292, 241, 500, 290, 280, 244, 130, 247, 249, 264, - 215, 192, 184, 181, 227, 226, 229, 0, 225, 240, - 240, 241, 270, 84, 273, 73, 242, 0, 251, 0, - 0, 242, 0, 291, 295, 297, 308, 311, 318, 322, - 326, 272, 0, 0, 0, 500, 395, 402, 409, 416, - 423, 92, 430, 437, 444, 451, 458, 464, 471, 478, - - 485, 492 + 0, 0, 73, 74, 67, 68, 74, 75, 611, 610, + 631, 660, 80, 87, 601, 660, 0, 0, 660, 598, + 660, 660, 660, 585, 660, 75, 574, 579, 76, 82, + 62, 660, 560, 660, 63, 72, 65, 66, 81, 71, + 71, 77, 73, 80, 75, 96, 92, 105, 660, 482, + 480, 71, 660, 660, 133, 0, 152, 0, 0, 164, + 0, 0, 501, 170, 477, 660, 0, 0, 660, 527, + 173, 526, 160, 133, 660, 159, 164, 175, 524, 523, + 518, 660, 110, 0, 122, 143, 148, 147, 0, 0, + 161, 160, 155, 163, 0, 0, 154, 159, 161, 168, + + 175, 660, 660, 660, 660, 186, 660, 0, 226, 530, + 660, 522, 467, 660, 0, 230, 660, 531, 519, 464, + 660, 0, 660, 514, 236, 462, 225, 193, 231, 227, + 235, 239, 512, 511, 509, 660, 0, 197, 0, 206, + 220, 221, 227, 0, 226, 229, 0, 235, 221, 226, + 660, 515, 513, 267, 660, 517, 508, 271, 490, 146, + 290, 292, 270, 489, 484, 483, 481, 478, 280, 470, + 251, 243, 265, 0, 262, 0, 278, 282, 281, 282, + 310, 414, 313, 400, 450, 306, 310, 440, 289, 0, + 289, 0, 0, 281, 295, 0, 341, 345, 361, 363, + + 347, 367, 351, 372, 438, 359, 362, 437, 300, 0, + 354, 0, 434, 367, 372, 421, 0, 0, 416, 375, + 379, 413, 405, 380, 392, 403, 402, 397, 400, 393, + 387, 410, 417, 385, 383, 422, 427, 382, 374, 430, + 435, 369, 366, 443, 447, 348, 320, 448, 455, 258, + 247, 460, 463, 211, 198, 468, 473, 195, 187, 476, + 488, 660, 137, 493, 498, 99, 501, 660, 553, 560, + 567, 574, 581, 94, 588, 595, 602, 609, 616, 622, + 629, 636, 643, 650 } ; -static yyconst flex_int16_t yy_def[203] = +static yyconst flex_int16_t yy_def[285] = { 0, - 186, 1, 187, 187, 188, 188, 189, 189, 190, 190, - 186, 186, 186, 186, 186, 186, 191, 192, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 192, 186, - 186, 186, 186, 186, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 186, 186, 186, - 186, 186, 186, 186, 193, 186, 194, 195, 186, 196, - 197, 186, 186, 186, 186, 191, 192, 186, 186, 186, - 186, 186, 186, 186, 186, 192, 192, 186, 186, 186, - 186, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 186, 186, 186, 186, - - 186, 186, 193, 186, 198, 186, 186, 186, 186, 195, - 186, 186, 199, 186, 186, 186, 197, 186, 200, 186, - 186, 186, 186, 186, 186, 192, 186, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 186, 198, - 198, 186, 186, 199, 199, 186, 200, 200, 200, 186, - 186, 186, 186, 186, 192, 192, 192, 192, 192, 192, - 192, 192, 201, 186, 202, 186, 192, 192, 192, 192, - 192, 192, 192, 201, 201, 201, 201, 202, 202, 202, - 202, 192, 192, 192, 192, 0, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - - 186, 186 + 268, 1, 269, 269, 270, 270, 271, 271, 272, 272, + 268, 268, 268, 268, 268, 268, 273, 274, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 274, 268, + 268, 268, 268, 268, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 268, 268, + 268, 268, 268, 268, 268, 275, 268, 276, 277, 268, + 278, 279, 268, 268, 268, 268, 273, 274, 268, 268, + 268, 268, 268, 268, 268, 268, 274, 274, 268, 268, + 268, 268, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + + 274, 268, 268, 268, 268, 268, 268, 275, 268, 280, + 268, 268, 268, 268, 277, 268, 268, 281, 268, 268, + 268, 279, 268, 268, 282, 268, 268, 268, 268, 268, + 268, 274, 268, 274, 268, 268, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 268, 280, 280, 268, 268, 281, 281, 268, 268, 282, + 282, 282, 268, 268, 268, 268, 268, 268, 274, 268, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 283, 268, 284, 268, 268, 268, 274, 268, 274, 274, + 274, 274, 274, 274, 274, 274, 283, 283, 283, 283, + + 284, 284, 284, 284, 268, 268, 274, 268, 274, 274, + 274, 274, 268, 268, 274, 268, 274, 274, 268, 268, + 274, 268, 268, 268, 274, 268, 268, 268, 274, 268, + 268, 268, 274, 268, 268, 268, 274, 268, 268, 268, + 274, 268, 268, 268, 274, 268, 268, 268, 274, 268, + 268, 268, 274, 268, 268, 268, 274, 268, 268, 268, + 274, 268, 268, 268, 274, 268, 268, 0, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268 } ; -static yyconst flex_int16_t yy_nxt[574] = +static yyconst flex_int16_t yy_nxt[736] = { 0, 12, 13, 14, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 19, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 18, 18, 37, - 38, 39, 40, 41, 42, 18, 18, 43, 18, 44, - 45, 18, 18, 46, 47, 12, 48, 35, 36, 18, - 18, 37, 38, 39, 40, 41, 42, 18, 18, 43, - 18, 44, 45, 18, 18, 46, 47, 49, 50, 51, - 12, 12, 12, 53, 53, 56, 56, 59, 59, 63, - 63, 63, 80, 65, 54, 54, 63, 63, 63, 70, - 71, 75, 72, 76, 78, 67, 78, 82, 84, 79, - - 85, 83, 77, 86, 87, 88, 89, 90, 93, 91, - 57, 57, 92, 94, 95, 96, 101, 60, 60, 82, - 84, 102, 85, 83, 77, 86, 87, 88, 89, 90, - 93, 91, 186, 186, 92, 94, 95, 96, 98, 99, - 100, 165, 104, 104, 104, 128, 64, 105, 63, 63, - 63, 106, 163, 64, 111, 111, 111, 107, 112, 113, - 119, 119, 119, 75, 73, 72, 123, 128, 75, 114, - 76, 129, 130, 122, 121, 124, 125, 131, 125, 77, - 132, 126, 133, 134, 135, 136, 137, 101, 138, 104, - 104, 104, 102, 129, 130, 122, 121, 124, 139, 131, - - 154, 77, 132, 154, 133, 134, 135, 136, 137, 108, - 138, 152, 111, 111, 111, 64, 143, 148, 119, 119, - 125, 115, 125, 123, 151, 150, 151, 120, 153, 152, - 153, 155, 124, 154, 152, 156, 157, 158, 159, 160, - 161, 162, 163, 163, 163, 165, 165, 165, 148, 119, - 119, 186, 186, 155, 124, 167, 108, 156, 157, 158, - 159, 160, 161, 162, 168, 169, 170, 171, 172, 173, - 182, 175, 163, 163, 179, 165, 165, 167, 180, 115, - 176, 183, 184, 150, 149, 145, 168, 169, 170, 171, - 172, 173, 182, 186, 186, 145, 175, 163, 163, 186, - - 186, 176, 141, 183, 184, 176, 141, 176, 185, 164, - 186, 186, 166, 186, 186, 149, 180, 148, 176, 179, - 165, 165, 126, 180, 186, 186, 150, 180, 186, 186, - 185, 180, 119, 111, 146, 145, 104, 142, 177, 141, - 127, 181, 79, 79, 73, 69, 63, 118, 63, 97, - 81, 74, 73, 69, 68, 65, 186, 62, 62, 186, - 186, 186, 186, 177, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 175, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 181, 186, 186, 186, - 186, 186, 186, 186, 179, 52, 52, 52, 52, 52, - - 52, 52, 55, 55, 55, 55, 55, 55, 55, 58, - 58, 58, 58, 58, 58, 58, 61, 61, 61, 61, - 61, 61, 61, 66, 186, 66, 66, 66, 66, 66, - 103, 103, 103, 103, 186, 186, 103, 109, 109, 109, - 109, 109, 109, 109, 110, 110, 186, 110, 110, 186, - 110, 116, 116, 116, 116, 116, 116, 116, 117, 117, - 117, 117, 117, 117, 140, 186, 140, 140, 140, 140, - 140, 144, 186, 144, 144, 144, 144, 144, 147, 147, - 147, 147, 147, 147, 147, 174, 174, 174, 174, 174, - 174, 174, 178, 178, 178, 178, 178, 178, 178, 11, - - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186 + 38, 39, 40, 41, 42, 18, 43, 44, 18, 45, + 46, 18, 18, 47, 48, 18, 12, 49, 35, 36, + 18, 18, 37, 38, 39, 40, 41, 42, 18, 43, + 44, 18, 45, 46, 18, 18, 47, 48, 18, 50, + 51, 52, 12, 12, 12, 54, 54, 57, 57, 60, + 60, 64, 64, 64, 81, 66, 55, 55, 64, 64, + 64, 71, 72, 76, 73, 77, 79, 68, 79, 83, + + 85, 80, 86, 84, 78, 87, 88, 89, 91, 92, + 93, 90, 97, 58, 58, 94, 95, 100, 266, 96, + 61, 61, 83, 85, 98, 86, 84, 78, 87, 88, + 89, 91, 92, 93, 90, 97, 101, 137, 94, 95, + 100, 99, 96, 103, 104, 105, 106, 98, 268, 268, + 65, 107, 74, 109, 109, 109, 266, 65, 110, 101, + 137, 129, 111, 138, 99, 116, 116, 116, 112, 117, + 118, 64, 64, 64, 125, 125, 125, 76, 130, 127, + 119, 76, 139, 132, 129, 140, 138, 131, 128, 133, + 141, 133, 78, 142, 134, 143, 144, 145, 146, 106, + + 147, 148, 149, 150, 107, 139, 263, 133, 140, 133, + 131, 128, 164, 141, 262, 78, 142, 259, 143, 144, + 145, 146, 113, 147, 148, 149, 150, 109, 109, 109, + 258, 116, 116, 116, 120, 155, 151, 161, 125, 125, + 65, 171, 76, 126, 163, 165, 130, 165, 172, 167, + 166, 167, 173, 128, 168, 131, 76, 174, 169, 175, + 176, 177, 178, 179, 171, 180, 255, 78, 181, 181, + 181, 172, 183, 183, 183, 173, 128, 254, 131, 189, + 174, 190, 175, 176, 177, 178, 179, 76, 180, 186, + 78, 161, 125, 125, 268, 268, 113, 76, 128, 187, + + 120, 191, 189, 192, 190, 193, 162, 194, 78, 195, + 196, 198, 181, 181, 202, 183, 183, 209, 203, 210, + 199, 128, 211, 76, 191, 206, 192, 76, 193, 207, + 194, 78, 195, 196, 128, 212, 217, 182, 78, 251, + 209, 184, 210, 268, 268, 211, 198, 181, 181, 268, + 268, 199, 203, 268, 268, 199, 203, 128, 212, 217, + 162, 78, 161, 268, 268, 268, 268, 250, 202, 183, + 183, 199, 203, 199, 268, 268, 76, 203, 214, 76, + 200, 215, 218, 204, 76, 247, 220, 128, 246, 76, + 78, 221, 76, 243, 224, 128, 76, 76, 225, 228, + + 78, 242, 239, 128, 238, 218, 235, 78, 128, 76, + 128, 229, 234, 78, 76, 200, 232, 76, 128, 233, + 78, 231, 230, 78, 227, 128, 128, 76, 78, 236, + 78, 128, 226, 198, 76, 223, 237, 204, 128, 76, + 222, 240, 202, 78, 76, 78, 241, 76, 128, 244, + 128, 78, 76, 219, 245, 78, 216, 213, 128, 208, + 76, 128, 248, 78, 76, 76, 249, 252, 78, 205, + 183, 128, 76, 128, 253, 78, 128, 76, 78, 256, + 76, 128, 257, 78, 181, 76, 78, 260, 128, 188, + 76, 78, 261, 76, 128, 264, 128, 168, 78, 128, + + 168, 78, 166, 166, 128, 76, 78, 265, 164, 185, + 76, 128, 267, 157, 78, 76, 78, 265, 76, 128, + 267, 128, 157, 153, 78, 153, 78, 128, 170, 128, + 134, 164, 125, 159, 116, 158, 157, 109, 154, 78, + 153, 136, 135, 80, 128, 74, 124, 64, 123, 78, + 64, 102, 128, 53, 53, 53, 53, 53, 53, 53, + 56, 56, 56, 56, 56, 56, 56, 59, 59, 59, + 59, 59, 59, 59, 62, 62, 62, 62, 62, 62, + 62, 67, 82, 67, 67, 67, 67, 67, 108, 108, + 108, 108, 75, 74, 108, 114, 114, 114, 114, 114, + + 114, 114, 115, 115, 70, 115, 115, 69, 115, 121, + 121, 121, 121, 121, 121, 121, 122, 122, 122, 122, + 122, 122, 152, 66, 152, 152, 152, 152, 152, 156, + 268, 156, 156, 156, 156, 156, 160, 160, 160, 160, + 160, 160, 160, 197, 197, 197, 197, 197, 197, 197, + 201, 201, 201, 201, 201, 201, 201, 63, 63, 11, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268 } ; -static yyconst flex_int16_t yy_chk[574] = +static yyconst flex_int16_t yy_chk[736] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -555,62 +598,80 @@ static yyconst flex_int16_t yy_chk[574] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 4, 5, 6, 7, 8, 13, - 13, 13, 31, 31, 3, 4, 14, 14, 14, 26, - 26, 29, 26, 29, 30, 192, 30, 35, 36, 30, - - 37, 35, 29, 38, 39, 40, 41, 42, 44, 43, - 5, 6, 43, 45, 46, 47, 54, 7, 8, 35, - 36, 54, 37, 35, 29, 38, 39, 40, 41, 42, - 44, 43, 147, 147, 43, 45, 46, 47, 51, 51, - 51, 166, 56, 56, 56, 82, 13, 56, 63, 63, - 63, 56, 164, 14, 59, 59, 59, 56, 59, 59, - 70, 70, 70, 72, 73, 72, 75, 82, 76, 59, - 76, 84, 85, 73, 72, 75, 77, 86, 77, 76, - 87, 77, 89, 90, 93, 94, 95, 101, 96, 104, - 104, 104, 101, 84, 85, 73, 72, 75, 104, 86, - - 154, 76, 87, 153, 89, 90, 93, 94, 95, 56, - 96, 152, 111, 111, 111, 63, 111, 119, 119, 119, - 121, 59, 121, 123, 122, 121, 122, 70, 124, 122, - 124, 129, 123, 124, 151, 131, 132, 133, 134, 135, - 137, 138, 142, 142, 142, 146, 146, 146, 148, 148, - 148, 149, 149, 129, 123, 155, 104, 131, 132, 133, - 134, 135, 137, 138, 156, 157, 159, 160, 161, 162, - 167, 163, 163, 163, 165, 165, 165, 155, 165, 111, - 163, 169, 172, 150, 119, 145, 156, 157, 159, 160, - 161, 162, 167, 174, 174, 144, 175, 175, 175, 176, - - 176, 174, 141, 169, 172, 175, 140, 176, 182, 142, - 177, 177, 146, 178, 178, 148, 178, 149, 177, 179, - 179, 179, 126, 179, 180, 180, 125, 180, 181, 181, - 182, 181, 120, 115, 114, 113, 108, 107, 163, 105, - 80, 165, 79, 78, 71, 69, 64, 62, 50, 49, - 33, 28, 27, 24, 20, 15, 11, 10, 9, 0, - 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, - 0, 0, 0, 0, 181, 187, 187, 187, 187, 187, - - 187, 187, 188, 188, 188, 188, 188, 188, 188, 189, - 189, 189, 189, 189, 189, 189, 190, 190, 190, 190, - 190, 190, 190, 191, 0, 191, 191, 191, 191, 191, - 193, 193, 193, 193, 0, 0, 193, 194, 194, 194, - 194, 194, 194, 194, 195, 195, 0, 195, 195, 0, - 195, 196, 196, 196, 196, 196, 196, 196, 197, 197, - 197, 197, 197, 197, 198, 0, 198, 198, 198, 198, - 198, 199, 0, 199, 199, 199, 199, 199, 200, 200, - 200, 200, 200, 200, 200, 201, 201, 201, 201, 201, - 201, 201, 202, 202, 202, 202, 202, 202, 202, 186, - - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186 + 1, 1, 1, 1, 1, 3, 4, 5, 6, 7, + 8, 13, 13, 13, 31, 31, 3, 4, 14, 14, + 14, 26, 26, 29, 26, 29, 30, 274, 30, 35, + + 36, 30, 37, 35, 29, 38, 39, 40, 41, 42, + 43, 40, 45, 5, 6, 43, 44, 47, 266, 44, + 7, 8, 35, 36, 46, 37, 35, 29, 38, 39, + 40, 41, 42, 43, 40, 45, 48, 83, 43, 44, + 47, 46, 44, 52, 52, 52, 55, 46, 160, 160, + 13, 55, 74, 57, 57, 57, 263, 14, 57, 48, + 83, 74, 57, 85, 46, 60, 60, 60, 57, 60, + 60, 64, 64, 64, 71, 71, 71, 73, 76, 73, + 60, 77, 86, 77, 74, 87, 85, 76, 73, 78, + 88, 78, 77, 91, 78, 92, 93, 94, 97, 106, + + 98, 99, 100, 101, 106, 86, 259, 128, 87, 128, + 76, 73, 128, 88, 258, 77, 91, 255, 92, 93, + 94, 97, 57, 98, 99, 100, 101, 109, 109, 109, + 254, 116, 116, 116, 60, 116, 109, 125, 125, 125, + 64, 138, 127, 71, 127, 129, 130, 129, 140, 131, + 129, 131, 141, 127, 131, 130, 132, 142, 132, 143, + 145, 146, 148, 149, 138, 150, 251, 132, 154, 154, + 154, 140, 158, 158, 158, 141, 127, 250, 130, 171, + 142, 172, 143, 145, 146, 148, 149, 163, 150, 163, + 132, 161, 161, 161, 162, 162, 109, 169, 163, 169, + + 116, 173, 171, 175, 172, 177, 125, 178, 169, 179, + 180, 181, 181, 181, 183, 183, 183, 189, 183, 191, + 181, 163, 194, 186, 173, 186, 175, 187, 177, 187, + 178, 169, 179, 180, 186, 195, 209, 154, 187, 247, + 189, 158, 191, 197, 197, 194, 198, 198, 198, 201, + 201, 197, 201, 203, 203, 198, 203, 186, 195, 209, + 161, 187, 162, 199, 199, 200, 200, 246, 202, 202, + 202, 199, 202, 200, 204, 204, 206, 204, 206, 207, + 181, 207, 211, 183, 214, 243, 214, 206, 242, 215, + 207, 215, 220, 239, 220, 214, 221, 224, 221, 224, + + 215, 238, 235, 220, 234, 211, 231, 221, 224, 225, + 206, 225, 230, 207, 228, 198, 228, 229, 214, 229, + 225, 227, 226, 215, 223, 228, 220, 232, 229, 232, + 221, 224, 222, 200, 233, 219, 233, 202, 232, 236, + 216, 236, 204, 225, 237, 233, 237, 240, 228, 240, + 236, 229, 241, 213, 241, 237, 208, 205, 240, 188, + 244, 232, 244, 241, 245, 248, 245, 248, 233, 185, + 184, 244, 249, 236, 249, 245, 248, 252, 237, 252, + 253, 240, 253, 249, 182, 256, 241, 256, 252, 170, + 257, 253, 257, 260, 244, 260, 256, 168, 245, 248, + + 167, 257, 166, 165, 260, 261, 249, 261, 164, 159, + 264, 252, 264, 157, 253, 265, 261, 265, 267, 256, + 267, 264, 156, 153, 257, 152, 265, 260, 135, 267, + 134, 133, 126, 124, 120, 119, 118, 113, 112, 261, + 110, 81, 80, 79, 264, 72, 70, 65, 63, 265, + 51, 50, 267, 269, 269, 269, 269, 269, 269, 269, + 270, 270, 270, 270, 270, 270, 270, 271, 271, 271, + 271, 271, 271, 271, 272, 272, 272, 272, 272, 272, + 272, 273, 33, 273, 273, 273, 273, 273, 275, 275, + 275, 275, 28, 27, 275, 276, 276, 276, 276, 276, + + 276, 276, 277, 277, 24, 277, 277, 20, 277, 278, + 278, 278, 278, 278, 278, 278, 279, 279, 279, 279, + 279, 279, 280, 15, 280, 280, 280, 280, 280, 281, + 11, 281, 281, 281, 281, 281, 282, 282, 282, 282, + 282, 282, 282, 283, 283, 283, 283, 283, 283, 283, + 284, 284, 284, 284, 284, 284, 284, 10, 9, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268 } ; /* The intent behind this definition is that it'll catch @@ -665,11 +726,16 @@ do {\ #define RETURN_ROW_ID() \ { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return ROW_ID; } +#define RETURN_REVERSED_EXPR_FUNC() \ + { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return REVERSED_EXPR_FUNC; } + + /*following character status will be rewrite by gen_parse.sh according to connection character*/ -#line 674 "ob_expr_parser_gbk_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +#line 740 "ob_expr_parser_gbk_lex.c" #define INITIAL 0 #define in_c_comment 1 @@ -917,9 +983,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 96 "ob_expr_parser_gbk.l" +#line 102 "ob_expr_parser_gbk.l" -#line 925 "ob_expr_parser_gbk_lex.c" +#line 991 "ob_expr_parser_gbk_lex.c" yylval = yylval_param; @@ -976,13 +1042,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 187 ) + if ( yy_current_state >= 269 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 500 ); + while ( yy_base[yy_current_state] != 660 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -1008,206 +1074,226 @@ YY_DECL case 1: YY_RULE_SETUP -#line 97 "ob_expr_parser_gbk.l" +#line 103 "ob_expr_parser_gbk.l" { return WHERE; } YY_BREAK case 2: YY_RULE_SETUP -#line 98 "ob_expr_parser_gbk.l" +#line 104 "ob_expr_parser_gbk.l" { return AS; } YY_BREAK case 3: YY_RULE_SETUP -#line 99 "ob_expr_parser_gbk.l" +#line 105 "ob_expr_parser_gbk.l" { return VALUES; } YY_BREAK case 4: YY_RULE_SETUP -#line 100 "ob_expr_parser_gbk.l" +#line 106 "ob_expr_parser_gbk.l" { return VALUES; } YY_BREAK case 5: YY_RULE_SETUP -#line 101 "ob_expr_parser_gbk.l" +#line 107 "ob_expr_parser_gbk.l" { return SET; } YY_BREAK case 6: YY_RULE_SETUP -#line 102 "ob_expr_parser_gbk.l" +#line 108 "ob_expr_parser_gbk.l" { return END_WHERE; } YY_BREAK case 7: YY_RULE_SETUP -#line 103 "ob_expr_parser_gbk.l" +#line 109 "ob_expr_parser_gbk.l" { return END_WHERE; } YY_BREAK case 8: YY_RULE_SETUP -#line 104 "ob_expr_parser_gbk.l" +#line 110 "ob_expr_parser_gbk.l" { return END_WHERE; } YY_BREAK case 9: YY_RULE_SETUP -#line 105 "ob_expr_parser_gbk.l" +#line 111 "ob_expr_parser_gbk.l" { return END_WHERE; } YY_BREAK case 10: YY_RULE_SETUP -#line 106 "ob_expr_parser_gbk.l" +#line 112 "ob_expr_parser_gbk.l" { RETURN_ROW_ID(); } YY_BREAK case 11: YY_RULE_SETUP -#line 108 "ob_expr_parser_gbk.l" +#line 114 "ob_expr_parser_gbk.l" { return JOIN; } YY_BREAK case 12: YY_RULE_SETUP -#line 109 "ob_expr_parser_gbk.l" +#line 115 "ob_expr_parser_gbk.l" { return ON; } YY_BREAK case 13: YY_RULE_SETUP -#line 110 "ob_expr_parser_gbk.l" +#line 116 "ob_expr_parser_gbk.l" { return BETWEEN; } YY_BREAK case 14: YY_RULE_SETUP -#line 111 "ob_expr_parser_gbk.l" +#line 117 "ob_expr_parser_gbk.l" { return AND_OP; } YY_BREAK case 15: YY_RULE_SETUP -#line 112 "ob_expr_parser_gbk.l" +#line 118 "ob_expr_parser_gbk.l" { return AND_OP; } YY_BREAK case 16: YY_RULE_SETUP -#line 113 "ob_expr_parser_gbk.l" +#line 119 "ob_expr_parser_gbk.l" { return OR_OP; } YY_BREAK case 17: YY_RULE_SETUP -#line 114 "ob_expr_parser_gbk.l" +#line 120 "ob_expr_parser_gbk.l" { return OR_OP; } YY_BREAK case 18: YY_RULE_SETUP -#line 115 "ob_expr_parser_gbk.l" +#line 121 "ob_expr_parser_gbk.l" { return IN; } YY_BREAK case 19: YY_RULE_SETUP -#line 116 "ob_expr_parser_gbk.l" -{ return COMP_EQ; } +#line 122 "ob_expr_parser_gbk.l" +{ return IS; } YY_BREAK case 20: YY_RULE_SETUP -#line 117 "ob_expr_parser_gbk.l" -{ return COMP_NSEQ; } +#line 123 "ob_expr_parser_gbk.l" +{ return TOKEN_NULL; } YY_BREAK case 21: YY_RULE_SETUP -#line 118 "ob_expr_parser_gbk.l" -{ return COMP_GE; } +#line 124 "ob_expr_parser_gbk.l" +{ return NOT; } YY_BREAK case 22: YY_RULE_SETUP -#line 119 "ob_expr_parser_gbk.l" -{ return COMP_GT; } +#line 125 "ob_expr_parser_gbk.l" +{ return COMP_EQ; } YY_BREAK case 23: YY_RULE_SETUP -#line 120 "ob_expr_parser_gbk.l" -{ return COMP_LE; } +#line 126 "ob_expr_parser_gbk.l" +{ return COMP_NSEQ; } YY_BREAK case 24: YY_RULE_SETUP -#line 121 "ob_expr_parser_gbk.l" -{ return COMP_LT; } +#line 127 "ob_expr_parser_gbk.l" +{ return COMP_GE; } YY_BREAK case 25: YY_RULE_SETUP -#line 122 "ob_expr_parser_gbk.l" -{ return COMP_NE; } +#line 128 "ob_expr_parser_gbk.l" +{ return COMP_GT; } YY_BREAK case 26: YY_RULE_SETUP -#line 123 "ob_expr_parser_gbk.l" -{ return PLACE_HOLDER; } +#line 129 "ob_expr_parser_gbk.l" +{ return COMP_LE; } YY_BREAK case 27: YY_RULE_SETUP -#line 124 "ob_expr_parser_gbk.l" -{ store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } +#line 130 "ob_expr_parser_gbk.l" +{ return COMP_LT; } YY_BREAK case 28: YY_RULE_SETUP -#line 126 "ob_expr_parser_gbk.l" -{ RETURN_INT_VAL(); } +#line 131 "ob_expr_parser_gbk.l" +{ return COMP_NE; } YY_BREAK case 29: YY_RULE_SETUP -#line 127 "ob_expr_parser_gbk.l" -{ RETURN_NUMBER_VAL(); } +#line 132 "ob_expr_parser_gbk.l" +{ return PLACE_HOLDER; } YY_BREAK case 30: YY_RULE_SETUP -#line 128 "ob_expr_parser_gbk.l" -{ RETURN_NAME_OB(); } +#line 133 "ob_expr_parser_gbk.l" +{ store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } YY_BREAK case 31: -/* rule 31 can match eol */ YY_RULE_SETUP -#line 129 "ob_expr_parser_gbk.l" -{ } +#line 134 "ob_expr_parser_gbk.l" +{ RETURN_REVERSED_EXPR_FUNC();} YY_BREAK case 32: YY_RULE_SETUP -#line 130 "ob_expr_parser_gbk.l" -{ return ','; } +#line 136 "ob_expr_parser_gbk.l" +{ RETURN_INT_VAL(); } YY_BREAK case 33: YY_RULE_SETUP -#line 131 "ob_expr_parser_gbk.l" -{ return '('; } +#line 137 "ob_expr_parser_gbk.l" +{ RETURN_NUMBER_VAL(); } YY_BREAK case 34: YY_RULE_SETUP -#line 132 "ob_expr_parser_gbk.l" -{ return ')'; } +#line 138 "ob_expr_parser_gbk.l" +{ RETURN_NAME_OB(); } YY_BREAK case 35: +/* rule 35 can match eol */ YY_RULE_SETUP -#line 133 "ob_expr_parser_gbk.l" +#line 139 "ob_expr_parser_gbk.l" +{ } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 140 "ob_expr_parser_gbk.l" +{ return ','; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 141 "ob_expr_parser_gbk.l" +{ return '('; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 142 "ob_expr_parser_gbk.l" +{ return ')'; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 143 "ob_expr_parser_gbk.l" { return yytext[0]; } YY_BREAK /* comment */ -case 36: +case 40: YY_RULE_SETUP -#line 136 "ob_expr_parser_gbk.l" +#line 146 "ob_expr_parser_gbk.l" { PUSH_STATE(in_c_comment); } YY_BREAK -case 37: +case 41: YY_RULE_SETUP -#line 137 "ob_expr_parser_gbk.l" +#line 147 "ob_expr_parser_gbk.l" { POP_STATE(); } YY_BREAK -case 38: -/* rule 38 can match eol */ +case 42: +/* rule 42 can match eol */ YY_RULE_SETUP -#line 138 "ob_expr_parser_gbk.l" +#line 148 "ob_expr_parser_gbk.l" {} YY_BREAK -case 39: +case 43: YY_RULE_SETUP -#line 139 "ob_expr_parser_gbk.l" +#line 149 "ob_expr_parser_gbk.l" {} YY_BREAK /* quote */ -case 40: +case 44: YY_RULE_SETUP -#line 142 "ob_expr_parser_gbk.l" +#line 152 "ob_expr_parser_gbk.l" { PUSH_STATE(sq); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1218,10 +1304,10 @@ YY_RULE_SETUP } } YY_BREAK -case 41: -/* rule 41 can match eol */ +case 45: +/* rule 45 can match eol */ YY_RULE_SETUP -#line 152 "ob_expr_parser_gbk.l" +#line 162 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1229,9 +1315,9 @@ YY_RULE_SETUP } } YY_BREAK -case 42: +case 46: YY_RULE_SETUP -#line 159 "ob_expr_parser_gbk.l" +#line 169 "ob_expr_parser_gbk.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1241,15 +1327,15 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 43: +case 47: YY_RULE_SETUP -#line 168 "ob_expr_parser_gbk.l" +#line 178 "ob_expr_parser_gbk.l" {} YY_BREAK -case 44: -/* rule 44 can match eol */ +case 48: +/* rule 48 can match eol */ YY_RULE_SETUP -#line 169 "ob_expr_parser_gbk.l" +#line 179 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1257,20 +1343,20 @@ YY_RULE_SETUP } } YY_BREAK -case 45: -/* rule 45 can match eol */ +case 49: +/* rule 49 can match eol */ YY_RULE_SETUP -#line 175 "ob_expr_parser_gbk.l" +#line 185 "ob_expr_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 176 "ob_expr_parser_gbk.l" +#line 186 "ob_expr_parser_gbk.l" { return ERROR; } YY_BREAK /* dquote */ -case 46: +case 50: YY_RULE_SETUP -#line 180 "ob_expr_parser_gbk.l" +#line 190 "ob_expr_parser_gbk.l" { PUSH_STATE(dq); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1281,10 +1367,10 @@ YY_RULE_SETUP } } YY_BREAK -case 47: -/* rule 47 can match eol */ +case 51: +/* rule 51 can match eol */ YY_RULE_SETUP -#line 190 "ob_expr_parser_gbk.l" +#line 200 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1292,9 +1378,9 @@ YY_RULE_SETUP } } YY_BREAK -case 48: +case 52: YY_RULE_SETUP -#line 197 "ob_expr_parser_gbk.l" +#line 207 "ob_expr_parser_gbk.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1307,31 +1393,31 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 49: +case 53: YY_RULE_SETUP -#line 209 "ob_expr_parser_gbk.l" +#line 219 "ob_expr_parser_gbk.l" {} YY_BREAK -case 50: -/* rule 50 can match eol */ +case 54: +/* rule 54 can match eol */ YY_RULE_SETUP -#line 210 "ob_expr_parser_gbk.l" +#line 220 "ob_expr_parser_gbk.l" {} YY_BREAK -case 51: -/* rule 51 can match eol */ +case 55: +/* rule 55 can match eol */ YY_RULE_SETUP -#line 211 "ob_expr_parser_gbk.l" +#line 221 "ob_expr_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 212 "ob_expr_parser_gbk.l" +#line 222 "ob_expr_parser_gbk.l" { return ERROR; } YY_BREAK /* backtick */ -case 52: +case 56: YY_RULE_SETUP -#line 216 "ob_expr_parser_gbk.l" +#line 226 "ob_expr_parser_gbk.l" { PUSH_STATE(bt); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1342,9 +1428,9 @@ YY_RULE_SETUP } } YY_BREAK -case 53: +case 57: YY_RULE_SETUP -#line 226 "ob_expr_parser_gbk.l" +#line 236 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -1352,10 +1438,10 @@ YY_RULE_SETUP } } YY_BREAK -case 54: -/* rule 54 can match eol */ +case 58: +/* rule 58 can match eol */ YY_RULE_SETUP -#line 233 "ob_expr_parser_gbk.l" +#line 243 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -1364,9 +1450,9 @@ YY_RULE_SETUP } } YY_BREAK -case 55: +case 59: YY_RULE_SETUP -#line 241 "ob_expr_parser_gbk.l" +#line 251 "ob_expr_parser_gbk.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1379,27 +1465,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 252 "ob_expr_parser_gbk.l" +#line 262 "ob_expr_parser_gbk.l" { return ERROR; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(in_c_comment): -#line 256 "ob_expr_parser_gbk.l" +#line 266 "ob_expr_parser_gbk.l" { return END_P; } YY_BREAK -case 56: +case 60: YY_RULE_SETUP -#line 257 "ob_expr_parser_gbk.l" +#line 267 "ob_expr_parser_gbk.l" { return IGNORED_WORD; } YY_BREAK -case 57: +case 61: YY_RULE_SETUP -#line 258 "ob_expr_parser_gbk.l" +#line 268 "ob_expr_parser_gbk.l" ECHO; YY_BREAK -#line 1405 "ob_expr_parser_gbk_lex.c" +#line 1491 "ob_expr_parser_gbk_lex.c" case YY_END_OF_BUFFER: { @@ -1691,7 +1777,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 187 ) + if ( yy_current_state >= 269 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1720,11 +1806,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 187 ) + if ( yy_current_state >= 269 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 186); + yy_is_jam = (yy_current_state == 268); return yy_is_jam ? 0 : yy_current_state; } @@ -2549,7 +2635,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 258 "ob_expr_parser_gbk.l" +#line 268 "ob_expr_parser_gbk.l" @@ -2680,22 +2766,26 @@ extern int ob_expr_parser_gbk_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.h b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.h index c3edcf27..6f76d34d 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.h @@ -341,7 +341,7 @@ extern int ob_expr_parser_gbk_yylex \ #undef YY_DECL #endif -#line 258 "ob_expr_parser_gbk.l" +#line 268 "ob_expr_parser_gbk.l" #line 348 "ob_expr_parser_gbk_lex.h" diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.c b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.c index 46a18aa7..41f0d84c 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.c +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.c @@ -139,22 +139,26 @@ extern int ob_expr_parser_gbk_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif @@ -232,8 +236,8 @@ static inline void add_token_list(ObProxyTokenList *list, ObProxyTokenList *next if (OB_ISNULL(list) || OB_ISNULL(next_list)) { } else if (NULL != list->tail_ && NULL != next_list->head_ - && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_) - && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_)) { + && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_ || TOKEN_FUNC == list->tail_->type_) + && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_ || TOKEN_FUNC == next_list->head_->type_)) { list->tail_->next_ = next_list->head_; list->tail_ = next_list->head_; list->tail_->next_ = NULL; @@ -305,11 +309,18 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar for (i = 0; i < result->part_key_info_.key_num_; ++i) { if (is_equal(column_name, &result->part_key_info_.part_keys_[i].name_)) { result->part_key_info_.part_keys_[i].idx_ = result->column_idx_; - break; + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; } } } +static inline void init_part_key_all_match(ObExprParseResult *result) +{ + for (int64_t i = 0; i < result->part_key_info_.key_num_; ++i) { + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; + } +} + #define malloc_node(node, result, type) \ do { \ if (OB_ISNULL(node = ((ObProxyTokenNode *)obproxy_parse_malloc(sizeof(ObProxyTokenNode), \ @@ -344,21 +355,13 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar do { \ if (NULL == relation) { \ } else { \ - int64_t new_mask = get_mask(relation->type_, relation->level_); \ - bool has_rowid = result->has_rowid_; \ - if (((result->cur_mask_ | new_mask) != result->cur_mask_) \ - || (has_rowid \ - && is_equal_to_rowid(&relation->left_value_->column_node_->column_name_))) { \ + if (relation->level_ != PART_KEY_LEVEL_ZERO) { \ if (result->relation_info_.relation_num_ < OBPROXY_MAX_RELATION_NUM) { \ result->relation_info_.relations_[result->relation_info_.relation_num_++] = relation; \ - result->cur_mask_ = (result->cur_mask_ | new_mask); \ } else { \ /* YYACCEPT; */ \ } \ } \ - if ((result->cur_mask_ & result->target_mask_) == result->target_mask_) { \ - /* YYACCEPT; */ \ - } \ } \ } while(0) \ @@ -428,6 +431,92 @@ static inline void add_relation(ObExprParseResult *result, } } +static inline void set_relation_part_with_column_idx(int64_t idx_in_schema_columns, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(level) && OB_ISNULL(first_part_column_idx) && + OB_ISNULL(second_part_column_idx) && OB_ISNULL(result)) { + // do nothing + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (idx_in_schema_columns == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + +static inline void set_relation_part_with_column_name(ObProxyParseString *column, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(column) + || OB_ISNULL(result) + || OB_ISNULL(level) + || OB_ISNULL(first_part_column_idx) + || OB_ISNULL(second_part_column_idx)) { + // do nothing + } else if (result->has_rowid_ + && is_equal_to_rowid(column)) { + // handle rowid + *level = PART_KEY_LEVEL_ONE; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + if (is_equal(&result->part_key_info_.part_keys_[i].name_, column)) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *left_value, @@ -438,25 +527,25 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *tmp_left = NULL; ObProxyTokenList *tmp_right = NULL; ObProxyFunctionType tmp_type = F_NONE; - ObProxyPartKeyLevel tmp_level = PART_KEY_LEVEL_ZERO; int64_t tmp_column_idx_ = -1; + ObProxyParseString *tmp_column = NULL; if (NULL != left_value->column_node_ && TOKEN_COLUMN == left_value->column_node_->type_ && left_value->column_node_->part_key_idx_ >= 0) { tmp_left = left_value; - tmp_level = result->part_key_info_.part_keys_[left_value->column_node_->part_key_idx_].level_; tmp_right = right_value; tmp_type = type; tmp_column_idx_ = left_value->column_node_->part_key_idx_; + tmp_column = &left_value->column_node_->column_name_; } else if (NULL != right_value->column_node_ && TOKEN_COLUMN == right_value->column_node_->type_ && right_value->column_node_->part_key_idx_ >= 0) { tmp_left = right_value; - tmp_level = result->part_key_info_.part_keys_[right_value->column_node_->part_key_idx_].level_; tmp_right = left_value; tmp_type = get_reverse_func(type); tmp_column_idx_ = right_value->column_node_->part_key_idx_; + tmp_column = &right_value->column_node_->column_name_; } if (NULL == tmp_left || NULL == tmp_right || F_COMP_NE == tmp_type) { @@ -469,7 +558,11 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, relation->left_value_ = tmp_left; relation->type_ = tmp_type; relation->right_value_ = tmp_right; - relation->level_ = tmp_level; + set_relation_part_with_column_name(tmp_column, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } return relation; } @@ -483,14 +576,20 @@ static inline ObProxyRelationExpr *get_values_relation(ObExprParseResult *result } else { int64_t i = 0; for (i = 0; i < result->part_key_info_.key_num_; ++i) { - if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { if (OB_ISNULL(relation = ((ObProxyRelationExpr *)obproxy_parse_malloc( sizeof(ObProxyRelationExpr), result->malloc_pool_)))) { } else { relation->column_idx_ = i; relation->type_ = F_COMP_EQ; relation->right_value_ = right_value; - relation->level_ = result->part_key_info_.part_keys_[i].level_; + relation->left_value_ = NULL; + set_relation_part_with_column_idx(result->values_list_idx_, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } break; } @@ -752,20 +851,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 17 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 231 +#define YYLAST 242 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 44 +#define YYNTOKENS 48 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 24 /* YYNRULES -- Number of rules. */ -#define YYNRULES 80 +#define YYNRULES 83 /* YYNRULES -- Number of states. */ -#define YYNSTATES 144 +#define YYNSTATES 149 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 286 +#define YYMAXUTOK 290 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -776,9 +875,9 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 43, 2, 2, 2, 41, 42, 2, - 35, 32, 39, 37, 36, 38, 34, 40, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, + 2, 2, 2, 47, 2, 2, 2, 45, 46, 2, + 39, 36, 43, 41, 40, 42, 38, 44, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -801,7 +900,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35 }; #if YYDEBUG @@ -812,57 +912,58 @@ static const yytype_uint16 yyprhs[] = 0, 0, 3, 6, 9, 13, 16, 21, 23, 25, 27, 29, 31, 33, 36, 40, 43, 48, 52, 57, 63, 70, 72, 76, 82, 86, 92, 96, 102, 108, - 114, 120, 122, 124, 126, 128, 130, 132, 134, 136, - 140, 142, 144, 147, 148, 152, 156, 158, 160, 164, - 170, 175, 180, 182, 184, 186, 188, 190, 192, 194, - 196, 198, 200, 202, 204, 209, 214, 218, 220, 224, - 230, 231, 235, 237, 241, 243, 245, 249, 251, 255, - 256 + 114, 120, 124, 129, 131, 133, 135, 137, 139, 141, + 143, 145, 149, 151, 153, 156, 157, 161, 165, 167, + 169, 173, 179, 181, 186, 191, 193, 195, 197, 199, + 201, 203, 205, 207, 209, 211, 213, 215, 220, 225, + 229, 231, 235, 241, 242, 246, 248, 252, 254, 256, + 260, 262, 266, 267 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 45, 0, -1, 3, 46, -1, 4, 60, -1, 5, - 51, 47, -1, 48, 47, -1, 48, 5, 51, 47, - -1, 1, -1, 9, -1, 32, -1, 33, -1, 24, - -1, 49, -1, 48, 49, -1, 50, 14, 51, -1, - 10, 27, -1, 10, 27, 34, 27, -1, 10, 27, - 27, -1, 10, 27, 6, 27, -1, 10, 27, 34, - 27, 27, -1, 10, 27, 34, 27, 6, 27, -1, - 52, -1, 51, 11, 52, -1, 35, 51, 11, 52, - 32, -1, 51, 12, 52, -1, 35, 51, 12, 52, - 32, -1, 55, 53, 55, -1, 55, 53, 35, 55, - 32, -1, 35, 55, 53, 55, 32, -1, 55, 13, - 35, 54, 32, -1, 55, 15, 55, 11, 55, -1, - 16, -1, 17, -1, 18, -1, 19, -1, 20, -1, - 21, -1, 22, -1, 55, -1, 54, 36, 55, -1, - 56, -1, 58, -1, 56, 58, -1, -1, 56, 36, - 56, -1, 57, 36, 56, -1, 29, -1, 27, -1, - 27, 34, 27, -1, 27, 34, 27, 34, 27, -1, - 27, 35, 56, 32, -1, 27, 35, 57, 32, -1, - 30, -1, 28, -1, 59, -1, 23, -1, 31, -1, - 37, -1, 38, -1, 39, -1, 40, -1, 41, -1, - 42, -1, 43, -1, 62, 7, 61, 47, -1, 8, - 66, 67, 47, -1, 14, 51, 47, -1, 46, -1, - 35, 65, 32, -1, 61, 36, 35, 65, 32, -1, - -1, 35, 63, 32, -1, 64, -1, 63, 36, 64, - -1, 27, -1, 55, -1, 65, 36, 55, -1, 52, - -1, 66, 36, 52, -1, -1, 5, 51, -1 + 49, 0, -1, 3, 50, -1, 4, 64, -1, 5, + 55, 51, -1, 52, 51, -1, 52, 5, 55, 51, + -1, 1, -1, 9, -1, 36, -1, 37, -1, 27, + -1, 53, -1, 52, 53, -1, 54, 14, 55, -1, + 10, 30, -1, 10, 30, 38, 30, -1, 10, 30, + 30, -1, 10, 30, 6, 30, -1, 10, 30, 38, + 30, 30, -1, 10, 30, 38, 30, 6, 30, -1, + 56, -1, 55, 11, 56, -1, 39, 55, 11, 56, + 36, -1, 55, 12, 56, -1, 39, 55, 12, 56, + 36, -1, 59, 57, 59, -1, 59, 57, 39, 59, + 36, -1, 39, 59, 57, 59, 36, -1, 59, 13, + 39, 58, 36, -1, 59, 15, 59, 11, 59, -1, + 59, 16, 17, -1, 59, 16, 18, 17, -1, 19, + -1, 20, -1, 21, -1, 22, -1, 23, -1, 24, + -1, 25, -1, 59, -1, 58, 40, 59, -1, 60, + -1, 62, -1, 60, 62, -1, -1, 60, 40, 60, + -1, 61, 40, 60, -1, 32, -1, 30, -1, 30, + 38, 30, -1, 30, 38, 30, 38, 30, -1, 33, + -1, 30, 39, 60, 36, -1, 30, 39, 61, 36, + -1, 34, -1, 31, -1, 63, -1, 26, -1, 35, + -1, 41, -1, 42, -1, 43, -1, 44, -1, 45, + -1, 46, -1, 47, -1, 66, 7, 65, 51, -1, + 8, 70, 71, 51, -1, 14, 55, 51, -1, 50, + -1, 39, 69, 36, -1, 65, 40, 39, 69, 36, + -1, -1, 39, 67, 36, -1, 68, -1, 67, 40, + 68, -1, 30, -1, 59, -1, 69, 40, 59, -1, + 56, -1, 70, 40, 56, -1, -1, 5, 55, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 380, 380, 381, 383, 384, 385, 386, 388, 389, - 390, 391, 393, 394, 396, 398, 399, 400, 401, 402, - 403, 405, 406, 407, 408, 409, 411, 412, 413, 414, - 415, 426, 427, 428, 429, 430, 431, 432, 434, 435, - 437, 439, 440, 442, 443, 444, 447, 454, 460, 466, - 472, 478, 484, 485, 486, 487, 493, 499, 500, 501, - 502, 503, 504, 505, 507, 508, 509, 510, 512, 516, - 521, 522, 527, 531, 536, 542, 552, 562, 563, 565, - 566 + 0, 475, 475, 476, 478, 479, 480, 481, 483, 484, + 485, 486, 488, 489, 491, 493, 494, 495, 496, 497, + 498, 500, 501, 502, 503, 504, 506, 507, 508, 509, + 510, 520, 521, 523, 524, 525, 526, 527, 528, 529, + 531, 532, 534, 536, 537, 539, 540, 541, 544, 551, + 557, 563, 569, 574, 580, 586, 587, 588, 589, 595, + 601, 602, 603, 604, 605, 606, 607, 609, 610, 611, + 612, 614, 618, 623, 624, 629, 633, 638, 644, 654, + 664, 665, 667, 668 }; #endif @@ -873,13 +974,14 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "DUMMY_SELECT_CLAUSE", "DUMMY_INSERT_CLAUSE", "WHERE", "AS", "VALUES", "SET", "END_WHERE", - "JOIN", "AND_OP", "OR_OP", "IN", "ON", "BETWEEN", "COMP_EQ", "COMP_NSEQ", - "COMP_GE", "COMP_GT", "COMP_LE", "COMP_LT", "COMP_NE", "PLACE_HOLDER", - "END_P", "ERROR", "IGNORED_WORD", "NAME_OB", "STR_VAL", "ROW_ID", - "INT_VAL", "POS_PLACE_HOLDER", "')'", "';'", "'.'", "'('", "','", "'+'", - "'-'", "'*'", "'/'", "'%'", "'&'", "'!'", "$accept", "start", - "select_root", "end_flag", "join_expr_list", "join_on_expr", "join_expr", - "cond_expr", "bool_pri", "comp", "in_expr_list", "expr", "token_list", + "JOIN", "AND_OP", "OR_OP", "IN", "ON", "BETWEEN", "IS", "TOKEN_NULL", + "NOT", "COMP_EQ", "COMP_NSEQ", "COMP_GE", "COMP_GT", "COMP_LE", + "COMP_LT", "COMP_NE", "PLACE_HOLDER", "END_P", "ERROR", "IGNORED_WORD", + "NAME_OB", "STR_VAL", "ROW_ID", "REVERSED_EXPR_FUNC", "INT_VAL", + "POS_PLACE_HOLDER", "')'", "';'", "'.'", "'('", "','", "'+'", "'-'", + "'*'", "'/'", "'%'", "'&'", "'!'", "$accept", "start", "select_root", + "end_flag", "join_expr_list", "join_on_expr", "join_expr", "cond_expr", + "bool_pri", "comp", "in_expr_list", "expr", "token_list", "func_param_list", "token", "operator", "insert_root", "values_expr_lists", "opt_column_list", "column_list", "opt_column", "values_expr_list", "set_expr", "opt_where_clause", 0 @@ -894,23 +996,23 @@ static const yytype_uint16 yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 41, 59, 46, 40, 44, 43, 45, 42, - 47, 37, 38, 33 + 285, 286, 287, 288, 289, 290, 41, 59, 46, 40, + 44, 43, 45, 42, 47, 37, 38, 33 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 44, 45, 45, 46, 46, 46, 46, 47, 47, - 47, 47, 48, 48, 49, 50, 50, 50, 50, 50, - 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, - 52, 53, 53, 53, 53, 53, 53, 53, 54, 54, - 55, 56, 56, 57, 57, 57, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, - 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, - 62, 62, 63, 63, 64, 65, 65, 66, 66, 67, - 67 + 0, 48, 49, 49, 50, 50, 50, 50, 51, 51, + 51, 51, 52, 52, 53, 54, 54, 54, 54, 54, + 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, + 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, + 58, 58, 59, 60, 60, 61, 61, 61, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, + 64, 65, 65, 66, 66, 67, 67, 68, 69, 69, + 70, 70, 71, 71 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -919,12 +1021,12 @@ static const yytype_uint8 yyr2[] = 0, 2, 2, 2, 3, 2, 4, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 4, 5, 6, 1, 3, 5, 3, 5, 3, 5, 5, 5, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 1, 1, 2, 0, 3, 3, 1, 1, 3, 5, - 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 4, 3, 1, 3, 5, - 0, 3, 1, 3, 1, 1, 3, 1, 3, 0, - 2 + 5, 3, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 2, 0, 3, 3, 1, 1, + 3, 5, 1, 4, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 4, 4, 3, + 1, 3, 5, 0, 3, 1, 3, 1, 1, 3, + 1, 3, 0, 2 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -933,140 +1035,142 @@ static const yytype_uint8 yyr2[] = static const yytype_uint8 yydefact[] = { 0, 0, 0, 0, 7, 0, 0, 2, 0, 12, - 0, 0, 0, 0, 67, 3, 0, 1, 55, 47, - 53, 46, 52, 56, 0, 57, 58, 59, 60, 61, - 62, 63, 0, 21, 0, 40, 41, 54, 15, 0, - 8, 11, 9, 10, 5, 13, 0, 0, 77, 79, - 0, 74, 0, 72, 0, 0, 43, 0, 0, 0, - 0, 4, 0, 0, 31, 32, 33, 34, 35, 36, - 37, 0, 42, 0, 17, 0, 0, 14, 0, 0, - 0, 0, 66, 71, 0, 0, 0, 48, 0, 0, - 0, 0, 0, 22, 24, 0, 0, 0, 26, 18, - 16, 6, 0, 80, 78, 65, 73, 75, 0, 0, - 64, 0, 50, 0, 51, 0, 22, 24, 26, 0, - 38, 0, 0, 0, 19, 0, 68, 0, 0, 49, - 44, 45, 23, 25, 28, 29, 0, 30, 27, 20, - 76, 0, 39, 69 + 0, 0, 0, 0, 70, 3, 0, 1, 58, 49, + 56, 48, 52, 55, 59, 0, 60, 61, 62, 63, + 64, 65, 66, 0, 21, 0, 42, 43, 57, 15, + 0, 8, 11, 9, 10, 5, 13, 0, 0, 80, + 82, 0, 77, 0, 75, 0, 0, 45, 0, 0, + 0, 0, 4, 0, 0, 0, 33, 34, 35, 36, + 37, 38, 39, 0, 44, 0, 17, 0, 0, 14, + 0, 0, 0, 0, 69, 74, 0, 0, 0, 50, + 0, 0, 0, 0, 0, 22, 24, 0, 0, 31, + 0, 0, 26, 18, 16, 6, 0, 83, 81, 68, + 76, 78, 0, 0, 67, 0, 53, 0, 54, 0, + 22, 24, 26, 0, 40, 0, 32, 0, 0, 19, + 0, 71, 0, 0, 51, 46, 47, 23, 25, 28, + 29, 0, 30, 27, 20, 79, 0, 41, 72 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 3, 7, 44, 8, 9, 10, 32, 33, 71, - 119, 34, 35, 89, 36, 37, 15, 86, 16, 52, - 53, 108, 49, 81 + -1, 3, 7, 45, 8, 9, 10, 33, 34, 73, + 123, 35, 36, 91, 37, 38, 15, 88, 16, 53, + 54, 112, 50, 83 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -52 +#define YYPACT_NINF -54 static const yytype_int16 yypact[] = { - 41, 16, 1, 13, -52, 108, -9, -52, 22, -52, - 14, 129, 108, 6, -52, -52, 33, -52, -52, 31, - -52, -52, -52, -52, 108, -52, -52, -52, -52, -52, - -52, -52, 76, -52, 202, 171, -52, -52, 8, 108, - -52, -52, -52, -52, -52, -52, 108, 171, -52, 7, - 76, -52, -12, -52, 3, 24, 171, 84, 202, 129, - 129, -52, 25, 171, -52, -52, -52, -52, -52, -52, - -52, 150, -52, 30, -52, 45, 76, 90, 209, 108, - 129, 60, -52, -52, 6, 171, 43, 49, 87, -7, - 129, 129, 150, -52, -52, 171, 66, 171, -52, -52, - 10, -52, 171, 90, -52, -52, -52, -52, 27, 54, - -52, 64, -52, 171, -52, 171, 73, 74, 75, 50, - -52, 171, 79, 86, -52, 75, -52, 171, 171, -52, - 171, 171, -52, -52, -52, -52, 171, -52, -52, -52, - -52, 58, -52, -52 + 16, 77, 8, 7, -54, 109, -5, -54, 22, -54, + 24, 131, 109, 38, -54, -54, 44, -54, -54, 6, + -54, -54, -54, -54, -54, 109, -54, -54, -54, -54, + -54, -54, -54, 68, -54, 210, 175, -54, -54, 5, + 109, -54, -54, -54, -54, -54, -54, 109, 175, -54, + 0, 68, -54, -28, -54, 15, 43, 175, 79, 210, + 131, 131, -54, 36, 175, 75, -54, -54, -54, -54, + -54, -54, -54, 153, -54, 53, -54, 56, 68, 85, + 217, 109, 131, 62, -54, -54, 38, 175, -3, 50, + 87, -10, 131, 131, 153, -54, -54, 175, 83, -54, + 86, 175, -54, -54, 11, -54, 175, 85, -54, -54, + -54, -54, 10, 67, -54, 80, -54, 175, -54, 175, + 73, 76, 78, 21, -54, 175, -54, 88, 81, -54, + 78, -54, 175, 175, -54, 175, 175, -54, -54, -54, + -54, 175, -54, -54, -54, -54, 27, -54, -54 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -52, -52, 118, -28, -52, 113, -52, -5, -10, -48, - -52, -24, -51, -52, -32, -52, -52, -52, -52, -52, - 38, 4, -52, -52 + -54, -54, 113, -23, -54, 117, -54, -11, -8, -38, + -54, -25, -53, -54, -34, -54, -54, -54, -54, -54, + 40, 3, -54, -54 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -71 +#define YYTABLE_NINF -74 static const yytype_int16 yytable[] = { - 58, 48, 4, 72, 61, 88, 5, 50, -70, 11, - 92, 6, 79, 17, 73, 12, 123, 4, 38, 57, - 83, 5, 82, 78, 84, 114, 6, 39, 46, 115, - 102, 40, 6, 51, 76, 74, 13, 124, 85, 96, - 54, 77, 75, 80, 1, 2, 41, 98, 101, 93, - 94, 87, 40, 105, 42, 43, 72, 99, 110, 126, - 95, 107, 130, 127, 131, 55, 56, 41, 118, 40, - 104, 120, 100, 122, 103, 42, 43, 121, 125, 109, - 116, 117, 135, 111, 41, 40, 136, 59, 60, 128, - 143, 129, 42, 43, 127, 90, 91, 137, 72, 72, - 41, 59, 60, 140, 107, 132, 133, 134, 42, 43, - 18, 138, 142, 139, 19, 20, 21, 22, 23, 112, - 14, 45, 106, 113, 25, 26, 27, 28, 29, 30, - 31, 18, 141, 0, 0, 19, 20, 21, 22, 23, - 0, 0, 0, 24, 0, 25, 26, 27, 28, 29, - 30, 31, 18, 0, 0, 0, 19, 20, 21, 22, - 23, 0, 0, 0, 47, 0, 25, 26, 27, 28, - 29, 30, 31, 18, 0, 0, 0, 19, 20, 21, - 22, 23, 0, 0, 0, 97, 0, 25, 26, 27, - 28, 29, 30, 31, 18, 0, 0, 0, 19, 20, - 21, 22, 23, 0, 0, 0, 0, 0, 25, 26, - 27, 28, 29, 30, 31, 62, 0, 63, 64, 65, - 66, 67, 68, 69, 70, 64, 65, 66, 67, 68, - 69, 70 + 59, 51, 74, 49, 90, 81, 41, 17, 85, 4, + 62, 75, 86, 5, 58, -73, 11, 128, 6, 1, + 2, 94, 12, 80, 42, 39, 118, 40, 84, 78, + 119, 41, 6, 43, 44, 76, 79, 113, 47, 98, + 82, 129, 106, 77, 56, 57, 131, 13, 102, 42, + 132, 55, 95, 96, 87, 105, 74, 140, 43, 44, + 109, 141, 111, 148, 135, 114, 136, 132, 52, 122, + 107, 41, 124, 89, 108, 97, 127, 41, 4, 60, + 61, 130, 5, 103, 120, 121, 104, 6, 115, 42, + 92, 93, 99, 100, 125, 42, 60, 61, 43, 44, + 142, 74, 74, 126, 43, 44, 133, 145, 111, 137, + 134, 144, 138, 18, 139, 14, 147, 19, 20, 21, + 22, 23, 24, 116, 143, 46, 110, 117, 26, 27, + 28, 29, 30, 31, 32, 18, 146, 0, 0, 19, + 20, 21, 22, 23, 24, 0, 0, 0, 25, 0, + 26, 27, 28, 29, 30, 31, 32, 18, 0, 0, + 0, 19, 20, 21, 22, 23, 24, 0, 0, 0, + 48, 0, 26, 27, 28, 29, 30, 31, 32, 18, + 0, 0, 0, 19, 20, 21, 22, 23, 24, 0, + 0, 0, 101, 0, 26, 27, 28, 29, 30, 31, + 32, 18, 0, 0, 0, 19, 20, 21, 22, 23, + 24, 0, 0, 0, 0, 0, 26, 27, 28, 29, + 30, 31, 32, 63, 0, 64, 65, 0, 0, 66, + 67, 68, 69, 70, 71, 72, 66, 67, 68, 69, + 70, 71, 72 }; static const yytype_int16 yycheck[] = { - 24, 11, 1, 35, 32, 56, 5, 12, 7, 8, - 58, 10, 5, 0, 6, 14, 6, 1, 27, 24, - 32, 5, 50, 47, 36, 32, 10, 5, 14, 36, - 78, 9, 10, 27, 39, 27, 35, 27, 35, 63, - 7, 46, 34, 36, 3, 4, 24, 71, 76, 59, - 60, 27, 9, 81, 32, 33, 88, 27, 86, 32, - 35, 85, 113, 36, 115, 34, 35, 24, 92, 9, - 80, 95, 27, 97, 79, 32, 33, 11, 102, 36, - 90, 91, 32, 34, 24, 9, 36, 11, 12, 35, - 32, 27, 32, 33, 36, 11, 12, 121, 130, 131, - 24, 11, 12, 127, 128, 32, 32, 32, 32, 33, - 23, 32, 136, 27, 27, 28, 29, 30, 31, 32, - 2, 8, 84, 36, 37, 38, 39, 40, 41, 42, - 43, 23, 128, -1, -1, 27, 28, 29, 30, 31, - -1, -1, -1, 35, -1, 37, 38, 39, 40, 41, - 42, 43, 23, -1, -1, -1, 27, 28, 29, 30, - 31, -1, -1, -1, 35, -1, 37, 38, 39, 40, - 41, 42, 43, 23, -1, -1, -1, 27, 28, 29, - 30, 31, -1, -1, -1, 35, -1, 37, 38, 39, - 40, 41, 42, 43, 23, -1, -1, -1, 27, 28, - 29, 30, 31, -1, -1, -1, -1, -1, 37, 38, - 39, 40, 41, 42, 43, 13, -1, 15, 16, 17, - 18, 19, 20, 21, 22, 16, 17, 18, 19, 20, - 21, 22 + 25, 12, 36, 11, 57, 5, 9, 0, 36, 1, + 33, 6, 40, 5, 25, 7, 8, 6, 10, 3, + 4, 59, 14, 48, 27, 30, 36, 5, 51, 40, + 40, 9, 10, 36, 37, 30, 47, 40, 14, 64, + 40, 30, 80, 38, 38, 39, 36, 39, 73, 27, + 40, 7, 60, 61, 39, 78, 90, 36, 36, 37, + 83, 40, 87, 36, 117, 88, 119, 40, 30, 94, + 81, 9, 97, 30, 82, 39, 101, 9, 1, 11, + 12, 106, 5, 30, 92, 93, 30, 10, 38, 27, + 11, 12, 17, 18, 11, 27, 11, 12, 36, 37, + 125, 135, 136, 17, 36, 37, 39, 132, 133, 36, + 30, 30, 36, 26, 36, 2, 141, 30, 31, 32, + 33, 34, 35, 36, 36, 8, 86, 40, 41, 42, + 43, 44, 45, 46, 47, 26, 133, -1, -1, 30, + 31, 32, 33, 34, 35, -1, -1, -1, 39, -1, + 41, 42, 43, 44, 45, 46, 47, 26, -1, -1, + -1, 30, 31, 32, 33, 34, 35, -1, -1, -1, + 39, -1, 41, 42, 43, 44, 45, 46, 47, 26, + -1, -1, -1, 30, 31, 32, 33, 34, 35, -1, + -1, -1, 39, -1, 41, 42, 43, 44, 45, 46, + 47, 26, -1, -1, -1, 30, 31, 32, 33, 34, + 35, -1, -1, -1, -1, -1, 41, 42, 43, 44, + 45, 46, 47, 13, -1, 15, 16, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, + 23, 24, 25 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 45, 1, 5, 10, 46, 48, 49, - 50, 8, 14, 35, 46, 60, 62, 0, 23, 27, - 28, 29, 30, 31, 35, 37, 38, 39, 40, 41, - 42, 43, 51, 52, 55, 56, 58, 59, 27, 5, - 9, 24, 32, 33, 47, 49, 14, 35, 52, 66, - 51, 27, 63, 64, 7, 34, 35, 51, 55, 11, - 12, 47, 13, 15, 16, 17, 18, 19, 20, 21, - 22, 53, 58, 6, 27, 34, 51, 51, 55, 5, - 36, 67, 47, 32, 36, 35, 61, 27, 56, 57, - 11, 12, 53, 52, 52, 35, 55, 35, 55, 27, - 27, 47, 53, 51, 52, 47, 64, 55, 65, 36, - 47, 34, 32, 36, 32, 36, 52, 52, 55, 54, - 55, 11, 55, 6, 27, 55, 32, 36, 35, 27, - 56, 56, 32, 32, 32, 32, 36, 55, 32, 27, - 55, 65, 55, 32 + 0, 3, 4, 49, 1, 5, 10, 50, 52, 53, + 54, 8, 14, 39, 50, 64, 66, 0, 26, 30, + 31, 32, 33, 34, 35, 39, 41, 42, 43, 44, + 45, 46, 47, 55, 56, 59, 60, 62, 63, 30, + 5, 9, 27, 36, 37, 51, 53, 14, 39, 56, + 70, 55, 30, 67, 68, 7, 38, 39, 55, 59, + 11, 12, 51, 13, 15, 16, 19, 20, 21, 22, + 23, 24, 25, 57, 62, 6, 30, 38, 55, 55, + 59, 5, 40, 71, 51, 36, 40, 39, 65, 30, + 60, 61, 11, 12, 57, 56, 56, 39, 59, 17, + 18, 39, 59, 30, 30, 51, 57, 55, 56, 51, + 68, 59, 69, 40, 51, 38, 36, 40, 36, 40, + 56, 56, 59, 58, 59, 11, 17, 59, 6, 30, + 59, 36, 40, 39, 30, 60, 60, 36, 36, 36, + 36, 40, 59, 36, 30, 59, 69, 59, 36 }; #define yyerrok (yyerrstatus = 0) @@ -2003,47 +2107,47 @@ YYLTYPE yylloc; case 31: - { (yyval.func) = F_COMP_EQ; ;} + { (yyval.relation) = NULL; ;} break; case 32: - { (yyval.func) = F_COMP_NSEQ; ;} + { (yyval.relation) = NULL; ;} break; case 33: - { (yyval.func) = F_COMP_GE; ;} + { (yyval.func) = F_COMP_EQ; ;} break; case 34: - { (yyval.func) = F_COMP_GT; ;} + { (yyval.func) = F_COMP_NSEQ; ;} break; case 35: - { (yyval.func) = F_COMP_LE; ;} + { (yyval.func) = F_COMP_GE; ;} break; case 36: - { (yyval.func) = F_COMP_LT; ;} + { (yyval.func) = F_COMP_GT; ;} break; case 37: - { (yyval.func) = F_COMP_NE; ;} + { (yyval.func) = F_COMP_LE; ;} break; case 38: - { (yyval.list) = (yyvsp[(1) - (1)].list); ;} + { (yyval.func) = F_COMP_LT; ;} break; case 39: - { (yyval.list) = (yyvsp[(1) - (3)].list); add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} + { (yyval.func) = F_COMP_NE; ;} break; case 40: @@ -2053,31 +2157,41 @@ YYLTYPE yylloc; case 41: - { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); ;} + { (yyval.list) = (yyvsp[(1) - (3)].list); add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; case 42: - { add_token((yyvsp[(1) - (2)].list), result, (yyvsp[(2) - (2)].node)); (yyval.list) = (yyvsp[(1) - (2)].list); ;} + { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; case 43: - { (yyval.list) = NULL; ;} + { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); ;} break; case 44: - { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + { add_token((yyvsp[(1) - (2)].list), result, (yyvsp[(2) - (2)].node)); (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; case 45: - { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + { (yyval.list) = NULL; ;} break; case 46: + { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + break; + + case 47: + + { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + break; + + case 48: + { malloc_node((yyval.node), result, TOKEN_COLUMN); (yyval.node)->part_key_idx_ = 0; @@ -2086,7 +2200,7 @@ YYLTYPE yylloc; ;} break; - case 47: + case 49: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2095,7 +2209,7 @@ YYLTYPE yylloc; ;} break; - case 48: + case 50: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2104,7 +2218,7 @@ YYLTYPE yylloc; ;} break; - case 49: + case 51: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2113,7 +2227,15 @@ YYLTYPE yylloc; ;} break; - case 50: + case 52: + + { + malloc_node((yyval.node), result, TOKEN_FUNC); + (yyval.node)->str_value_ = (yyvsp[(1) - (1)].str); + ;} + break; + + case 53: { malloc_node((yyval.node), result, TOKEN_FUNC); @@ -2122,7 +2244,7 @@ YYLTYPE yylloc; ;} break; - case 51: + case 54: { malloc_node((yyval.node), result, TOKEN_FUNC); @@ -2131,22 +2253,22 @@ YYLTYPE yylloc; ;} break; - case 52: + case 55: { malloc_node((yyval.node), result, TOKEN_INT_VAL); (yyval.node)->int_value_ = (yyvsp[(1) - (1)].num); ;} break; - case 53: + case 56: { malloc_node((yyval.node), result, TOKEN_STR_VAL); (yyval.node)->str_value_ = (yyvsp[(1) - (1)].str); ;} break; - case 54: + case 57: { malloc_node((yyval.node), result, TOKEN_OPERATOR); (yyval.node)->operator_ = (yyvsp[(1) - (1)].operator); ;} break; - case 55: + case 58: { result->placeholder_list_idx_++; @@ -2155,7 +2277,7 @@ YYLTYPE yylloc; ;} break; - case 56: + case 59: { malloc_node((yyval.node), result, TOKEN_PLACE_HOLDER); @@ -2163,71 +2285,76 @@ YYLTYPE yylloc; ;} break; - case 57: + case 60: { (yyval.operator) = OPT_ADD; ;} break; - case 58: + case 61: { (yyval.operator) = OPT_MINUS; ;} break; - case 59: + case 62: { (yyval.operator) = OPT_MUL; ;} break; - case 60: + case 63: { (yyval.operator) = OPT_DIV; ;} break; - case 61: + case 64: { (yyval.operator) = OPT_MOD; ;} break; - case 62: + case 65: { (yyval.operator) = OPT_AND; ;} break; - case 63: + case 66: { (yyval.operator) = OPT_NOT; ;} break; - case 64: + case 67: { YYACCEPT; ;} break; - case 65: + case 68: { YYACCEPT; ;} break; - case 66: + case 69: { YYACCEPT; ;} break; - case 68: + case 71: { result->multi_param_values_++; ;} break; - case 69: + case 72: { result->multi_param_values_++; ;} break; - case 72: + case 73: + + { init_part_key_all_match(result);;} + break; + + case 75: { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); @@ -2235,7 +2362,7 @@ YYLTYPE yylloc; ;} break; - case 73: + case 76: { malloc_list((yyval.list), result, (yyvsp[(3) - (3)].node)); @@ -2243,7 +2370,7 @@ YYLTYPE yylloc; ;} break; - case 74: + case 77: { set_part_key_column_idx(result, &(yyvsp[(1) - (1)].str)); @@ -2253,7 +2380,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 78: { if (result->multi_param_values_ < 1) { @@ -2266,7 +2393,7 @@ YYLTYPE yylloc; ;} break; - case 76: + case 79: { if (result->multi_param_values_ < 1) { @@ -2278,17 +2405,17 @@ YYLTYPE yylloc; ;} break; - case 77: + case 80: { check_and_add_relation(result, (yyvsp[(1) - (1)].relation)); ;} break; - case 78: + case 81: { check_and_add_relation(result, (yyvsp[(3) - (3)].relation)); ;} break; - case 80: + case 83: {;} break; diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.h b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.h index 8c63ec12..9c8c5a66 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.h @@ -69,22 +69,26 @@ extern int ob_expr_parser_gbk_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c index 59356d32..c9ed9c7b 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 57 -#define YY_END_OF_BUFFER 58 +#define YY_NUM_RULES 61 +#define YY_END_OF_BUFFER 62 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,30 +357,38 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[197] = +static yyconst flex_int16_t yy_accept[279] = { 0, - 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, - 58, 56, 31, 31, 35, 46, 31, 30, 35, 35, - 40, 33, 34, 35, 32, 35, 35, 35, 28, 35, - 24, 19, 22, 26, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 52, 35, 56, - 56, 39, 38, 39, 41, 42, 57, 47, 48, 57, - 54, 55, 31, 0, 25, 31, 30, 15, 28, 0, - 0, 28, 29, 36, 29, 28, 30, 0, 27, 23, - 21, 30, 2, 30, 30, 30, 30, 18, 30, 30, - 12, 16, 30, 30, 30, 30, 17, 0, 0, 0, - - 37, 41, 0, 0, 43, 0, 0, 44, 47, 0, - 49, 0, 0, 0, 50, 54, 53, 31, 0, 0, - 0, 29, 0, 0, 29, 20, 14, 30, 6, 30, - 30, 30, 30, 30, 5, 30, 30, 33, 34, 32, - 45, 0, 45, 0, 0, 51, 0, 51, 0, 0, - 31, 31, 31, 0, 29, 0, 29, 0, 29, 30, - 30, 30, 11, 30, 30, 30, 30, 0, 0, 0, - 0, 31, 30, 8, 30, 7, 10, 4, 1, 0, - 0, 45, 0, 0, 0, 0, 51, 0, 0, 30, - 9, 3, 0, 0, 13, 0 - + 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 60, 35, 35, 39, 50, 35, 34, 39, 39, + 44, 37, 38, 39, 36, 39, 39, 39, 32, 39, + 27, 22, 25, 29, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 56, 39, + 60, 60, 43, 42, 43, 45, 46, 61, 51, 52, + 61, 58, 59, 35, 0, 28, 35, 34, 15, 32, + 0, 0, 32, 33, 40, 33, 32, 34, 0, 30, + 26, 24, 34, 2, 34, 34, 34, 34, 18, 19, + 34, 34, 34, 34, 12, 16, 34, 34, 34, 34, + + 34, 17, 0, 0, 0, 41, 45, 0, 0, 47, + 0, 0, 48, 51, 0, 53, 0, 0, 0, 54, + 58, 57, 32, 35, 0, 32, 0, 0, 33, 0, + 32, 0, 33, 30, 23, 14, 34, 6, 34, 34, + 34, 34, 21, 34, 34, 5, 34, 34, 34, 37, + 38, 36, 49, 0, 49, 0, 0, 55, 0, 55, + 0, 0, 32, 35, 35, 35, 0, 32, 33, 0, + 33, 0, 33, 32, 30, 34, 34, 34, 11, 34, + 20, 34, 34, 34, 34, 0, 0, 0, 0, 32, + 35, 32, 32, 30, 34, 8, 34, 7, 10, 34, + + 4, 1, 0, 0, 49, 0, 0, 0, 0, 55, + 0, 0, 32, 32, 32, 30, 34, 9, 34, 3, + 0, 0, 32, 32, 32, 30, 13, 31, 32, 32, + 32, 30, 32, 32, 32, 30, 32, 32, 32, 30, + 32, 32, 32, 30, 32, 32, 32, 30, 32, 32, + 32, 30, 32, 32, 32, 30, 32, 32, 32, 30, + 32, 32, 32, 30, 32, 32, 32, 30, 32, 32, + 33, 30, 33, 33, 33, 33, 33, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -393,167 +401,204 @@ static yyconst flex_int32_t yy_ec[256] = 20, 20, 20, 20, 20, 20, 20, 21, 9, 22, 23, 24, 25, 9, 26, 27, 8, 28, 29, 30, 31, 32, 33, 34, 8, 35, 36, 37, 38, 39, - 8, 40, 41, 42, 43, 44, 45, 8, 8, 8, - 1, 46, 1, 9, 8, 47, 48, 49, 8, 50, + 8, 40, 41, 42, 43, 44, 45, 8, 46, 8, + 1, 47, 1, 9, 8, 48, 49, 50, 8, 51, - 51, 52, 53, 54, 55, 56, 8, 57, 58, 59, - 60, 61, 8, 62, 63, 64, 65, 66, 67, 8, - 8, 8, 1, 68, 1, 9, 1, 69, 1, 1, - 1, 1, 1, 1, 1, 70, 71, 1, 1, 72, + 52, 53, 54, 55, 56, 57, 8, 58, 59, 60, + 61, 62, 8, 63, 64, 65, 66, 67, 68, 8, + 69, 8, 1, 70, 1, 9, 1, 71, 1, 1, + 1, 1, 1, 1, 1, 72, 73, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 73, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 74, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 75, 1, + 1, 1, 1, 1, 1, 1, 76, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[76] = +static yyconst flex_int32_t yy_meta[78] = { 0, 1, 1, 2, 2, 1, 3, 1, 4, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 6, 7, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, - 1, 1, 1, 1, 1 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, + 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[213] = +static yyconst flex_int16_t yy_base[295] = { 0, - 0, 0, 73, 74, 67, 68, 74, 75, 330, 329, - 375, 517, 80, 87, 351, 517, 0, 0, 517, 363, - 517, 517, 517, 352, 517, 75, 351, 356, 76, 82, - 62, 517, 346, 517, 63, 72, 65, 66, 81, 71, - 71, 77, 75, 73, 87, 91, 86, 517, 300, 297, - 292, 517, 517, 105, 0, 139, 0, 0, 145, 0, - 0, 317, 155, 294, 517, 0, 0, 517, 342, 161, - 341, 148, 116, 517, 124, 151, 159, 340, 339, 334, - 517, 132, 0, 128, 132, 135, 134, 0, 148, 147, - 0, 0, 139, 143, 151, 158, 517, 288, 118, 177, - - 517, 0, 212, 345, 517, 338, 285, 517, 0, 218, - 517, 347, 334, 281, 517, 0, 517, 208, 273, 210, - 211, 212, 219, 318, 311, 517, 0, 173, 0, 190, - 204, 201, 209, 210, 0, 201, 205, 517, 517, 517, - 517, 312, 306, 244, 247, 517, 296, 294, 247, 229, - 194, 250, 253, 220, 268, 255, 250, 197, 184, 229, - 222, 225, 0, 226, 241, 242, 243, 274, 132, 293, - 124, 270, 250, 0, 250, 0, 0, 246, 0, 301, - 304, 316, 322, 86, 307, 326, 331, 337, 66, 277, - 0, 0, 341, 343, 0, 517, 412, 419, 426, 433, - - 440, 94, 447, 454, 461, 468, 475, 481, 488, 495, - 502, 509 + 0, 0, 75, 76, 69, 70, 76, 77, 533, 532, + 579, 696, 82, 89, 555, 696, 0, 0, 696, 566, + 696, 696, 696, 555, 696, 77, 552, 557, 78, 84, + 64, 696, 547, 696, 65, 74, 67, 68, 83, 73, + 73, 79, 75, 82, 77, 98, 94, 107, 696, 499, + 496, 491, 696, 696, 132, 0, 152, 0, 0, 168, + 0, 0, 517, 145, 493, 696, 0, 0, 696, 543, + 174, 542, 161, 132, 696, 137, 162, 177, 541, 540, + 532, 696, 132, 0, 122, 133, 148, 144, 0, 0, + 160, 159, 157, 165, 0, 0, 156, 160, 162, 169, + + 177, 696, 482, 158, 191, 696, 0, 231, 538, 696, + 530, 475, 696, 0, 234, 696, 538, 520, 465, 696, + 0, 696, 511, 243, 457, 223, 200, 234, 219, 238, + 239, 507, 502, 499, 696, 0, 211, 0, 217, 228, + 225, 230, 0, 229, 232, 0, 238, 224, 229, 696, + 696, 696, 696, 497, 492, 270, 424, 696, 485, 482, + 274, 416, 464, 204, 278, 290, 396, 277, 442, 437, + 435, 434, 433, 280, 430, 270, 262, 265, 0, 261, + 0, 276, 279, 279, 282, 310, 375, 314, 372, 422, + 332, 319, 320, 419, 301, 0, 302, 0, 0, 299, + + 301, 0, 340, 355, 359, 364, 366, 370, 375, 379, + 385, 362, 406, 375, 376, 403, 332, 0, 355, 0, + 395, 405, 402, 392, 395, 399, 0, 0, 397, 396, + 400, 382, 381, 412, 416, 380, 377, 420, 440, 367, + 360, 441, 445, 340, 335, 453, 457, 332, 327, 460, + 461, 325, 303, 465, 478, 295, 276, 481, 482, 250, + 199, 486, 496, 192, 178, 500, 503, 148, 133, 506, + 521, 696, 120, 522, 525, 101, 539, 696, 591, 598, + 605, 612, 619, 96, 626, 633, 640, 647, 654, 660, + 667, 674, 681, 688 + } ; -static yyconst flex_int16_t yy_def[213] = +static yyconst flex_int16_t yy_def[295] = { 0, - 196, 1, 197, 197, 198, 198, 199, 199, 200, 200, - 196, 196, 196, 196, 196, 196, 201, 202, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 202, 196, - 196, 196, 196, 196, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 196, 196, 196, - 196, 196, 196, 196, 203, 196, 204, 205, 196, 206, - 207, 196, 196, 196, 196, 201, 202, 196, 196, 196, - 196, 196, 196, 196, 196, 202, 202, 196, 196, 196, - 196, 202, 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 196, 196, 196, 196, - - 196, 203, 196, 208, 196, 196, 196, 196, 205, 196, - 196, 209, 196, 196, 196, 207, 196, 210, 196, 196, - 196, 196, 196, 196, 202, 196, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 196, 196, 196, - 196, 208, 208, 196, 196, 196, 209, 209, 196, 196, - 210, 210, 210, 196, 196, 196, 196, 196, 196, 202, - 202, 202, 202, 202, 202, 202, 202, 211, 196, 212, - 196, 210, 202, 202, 202, 202, 202, 202, 202, 211, - 211, 211, 211, 196, 212, 212, 212, 212, 196, 202, - 202, 202, 211, 212, 202, 0, 196, 196, 196, 196, - - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196 + 278, 1, 279, 279, 280, 280, 281, 281, 282, 282, + 278, 278, 278, 278, 278, 278, 283, 284, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 284, 278, + 278, 278, 278, 278, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 278, 278, + 278, 278, 278, 278, 278, 285, 278, 286, 287, 278, + 288, 289, 278, 278, 278, 278, 283, 284, 278, 278, + 278, 278, 278, 278, 278, 278, 284, 284, 278, 278, + 278, 278, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + + 284, 278, 278, 278, 278, 278, 285, 278, 290, 278, + 278, 278, 278, 287, 278, 278, 291, 278, 278, 278, + 289, 278, 278, 292, 278, 278, 278, 278, 278, 278, + 284, 278, 284, 278, 278, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 278, + 278, 278, 278, 290, 290, 278, 278, 278, 291, 291, + 278, 278, 278, 292, 292, 292, 278, 278, 278, 278, + 278, 278, 278, 284, 278, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 293, 278, 294, 278, 278, + 292, 278, 284, 278, 284, 284, 284, 284, 284, 284, + + 284, 284, 293, 293, 293, 293, 278, 294, 294, 294, + 294, 278, 278, 278, 284, 278, 284, 284, 284, 284, + 293, 294, 278, 278, 284, 278, 284, 284, 278, 278, + 284, 278, 278, 278, 284, 278, 278, 278, 284, 278, + 278, 278, 284, 278, 278, 278, 284, 278, 278, 278, + 284, 278, 278, 278, 284, 278, 278, 278, 284, 278, + 278, 278, 284, 278, 278, 278, 284, 278, 278, 278, + 284, 278, 278, 278, 284, 278, 278, 0, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278 + } ; -static yyconst flex_int16_t yy_nxt[593] = +static yyconst flex_int16_t yy_nxt[774] = { 0, 12, 13, 14, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 19, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 18, 18, 37, - 38, 39, 40, 41, 42, 18, 18, 43, 18, 44, - 45, 18, 18, 46, 47, 12, 48, 35, 36, 18, - 18, 37, 38, 39, 40, 41, 42, 18, 18, 43, - 18, 44, 45, 18, 18, 46, 47, 49, 12, 12, - 12, 12, 12, 50, 51, 53, 53, 56, 56, 59, - 59, 63, 63, 63, 80, 65, 54, 54, 63, 63, - 63, 70, 71, 75, 72, 76, 78, 67, 78, 82, - - 84, 79, 85, 83, 77, 86, 87, 88, 89, 90, - 93, 91, 57, 57, 92, 94, 95, 96, 100, 60, - 60, 82, 84, 101, 85, 83, 77, 86, 87, 88, - 89, 90, 93, 91, 170, 73, 92, 94, 95, 96, - 103, 103, 103, 122, 121, 104, 110, 110, 110, 105, - 111, 112, 123, 64, 168, 106, 63, 63, 63, 127, - 64, 113, 118, 118, 118, 75, 121, 72, 75, 128, - 76, 129, 130, 124, 123, 124, 120, 131, 125, 77, - 132, 127, 133, 134, 135, 136, 137, 138, 139, 140, - 100, 128, 189, 129, 130, 101, 196, 196, 120, 131, - - 184, 77, 132, 159, 133, 134, 135, 136, 137, 152, - 118, 118, 107, 103, 103, 103, 159, 160, 114, 110, - 110, 110, 141, 146, 124, 156, 124, 156, 64, 155, - 157, 122, 161, 158, 119, 158, 162, 163, 159, 160, - 123, 164, 165, 166, 167, 168, 168, 168, 170, 170, - 170, 152, 118, 118, 161, 196, 196, 173, 162, 163, - 174, 175, 123, 164, 165, 166, 167, 176, 177, 157, - 178, 179, 196, 196, 157, 181, 168, 168, 190, 173, - 191, 153, 174, 175, 182, 107, 192, 155, 118, 176, - 177, 114, 178, 179, 186, 170, 170, 110, 187, 148, - - 190, 148, 191, 196, 196, 181, 168, 168, 192, 196, - 196, 182, 187, 195, 182, 103, 143, 169, 196, 196, - 171, 172, 143, 153, 196, 196, 182, 186, 170, 170, - 125, 187, 182, 196, 196, 195, 187, 155, 152, 196, - 196, 154, 187, 196, 196, 196, 196, 183, 187, 150, - 149, 182, 148, 145, 144, 143, 63, 126, 79, 79, - 73, 69, 98, 117, 99, 98, 188, 97, 81, 74, - 73, 69, 68, 65, 196, 62, 62, 183, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 193, 196, 196, 196, 196, 196, 196, 196, 196, 188, - - 196, 196, 196, 196, 196, 194, 196, 196, 196, 181, - 196, 186, 52, 52, 52, 52, 52, 52, 52, 55, - 55, 55, 55, 55, 55, 55, 58, 58, 58, 58, - 58, 58, 58, 61, 61, 61, 61, 61, 61, 61, - 66, 196, 66, 66, 66, 66, 66, 102, 102, 102, - 102, 196, 196, 102, 108, 108, 108, 108, 108, 108, - 108, 109, 109, 196, 109, 109, 196, 109, 115, 115, - 115, 115, 115, 115, 115, 116, 116, 116, 116, 116, - 116, 142, 196, 142, 142, 142, 142, 142, 147, 196, - 147, 147, 147, 147, 147, 151, 151, 151, 151, 151, - - 151, 151, 180, 180, 180, 180, 180, 180, 180, 185, - 185, 185, 185, 185, 185, 185, 11, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196 - + 38, 39, 40, 41, 42, 18, 43, 44, 18, 45, + 46, 18, 18, 47, 48, 18, 12, 49, 35, 36, + 18, 18, 37, 38, 39, 40, 41, 42, 18, 43, + 44, 18, 45, 46, 18, 18, 47, 48, 18, 50, + 12, 12, 12, 12, 12, 51, 52, 54, 54, 57, + 57, 60, 60, 64, 64, 64, 81, 66, 55, 55, + 64, 64, 64, 71, 72, 76, 73, 77, 79, 68, + + 79, 83, 85, 80, 86, 84, 78, 87, 88, 89, + 91, 92, 93, 90, 97, 58, 58, 94, 95, 100, + 276, 96, 61, 61, 83, 85, 98, 86, 84, 78, + 87, 88, 89, 91, 92, 93, 90, 97, 101, 276, + 94, 95, 100, 99, 96, 105, 64, 64, 64, 98, + 106, 74, 273, 108, 108, 108, 129, 65, 109, 136, + 128, 101, 110, 137, 65, 130, 99, 272, 111, 115, + 115, 115, 138, 116, 117, 124, 124, 124, 76, 76, + 126, 131, 136, 128, 118, 139, 137, 140, 130, 127, + 78, 132, 141, 132, 142, 138, 133, 269, 143, 144, + + 145, 146, 147, 148, 105, 149, 278, 278, 139, 106, + 140, 268, 127, 78, 132, 141, 132, 142, 265, 169, + 65, 143, 144, 145, 146, 147, 148, 112, 149, 150, + 151, 152, 108, 108, 108, 115, 115, 115, 129, 158, + 76, 153, 168, 119, 165, 124, 124, 130, 170, 125, + 170, 127, 172, 171, 172, 176, 76, 173, 174, 177, + 178, 179, 180, 181, 182, 183, 184, 78, 185, 264, + 130, 186, 186, 186, 127, 188, 188, 188, 176, 165, + 124, 124, 177, 178, 179, 180, 181, 182, 183, 184, + 78, 185, 278, 278, 76, 261, 192, 76, 195, 193, + + 196, 197, 198, 199, 200, 127, 112, 201, 78, 119, + 202, 204, 186, 186, 260, 209, 188, 188, 166, 210, + 205, 195, 257, 196, 197, 198, 199, 200, 127, 217, + 201, 78, 218, 202, 278, 278, 76, 76, 214, 215, + 219, 220, 278, 278, 256, 187, 253, 127, 78, 189, + 205, 252, 217, 166, 249, 218, 204, 186, 186, 248, + 191, 278, 278, 219, 220, 205, 278, 278, 227, 205, + 127, 78, 278, 278, 205, 210, 209, 188, 188, 245, + 210, 278, 278, 228, 210, 206, 244, 278, 278, 211, + 210, 227, 76, 76, 224, 225, 241, 278, 278, 240, + + 237, 236, 165, 127, 78, 205, 228, 278, 278, 76, + 210, 230, 76, 76, 231, 234, 233, 76, 232, 235, + 127, 229, 226, 78, 127, 223, 127, 78, 78, 76, + 206, 238, 188, 76, 221, 239, 186, 76, 216, 242, + 127, 213, 212, 127, 78, 207, 78, 127, 127, 194, + 211, 78, 173, 173, 171, 222, 171, 76, 76, 243, + 246, 169, 76, 127, 247, 204, 124, 78, 78, 127, + 76, 127, 250, 78, 76, 209, 251, 76, 76, 254, + 255, 127, 76, 190, 258, 78, 115, 160, 127, 78, + 160, 78, 127, 127, 108, 76, 78, 259, 76, 76, + + 262, 263, 155, 76, 127, 266, 78, 155, 78, 127, + 78, 127, 78, 76, 127, 267, 127, 76, 175, 270, + 76, 133, 271, 76, 78, 274, 169, 167, 127, 78, + 163, 78, 127, 78, 127, 162, 161, 127, 76, 76, + 275, 277, 76, 160, 275, 157, 156, 78, 155, 78, + 127, 127, 64, 78, 78, 135, 76, 127, 277, 134, + 80, 74, 123, 103, 122, 104, 103, 127, 102, 82, + 75, 74, 78, 127, 70, 69, 78, 66, 278, 63, + 63, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 127, 53, 53, 53, 53, 53, 53, 53, 56, 56, + + 56, 56, 56, 56, 56, 59, 59, 59, 59, 59, + 59, 59, 62, 62, 62, 62, 62, 62, 62, 67, + 278, 67, 67, 67, 67, 67, 107, 107, 107, 107, + 278, 278, 107, 113, 113, 113, 113, 113, 113, 113, + 114, 114, 278, 114, 114, 278, 114, 120, 120, 120, + 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, + 154, 278, 154, 154, 154, 154, 154, 159, 278, 159, + 159, 159, 159, 159, 164, 164, 164, 164, 164, 164, + 164, 203, 203, 203, 203, 203, 203, 203, 208, 208, + 208, 208, 208, 208, 208, 11, 278, 278, 278, 278, + + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278 } ; -static yyconst flex_int16_t yy_chk[593] = +static yyconst flex_int16_t yy_chk[774] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -562,65 +607,84 @@ static yyconst flex_int16_t yy_chk[593] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 4, 5, 6, 7, - 8, 13, 13, 13, 31, 31, 3, 4, 14, 14, - 14, 26, 26, 29, 26, 29, 30, 202, 30, 35, - - 36, 30, 37, 35, 29, 38, 39, 40, 41, 42, - 44, 43, 5, 6, 43, 45, 46, 47, 54, 7, - 8, 35, 36, 54, 37, 35, 29, 38, 39, 40, - 41, 42, 44, 43, 189, 73, 43, 45, 46, 47, - 56, 56, 56, 75, 73, 56, 59, 59, 59, 56, - 59, 59, 75, 13, 184, 56, 63, 63, 63, 82, - 14, 59, 70, 70, 70, 72, 73, 72, 76, 84, - 76, 85, 86, 77, 75, 77, 72, 87, 77, 76, - 89, 82, 90, 93, 94, 95, 96, 99, 99, 99, - 100, 84, 171, 85, 86, 100, 151, 151, 72, 87, - - 169, 76, 89, 159, 90, 93, 94, 95, 96, 118, - 118, 118, 56, 103, 103, 103, 158, 128, 59, 110, - 110, 110, 103, 110, 120, 121, 120, 121, 63, 120, - 121, 122, 130, 123, 70, 123, 131, 132, 123, 128, - 122, 133, 134, 136, 137, 144, 144, 144, 149, 149, - 149, 152, 152, 152, 130, 153, 153, 160, 131, 132, - 161, 162, 122, 133, 134, 136, 137, 164, 165, 157, - 166, 167, 172, 172, 156, 168, 168, 168, 173, 160, - 175, 118, 161, 162, 168, 103, 178, 155, 154, 164, - 165, 110, 166, 167, 170, 170, 170, 150, 170, 148, - - 173, 147, 175, 180, 180, 181, 181, 181, 178, 185, - 185, 180, 185, 190, 181, 145, 143, 144, 182, 182, - 149, 153, 142, 152, 183, 183, 182, 186, 186, 186, - 125, 186, 183, 187, 187, 190, 187, 124, 172, 188, - 188, 119, 188, 193, 193, 194, 194, 168, 194, 114, - 113, 193, 112, 107, 106, 104, 98, 80, 79, 78, - 71, 69, 64, 62, 51, 50, 170, 49, 33, 28, - 27, 24, 20, 15, 11, 10, 9, 181, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 183, 0, 0, 0, 0, 0, 0, 0, 0, 186, - - 0, 0, 0, 0, 0, 188, 0, 0, 0, 193, - 0, 194, 197, 197, 197, 197, 197, 197, 197, 198, - 198, 198, 198, 198, 198, 198, 199, 199, 199, 199, - 199, 199, 199, 200, 200, 200, 200, 200, 200, 200, - 201, 0, 201, 201, 201, 201, 201, 203, 203, 203, - 203, 0, 0, 203, 204, 204, 204, 204, 204, 204, - 204, 205, 205, 0, 205, 205, 0, 205, 206, 206, - 206, 206, 206, 206, 206, 207, 207, 207, 207, 207, - 207, 208, 0, 208, 208, 208, 208, 208, 209, 0, - 209, 209, 209, 209, 209, 210, 210, 210, 210, 210, - - 210, 210, 211, 211, 211, 211, 211, 211, 211, 212, - 212, 212, 212, 212, 212, 212, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196 - + 1, 1, 1, 1, 1, 1, 1, 3, 4, 5, + 6, 7, 8, 13, 13, 13, 31, 31, 3, 4, + 14, 14, 14, 26, 26, 29, 26, 29, 30, 284, + + 30, 35, 36, 30, 37, 35, 29, 38, 39, 40, + 41, 42, 43, 40, 45, 5, 6, 43, 44, 47, + 276, 44, 7, 8, 35, 36, 46, 37, 35, 29, + 38, 39, 40, 41, 42, 43, 40, 45, 48, 273, + 43, 44, 47, 46, 44, 55, 64, 64, 64, 46, + 55, 74, 269, 57, 57, 57, 76, 13, 57, 83, + 74, 48, 57, 85, 14, 76, 46, 268, 57, 60, + 60, 60, 86, 60, 60, 71, 71, 71, 73, 77, + 73, 77, 83, 74, 60, 87, 85, 88, 76, 73, + 77, 78, 91, 78, 92, 86, 78, 265, 93, 94, + + 97, 98, 99, 100, 105, 101, 164, 164, 87, 105, + 88, 264, 73, 77, 127, 91, 127, 92, 261, 127, + 64, 93, 94, 97, 98, 99, 100, 57, 101, 104, + 104, 104, 108, 108, 108, 115, 115, 115, 129, 115, + 126, 108, 126, 60, 124, 124, 124, 129, 128, 71, + 128, 126, 130, 128, 130, 137, 131, 130, 131, 139, + 140, 141, 142, 144, 145, 147, 148, 131, 149, 260, + 129, 156, 156, 156, 126, 161, 161, 161, 137, 165, + 165, 165, 139, 140, 141, 142, 144, 145, 147, 148, + 131, 149, 166, 166, 168, 257, 168, 174, 176, 174, + + 177, 178, 180, 182, 183, 168, 108, 184, 174, 115, + 185, 186, 186, 186, 256, 188, 188, 188, 124, 188, + 186, 176, 253, 177, 178, 180, 182, 183, 168, 195, + 184, 174, 197, 185, 191, 191, 192, 193, 192, 193, + 200, 201, 203, 203, 252, 156, 249, 192, 193, 161, + 203, 248, 195, 165, 245, 197, 204, 204, 204, 244, + 166, 205, 205, 200, 201, 204, 206, 206, 217, 205, + 192, 193, 208, 208, 206, 208, 209, 209, 209, 241, + 209, 210, 210, 219, 210, 186, 240, 211, 211, 188, + 211, 217, 214, 215, 214, 215, 237, 221, 221, 236, + + 233, 232, 191, 214, 215, 221, 219, 222, 222, 224, + 222, 224, 225, 230, 225, 230, 229, 231, 226, 231, + 224, 223, 216, 225, 230, 213, 214, 215, 231, 234, + 204, 234, 212, 235, 206, 235, 207, 238, 194, 238, + 234, 190, 189, 224, 235, 187, 225, 230, 238, 175, + 209, 231, 173, 172, 171, 211, 170, 239, 242, 239, + 242, 169, 243, 234, 243, 221, 167, 235, 239, 242, + 246, 238, 246, 243, 247, 222, 247, 250, 251, 250, + 251, 246, 254, 163, 254, 247, 162, 160, 250, 251, + 159, 239, 242, 254, 157, 255, 243, 255, 258, 259, + + 258, 259, 155, 262, 246, 262, 255, 154, 247, 258, + 259, 250, 251, 263, 262, 263, 254, 266, 134, 266, + 267, 133, 267, 270, 263, 270, 132, 125, 266, 255, + 123, 267, 258, 259, 270, 119, 118, 262, 271, 274, + 271, 274, 275, 117, 275, 112, 111, 263, 109, 271, + 274, 266, 103, 275, 267, 81, 277, 270, 277, 80, + 79, 72, 70, 65, 63, 52, 51, 277, 50, 33, + 28, 27, 271, 274, 24, 20, 275, 15, 11, 10, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 277, 279, 279, 279, 279, 279, 279, 279, 280, 280, + + 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, + 281, 281, 282, 282, 282, 282, 282, 282, 282, 283, + 0, 283, 283, 283, 283, 283, 285, 285, 285, 285, + 0, 0, 285, 286, 286, 286, 286, 286, 286, 286, + 287, 287, 0, 287, 287, 0, 287, 288, 288, 288, + 288, 288, 288, 288, 289, 289, 289, 289, 289, 289, + 290, 0, 290, 290, 290, 290, 290, 291, 0, 291, + 291, 291, 291, 291, 292, 292, 292, 292, 292, 292, + 292, 293, 293, 293, 293, 293, 293, 293, 294, 294, + 294, 294, 294, 294, 294, 278, 278, 278, 278, 278, + + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278 } ; /* The intent behind this definition is that it'll catch @@ -675,11 +739,16 @@ do {\ #define RETURN_ROW_ID() \ { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return ROW_ID; } +#define RETURN_REVERSED_EXPR_FUNC() \ + { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return REVERSED_EXPR_FUNC; } + + /*following character status will be rewrite by gen_parse.sh according to connection character*/ -#line 684 "ob_expr_parser_utf8_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +#line 753 "ob_expr_parser_utf8_lex.c" #define INITIAL 0 #define in_c_comment 1 @@ -927,9 +996,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 96 "ob_expr_parser_utf8.l" +#line 102 "ob_expr_parser_utf8.l" -#line 935 "ob_expr_parser_utf8_lex.c" +#line 1004 "ob_expr_parser_utf8_lex.c" yylval = yylval_param; @@ -986,13 +1055,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 197 ) + if ( yy_current_state >= 279 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 517 ); + while ( yy_base[yy_current_state] != 696 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -1018,206 +1087,226 @@ YY_DECL case 1: YY_RULE_SETUP -#line 97 "ob_expr_parser_utf8.l" +#line 103 "ob_expr_parser_utf8.l" { return WHERE; } YY_BREAK case 2: YY_RULE_SETUP -#line 98 "ob_expr_parser_utf8.l" +#line 104 "ob_expr_parser_utf8.l" { return AS; } YY_BREAK case 3: YY_RULE_SETUP -#line 99 "ob_expr_parser_utf8.l" +#line 105 "ob_expr_parser_utf8.l" { return VALUES; } YY_BREAK case 4: YY_RULE_SETUP -#line 100 "ob_expr_parser_utf8.l" +#line 106 "ob_expr_parser_utf8.l" { return VALUES; } YY_BREAK case 5: YY_RULE_SETUP -#line 101 "ob_expr_parser_utf8.l" +#line 107 "ob_expr_parser_utf8.l" { return SET; } YY_BREAK case 6: YY_RULE_SETUP -#line 102 "ob_expr_parser_utf8.l" +#line 108 "ob_expr_parser_utf8.l" { return END_WHERE; } YY_BREAK case 7: YY_RULE_SETUP -#line 103 "ob_expr_parser_utf8.l" +#line 109 "ob_expr_parser_utf8.l" { return END_WHERE; } YY_BREAK case 8: YY_RULE_SETUP -#line 104 "ob_expr_parser_utf8.l" +#line 110 "ob_expr_parser_utf8.l" { return END_WHERE; } YY_BREAK case 9: YY_RULE_SETUP -#line 105 "ob_expr_parser_utf8.l" +#line 111 "ob_expr_parser_utf8.l" { return END_WHERE; } YY_BREAK case 10: YY_RULE_SETUP -#line 106 "ob_expr_parser_utf8.l" +#line 112 "ob_expr_parser_utf8.l" { RETURN_ROW_ID(); } YY_BREAK case 11: YY_RULE_SETUP -#line 108 "ob_expr_parser_utf8.l" +#line 114 "ob_expr_parser_utf8.l" { return JOIN; } YY_BREAK case 12: YY_RULE_SETUP -#line 109 "ob_expr_parser_utf8.l" +#line 115 "ob_expr_parser_utf8.l" { return ON; } YY_BREAK case 13: YY_RULE_SETUP -#line 110 "ob_expr_parser_utf8.l" +#line 116 "ob_expr_parser_utf8.l" { return BETWEEN; } YY_BREAK case 14: YY_RULE_SETUP -#line 111 "ob_expr_parser_utf8.l" +#line 117 "ob_expr_parser_utf8.l" { return AND_OP; } YY_BREAK case 15: YY_RULE_SETUP -#line 112 "ob_expr_parser_utf8.l" +#line 118 "ob_expr_parser_utf8.l" { return AND_OP; } YY_BREAK case 16: YY_RULE_SETUP -#line 113 "ob_expr_parser_utf8.l" +#line 119 "ob_expr_parser_utf8.l" { return OR_OP; } YY_BREAK case 17: YY_RULE_SETUP -#line 114 "ob_expr_parser_utf8.l" +#line 120 "ob_expr_parser_utf8.l" { return OR_OP; } YY_BREAK case 18: YY_RULE_SETUP -#line 115 "ob_expr_parser_utf8.l" +#line 121 "ob_expr_parser_utf8.l" { return IN; } YY_BREAK case 19: YY_RULE_SETUP -#line 116 "ob_expr_parser_utf8.l" -{ return COMP_EQ; } +#line 122 "ob_expr_parser_utf8.l" +{ return IS; } YY_BREAK case 20: YY_RULE_SETUP -#line 117 "ob_expr_parser_utf8.l" -{ return COMP_NSEQ; } +#line 123 "ob_expr_parser_utf8.l" +{ return TOKEN_NULL; } YY_BREAK case 21: YY_RULE_SETUP -#line 118 "ob_expr_parser_utf8.l" -{ return COMP_GE; } +#line 124 "ob_expr_parser_utf8.l" +{ return NOT; } YY_BREAK case 22: YY_RULE_SETUP -#line 119 "ob_expr_parser_utf8.l" -{ return COMP_GT; } +#line 125 "ob_expr_parser_utf8.l" +{ return COMP_EQ; } YY_BREAK case 23: YY_RULE_SETUP -#line 120 "ob_expr_parser_utf8.l" -{ return COMP_LE; } +#line 126 "ob_expr_parser_utf8.l" +{ return COMP_NSEQ; } YY_BREAK case 24: YY_RULE_SETUP -#line 121 "ob_expr_parser_utf8.l" -{ return COMP_LT; } +#line 127 "ob_expr_parser_utf8.l" +{ return COMP_GE; } YY_BREAK case 25: YY_RULE_SETUP -#line 122 "ob_expr_parser_utf8.l" -{ return COMP_NE; } +#line 128 "ob_expr_parser_utf8.l" +{ return COMP_GT; } YY_BREAK case 26: YY_RULE_SETUP -#line 123 "ob_expr_parser_utf8.l" -{ return PLACE_HOLDER; } +#line 129 "ob_expr_parser_utf8.l" +{ return COMP_LE; } YY_BREAK case 27: YY_RULE_SETUP -#line 124 "ob_expr_parser_utf8.l" -{ store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } +#line 130 "ob_expr_parser_utf8.l" +{ return COMP_LT; } YY_BREAK case 28: YY_RULE_SETUP -#line 126 "ob_expr_parser_utf8.l" -{ RETURN_INT_VAL(); } +#line 131 "ob_expr_parser_utf8.l" +{ return COMP_NE; } YY_BREAK case 29: YY_RULE_SETUP -#line 127 "ob_expr_parser_utf8.l" -{ RETURN_NUMBER_VAL(); } +#line 132 "ob_expr_parser_utf8.l" +{ return PLACE_HOLDER; } YY_BREAK case 30: YY_RULE_SETUP -#line 128 "ob_expr_parser_utf8.l" -{ RETURN_NAME_OB(); } +#line 133 "ob_expr_parser_utf8.l" +{ store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } YY_BREAK case 31: -/* rule 31 can match eol */ YY_RULE_SETUP -#line 129 "ob_expr_parser_utf8.l" -{ } +#line 134 "ob_expr_parser_utf8.l" +{ RETURN_REVERSED_EXPR_FUNC();} YY_BREAK case 32: YY_RULE_SETUP -#line 130 "ob_expr_parser_utf8.l" -{ return ','; } +#line 136 "ob_expr_parser_utf8.l" +{ RETURN_INT_VAL(); } YY_BREAK case 33: YY_RULE_SETUP -#line 131 "ob_expr_parser_utf8.l" -{ return '('; } +#line 137 "ob_expr_parser_utf8.l" +{ RETURN_NUMBER_VAL(); } YY_BREAK case 34: YY_RULE_SETUP -#line 132 "ob_expr_parser_utf8.l" -{ return ')'; } +#line 138 "ob_expr_parser_utf8.l" +{ RETURN_NAME_OB(); } YY_BREAK case 35: +/* rule 35 can match eol */ YY_RULE_SETUP -#line 133 "ob_expr_parser_utf8.l" +#line 139 "ob_expr_parser_utf8.l" +{ } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 140 "ob_expr_parser_utf8.l" +{ return ','; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 141 "ob_expr_parser_utf8.l" +{ return '('; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 142 "ob_expr_parser_utf8.l" +{ return ')'; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 143 "ob_expr_parser_utf8.l" { return yytext[0]; } YY_BREAK /* comment */ -case 36: +case 40: YY_RULE_SETUP -#line 136 "ob_expr_parser_utf8.l" +#line 146 "ob_expr_parser_utf8.l" { PUSH_STATE(in_c_comment); } YY_BREAK -case 37: +case 41: YY_RULE_SETUP -#line 137 "ob_expr_parser_utf8.l" +#line 147 "ob_expr_parser_utf8.l" { POP_STATE(); } YY_BREAK -case 38: -/* rule 38 can match eol */ +case 42: +/* rule 42 can match eol */ YY_RULE_SETUP -#line 138 "ob_expr_parser_utf8.l" +#line 148 "ob_expr_parser_utf8.l" {} YY_BREAK -case 39: +case 43: YY_RULE_SETUP -#line 139 "ob_expr_parser_utf8.l" +#line 149 "ob_expr_parser_utf8.l" {} YY_BREAK /* quote */ -case 40: +case 44: YY_RULE_SETUP -#line 142 "ob_expr_parser_utf8.l" +#line 152 "ob_expr_parser_utf8.l" { PUSH_STATE(sq); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1228,10 +1317,10 @@ YY_RULE_SETUP } } YY_BREAK -case 41: -/* rule 41 can match eol */ +case 45: +/* rule 45 can match eol */ YY_RULE_SETUP -#line 152 "ob_expr_parser_utf8.l" +#line 162 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1239,9 +1328,9 @@ YY_RULE_SETUP } } YY_BREAK -case 42: +case 46: YY_RULE_SETUP -#line 159 "ob_expr_parser_utf8.l" +#line 169 "ob_expr_parser_utf8.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1251,15 +1340,15 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 43: +case 47: YY_RULE_SETUP -#line 168 "ob_expr_parser_utf8.l" +#line 178 "ob_expr_parser_utf8.l" {} YY_BREAK -case 44: -/* rule 44 can match eol */ +case 48: +/* rule 48 can match eol */ YY_RULE_SETUP -#line 169 "ob_expr_parser_utf8.l" +#line 179 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1267,20 +1356,20 @@ YY_RULE_SETUP } } YY_BREAK -case 45: -/* rule 45 can match eol */ +case 49: +/* rule 49 can match eol */ YY_RULE_SETUP -#line 175 "ob_expr_parser_utf8.l" +#line 185 "ob_expr_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 176 "ob_expr_parser_utf8.l" +#line 186 "ob_expr_parser_utf8.l" { return ERROR; } YY_BREAK /* dquote */ -case 46: +case 50: YY_RULE_SETUP -#line 180 "ob_expr_parser_utf8.l" +#line 190 "ob_expr_parser_utf8.l" { PUSH_STATE(dq); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1291,10 +1380,10 @@ YY_RULE_SETUP } } YY_BREAK -case 47: -/* rule 47 can match eol */ +case 51: +/* rule 51 can match eol */ YY_RULE_SETUP -#line 190 "ob_expr_parser_utf8.l" +#line 200 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1302,9 +1391,9 @@ YY_RULE_SETUP } } YY_BREAK -case 48: +case 52: YY_RULE_SETUP -#line 197 "ob_expr_parser_utf8.l" +#line 207 "ob_expr_parser_utf8.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1317,31 +1406,31 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 49: +case 53: YY_RULE_SETUP -#line 209 "ob_expr_parser_utf8.l" +#line 219 "ob_expr_parser_utf8.l" {} YY_BREAK -case 50: -/* rule 50 can match eol */ +case 54: +/* rule 54 can match eol */ YY_RULE_SETUP -#line 210 "ob_expr_parser_utf8.l" +#line 220 "ob_expr_parser_utf8.l" {} YY_BREAK -case 51: -/* rule 51 can match eol */ +case 55: +/* rule 55 can match eol */ YY_RULE_SETUP -#line 211 "ob_expr_parser_utf8.l" +#line 221 "ob_expr_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 212 "ob_expr_parser_utf8.l" +#line 222 "ob_expr_parser_utf8.l" { return ERROR; } YY_BREAK /* backtick */ -case 52: +case 56: YY_RULE_SETUP -#line 216 "ob_expr_parser_utf8.l" +#line 226 "ob_expr_parser_utf8.l" { PUSH_STATE(bt); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1352,9 +1441,9 @@ YY_RULE_SETUP } } YY_BREAK -case 53: +case 57: YY_RULE_SETUP -#line 226 "ob_expr_parser_utf8.l" +#line 236 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -1362,10 +1451,10 @@ YY_RULE_SETUP } } YY_BREAK -case 54: -/* rule 54 can match eol */ +case 58: +/* rule 58 can match eol */ YY_RULE_SETUP -#line 233 "ob_expr_parser_utf8.l" +#line 243 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -1374,9 +1463,9 @@ YY_RULE_SETUP } } YY_BREAK -case 55: +case 59: YY_RULE_SETUP -#line 241 "ob_expr_parser_utf8.l" +#line 251 "ob_expr_parser_utf8.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1389,27 +1478,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 252 "ob_expr_parser_utf8.l" +#line 262 "ob_expr_parser_utf8.l" { return ERROR; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(in_c_comment): -#line 256 "ob_expr_parser_utf8.l" +#line 266 "ob_expr_parser_utf8.l" { return END_P; } YY_BREAK -case 56: +case 60: YY_RULE_SETUP -#line 257 "ob_expr_parser_utf8.l" +#line 267 "ob_expr_parser_utf8.l" { return IGNORED_WORD; } YY_BREAK -case 57: +case 61: YY_RULE_SETUP -#line 258 "ob_expr_parser_utf8.l" +#line 268 "ob_expr_parser_utf8.l" ECHO; YY_BREAK -#line 1415 "ob_expr_parser_utf8_lex.c" +#line 1504 "ob_expr_parser_utf8_lex.c" case YY_END_OF_BUFFER: { @@ -1701,7 +1790,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 197 ) + if ( yy_current_state >= 279 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1730,11 +1819,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 197 ) + if ( yy_current_state >= 279 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 196); + yy_is_jam = (yy_current_state == 278); return yy_is_jam ? 0 : yy_current_state; } @@ -2559,7 +2648,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 258 "ob_expr_parser_utf8.l" +#line 268 "ob_expr_parser_utf8.l" @@ -2690,22 +2779,26 @@ extern int ob_expr_parser_utf8_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h index 4d9bbc92..330e2a73 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h @@ -341,7 +341,7 @@ extern int ob_expr_parser_utf8_yylex \ #undef YY_DECL #endif -#line 258 "ob_expr_parser_utf8.l" +#line 268 "ob_expr_parser_utf8.l" #line 348 "ob_expr_parser_utf8_lex.h" diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c index 2bcad007..437bec45 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c @@ -139,22 +139,26 @@ extern int ob_expr_parser_utf8_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif @@ -232,8 +236,8 @@ static inline void add_token_list(ObProxyTokenList *list, ObProxyTokenList *next if (OB_ISNULL(list) || OB_ISNULL(next_list)) { } else if (NULL != list->tail_ && NULL != next_list->head_ - && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_) - && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_)) { + && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_ || TOKEN_FUNC == list->tail_->type_) + && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_ || TOKEN_FUNC == next_list->head_->type_)) { list->tail_->next_ = next_list->head_; list->tail_ = next_list->head_; list->tail_->next_ = NULL; @@ -305,11 +309,18 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar for (i = 0; i < result->part_key_info_.key_num_; ++i) { if (is_equal(column_name, &result->part_key_info_.part_keys_[i].name_)) { result->part_key_info_.part_keys_[i].idx_ = result->column_idx_; - break; + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; } } } +static inline void init_part_key_all_match(ObExprParseResult *result) +{ + for (int64_t i = 0; i < result->part_key_info_.key_num_; ++i) { + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; + } +} + #define malloc_node(node, result, type) \ do { \ if (OB_ISNULL(node = ((ObProxyTokenNode *)obproxy_parse_malloc(sizeof(ObProxyTokenNode), \ @@ -344,21 +355,13 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar do { \ if (NULL == relation) { \ } else { \ - int64_t new_mask = get_mask(relation->type_, relation->level_); \ - bool has_rowid = result->has_rowid_; \ - if (((result->cur_mask_ | new_mask) != result->cur_mask_) \ - || (has_rowid \ - && is_equal_to_rowid(&relation->left_value_->column_node_->column_name_))) { \ + if (relation->level_ != PART_KEY_LEVEL_ZERO) { \ if (result->relation_info_.relation_num_ < OBPROXY_MAX_RELATION_NUM) { \ result->relation_info_.relations_[result->relation_info_.relation_num_++] = relation; \ - result->cur_mask_ = (result->cur_mask_ | new_mask); \ } else { \ /* YYACCEPT; */ \ } \ } \ - if ((result->cur_mask_ & result->target_mask_) == result->target_mask_) { \ - /* YYACCEPT; */ \ - } \ } \ } while(0) \ @@ -428,6 +431,92 @@ static inline void add_relation(ObExprParseResult *result, } } +static inline void set_relation_part_with_column_idx(int64_t idx_in_schema_columns, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(level) && OB_ISNULL(first_part_column_idx) && + OB_ISNULL(second_part_column_idx) && OB_ISNULL(result)) { + // do nothing + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (idx_in_schema_columns == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + +static inline void set_relation_part_with_column_name(ObProxyParseString *column, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(column) + || OB_ISNULL(result) + || OB_ISNULL(level) + || OB_ISNULL(first_part_column_idx) + || OB_ISNULL(second_part_column_idx)) { + // do nothing + } else if (result->has_rowid_ + && is_equal_to_rowid(column)) { + // handle rowid + *level = PART_KEY_LEVEL_ONE; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + if (is_equal(&result->part_key_info_.part_keys_[i].name_, column)) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *left_value, @@ -438,25 +527,25 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *tmp_left = NULL; ObProxyTokenList *tmp_right = NULL; ObProxyFunctionType tmp_type = F_NONE; - ObProxyPartKeyLevel tmp_level = PART_KEY_LEVEL_ZERO; int64_t tmp_column_idx_ = -1; + ObProxyParseString *tmp_column = NULL; if (NULL != left_value->column_node_ && TOKEN_COLUMN == left_value->column_node_->type_ && left_value->column_node_->part_key_idx_ >= 0) { tmp_left = left_value; - tmp_level = result->part_key_info_.part_keys_[left_value->column_node_->part_key_idx_].level_; tmp_right = right_value; tmp_type = type; tmp_column_idx_ = left_value->column_node_->part_key_idx_; + tmp_column = &left_value->column_node_->column_name_; } else if (NULL != right_value->column_node_ && TOKEN_COLUMN == right_value->column_node_->type_ && right_value->column_node_->part_key_idx_ >= 0) { tmp_left = right_value; - tmp_level = result->part_key_info_.part_keys_[right_value->column_node_->part_key_idx_].level_; tmp_right = left_value; tmp_type = get_reverse_func(type); tmp_column_idx_ = right_value->column_node_->part_key_idx_; + tmp_column = &right_value->column_node_->column_name_; } if (NULL == tmp_left || NULL == tmp_right || F_COMP_NE == tmp_type) { @@ -469,7 +558,11 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, relation->left_value_ = tmp_left; relation->type_ = tmp_type; relation->right_value_ = tmp_right; - relation->level_ = tmp_level; + set_relation_part_with_column_name(tmp_column, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } return relation; } @@ -483,14 +576,20 @@ static inline ObProxyRelationExpr *get_values_relation(ObExprParseResult *result } else { int64_t i = 0; for (i = 0; i < result->part_key_info_.key_num_; ++i) { - if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { if (OB_ISNULL(relation = ((ObProxyRelationExpr *)obproxy_parse_malloc( sizeof(ObProxyRelationExpr), result->malloc_pool_)))) { } else { relation->column_idx_ = i; relation->type_ = F_COMP_EQ; relation->right_value_ = right_value; - relation->level_ = result->part_key_info_.part_keys_[i].level_; + relation->left_value_ = NULL; + set_relation_part_with_column_idx(result->values_list_idx_, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } break; } @@ -752,20 +851,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 17 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 231 +#define YYLAST 242 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 44 +#define YYNTOKENS 48 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 24 /* YYNRULES -- Number of rules. */ -#define YYNRULES 80 +#define YYNRULES 83 /* YYNRULES -- Number of states. */ -#define YYNSTATES 144 +#define YYNSTATES 149 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 286 +#define YYMAXUTOK 290 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -776,9 +875,9 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 43, 2, 2, 2, 41, 42, 2, - 35, 32, 39, 37, 36, 38, 34, 40, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, + 2, 2, 2, 47, 2, 2, 2, 45, 46, 2, + 39, 36, 43, 41, 40, 42, 38, 44, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -801,7 +900,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35 }; #if YYDEBUG @@ -812,57 +912,58 @@ static const yytype_uint16 yyprhs[] = 0, 0, 3, 6, 9, 13, 16, 21, 23, 25, 27, 29, 31, 33, 36, 40, 43, 48, 52, 57, 63, 70, 72, 76, 82, 86, 92, 96, 102, 108, - 114, 120, 122, 124, 126, 128, 130, 132, 134, 136, - 140, 142, 144, 147, 148, 152, 156, 158, 160, 164, - 170, 175, 180, 182, 184, 186, 188, 190, 192, 194, - 196, 198, 200, 202, 204, 209, 214, 218, 220, 224, - 230, 231, 235, 237, 241, 243, 245, 249, 251, 255, - 256 + 114, 120, 124, 129, 131, 133, 135, 137, 139, 141, + 143, 145, 149, 151, 153, 156, 157, 161, 165, 167, + 169, 173, 179, 181, 186, 191, 193, 195, 197, 199, + 201, 203, 205, 207, 209, 211, 213, 215, 220, 225, + 229, 231, 235, 241, 242, 246, 248, 252, 254, 256, + 260, 262, 266, 267 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 45, 0, -1, 3, 46, -1, 4, 60, -1, 5, - 51, 47, -1, 48, 47, -1, 48, 5, 51, 47, - -1, 1, -1, 9, -1, 32, -1, 33, -1, 24, - -1, 49, -1, 48, 49, -1, 50, 14, 51, -1, - 10, 27, -1, 10, 27, 34, 27, -1, 10, 27, - 27, -1, 10, 27, 6, 27, -1, 10, 27, 34, - 27, 27, -1, 10, 27, 34, 27, 6, 27, -1, - 52, -1, 51, 11, 52, -1, 35, 51, 11, 52, - 32, -1, 51, 12, 52, -1, 35, 51, 12, 52, - 32, -1, 55, 53, 55, -1, 55, 53, 35, 55, - 32, -1, 35, 55, 53, 55, 32, -1, 55, 13, - 35, 54, 32, -1, 55, 15, 55, 11, 55, -1, - 16, -1, 17, -1, 18, -1, 19, -1, 20, -1, - 21, -1, 22, -1, 55, -1, 54, 36, 55, -1, - 56, -1, 58, -1, 56, 58, -1, -1, 56, 36, - 56, -1, 57, 36, 56, -1, 29, -1, 27, -1, - 27, 34, 27, -1, 27, 34, 27, 34, 27, -1, - 27, 35, 56, 32, -1, 27, 35, 57, 32, -1, - 30, -1, 28, -1, 59, -1, 23, -1, 31, -1, - 37, -1, 38, -1, 39, -1, 40, -1, 41, -1, - 42, -1, 43, -1, 62, 7, 61, 47, -1, 8, - 66, 67, 47, -1, 14, 51, 47, -1, 46, -1, - 35, 65, 32, -1, 61, 36, 35, 65, 32, -1, - -1, 35, 63, 32, -1, 64, -1, 63, 36, 64, - -1, 27, -1, 55, -1, 65, 36, 55, -1, 52, - -1, 66, 36, 52, -1, -1, 5, 51, -1 + 49, 0, -1, 3, 50, -1, 4, 64, -1, 5, + 55, 51, -1, 52, 51, -1, 52, 5, 55, 51, + -1, 1, -1, 9, -1, 36, -1, 37, -1, 27, + -1, 53, -1, 52, 53, -1, 54, 14, 55, -1, + 10, 30, -1, 10, 30, 38, 30, -1, 10, 30, + 30, -1, 10, 30, 6, 30, -1, 10, 30, 38, + 30, 30, -1, 10, 30, 38, 30, 6, 30, -1, + 56, -1, 55, 11, 56, -1, 39, 55, 11, 56, + 36, -1, 55, 12, 56, -1, 39, 55, 12, 56, + 36, -1, 59, 57, 59, -1, 59, 57, 39, 59, + 36, -1, 39, 59, 57, 59, 36, -1, 59, 13, + 39, 58, 36, -1, 59, 15, 59, 11, 59, -1, + 59, 16, 17, -1, 59, 16, 18, 17, -1, 19, + -1, 20, -1, 21, -1, 22, -1, 23, -1, 24, + -1, 25, -1, 59, -1, 58, 40, 59, -1, 60, + -1, 62, -1, 60, 62, -1, -1, 60, 40, 60, + -1, 61, 40, 60, -1, 32, -1, 30, -1, 30, + 38, 30, -1, 30, 38, 30, 38, 30, -1, 33, + -1, 30, 39, 60, 36, -1, 30, 39, 61, 36, + -1, 34, -1, 31, -1, 63, -1, 26, -1, 35, + -1, 41, -1, 42, -1, 43, -1, 44, -1, 45, + -1, 46, -1, 47, -1, 66, 7, 65, 51, -1, + 8, 70, 71, 51, -1, 14, 55, 51, -1, 50, + -1, 39, 69, 36, -1, 65, 40, 39, 69, 36, + -1, -1, 39, 67, 36, -1, 68, -1, 67, 40, + 68, -1, 30, -1, 59, -1, 69, 40, 59, -1, + 56, -1, 70, 40, 56, -1, -1, 5, 55, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 380, 380, 381, 383, 384, 385, 386, 388, 389, - 390, 391, 393, 394, 396, 398, 399, 400, 401, 402, - 403, 405, 406, 407, 408, 409, 411, 412, 413, 414, - 415, 426, 427, 428, 429, 430, 431, 432, 434, 435, - 437, 439, 440, 442, 443, 444, 447, 454, 460, 466, - 472, 478, 484, 485, 486, 487, 493, 499, 500, 501, - 502, 503, 504, 505, 507, 508, 509, 510, 512, 516, - 521, 522, 527, 531, 536, 542, 552, 562, 563, 565, - 566 + 0, 475, 475, 476, 478, 479, 480, 481, 483, 484, + 485, 486, 488, 489, 491, 493, 494, 495, 496, 497, + 498, 500, 501, 502, 503, 504, 506, 507, 508, 509, + 510, 520, 521, 523, 524, 525, 526, 527, 528, 529, + 531, 532, 534, 536, 537, 539, 540, 541, 544, 551, + 557, 563, 569, 574, 580, 586, 587, 588, 589, 595, + 601, 602, 603, 604, 605, 606, 607, 609, 610, 611, + 612, 614, 618, 623, 624, 629, 633, 638, 644, 654, + 664, 665, 667, 668 }; #endif @@ -873,13 +974,14 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "DUMMY_SELECT_CLAUSE", "DUMMY_INSERT_CLAUSE", "WHERE", "AS", "VALUES", "SET", "END_WHERE", - "JOIN", "AND_OP", "OR_OP", "IN", "ON", "BETWEEN", "COMP_EQ", "COMP_NSEQ", - "COMP_GE", "COMP_GT", "COMP_LE", "COMP_LT", "COMP_NE", "PLACE_HOLDER", - "END_P", "ERROR", "IGNORED_WORD", "NAME_OB", "STR_VAL", "ROW_ID", - "INT_VAL", "POS_PLACE_HOLDER", "')'", "';'", "'.'", "'('", "','", "'+'", - "'-'", "'*'", "'/'", "'%'", "'&'", "'!'", "$accept", "start", - "select_root", "end_flag", "join_expr_list", "join_on_expr", "join_expr", - "cond_expr", "bool_pri", "comp", "in_expr_list", "expr", "token_list", + "JOIN", "AND_OP", "OR_OP", "IN", "ON", "BETWEEN", "IS", "TOKEN_NULL", + "NOT", "COMP_EQ", "COMP_NSEQ", "COMP_GE", "COMP_GT", "COMP_LE", + "COMP_LT", "COMP_NE", "PLACE_HOLDER", "END_P", "ERROR", "IGNORED_WORD", + "NAME_OB", "STR_VAL", "ROW_ID", "REVERSED_EXPR_FUNC", "INT_VAL", + "POS_PLACE_HOLDER", "')'", "';'", "'.'", "'('", "','", "'+'", "'-'", + "'*'", "'/'", "'%'", "'&'", "'!'", "$accept", "start", "select_root", + "end_flag", "join_expr_list", "join_on_expr", "join_expr", "cond_expr", + "bool_pri", "comp", "in_expr_list", "expr", "token_list", "func_param_list", "token", "operator", "insert_root", "values_expr_lists", "opt_column_list", "column_list", "opt_column", "values_expr_list", "set_expr", "opt_where_clause", 0 @@ -894,23 +996,23 @@ static const yytype_uint16 yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 41, 59, 46, 40, 44, 43, 45, 42, - 47, 37, 38, 33 + 285, 286, 287, 288, 289, 290, 41, 59, 46, 40, + 44, 43, 45, 42, 47, 37, 38, 33 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 44, 45, 45, 46, 46, 46, 46, 47, 47, - 47, 47, 48, 48, 49, 50, 50, 50, 50, 50, - 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, - 52, 53, 53, 53, 53, 53, 53, 53, 54, 54, - 55, 56, 56, 57, 57, 57, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, - 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, - 62, 62, 63, 63, 64, 65, 65, 66, 66, 67, - 67 + 0, 48, 49, 49, 50, 50, 50, 50, 51, 51, + 51, 51, 52, 52, 53, 54, 54, 54, 54, 54, + 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, + 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, + 58, 58, 59, 60, 60, 61, 61, 61, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, + 64, 65, 65, 66, 66, 67, 67, 68, 69, 69, + 70, 70, 71, 71 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -919,12 +1021,12 @@ static const yytype_uint8 yyr2[] = 0, 2, 2, 2, 3, 2, 4, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 4, 5, 6, 1, 3, 5, 3, 5, 3, 5, 5, 5, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 1, 1, 2, 0, 3, 3, 1, 1, 3, 5, - 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 4, 3, 1, 3, 5, - 0, 3, 1, 3, 1, 1, 3, 1, 3, 0, - 2 + 5, 3, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 2, 0, 3, 3, 1, 1, + 3, 5, 1, 4, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 4, 4, 3, + 1, 3, 5, 0, 3, 1, 3, 1, 1, 3, + 1, 3, 0, 2 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -933,140 +1035,142 @@ static const yytype_uint8 yyr2[] = static const yytype_uint8 yydefact[] = { 0, 0, 0, 0, 7, 0, 0, 2, 0, 12, - 0, 0, 0, 0, 67, 3, 0, 1, 55, 47, - 53, 46, 52, 56, 0, 57, 58, 59, 60, 61, - 62, 63, 0, 21, 0, 40, 41, 54, 15, 0, - 8, 11, 9, 10, 5, 13, 0, 0, 77, 79, - 0, 74, 0, 72, 0, 0, 43, 0, 0, 0, - 0, 4, 0, 0, 31, 32, 33, 34, 35, 36, - 37, 0, 42, 0, 17, 0, 0, 14, 0, 0, - 0, 0, 66, 71, 0, 0, 0, 48, 0, 0, - 0, 0, 0, 22, 24, 0, 0, 0, 26, 18, - 16, 6, 0, 80, 78, 65, 73, 75, 0, 0, - 64, 0, 50, 0, 51, 0, 22, 24, 26, 0, - 38, 0, 0, 0, 19, 0, 68, 0, 0, 49, - 44, 45, 23, 25, 28, 29, 0, 30, 27, 20, - 76, 0, 39, 69 + 0, 0, 0, 0, 70, 3, 0, 1, 58, 49, + 56, 48, 52, 55, 59, 0, 60, 61, 62, 63, + 64, 65, 66, 0, 21, 0, 42, 43, 57, 15, + 0, 8, 11, 9, 10, 5, 13, 0, 0, 80, + 82, 0, 77, 0, 75, 0, 0, 45, 0, 0, + 0, 0, 4, 0, 0, 0, 33, 34, 35, 36, + 37, 38, 39, 0, 44, 0, 17, 0, 0, 14, + 0, 0, 0, 0, 69, 74, 0, 0, 0, 50, + 0, 0, 0, 0, 0, 22, 24, 0, 0, 31, + 0, 0, 26, 18, 16, 6, 0, 83, 81, 68, + 76, 78, 0, 0, 67, 0, 53, 0, 54, 0, + 22, 24, 26, 0, 40, 0, 32, 0, 0, 19, + 0, 71, 0, 0, 51, 46, 47, 23, 25, 28, + 29, 0, 30, 27, 20, 79, 0, 41, 72 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 3, 7, 44, 8, 9, 10, 32, 33, 71, - 119, 34, 35, 89, 36, 37, 15, 86, 16, 52, - 53, 108, 49, 81 + -1, 3, 7, 45, 8, 9, 10, 33, 34, 73, + 123, 35, 36, 91, 37, 38, 15, 88, 16, 53, + 54, 112, 50, 83 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -52 +#define YYPACT_NINF -54 static const yytype_int16 yypact[] = { - 41, 16, 1, 13, -52, 108, -9, -52, 22, -52, - 14, 129, 108, 6, -52, -52, 33, -52, -52, 31, - -52, -52, -52, -52, 108, -52, -52, -52, -52, -52, - -52, -52, 76, -52, 202, 171, -52, -52, 8, 108, - -52, -52, -52, -52, -52, -52, 108, 171, -52, 7, - 76, -52, -12, -52, 3, 24, 171, 84, 202, 129, - 129, -52, 25, 171, -52, -52, -52, -52, -52, -52, - -52, 150, -52, 30, -52, 45, 76, 90, 209, 108, - 129, 60, -52, -52, 6, 171, 43, 49, 87, -7, - 129, 129, 150, -52, -52, 171, 66, 171, -52, -52, - 10, -52, 171, 90, -52, -52, -52, -52, 27, 54, - -52, 64, -52, 171, -52, 171, 73, 74, 75, 50, - -52, 171, 79, 86, -52, 75, -52, 171, 171, -52, - 171, 171, -52, -52, -52, -52, 171, -52, -52, -52, - -52, 58, -52, -52 + 16, 77, 8, 7, -54, 109, -5, -54, 22, -54, + 24, 131, 109, 38, -54, -54, 44, -54, -54, 6, + -54, -54, -54, -54, -54, 109, -54, -54, -54, -54, + -54, -54, -54, 68, -54, 210, 175, -54, -54, 5, + 109, -54, -54, -54, -54, -54, -54, 109, 175, -54, + 0, 68, -54, -28, -54, 15, 43, 175, 79, 210, + 131, 131, -54, 36, 175, 75, -54, -54, -54, -54, + -54, -54, -54, 153, -54, 53, -54, 56, 68, 85, + 217, 109, 131, 62, -54, -54, 38, 175, -3, 50, + 87, -10, 131, 131, 153, -54, -54, 175, 83, -54, + 86, 175, -54, -54, 11, -54, 175, 85, -54, -54, + -54, -54, 10, 67, -54, 80, -54, 175, -54, 175, + 73, 76, 78, 21, -54, 175, -54, 88, 81, -54, + 78, -54, 175, 175, -54, 175, 175, -54, -54, -54, + -54, 175, -54, -54, -54, -54, 27, -54, -54 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -52, -52, 118, -28, -52, 113, -52, -5, -10, -48, - -52, -24, -51, -52, -32, -52, -52, -52, -52, -52, - 38, 4, -52, -52 + -54, -54, 113, -23, -54, 117, -54, -11, -8, -38, + -54, -25, -53, -54, -34, -54, -54, -54, -54, -54, + 40, 3, -54, -54 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -71 +#define YYTABLE_NINF -74 static const yytype_int16 yytable[] = { - 58, 48, 4, 72, 61, 88, 5, 50, -70, 11, - 92, 6, 79, 17, 73, 12, 123, 4, 38, 57, - 83, 5, 82, 78, 84, 114, 6, 39, 46, 115, - 102, 40, 6, 51, 76, 74, 13, 124, 85, 96, - 54, 77, 75, 80, 1, 2, 41, 98, 101, 93, - 94, 87, 40, 105, 42, 43, 72, 99, 110, 126, - 95, 107, 130, 127, 131, 55, 56, 41, 118, 40, - 104, 120, 100, 122, 103, 42, 43, 121, 125, 109, - 116, 117, 135, 111, 41, 40, 136, 59, 60, 128, - 143, 129, 42, 43, 127, 90, 91, 137, 72, 72, - 41, 59, 60, 140, 107, 132, 133, 134, 42, 43, - 18, 138, 142, 139, 19, 20, 21, 22, 23, 112, - 14, 45, 106, 113, 25, 26, 27, 28, 29, 30, - 31, 18, 141, 0, 0, 19, 20, 21, 22, 23, - 0, 0, 0, 24, 0, 25, 26, 27, 28, 29, - 30, 31, 18, 0, 0, 0, 19, 20, 21, 22, - 23, 0, 0, 0, 47, 0, 25, 26, 27, 28, - 29, 30, 31, 18, 0, 0, 0, 19, 20, 21, - 22, 23, 0, 0, 0, 97, 0, 25, 26, 27, - 28, 29, 30, 31, 18, 0, 0, 0, 19, 20, - 21, 22, 23, 0, 0, 0, 0, 0, 25, 26, - 27, 28, 29, 30, 31, 62, 0, 63, 64, 65, - 66, 67, 68, 69, 70, 64, 65, 66, 67, 68, - 69, 70 + 59, 51, 74, 49, 90, 81, 41, 17, 85, 4, + 62, 75, 86, 5, 58, -73, 11, 128, 6, 1, + 2, 94, 12, 80, 42, 39, 118, 40, 84, 78, + 119, 41, 6, 43, 44, 76, 79, 113, 47, 98, + 82, 129, 106, 77, 56, 57, 131, 13, 102, 42, + 132, 55, 95, 96, 87, 105, 74, 140, 43, 44, + 109, 141, 111, 148, 135, 114, 136, 132, 52, 122, + 107, 41, 124, 89, 108, 97, 127, 41, 4, 60, + 61, 130, 5, 103, 120, 121, 104, 6, 115, 42, + 92, 93, 99, 100, 125, 42, 60, 61, 43, 44, + 142, 74, 74, 126, 43, 44, 133, 145, 111, 137, + 134, 144, 138, 18, 139, 14, 147, 19, 20, 21, + 22, 23, 24, 116, 143, 46, 110, 117, 26, 27, + 28, 29, 30, 31, 32, 18, 146, 0, 0, 19, + 20, 21, 22, 23, 24, 0, 0, 0, 25, 0, + 26, 27, 28, 29, 30, 31, 32, 18, 0, 0, + 0, 19, 20, 21, 22, 23, 24, 0, 0, 0, + 48, 0, 26, 27, 28, 29, 30, 31, 32, 18, + 0, 0, 0, 19, 20, 21, 22, 23, 24, 0, + 0, 0, 101, 0, 26, 27, 28, 29, 30, 31, + 32, 18, 0, 0, 0, 19, 20, 21, 22, 23, + 24, 0, 0, 0, 0, 0, 26, 27, 28, 29, + 30, 31, 32, 63, 0, 64, 65, 0, 0, 66, + 67, 68, 69, 70, 71, 72, 66, 67, 68, 69, + 70, 71, 72 }; static const yytype_int16 yycheck[] = { - 24, 11, 1, 35, 32, 56, 5, 12, 7, 8, - 58, 10, 5, 0, 6, 14, 6, 1, 27, 24, - 32, 5, 50, 47, 36, 32, 10, 5, 14, 36, - 78, 9, 10, 27, 39, 27, 35, 27, 35, 63, - 7, 46, 34, 36, 3, 4, 24, 71, 76, 59, - 60, 27, 9, 81, 32, 33, 88, 27, 86, 32, - 35, 85, 113, 36, 115, 34, 35, 24, 92, 9, - 80, 95, 27, 97, 79, 32, 33, 11, 102, 36, - 90, 91, 32, 34, 24, 9, 36, 11, 12, 35, - 32, 27, 32, 33, 36, 11, 12, 121, 130, 131, - 24, 11, 12, 127, 128, 32, 32, 32, 32, 33, - 23, 32, 136, 27, 27, 28, 29, 30, 31, 32, - 2, 8, 84, 36, 37, 38, 39, 40, 41, 42, - 43, 23, 128, -1, -1, 27, 28, 29, 30, 31, - -1, -1, -1, 35, -1, 37, 38, 39, 40, 41, - 42, 43, 23, -1, -1, -1, 27, 28, 29, 30, - 31, -1, -1, -1, 35, -1, 37, 38, 39, 40, - 41, 42, 43, 23, -1, -1, -1, 27, 28, 29, - 30, 31, -1, -1, -1, 35, -1, 37, 38, 39, - 40, 41, 42, 43, 23, -1, -1, -1, 27, 28, - 29, 30, 31, -1, -1, -1, -1, -1, 37, 38, - 39, 40, 41, 42, 43, 13, -1, 15, 16, 17, - 18, 19, 20, 21, 22, 16, 17, 18, 19, 20, - 21, 22 + 25, 12, 36, 11, 57, 5, 9, 0, 36, 1, + 33, 6, 40, 5, 25, 7, 8, 6, 10, 3, + 4, 59, 14, 48, 27, 30, 36, 5, 51, 40, + 40, 9, 10, 36, 37, 30, 47, 40, 14, 64, + 40, 30, 80, 38, 38, 39, 36, 39, 73, 27, + 40, 7, 60, 61, 39, 78, 90, 36, 36, 37, + 83, 40, 87, 36, 117, 88, 119, 40, 30, 94, + 81, 9, 97, 30, 82, 39, 101, 9, 1, 11, + 12, 106, 5, 30, 92, 93, 30, 10, 38, 27, + 11, 12, 17, 18, 11, 27, 11, 12, 36, 37, + 125, 135, 136, 17, 36, 37, 39, 132, 133, 36, + 30, 30, 36, 26, 36, 2, 141, 30, 31, 32, + 33, 34, 35, 36, 36, 8, 86, 40, 41, 42, + 43, 44, 45, 46, 47, 26, 133, -1, -1, 30, + 31, 32, 33, 34, 35, -1, -1, -1, 39, -1, + 41, 42, 43, 44, 45, 46, 47, 26, -1, -1, + -1, 30, 31, 32, 33, 34, 35, -1, -1, -1, + 39, -1, 41, 42, 43, 44, 45, 46, 47, 26, + -1, -1, -1, 30, 31, 32, 33, 34, 35, -1, + -1, -1, 39, -1, 41, 42, 43, 44, 45, 46, + 47, 26, -1, -1, -1, 30, 31, 32, 33, 34, + 35, -1, -1, -1, -1, -1, 41, 42, 43, 44, + 45, 46, 47, 13, -1, 15, 16, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, + 23, 24, 25 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 45, 1, 5, 10, 46, 48, 49, - 50, 8, 14, 35, 46, 60, 62, 0, 23, 27, - 28, 29, 30, 31, 35, 37, 38, 39, 40, 41, - 42, 43, 51, 52, 55, 56, 58, 59, 27, 5, - 9, 24, 32, 33, 47, 49, 14, 35, 52, 66, - 51, 27, 63, 64, 7, 34, 35, 51, 55, 11, - 12, 47, 13, 15, 16, 17, 18, 19, 20, 21, - 22, 53, 58, 6, 27, 34, 51, 51, 55, 5, - 36, 67, 47, 32, 36, 35, 61, 27, 56, 57, - 11, 12, 53, 52, 52, 35, 55, 35, 55, 27, - 27, 47, 53, 51, 52, 47, 64, 55, 65, 36, - 47, 34, 32, 36, 32, 36, 52, 52, 55, 54, - 55, 11, 55, 6, 27, 55, 32, 36, 35, 27, - 56, 56, 32, 32, 32, 32, 36, 55, 32, 27, - 55, 65, 55, 32 + 0, 3, 4, 49, 1, 5, 10, 50, 52, 53, + 54, 8, 14, 39, 50, 64, 66, 0, 26, 30, + 31, 32, 33, 34, 35, 39, 41, 42, 43, 44, + 45, 46, 47, 55, 56, 59, 60, 62, 63, 30, + 5, 9, 27, 36, 37, 51, 53, 14, 39, 56, + 70, 55, 30, 67, 68, 7, 38, 39, 55, 59, + 11, 12, 51, 13, 15, 16, 19, 20, 21, 22, + 23, 24, 25, 57, 62, 6, 30, 38, 55, 55, + 59, 5, 40, 71, 51, 36, 40, 39, 65, 30, + 60, 61, 11, 12, 57, 56, 56, 39, 59, 17, + 18, 39, 59, 30, 30, 51, 57, 55, 56, 51, + 68, 59, 69, 40, 51, 38, 36, 40, 36, 40, + 56, 56, 59, 58, 59, 11, 17, 59, 6, 30, + 59, 36, 40, 39, 30, 60, 60, 36, 36, 36, + 36, 40, 59, 36, 30, 59, 69, 59, 36 }; #define yyerrok (yyerrstatus = 0) @@ -2003,47 +2107,47 @@ YYLTYPE yylloc; case 31: - { (yyval.func) = F_COMP_EQ; ;} + { (yyval.relation) = NULL; ;} break; case 32: - { (yyval.func) = F_COMP_NSEQ; ;} + { (yyval.relation) = NULL; ;} break; case 33: - { (yyval.func) = F_COMP_GE; ;} + { (yyval.func) = F_COMP_EQ; ;} break; case 34: - { (yyval.func) = F_COMP_GT; ;} + { (yyval.func) = F_COMP_NSEQ; ;} break; case 35: - { (yyval.func) = F_COMP_LE; ;} + { (yyval.func) = F_COMP_GE; ;} break; case 36: - { (yyval.func) = F_COMP_LT; ;} + { (yyval.func) = F_COMP_GT; ;} break; case 37: - { (yyval.func) = F_COMP_NE; ;} + { (yyval.func) = F_COMP_LE; ;} break; case 38: - { (yyval.list) = (yyvsp[(1) - (1)].list); ;} + { (yyval.func) = F_COMP_LT; ;} break; case 39: - { (yyval.list) = (yyvsp[(1) - (3)].list); add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} + { (yyval.func) = F_COMP_NE; ;} break; case 40: @@ -2053,31 +2157,41 @@ YYLTYPE yylloc; case 41: - { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); ;} + { (yyval.list) = (yyvsp[(1) - (3)].list); add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; case 42: - { add_token((yyvsp[(1) - (2)].list), result, (yyvsp[(2) - (2)].node)); (yyval.list) = (yyvsp[(1) - (2)].list); ;} + { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; case 43: - { (yyval.list) = NULL; ;} + { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); ;} break; case 44: - { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + { add_token((yyvsp[(1) - (2)].list), result, (yyvsp[(2) - (2)].node)); (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; case 45: - { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + { (yyval.list) = NULL; ;} break; case 46: + { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + break; + + case 47: + + { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + break; + + case 48: + { malloc_node((yyval.node), result, TOKEN_COLUMN); (yyval.node)->part_key_idx_ = 0; @@ -2086,7 +2200,7 @@ YYLTYPE yylloc; ;} break; - case 47: + case 49: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2095,7 +2209,7 @@ YYLTYPE yylloc; ;} break; - case 48: + case 50: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2104,7 +2218,7 @@ YYLTYPE yylloc; ;} break; - case 49: + case 51: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2113,7 +2227,15 @@ YYLTYPE yylloc; ;} break; - case 50: + case 52: + + { + malloc_node((yyval.node), result, TOKEN_FUNC); + (yyval.node)->str_value_ = (yyvsp[(1) - (1)].str); + ;} + break; + + case 53: { malloc_node((yyval.node), result, TOKEN_FUNC); @@ -2122,7 +2244,7 @@ YYLTYPE yylloc; ;} break; - case 51: + case 54: { malloc_node((yyval.node), result, TOKEN_FUNC); @@ -2131,22 +2253,22 @@ YYLTYPE yylloc; ;} break; - case 52: + case 55: { malloc_node((yyval.node), result, TOKEN_INT_VAL); (yyval.node)->int_value_ = (yyvsp[(1) - (1)].num); ;} break; - case 53: + case 56: { malloc_node((yyval.node), result, TOKEN_STR_VAL); (yyval.node)->str_value_ = (yyvsp[(1) - (1)].str); ;} break; - case 54: + case 57: { malloc_node((yyval.node), result, TOKEN_OPERATOR); (yyval.node)->operator_ = (yyvsp[(1) - (1)].operator); ;} break; - case 55: + case 58: { result->placeholder_list_idx_++; @@ -2155,7 +2277,7 @@ YYLTYPE yylloc; ;} break; - case 56: + case 59: { malloc_node((yyval.node), result, TOKEN_PLACE_HOLDER); @@ -2163,71 +2285,76 @@ YYLTYPE yylloc; ;} break; - case 57: + case 60: { (yyval.operator) = OPT_ADD; ;} break; - case 58: + case 61: { (yyval.operator) = OPT_MINUS; ;} break; - case 59: + case 62: { (yyval.operator) = OPT_MUL; ;} break; - case 60: + case 63: { (yyval.operator) = OPT_DIV; ;} break; - case 61: + case 64: { (yyval.operator) = OPT_MOD; ;} break; - case 62: + case 65: { (yyval.operator) = OPT_AND; ;} break; - case 63: + case 66: { (yyval.operator) = OPT_NOT; ;} break; - case 64: + case 67: { YYACCEPT; ;} break; - case 65: + case 68: { YYACCEPT; ;} break; - case 66: + case 69: { YYACCEPT; ;} break; - case 68: + case 71: { result->multi_param_values_++; ;} break; - case 69: + case 72: { result->multi_param_values_++; ;} break; - case 72: + case 73: + + { init_part_key_all_match(result);;} + break; + + case 75: { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); @@ -2235,7 +2362,7 @@ YYLTYPE yylloc; ;} break; - case 73: + case 76: { malloc_list((yyval.list), result, (yyvsp[(3) - (3)].node)); @@ -2243,7 +2370,7 @@ YYLTYPE yylloc; ;} break; - case 74: + case 77: { set_part_key_column_idx(result, &(yyvsp[(1) - (1)].str)); @@ -2253,7 +2380,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 78: { if (result->multi_param_values_ < 1) { @@ -2266,7 +2393,7 @@ YYLTYPE yylloc; ;} break; - case 76: + case 79: { if (result->multi_param_values_ < 1) { @@ -2278,17 +2405,17 @@ YYLTYPE yylloc; ;} break; - case 77: + case 80: { check_and_add_relation(result, (yyvsp[(1) - (1)].relation)); ;} break; - case 78: + case 81: { check_and_add_relation(result, (yyvsp[(3) - (3)].relation)); ;} break; - case 80: + case 83: {;} break; diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h index 8c2fb973..9fee1347 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h @@ -69,22 +69,26 @@ extern int ob_expr_parser_utf8_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif diff --git a/src/obproxy/opsql/expr_resolver/ob_expr_resolver.cpp b/src/obproxy/opsql/expr_resolver/ob_expr_resolver.cpp index e0964303..6a656e7e 100644 --- a/src/obproxy/opsql/expr_resolver/ob_expr_resolver.cpp +++ b/src/obproxy/opsql/expr_resolver/ob_expr_resolver.cpp @@ -11,6 +11,10 @@ */ #define USING_LOG_PREFIX PROXY +#include "opsql/func_expr_resolver/ob_func_expr_resolver.h" +#include "opsql/func_expr_parser/ob_func_expr_parser.h" +#include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_factory.h" +#include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h" #include "opsql/expr_resolver/ob_expr_resolver.h" #include "proxy/route/obproxy_part_info.h" #include "proxy/route/obproxy_expr_calculator.h" @@ -20,11 +24,14 @@ #include "proxy/mysql/ob_prepare_statement_struct.h" #include "obutils/ob_proxy_sql_parser.h" #include "utils/ob_proxy_utils.h" +#include "dbconfig/ob_proxy_db_config_info.h" +#include "common/ob_obj_compare.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::proxy; using namespace oceanbase::obproxy::obutils; using namespace oceanbase::obmysql; +using namespace oceanbase::obproxy::dbconfig; namespace oceanbase { @@ -60,6 +67,51 @@ int64_t ObExprResolverResult::to_string(char *buf, const int64_t buf_len) const return pos; } +/** + * @brief The range's border flag is decided by the last valid column. + * If use range directly, the range will cover partition which + * doesn't contain the data. + * + * @param range + * @param border_flags all columns' border flag + * @return int + */ +int ObExprResolver::preprocess_range(ObNewRange &range, ObIArray &border_flags) { + int ret = OB_SUCCESS; + ObObj *obj_start = const_cast(range.start_key_.get_obj_ptr()); + ObObj *obj_end = const_cast(range.end_key_.get_obj_ptr()); + int64_t invalid_idx = range.start_key_.get_obj_cnt(); + for (int64_t i = 0; i < range.start_key_.get_obj_cnt(); i++) { + // find the last valid col, + // use the last valid col's border flag as range's border flag + range.border_flag_.set_data(border_flags.at(i).get_data()); + if (OB_ISNULL(obj_start) || OB_ISNULL(obj_end)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null pointer"); + } else { + ObCompareCtx cmp_ctx(ObMaxType, CS_TYPE_INVALID, true, INVALID_TZ_OFF); + bool need_cast = false; + ObObj cmp_result(false); + if (OB_FAIL(ObObjCmpFuncs::compare(cmp_result, *obj_start, *obj_end, cmp_ctx, ObCmpOp::CO_EQ, need_cast))) { + LOG_WARN("fail to compare", K(ret)); + invalid_idx = i + 1; + ret = OB_SUCCESS; + break; + } else if (!cmp_result.get_bool()) { + invalid_idx = i + 1; + break; + } + } + } + // set the cols after invalid_idx(included) to (max : min) + for (int64_t i = invalid_idx; i < range.start_key_.get_obj_cnt(); i++) { + (obj_start + i)->set_max_value(); + (obj_end + i)->set_min_value(); + } + LOG_DEBUG("succ to simplify range", K(range)); + return ret; +} + int ObExprResolver::resolve(ObExprResolverContext &ctx, ObExprResolverResult &result) { int ret = OB_SUCCESS; @@ -67,27 +119,156 @@ int ObExprResolver::resolve(ObExprResolverContext &ctx, ObExprResolverResult &re ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid ctx", K(ctx.relation_info_), K(ret)); } else { - // ignore ret in for loop - for (int64_t i = 0; i < ctx.relation_info_->relation_num_; ++i) { - if (OB_ISNULL(ctx.relation_info_->relations_[i])) { - LOG_INFO("relations is not valid here, ignore it", - K(ctx.relation_info_->relations_[i]), K(i)); - } else if (OB_UNLIKELY(ctx.relation_info_->relations_[i]->level_ == PART_KEY_LEVEL_ZERO)) { - LOG_INFO("level is zero, ignore it"); + proxy::ObProxyPartInfo *part_info = ctx.part_info_; + + // to store partition column's border flag as order above like + // "where c2 > 1 and c1 < 33" => ordered_part_col_border [(exclusive_start, exclusive_end] + ObSEArray part_columns_border; + ObSEArray sub_part_columns_border; + + // init range and border + if (part_info->get_part_level() >= share::schema::PARTITION_LEVEL_ONE) { + if (OB_FAIL(result.ranges_[0].build_row_key(part_info->get_part_columns().count(), allocator_))) { + LOG_WARN("fail to init range", K(ret)); } else { - int64_t part_idx = (ctx.relation_info_->relations_[i]->level_ >= PART_KEY_LEVEL_BOTH) ? 0 - : static_cast(ctx.relation_info_->relations_[i]->level_ - 1); - if (OB_FAIL(resolve_token_list(ctx.relation_info_->relations_[i], - ctx.part_info_, - ctx.client_request_, - ctx.client_info_, - ctx.ps_id_entry_, - ctx.text_ps_entry_, - result.ranges_[part_idx]))) { - LOG_INFO("fail to resolve token list, ignore it", K(ret)); + for (int i = 0; OB_SUCC(ret) && i < part_info->get_part_columns().count(); i++) { + if (OB_FAIL(part_columns_border.push_back(ObBorderFlag()))) { + LOG_WARN("fail to push border flag", K(i), K(ret)); + } + } + } + } + if (part_info->get_part_level() == share::schema::PARTITION_LEVEL_TWO) { + if (OB_FAIL(result.ranges_[1].build_row_key(part_info->get_sub_part_columns().count(), allocator_))) { + LOG_WARN("fail to init range", K(ret)); + } else { + for (int i = 0; OB_SUCC(ret) && i < part_info->get_sub_part_columns().count(); i++) { + if (OB_FAIL(sub_part_columns_border.push_back(ObBorderFlag()))) { + LOG_WARN("fail to push border flag", K(i), K(ret)); + } } } } + + if (OB_SUCC(ret)) { + ObObj *target_obj = NULL; + void *tmp_buf = NULL; + + // ignore ret in for loop + // resolve every relation + for (int64_t i = 0; i < ctx.relation_info_->relation_num_; ++i) { + if (OB_ISNULL(ctx.relation_info_->relations_[i])) { + LOG_INFO("relations is not valid here, ignore it", + K(ctx.relation_info_->relations_[i]), K(i)); + } else if (OB_UNLIKELY(ctx.relation_info_->relations_[i]->level_ == PART_KEY_LEVEL_ZERO)) { + LOG_INFO("level is zero, ignore it"); + } else { + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObObj)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc new obj", K(ret)); + } else if (OB_ISNULL(target_obj = new (tmp_buf) ObObj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to do placement new", K(ret)); + } else if (OB_FAIL(resolve_token_list(ctx.relation_info_->relations_[i], ctx.part_info_, ctx.client_request_, + ctx.client_info_, ctx.ps_id_entry_, ctx.text_ps_entry_, target_obj, + ctx.sql_field_result_))) { + LOG_INFO("fail to resolve token list, ignore it", K(ret)); + } else if ((PART_KEY_LEVEL_ONE == ctx.relation_info_->relations_[i]->level_ || + PART_KEY_LEVEL_BOTH == ctx.relation_info_->relations_[i]->level_) && + OB_FAIL(place_obj_to_range(ctx.relation_info_->relations_[i]->type_, + ctx.relation_info_->relations_[i]->first_part_column_idx_, + target_obj, &result.ranges_[0], part_columns_border))) { + LOG_WARN("fail to place obj to range of part level one", K(ret)); + } else if ((PART_KEY_LEVEL_TWO == ctx.relation_info_->relations_[i]->level_ || + PART_KEY_LEVEL_BOTH == ctx.relation_info_->relations_[i]->level_) && + OB_FAIL(place_obj_to_range(ctx.relation_info_->relations_[i]->type_, + ctx.relation_info_->relations_[i]->second_part_column_idx_, + target_obj, &result.ranges_[1], sub_part_columns_border))) { + LOG_WARN("fail to place obj to range of part level two", K(ret)); + } else {} + if (OB_NOT_NULL(target_obj)) { + allocator_.free(target_obj); + } + } + } + + if (OB_SUCC(ret) && ctx.is_insert_stm_) { + if(OB_FAIL(handle_default_value(ctx.parse_result_->part_key_info_, + ctx.client_info_, result.ranges_, + ctx.sql_field_result_,part_columns_border, + sub_part_columns_border, part_info->is_oracle_mode()))){ + LOG_WARN("fail to handle default value of part keys", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(preprocess_range(result.ranges_[0], part_columns_border))) { + LOG_WARN("fail to preprocess range, part key level 0", K(ret)); + } else if (OB_FAIL(preprocess_range(result.ranges_[1], sub_part_columns_border))) { + LOG_WARN("fail to preprocess range, part key level 1", K(ret)); + } else {} + } + } + } + return ret; +} + +/** + * @brief 1. Place the resolved partition obj to range.start_key_/range.end_key_[idx]. + * The idx is the obj's according column's idx in partition expression. + * 2. Set the border flag of the partition obj. Use the border flag later in ObExprResolver::preprocess_range. + * + * @param relation + * @param part_info + * @param target_obj + * @param range out + * @param border_flags out + * @param part_columns + * @return int + */ +int ObExprResolver::place_obj_to_range(ObProxyFunctionType type, + int64_t idx_in_part_columns, + ObObj *target_obj, + ObNewRange *range, + ObIArray &border_flags) +{ + int ret = OB_SUCCESS; + ObObj *start_obj = const_cast(range->start_key_.get_obj_ptr()) + idx_in_part_columns; + ObObj *end_obj = const_cast(range->end_key_.get_obj_ptr()) + idx_in_part_columns; + if (OB_ISNULL(start_obj) || OB_ISNULL(end_obj) || OB_ISNULL(target_obj)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null pointer"); + } + + // 1. deep copy the resolved obj to right position in result.ranges_[x] + // 2. set the resolved obj's border flag + if (OB_SUCC(ret)) { + switch (type) { + case F_COMP_EQ: + *start_obj = *target_obj; + *end_obj = *target_obj; + border_flags.at(idx_in_part_columns).set_inclusive_start(); + border_flags.at(idx_in_part_columns).set_inclusive_end(); + break; + case F_COMP_GE: + *start_obj = *target_obj; + border_flags.at(idx_in_part_columns).set_inclusive_start(); + break; + case F_COMP_GT: + *start_obj = *target_obj; + break; + case F_COMP_LE: + *end_obj = *target_obj; + border_flags.at(idx_in_part_columns).set_inclusive_end(); + break; + case F_COMP_LT: + *end_obj = *target_obj; + break; + default: + LOG_INFO("this func is not useful for range", "func_type", + get_obproxy_function_type(type)); + break; + } // end of switch } return ret; } @@ -108,179 +289,365 @@ int ObExprResolver::resolve_token_list(ObProxyRelationExpr *relation, ObClientSessionInfo *client_info, ObPsIdEntry *ps_id_entry, ObTextPsEntry *text_ps_entry, - ObNewRange &range, + ObObj *target_obj, + SqlFieldResult *sql_field_result, const bool has_rowid) { int ret = OB_SUCCESS; UNUSED(text_ps_entry); - if (OB_ISNULL(relation) || OB_ISNULL(part_info)) { + if (OB_ISNULL(target_obj)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("target_obj is null"); + } else if (OB_ISNULL(relation) || OB_ISNULL(part_info)) { ret = OB_INVALID_ARGUMENT; LOG_INFO("relation or part info is null", K(relation), K(part_info), K(ret)); } else if (OB_ISNULL(relation->right_value_) || OB_ISNULL(relation->right_value_->head_)) { ret = OB_INVALID_ARGUMENT; LOG_INFO("token list or head is null", K(relation->right_value_), K(ret)); } else { - ObObj *target_obj = NULL; - void *tmp_buf = NULL; + ObProxyTokenNode *token = relation->right_value_->head_; + int64_t col_idx = relation->column_idx_; + if (TOKEN_STR_VAL == token->type_) { + target_obj->set_varchar(token->str_value_.str_, token->str_value_.str_len_); + target_obj->set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + } else if (TOKEN_INT_VAL == token->type_) { + target_obj->set_int(token->int_value_); + } else if (TOKEN_PLACE_HOLDER == token->type_) { + int64_t param_index = token->placeholder_idx_; + if (OB_FAIL(get_obj_with_param(*target_obj, client_request, client_info, + part_info, ps_id_entry, param_index))) { + LOG_DEBUG("fail to get target obj with param", K(ret)); + } + } else if (TOKEN_FUNC == token->type_) { + if (OB_FAIL(calc_token_func_obj(token, client_info, *target_obj, sql_field_result, part_info->is_oracle_mode()))) { + LOG_WARN("fail to calc token func obj", K(ret)); + } + } else { + ret = OB_INVALID_ARGUMENT; + } + + if (OB_SUCC(ret) + && !has_rowid + && part_info->has_generated_key()) { + int64_t target_idx = -1; + ObProxyPartKeyInfo &part_key_info = part_info->get_part_key_info(); + if (col_idx >= part_key_info.key_num_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("relation column index is invalid", K(col_idx), K(part_key_info.key_num_), K(ret)); + } else if (part_key_info.part_keys_[col_idx].is_generated_) { + // do nothing, user sql explicitly contains value for generated key, no need to calculate + } else if (FALSE_IT(target_idx = part_key_info.part_keys_[col_idx].generated_col_idx_)) { + // will not come here + } else if (OB_UNLIKELY(0 > target_idx)) { + LOG_DEBUG("this relation's part key is not used to generate column"); + } else if (OB_UNLIKELY(target_idx >= part_key_info.key_num_) + || OB_UNLIKELY(!part_key_info.part_keys_[target_idx].is_generated_) + || OB_UNLIKELY(part_key_info.part_keys_[target_idx].level_ != relation->level_)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("fail to get generated key value, source key is not offered", + K(col_idx), K(part_key_info.key_num_), K(target_idx), K(ret)); + } else if (OB_FAIL(calc_generated_key_value(*target_obj, part_key_info.part_keys_[col_idx], + part_info->is_oracle_mode()))) { + LOG_WARN("fail to get generated key value", K(target_obj), K(ret)); + } else { + LOG_DEBUG("succ to calculate generated key value", K(target_obj), K(ret)); + } + } + + if (OB_SUCC(ret) && ObStringTC == target_obj->get_type_class()) { + // The character set of the string parsed from the parser uses the value of the variable collation_connection + target_obj->set_collation_type(static_cast(client_info->get_collation_connection())); + } + } // end of else + return ret; +} + +/* + * calculate func token, convert token node to param node to reuse func resolver + */ +int ObExprResolver::calc_token_func_obj(ObProxyTokenNode *token, + ObClientSessionInfo *client_session_info, + ObObj &target_obj, + SqlFieldResult *sql_field_result, + const bool is_oracle_mode) +{ + int ret = OB_SUCCESS; + ObProxyParamNode *param_node = NULL; + ObProxyExprFactory factory(allocator_); + ObFuncExprResolverContext ctx(&allocator_, &factory); + ObFuncExprResolver resolver(ctx); + ObProxyExpr *expr; + + if (OB_FAIL(convert_token_node_to_param_node(token, param_node))) { + LOG_WARN("fail to convert func token to param node", K(ret)); + } else if (OB_ISNULL(param_node)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to convert func token to param node", K(ret)); + } else if (OB_FAIL(resolver.resolve(param_node, expr))) { + LOG_WARN("proxy expr resolve failed", K(ret)); + } else { + ObSEArray result_array; + ObProxyExprCalcItem calc_item(const_cast(sql_field_result)); + ObProxyExprCtx expr_ctx(0, TESTLOAD_NON, false, &allocator_, client_session_info); + expr_ctx.is_oracle_mode = is_oracle_mode; + if (OB_FAIL(expr->calc(expr_ctx, calc_item, result_array))) { + LOG_WARN("calc expr result failed", K(ret)); + } else if (OB_FAIL(result_array.at(0, target_obj))) { + LOG_WARN("get expr calc result fail", K(ret)); + } + } + + return ret; +} + +int ObExprResolver::handle_default_value(ObProxyPartKeyInfo &part_key_info, + proxy::ObClientSessionInfo *client_info, + common::ObNewRange ranges[], + obutils::SqlFieldResult *sql_field_result, + ObIArray &part_border_flags, + ObIArray &sub_part_border_flags, + bool is_oracle_mode) +{ + int ret = OB_SUCCESS; + ObObj *target_obj = NULL; + void *tmp_buf = NULL; + for (int i = 0; OB_SUCC(ret) && i < part_key_info.key_num_; i++) { + ObProxyPartKeyLevel level = part_key_info.part_keys_[i].level_; + int64_t column_idx = part_key_info.part_keys_[i].idx_in_part_columns_; + bool is_need_default_val = false; + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObObj)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc new obj", K(ret)); - } else { - target_obj = new (tmp_buf) ObObj(); - - ObProxyFunctionType &func_type = relation->type_; - ObProxyTokenNode *token = relation->right_value_->head_; - int64_t col_idx = relation->column_idx_; - if (TOKEN_STR_VAL == token->type_) { - target_obj->set_varchar(token->str_value_.str_, token->str_value_.str_len_); - target_obj->set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - } else if (TOKEN_INT_VAL == token->type_) { - target_obj->set_int(token->int_value_); - } else if (TOKEN_PLACE_HOLDER == token->type_) { - int64_t param_index = token->placeholder_idx_; - if (OB_FAIL(get_obj_with_param(*target_obj, client_request, client_info, - part_info, ps_id_entry, param_index))) { - LOG_DEBUG("fail to get target obj with param", K(ret)); + } else if (OB_ISNULL(target_obj = new (tmp_buf) ObObj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to do placement new ObObj", K(ret)); + } + + if(OB_SUCC(ret)){ + if (part_key_info.part_keys_[i].is_generated_ && !part_key_info.part_keys_[i].is_exist_in_sql_) { + int source_idx = -1; + ObProxyParseString *var_str = NULL; + for (int j = 0; j < part_key_info.key_num_; j++) { + if (part_key_info.part_keys_[j].generated_col_idx_ == i + && !part_key_info.part_keys_[j].is_exist_in_sql_) { + source_idx = j; + break; + } } - } else if (TOKEN_FUNC == token->type_) { - if (OB_FAIL(calc_token_func_obj(token, client_info, *target_obj))) { - LOG_WARN("fail to calc token func obj", K(ret)); + if (source_idx >= 0) { + int64_t real_source_idx = part_key_info.part_keys_[source_idx].real_source_idx_; + if (real_source_idx < 0 || real_source_idx > OBPROXY_MAX_PART_KEY_NUM){ + // invalid real source idx + } else if (FALSE_IT(var_str = &part_key_info.part_keys_[real_source_idx].default_value_) || var_str->str_len_ < 0 ){ + } else if (OB_FAIL(parse_and_resolve_default_value(*var_str, client_info, sql_field_result, target_obj, is_oracle_mode))){ + LOG_WARN("parse and resolve default value of partition key failed", K(ret)); + } else if (OB_FAIL(calc_generated_key_value(*target_obj, part_key_info.part_keys_[source_idx], is_oracle_mode))) { + LOG_WARN("fail to get generated key value", K(target_obj), K(ret)); + } else { + is_need_default_val = true; + } + } + } else if (!part_key_info.part_keys_[i].is_exist_in_sql_) { + ObProxyParseString &var_str = part_key_info.part_keys_[i].default_value_; + if (var_str.str_len_ > 0) { + if (OB_FAIL(parse_and_resolve_default_value(var_str, client_info, sql_field_result, target_obj, is_oracle_mode))) { + LOG_WARN("parse and resolve default value of partition key failed", K(ret)); + } else { + is_need_default_val = true; + } } - } else { - ret = OB_INVALID_ARGUMENT; } + } + + if (OB_SUCC(ret) && is_need_default_val) { + if ((PART_KEY_LEVEL_ONE == level || PART_KEY_LEVEL_BOTH == level) && + OB_FAIL(place_obj_to_range(F_COMP_EQ, column_idx, target_obj, &ranges[0], part_border_flags))) { + LOG_WARN("fail to place obj to range of part level one", K(ret)); + } else if ((PART_KEY_LEVEL_TWO == level || PART_KEY_LEVEL_BOTH == level) && + OB_FAIL(place_obj_to_range(F_COMP_EQ, column_idx, target_obj, &ranges[1], sub_part_border_flags))) { + LOG_WARN("fail to place obj to range of part level two", K(ret)); + } else {} + } + if (OB_NOT_NULL(target_obj)) { + allocator_.free(target_obj); + } + } + return ret; +} - if (!has_rowid - && part_info->has_generated_key()) { - int64_t target_idx = -1; - ObProxyPartKeyInfo &part_key_info = part_info->get_part_key_info(); - if (col_idx >= part_key_info.key_num_) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("relation column index is invalid", K(col_idx), K(part_key_info.key_num_), K(ret)); - } else if (part_key_info.part_keys_[col_idx].is_generated_) { - // do nothing, user sql explicitly contains value for generated key, no need to calculate - } else if (FALSE_IT(target_idx = part_key_info.part_keys_[col_idx].generated_col_idx_)) { - // will not come here - } else if (OB_UNLIKELY(target_idx >= part_key_info.key_num_) - || OB_UNLIKELY(target_idx < 0) - || OB_UNLIKELY(!part_key_info.part_keys_[target_idx].is_generated_) - || OB_UNLIKELY(part_key_info.part_keys_[target_idx].level_ != relation->level_)) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("fail to get generated key value, source key is not offered", - K(col_idx), K(part_key_info.key_num_), K(target_idx), K(ret)); - } else if (OB_FAIL(calc_generated_key_value(*target_obj, part_key_info.part_keys_[col_idx], - part_info->is_oracle_mode()))) { - LOG_WARN("fail to get generated key value", K(target_obj), K(ret)); +int ObExprResolver::parse_and_resolve_default_value(ObProxyParseString &default_value, + ObClientSessionInfo *client_session_info, + SqlFieldResult *sql_field_result, + ObObj *target_obj, + bool is_oracle_mode) +{ + int ret = OB_SUCCESS; + number::ObNumber nb; + if (default_value.str_len_ > 0 ){ + int64_t tmp_pos = 0; + if (OB_FAIL(target_obj->deserialize(default_value.str_ , default_value.str_len_, tmp_pos))) { + LOG_WARN("fail to deserialize default value of part key"); + } else if (FALSE_IT(LOG_DEBUG("default value deserialize succ" , K(*target_obj)))) { + } else if (target_obj->is_varchar() && is_oracle_mode) { + // oracle mode return the default as a unresolved varchar type obj + ObString default_value_expr = target_obj->get_varchar(); + if (default_value_expr.empty()) { + target_obj->set_varchar(ObString()); + } else if ('\'' == default_value_expr[0]) { + // match string type + ObString dst; + if (2 >= default_value_expr.length()) { + dst = ObString(); + // remove single quotes + } else if (OB_FAIL(ob_sub_str(allocator_, default_value_expr, 1, default_value_expr.length() - 2, dst))) { + LOG_WARN("get sub stirng of default value failed", K(ret)); + } + if (OB_SUCC(ret)) { + target_obj->set_varchar(dst); + } + } else if ( OB_SUCCESS == nb.from(default_value_expr.ptr(), default_value_expr.length(), allocator_)) { + // match positive number + } else if ('-' == default_value_expr[0] && 4 <= default_value_expr.length()) { + // match megative number + // server return negative with brackets, -1 -> -(1) + ObString number_part; + char *buf = NULL; + if(OB_FAIL(ob_sub_str(allocator_, default_value_expr, 2, default_value_expr.length() - 2, number_part))) { + LOG_WARN("get default value number part fail", K(ret)); + } else if (OB_ISNULL(buf = static_cast(allocator_.alloc(number_part.length() + 1)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory failed", K(ret)); } else { - LOG_DEBUG("succ to calculate generated key value", K(target_obj), K(ret)); + MEMCPY(buf, "-", 1); + MEMCPY(buf + 1, number_part.ptr(), number_part.length()); + target_obj->set_varchar(ObString(number_part.length()+1, buf)); } - } + } else { + // match expr + ObFuncExprParser parser(allocator_, SHARDING_EXPR_FUNC_PARSE_MODE); + ObFuncExprParseResult result; - if (OB_SUCC(ret) && ObStringTC == target_obj->get_type_class()) { - // The character set of the string parsed from the parser uses the value of the variable collation_connection - target_obj->set_collation_type(static_cast(client_info->get_collation_connection())); - } + ObProxyExprFactory factory(allocator_); + ObFuncExprResolverContext ctx(&allocator_, &factory); + ObFuncExprResolver resolver(ctx); + ObProxyExpr *expr; - if (OB_SUCC(ret)) { - switch (func_type) { - case F_COMP_EQ: - range.start_key_.assign(target_obj, 1); - range.end_key_.assign(target_obj, 1); - range.border_flag_.set_inclusive_start(); - range.border_flag_.set_inclusive_end(); - break; - case F_COMP_GE: - range.start_key_.assign(target_obj, 1); - range.border_flag_.set_inclusive_start(); - break; - case F_COMP_GT: - range.start_key_.assign(target_obj, 1); - break; - case F_COMP_LE: - range.end_key_.assign(target_obj, 1); - range.border_flag_.set_inclusive_end(); - break; - case F_COMP_LT: - range.end_key_.assign(target_obj, 1); - break; - default: - LOG_INFO("this func is not useful for range", "func_type", - get_obproxy_function_type(func_type)); - break; - } // end of switch - } // end of if - } // end of else - } // end of else + if (OB_FAIL(parser.parse(default_value_expr, result))) { + LOG_INFO("parse default value expr failed", K(ret)); + } else if (OB_FAIL(resolver.resolve(result.param_node_, expr))) { + LOG_INFO("proxy expr resolve failed", K(ret)); + } else { + ObSEArray result_array; + ObProxyExprCalcItem calc_item(const_cast(sql_field_result)); + ObProxyExprCtx expr_ctx(0, TESTLOAD_NON, false, &allocator_, client_session_info); + expr_ctx.is_oracle_mode = is_oracle_mode; + if (OB_FAIL(expr->calc(expr_ctx, calc_item, result_array))) { + LOG_WARN("calc expr result failed", K(ret)); + } else if (OB_FAIL(result_array.at(0, *target_obj))) { + LOG_WARN("get expr calc result fail", K(ret)); + } + } + } + } else { + // mysql mode return the default value with resolved obj in column's type + // do nothing + } + } + if (OB_SUCC(ret) && ObStringTC == target_obj->get_type_class()) { + LOG_DEBUG("parse and resolve default value succ", K(*target_obj), K(ret)); + target_obj->set_collation_type(static_cast(client_session_info->get_collation_connection())); + } return ret; } -/* - * currently only support to_date/to_timestamp function - * currently support at least one param, at most two params now - */ -int ObExprResolver::calc_token_func_obj(ObProxyTokenNode *token, - ObClientSessionInfo *client_session_info, - ObObj &target_obj) +int ObExprResolver::convert_token_node_to_param_node(ObProxyTokenNode *token, + ObProxyParamNode *¶m) { int ret = OB_SUCCESS; - ObObjType target_type = ObMaxType; - ObString func_name(token->str_value_.str_len_ ,token->str_value_.str_); - - if (func_name.case_compare("to_date") == 0) { - target_type = ObDateTimeType; - } else if (func_name.case_compare("to_timestamp") == 0) { - target_type = ObTimestampNanoType; + if (OB_ISNULL(token)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret)); } else { - /* more function could be supported */ + void *tmp_buf = NULL; + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObProxyParamNode)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc new param node", K(ret)); + } else { + param = new(tmp_buf) ObProxyParamNode(); + param->next_ = NULL; + if (TOKEN_INT_VAL == token->type_) { + param->int_value_ = token->int_value_; + param->type_ = PARAM_INT_VAL; + } else if (TOKEN_STR_VAL == token->type_) { + param->str_value_ = token->str_value_; + param->type_ = PARAM_STR_VAL; + } else if (TOKEN_FUNC == token->type_) { + if (OB_FAIL(recursive_convert_func_token(token, param))) { + LOG_WARN("convert func token node to param node failed", K(ret)); + } + } else { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("unexpected token node type, please check", K(ret), K(param->type_)); + } + } } + return ret; +} - if (target_type == ObMaxType) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("fail to parse token func, unsupported function name", K(ret), K(func_name)); - } else if (OB_ISNULL(token->child_) - || OB_ISNULL(token->child_->head_)){ +int ObExprResolver::recursive_convert_func_token(ObProxyTokenNode *token, + ObProxyParamNode *param) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(token) || OB_ISNULL(param) || token->type_ != TOKEN_FUNC) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("fail to parse token func, param list null", K(ret), K(token->str_value_.str_)); - } else { - ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); - target_obj.set_collation_type(collation); - - ObProxyTokenNode *param_node = token->child_->head_; - if (param_node->type_ == TOKEN_STR_VAL) { - target_obj.set_varchar(param_node->str_value_.str_, param_node->str_value_.str_len_); - } else if (param_node->type_ == TOKEN_INT_VAL) { - target_obj.set_int(param_node->int_value_); + LOG_WARN("invalid argument", K(ret)); + } + + ObString func_name(token->str_value_.str_len_, token->str_value_.str_); + ObProxyExprType func_type = get_expr_token_func_type(&func_name); + if (OB_SUCC(ret) && func_type == OB_PROXY_EXPR_TYPE_NONE) { + ret = OB_ERR_FUNCTION_UNKNOWN; + LOG_WARN("unsupported func type", K(ret), K(func_name), K(func_type)); + } + + if (OB_SUCC(ret)) { + void *tmp_buf = NULL; + param->type_ = PARAM_FUNC; + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObFuncExprNode)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc new func expr node", K(ret)); } else { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("unexpected token node type, please check", K(ret), K(param_node->type_)); - } - - if (OB_SUCC(ret)) { - ObString nls_format; - if (param_node->next_ != NULL) { - nls_format.assign_ptr(param_node->next_->str_value_.str_, param_node->next_->str_value_.str_len_); - } - - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; + param->func_expr_node_ = new(tmp_buf) ObFuncExprNode(); + param->func_expr_node_->func_type_ = func_type; + param->func_expr_node_->child_ = NULL; - if (!nls_format.empty()) { - dtc_params.tz_info_ = &tz_info; - dtc_params.set_nls_format_by_type(target_type, nls_format); + if (OB_ISNULL(token->child_)) { + // do nothing + } else if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObProxyParamNodeList)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc new token list", K(ret)); } else { - dtc_params.tz_info_ = &tz_info; - if (OB_FAIL(ObExprCalcTool::build_dtc_params(client_session_info, target_type, dtc_params))) { - LOG_WARN("fail to build dtc params", K(ret), K(target_type)); + param->func_expr_node_->child_ = new(tmp_buf) ObProxyParamNodeList(); + ObProxyParamNode head; + ObProxyParamNode *param_cur = &head; + ObProxyTokenNode *token_child = token->child_->head_; + int64_t child_num = 0; + for (; OB_SUCC(ret) && token_child != NULL; token_child = token_child->next_, param_cur = param_cur->next_) { + if (OB_FAIL(convert_token_node_to_param_node(token_child, param_cur->next_))) { + LOG_WARN("recursive convert func token failed", K(ret)); + } else { + child_num++; + } + } + if (OB_SUCC(ret)) { + param->func_expr_node_->child_->tail_ = param_cur; + param->func_expr_node_->child_->head_ = head.next_; + param->func_expr_node_->child_->child_num_ = child_num; } - } - - ObCastCtx cast_ctx(&allocator_, &dtc_params, CM_NULL_ON_WARN, collation); - if (OB_SUCC(ret) && OB_FAIL(ObObjCasterV2::to_type(target_type, collation, cast_ctx, target_obj, target_obj))) { - LOG_WARN("fail to cast obj", K(ret), K(target_obj), K(target_type), K(collation)); } } } - return ret; } @@ -346,21 +713,21 @@ int ObExprResolver::get_obj_with_param(ObObj &target_obj, ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid placeholder idx", K(param_index), K(call_info), K(ret)); } else { - const ObProxyCallParam &call_param = call_info.params_.at(param_index); - if (CALL_TOKEN_INT_VAL == call_param.type_) { + const ObProxyCallParam* call_param = call_info.params_.at(param_index); + if (CALL_TOKEN_INT_VAL == call_param->type_) { int64_t int_val = 0; - if (OB_FAIL(get_int_value(call_param.str_value_.string_, int_val))) { - LOG_WARN("fail to get int value", K(call_param.str_value_.string_), K(ret)); + if (OB_FAIL(get_int_value(call_param->str_value_.config_string_, int_val))) { + LOG_WARN("fail to get int value", K(call_param->str_value_.config_string_), K(ret)); } else { target_obj.set_int(int_val); } - } else if (CALL_TOKEN_STR_VAL == call_param.type_) { - target_obj.set_varchar(call_param.str_value_.string_); + } else if (CALL_TOKEN_STR_VAL == call_param->type_) { + target_obj.set_varchar(call_param->str_value_.config_string_); target_obj.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - } else if (CALL_TOKEN_PLACE_HOLDER == call_param.type_) { + } else if (CALL_TOKEN_PLACE_HOLDER == call_param->type_) { need_use_execute_param = true; - if (OB_FAIL(get_int_value(call_param.str_value_.string_, execute_param_index))) { - LOG_WARN("fail to get int value", K(call_param.str_value_.string_), K(ret)); + if (OB_FAIL(get_int_value(call_param->str_value_.config_string_, execute_param_index))) { + LOG_WARN("fail to get int value", K(call_param->str_value_.config_string_), K(ret)); } } } @@ -400,8 +767,8 @@ int ObExprResolver::get_obj_with_param(ObObj &target_obj, LOG_WARN("param index is large than param count", K(execute_param_index), K(execute_info.param_count_), K(ret)); } else { - ObProxyTextPsParam ¶m = execute_info.params_.at(execute_param_index); - ObString user_variable_name = param.str_value_.string_; + ObProxyTextPsParam* param = execute_info.params_.at(execute_param_index); + ObString user_variable_name = param->str_value_.config_string_; if (OB_FAIL(static_cast(*client_info).get_user_variable_value(user_variable_name, target_obj))) { LOG_WARN("get user variable failed", K(ret), K(user_variable_name)); } else { @@ -449,6 +816,63 @@ int ObExprResolver::get_obj_with_param(ObObj &target_obj, return ret; } +ObProxyExprType ObExprResolver::get_expr_token_func_type(ObString *func) +{ + ObProxyExprType type = OB_PROXY_EXPR_TYPE_NONE; + if (func == NULL) { + type = OB_PROXY_EXPR_TYPE_NONE; + } else if (0 == func->case_compare("HASH")) { + type = OB_PROXY_EXPR_TYPE_FUNC_HASH; + } else if (0 == func->case_compare("SUBSTR")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; + } else if (0 == func->case_compare("CONCAT")) { + type = OB_PROXY_EXPR_TYPE_FUNC_CONCAT; + } else if (0 == func->case_compare("TOINT")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TOINT; + } else if (0 == func->case_compare("DIV")) { + type = OB_PROXY_EXPR_TYPE_FUNC_DIV; + } else if (0 == func->case_compare("ADD")) { + type = OB_PROXY_EXPR_TYPE_FUNC_ADD; + } else if (0 == func->case_compare("SUB")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SUB; + } else if (0 == func->case_compare("MUL")) { + type = OB_PROXY_EXPR_TYPE_FUNC_MUL; + } else if (0 == func->case_compare("SUM")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SUM; + } else if (0 == func->case_compare("CONUT")) { + type = OB_PROXY_EXPR_TYPE_FUNC_COUNT; + } else if (0 == func->case_compare("MAX")) { + type = OB_PROXY_EXPR_TYPE_FUNC_MAX; + } else if (0 == func->case_compare("MIN")) { + type = OB_PROXY_EXPR_TYPE_FUNC_MIN; + } else if (0 == func->case_compare("AVG")) { + type = OB_PROXY_EXPR_TYPE_FUNC_AVG; + } else if (0 == func->case_compare("GROUP")) { + type = OB_PROXY_EXPR_TYPE_FUNC_GROUP; + } else if (0 == func->case_compare("ORDER")) { + type = OB_PROXY_EXPR_TYPE_FUNC_ORDER; + } else if (0 == func->case_compare("TESTLOAD")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD; + } else if (0 == func->case_compare("SPLIT")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SPLIT; + } else if (0 == func->case_compare("TO_DATE")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TO_DATE; + } else if (0 == func->case_compare("TO_TIMESTAMP")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP; + } else if (0 == func->case_compare("NVL")) { + type = OB_PROXY_EXPR_TYPE_FUNC_NVL; + } else if (0 == func->case_compare("TO_CHAR")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR; + } else if (0 == func->case_compare("SYSDATE")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SYSDATE; + } else if (0 == func->case_compare("MOD")) { + type = OB_PROXY_EXPR_TYPE_FUNC_MOD; + } else { + type = OB_PROXY_EXPR_TYPE_NONE; + } + return type; +} + } // end of opsql } // end of obproxy } // end of oceanbase diff --git a/src/obproxy/opsql/expr_resolver/ob_expr_resolver.h b/src/obproxy/opsql/expr_resolver/ob_expr_resolver.h index 4f7f1c38..082b2eec 100644 --- a/src/obproxy/opsql/expr_resolver/ob_expr_resolver.h +++ b/src/obproxy/opsql/expr_resolver/ob_expr_resolver.h @@ -25,6 +25,12 @@ class ObNewRange; } namespace obproxy { + +namespace obutils +{ +struct SqlFieldResult; +} + namespace proxy { class ObProxyPartInfo; @@ -38,7 +44,8 @@ namespace opsql struct ObExprResolverContext { ObExprResolverContext() : relation_info_(NULL), part_info_(NULL), client_request_(NULL), - ps_id_entry_(NULL), text_ps_entry_(NULL), client_info_(NULL) {} + ps_id_entry_(NULL), text_ps_entry_(NULL), client_info_(NULL), + sql_field_result_(NULL) {} // parse result ObProxyRelationInfo *relation_info_; proxy::ObProxyPartInfo *part_info_; @@ -47,6 +54,9 @@ struct ObExprResolverContext proxy::ObPsIdEntry *ps_id_entry_; proxy::ObTextPsEntry *text_ps_entry_; proxy::ObClientSessionInfo *client_info_; + obutils::SqlFieldResult *sql_field_result_; + ObExprParseResult *parse_result_; + bool is_insert_stm_; }; class ObExprResolverResult @@ -73,12 +83,21 @@ class ObExprResolver proxy::ObClientSessionInfo *client_info, proxy::ObPsIdEntry *ps_entry, proxy::ObTextPsEntry *text_ps_entry, - common::ObNewRange &range, + common::ObObj *target_obj, + obutils::SqlFieldResult *sql_field_result, const bool has_rowid = false); private: + int preprocess_range(common::ObNewRange &range, common::ObIArray &border_flags); + int place_obj_to_range(ObProxyFunctionType type, + int64_t idx_in_part_columns, + common::ObObj *target_obj, + common::ObNewRange *range, + common::ObIArray &border_flags); int calc_token_func_obj(ObProxyTokenNode *token, proxy::ObClientSessionInfo *client_session_info, - common::ObObj &target_obj); + common::ObObj &target_obj, + obutils::SqlFieldResult *sql_field_result, + const bool is_oracle_mode); int calc_generated_key_value(common::ObObj &obj, const ObProxyPartKey &part_key, const bool is_oracle_mode); int get_obj_with_param(common::ObObj &target_obj, proxy::ObProxyMysqlRequest *client_request, @@ -86,6 +105,24 @@ class ObExprResolver proxy::ObProxyPartInfo *part_info, proxy::ObPsIdEntry *ps_entry, const int64_t param_index); + int convert_token_node_to_param_node(ObProxyTokenNode *token, + ObProxyParamNode *¶m); + int recursive_convert_func_token(ObProxyTokenNode *token, + ObProxyParamNode *param); + int handle_default_value(ObProxyPartKeyInfo &part_info, + proxy::ObClientSessionInfo *client_info, + common::ObNewRange range[], + obutils::SqlFieldResult *sql_field_result, + common::ObIArray &part_border_flags, + common::ObIArray &sub_part_border_flags, + bool is_oracle_mode); + int parse_and_resolve_default_value(ObProxyParseString &default_value_expr, + proxy::ObClientSessionInfo *client_session_info, + obutils::SqlFieldResult *sql_field_result, + common::ObObj *target_obj, + bool is_oracle_mode); + + ObProxyExprType get_expr_token_func_type(common::ObString *func); common::ObIAllocator &allocator_; DISALLOW_COPY_AND_ASSIGN(ObExprResolver); diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.l b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.l index 06aef3ab..420b291e 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.l +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.l @@ -63,8 +63,11 @@ do {\ space [ \t\n\r\f] identifer ([A-Za-z0-9$_]*) -int_num [\-\+]?[0-9]+ -number ([0-9]+E[-+]?[0-9]+)|([0-9]+"."[0-9]*E[-+]?[0-9]+)|("."[0-9]+E[-+]?[0-9]+)|([0-9]+"."[0-9]*)|("."[0-9]+) + +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +int_num [\-\+]?[0-9]{1,17} +number ([\-]?[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*E[-+]?[0-9]+)|([\-]?"."[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*)|([\-]?"."[0-9]+)|([\-\+]?[0-9]{18,}) + whitespace ({space}+) c_cmt_begin \/\* @@ -97,16 +100,22 @@ rightbracket \) endtoken \# %% -substr { return FUNC_SUBSTR; } -substring { return FUNC_SUBSTR; } -concat { return FUNC_CONCAT; } -hash { return FUNC_HASH; } -toint { return FUNC_TOINT; } -div { return FUNC_DIV; } -add { return FUNC_ADD; } -sub { return FUNC_SUB; } -mul { return FUNC_MUL; } -testload { return FUNC_TESTLOAD; } +substr { return FUNC_SUBSTR; } +substring { return FUNC_SUBSTR; } +concat { return FUNC_CONCAT; } +hash { return FUNC_HASH; } +toint { return FUNC_TOINT; } +div { return FUNC_DIV; } +add { return FUNC_ADD; } +sub { return FUNC_SUB; } +mul { return FUNC_MUL; } +testload { return FUNC_TESTLOAD; } +to_date { return FUNC_TO_DATE; } +to_timestamp { return FUNC_TO_TIMESTAMP; } +nvl { return FUNC_NVL; } +to_char { return FUNC_TO_CHAR; } +mod { return FUNC_MOD; } +sysdate { return FUNC_SYSDATE; } {endtoken} { return TOKEN_SPECIAL; } diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.y b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.y index db953fa1..5e32e90e 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.y +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.y @@ -83,11 +83,12 @@ static inline void add_param_node(ObProxyParamNodeList *list, ObFuncExprParseRes %token DUMMY_FUNCTION_CLAUSE /* reserved keyword */ %token TOKEN_SPECIAL FUNC_SUBSTR FUNC_CONCAT FUNC_HASH FUNC_TOINT FUNC_DIV FUNC_ADD FUNC_SUB FUNC_MUL FUNC_TESTLOAD +%token FUNC_TO_DATE FUNC_TO_TIMESTAMP FUNC_NVL FUNC_TO_CHAR FUNC_MOD FUNC_SYSDATE %token END_P ERROR IGNORED_WORD /* type token */ %token NAME_OB STR_VAL NUMBER_VAL %token INT_VAL -%type func_name +%type func_name reserved_func %type param_list %type func_expr %type param @@ -113,6 +114,11 @@ func_expr: func_name '(' param_list ')' malloc_func_expr_node($$, result, $1); $$->child_ = NULL; } + | reserved_func + { + malloc_func_expr_node($$, result, $1); + $$->child_ = NULL; + } func_name: FUNC_SUBSTR { $$ = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; } | FUNC_CONCAT { $$ = OB_PROXY_EXPR_TYPE_FUNC_CONCAT; } @@ -123,6 +129,13 @@ func_name: FUNC_SUBSTR { $$ = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; } | FUNC_SUB { $$ = OB_PROXY_EXPR_TYPE_FUNC_SUB; } | FUNC_MUL { $$ = OB_PROXY_EXPR_TYPE_FUNC_MUL; } | FUNC_TESTLOAD { $$ = OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD; } + | FUNC_TO_DATE { $$ = OB_PROXY_EXPR_TYPE_FUNC_TO_DATE; } + | FUNC_TO_TIMESTAMP { $$ = OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP; } + | FUNC_NVL { $$ = OB_PROXY_EXPR_TYPE_FUNC_NVL; } + | FUNC_TO_CHAR { $$ = OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR; } + | FUNC_MOD { $$ = OB_PROXY_EXPR_TYPE_FUNC_MOD; } + +reserved_func: FUNC_SYSDATE { $$ = OB_PROXY_EXPR_TYPE_FUNC_SYSDATE; } param_list: param { diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.c b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.c index 0a515233..3580edb3 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.c +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 41 -#define YY_END_OF_BUFFER 42 +#define YY_NUM_RULES 47 +#define YY_END_OF_BUFFER 48 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,21 +357,30 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[115] = +static yyconst flex_int16_t yy_accept[201] = { 0, - 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, - 42, 40, 18, 18, 19, 30, 11, 14, 24, 19, - 19, 19, 12, 14, 14, 14, 14, 14, 14, 14, - 36, 23, 22, 23, 25, 26, 41, 31, 32, 41, - 38, 39, 18, 16, 0, 14, 0, 15, 12, 13, - 20, 13, 12, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 17, 0, 21, 25, 0, 27, 28, - 31, 0, 33, 34, 38, 37, 0, 13, 0, 0, - 13, 7, 14, 6, 14, 9, 8, 14, 14, 29, - 35, 0, 13, 0, 13, 13, 14, 4, 14, 14, - - 14, 14, 14, 14, 5, 3, 1, 14, 14, 14, - 14, 10, 2, 0 + 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 46, 24, 24, 25, 36, 17, 20, 30, 25, + 25, 25, 25, 18, 20, 20, 20, 20, 20, 20, + 20, 20, 42, 29, 28, 29, 31, 32, 47, 37, + 38, 47, 44, 45, 24, 22, 0, 20, 0, 21, + 18, 0, 18, 19, 26, 19, 18, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, + 23, 0, 27, 31, 0, 33, 34, 37, 0, 39, + 40, 44, 43, 18, 18, 0, 0, 19, 0, 18, + 0, 19, 7, 20, 6, 20, 15, 9, 13, 8, + + 20, 20, 20, 20, 35, 41, 18, 18, 19, 0, + 19, 0, 19, 18, 20, 4, 20, 20, 20, 20, + 20, 20, 20, 18, 18, 18, 20, 20, 20, 20, + 5, 20, 20, 20, 18, 18, 18, 3, 1, 20, + 20, 20, 20, 20, 18, 18, 18, 20, 16, 20, + 14, 11, 20, 18, 18, 18, 20, 10, 20, 18, + 18, 18, 2, 20, 18, 18, 18, 20, 18, 18, + 18, 20, 18, 18, 18, 12, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 19, 19, 19, 19, 19, 19, 0 + } ; static yyconst flex_int32_t yy_ec[256] = @@ -380,16 +389,16 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 6, 7, 4, 4, 8, 4, - 4, 9, 10, 4, 10, 11, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 4, 4, 1, - 4, 1, 4, 4, 14, 15, 16, 17, 18, 7, - 19, 20, 21, 7, 7, 22, 23, 24, 25, 7, - 7, 26, 27, 28, 29, 30, 7, 7, 7, 7, - 1, 31, 1, 4, 7, 32, 33, 34, 35, 36, - - 37, 7, 38, 39, 40, 7, 7, 41, 42, 43, - 44, 7, 7, 45, 46, 47, 48, 49, 7, 7, - 7, 7, 1, 4, 1, 4, 1, 1, 1, 1, + 4, 9, 10, 4, 11, 12, 13, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 4, 4, 1, + 4, 1, 4, 4, 15, 16, 17, 18, 19, 7, + 20, 21, 22, 7, 7, 23, 24, 25, 26, 27, + 7, 28, 29, 30, 31, 32, 7, 7, 33, 7, + 1, 34, 1, 4, 35, 36, 37, 38, 39, 40, + + 41, 7, 42, 43, 44, 7, 7, 45, 46, 47, + 48, 49, 7, 50, 51, 52, 53, 54, 7, 7, + 55, 7, 1, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -406,123 +415,202 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[50] = +static yyconst flex_int32_t yy_meta[56] = { 0, 1, 1, 1, 1, 2, 1, 3, 4, 1, 1, - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3 + 3, 3, 3, 3, 3 } ; -static yyconst flex_int16_t yy_base[128] = +static yyconst flex_int16_t yy_base[214] = { 0, - 0, 0, 47, 48, 44, 45, 49, 50, 217, 216, - 247, 250, 56, 58, 250, 241, 250, 0, 237, 231, - 230, 233, 51, 46, 40, 45, 53, 39, 41, 53, - 209, 250, 250, 65, 0, 90, 0, 0, 97, 0, - 0, 208, 70, 250, 234, 0, 230, 250, 212, 78, - 250, 88, 92, 94, 77, 71, 78, 82, 89, 97, - 89, 96, 190, 250, 109, 250, 0, 130, 250, 250, - 0, 117, 250, 250, 0, 250, 113, 121, 127, 200, - 199, 0, 108, 0, 121, 0, 115, 116, 121, 250, - 250, 194, 193, 149, 146, 70, 132, 0, 119, 126, - - 121, 122, 125, 127, 0, 0, 132, 140, 131, 139, - 138, 0, 0, 250, 176, 182, 188, 194, 199, 76, - 200, 202, 208, 214, 220, 226, 232 + 0, 0, 53, 54, 50, 51, 55, 56, 384, 382, + 415, 508, 62, 64, 508, 403, 508, 0, 398, 389, + 56, 388, 390, 57, 54, 47, 52, 60, 51, 46, + 48, 61, 361, 508, 508, 79, 0, 103, 0, 0, + 105, 0, 0, 342, 110, 508, 369, 0, 365, 508, + 358, 351, 102, 101, 508, 103, 111, 117, 100, 94, + 92, 97, 111, 109, 110, 118, 106, 107, 115, 328, + 508, 136, 508, 0, 158, 508, 508, 0, 160, 508, + 508, 0, 508, 345, 155, 161, 166, 154, 168, 169, + 341, 340, 0, 147, 0, 149, 0, 0, 0, 155, + + 167, 157, 164, 173, 508, 508, 335, 185, 331, 328, + 326, 319, 317, 186, 178, 0, 164, 186, 179, 178, + 193, 202, 196, 316, 219, 223, 189, 193, 192, 202, + 0, 214, 202, 210, 314, 233, 234, 0, 227, 236, + 242, 230, 240, 242, 308, 251, 254, 237, 0, 249, + 0, 0, 240, 307, 274, 282, 256, 0, 248, 288, + 285, 291, 0, 270, 273, 294, 297, 266, 268, 305, + 306, 287, 258, 315, 325, 0, 206, 329, 338, 139, + 339, 348, 133, 349, 357, 125, 363, 369, 124, 372, + 373, 79, 381, 382, 77, 393, 397, 72, 405, 508, + + 446, 452, 458, 464, 469, 80, 470, 472, 478, 484, + 490, 496, 502 } ; -static yyconst flex_int16_t yy_def[128] = +static yyconst flex_int16_t yy_def[214] = { 0, - 114, 1, 115, 115, 116, 116, 117, 117, 118, 118, - 114, 114, 114, 114, 114, 119, 114, 120, 121, 114, - 114, 114, 120, 120, 120, 120, 120, 120, 120, 120, - 122, 114, 114, 114, 123, 114, 124, 125, 114, 126, - 127, 114, 114, 114, 119, 120, 121, 114, 114, 114, - 114, 114, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 122, 114, 114, 114, 123, 114, 114, 114, - 125, 114, 114, 114, 127, 114, 114, 114, 114, 114, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 114, - 114, 114, 114, 114, 114, 114, 120, 120, 120, 120, - - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 0, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114 + 200, 1, 201, 201, 202, 202, 203, 203, 204, 204, + 200, 200, 200, 200, 200, 205, 200, 206, 207, 200, + 200, 200, 200, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 208, 200, 200, 200, 209, 200, 210, 211, + 200, 212, 213, 200, 200, 200, 205, 206, 207, 200, + 200, 200, 200, 200, 200, 200, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 208, + 200, 200, 200, 209, 200, 200, 200, 211, 200, 200, + 200, 213, 200, 200, 200, 200, 200, 200, 200, 206, + 200, 206, 206, 206, 206, 206, 206, 206, 206, 206, + + 206, 206, 206, 206, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 200, 200, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 200, 200, 206, 206, 206, 206, + 206, 206, 206, 206, 200, 200, 206, 206, 206, 206, + 206, 206, 206, 200, 200, 206, 206, 206, 206, 200, + 200, 206, 206, 206, 200, 200, 206, 206, 200, 200, + 206, 206, 200, 200, 206, 206, 200, 200, 206, 200, + 200, 206, 200, 200, 206, 200, 200, 206, 200, 200, + 206, 200, 200, 206, 200, 200, 206, 200, 200, 0, + + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200 } ; -static yyconst flex_int16_t yy_nxt[300] = +static yyconst flex_int16_t yy_nxt[564] = { 0, 12, 13, 14, 15, 16, 17, 18, 19, 15, 20, - 21, 22, 23, 24, 18, 25, 26, 18, 18, 27, - 18, 18, 28, 18, 18, 18, 29, 30, 18, 18, - 12, 31, 24, 18, 25, 26, 18, 18, 27, 18, - 18, 28, 18, 18, 18, 29, 30, 18, 18, 33, - 33, 36, 36, 39, 39, 34, 34, 43, 43, 43, - 43, 52, 55, 53, 56, 57, 58, 59, 54, 60, - 61, 43, 43, 65, 37, 37, 66, 62, 46, 40, - 40, 55, 96, 56, 57, 58, 59, 54, 60, 61, - 50, 68, 68, 82, 83, 77, 62, 69, 72, 72, - - 78, 73, 52, 80, 53, 79, 81, 84, 85, 54, - 86, 87, 82, 83, 77, 88, 89, 65, 72, 72, - 66, 91, 92, 97, 79, 93, 84, 85, 54, 86, - 87, 68, 68, 78, 88, 89, 94, 90, 79, 95, - 98, 99, 97, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 79, 95, 98, - 99, 95, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 32, 32, 32, 32, - 32, 32, 35, 35, 35, 35, 35, 35, 38, 38, - 38, 38, 38, 38, 41, 41, 41, 41, 41, 41, - - 45, 45, 47, 47, 63, 93, 93, 63, 67, 67, - 67, 81, 96, 67, 70, 70, 70, 70, 70, 70, - 71, 64, 71, 71, 49, 71, 74, 74, 74, 74, - 74, 74, 75, 75, 75, 75, 75, 48, 44, 76, - 64, 51, 50, 49, 48, 44, 114, 42, 42, 11, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114 - + 21, 22, 23, 24, 25, 18, 26, 27, 18, 18, + 28, 18, 18, 29, 30, 18, 18, 18, 31, 32, + 18, 18, 18, 12, 18, 33, 25, 18, 26, 27, + 18, 18, 28, 18, 18, 29, 30, 18, 18, 18, + 31, 32, 18, 18, 18, 35, 35, 38, 38, 41, + 41, 36, 36, 45, 45, 45, 45, 52, 56, 53, + 57, 59, 60, 61, 62, 58, 63, 65, 66, 68, + 67, 64, 48, 39, 39, 198, 69, 72, 42, 42, + 198, 73, 195, 59, 60, 61, 62, 58, 63, 65, + + 66, 68, 67, 64, 75, 75, 79, 79, 69, 80, + 76, 45, 45, 56, 54, 85, 88, 93, 94, 87, + 86, 89, 56, 95, 90, 96, 91, 91, 97, 58, + 92, 98, 99, 100, 101, 102, 103, 192, 189, 93, + 94, 87, 86, 89, 72, 95, 186, 96, 73, 104, + 97, 58, 183, 98, 99, 100, 101, 102, 103, 75, + 75, 79, 79, 115, 106, 105, 56, 88, 108, 116, + 91, 91, 89, 86, 109, 110, 110, 112, 112, 111, + 56, 113, 114, 117, 118, 115, 119, 58, 120, 121, + 122, 116, 127, 128, 89, 86, 56, 56, 125, 126, + + 129, 130, 123, 86, 58, 117, 118, 131, 119, 58, + 120, 121, 122, 132, 127, 128, 133, 134, 138, 180, + 139, 140, 129, 130, 123, 86, 58, 141, 142, 131, + 56, 143, 136, 144, 56, 132, 137, 86, 133, 134, + 138, 58, 139, 140, 56, 56, 146, 147, 148, 141, + 142, 86, 58, 143, 149, 144, 150, 151, 152, 86, + 153, 157, 56, 58, 155, 56, 158, 156, 159, 86, + 148, 177, 58, 86, 58, 163, 149, 164, 150, 151, + 152, 173, 153, 157, 168, 56, 169, 161, 158, 172, + 159, 86, 86, 56, 58, 162, 56, 163, 166, 164, + + 58, 165, 56, 86, 167, 56, 168, 170, 56, 58, + 171, 172, 86, 176, 86, 58, 56, 56, 174, 175, + 160, 154, 58, 86, 58, 86, 56, 145, 178, 135, + 113, 58, 113, 86, 86, 176, 56, 58, 179, 111, + 56, 111, 181, 58, 109, 86, 58, 86, 124, 56, + 56, 182, 184, 92, 109, 86, 58, 86, 107, 56, + 56, 185, 187, 71, 54, 58, 58, 86, 56, 86, + 188, 84, 50, 46, 56, 58, 190, 83, 58, 86, + 56, 86, 191, 56, 56, 193, 194, 58, 58, 86, + 86, 58, 56, 56, 196, 197, 71, 58, 55, 86, + + 58, 54, 51, 86, 56, 50, 199, 46, 56, 58, + 197, 86, 86, 58, 200, 58, 56, 44, 199, 44, + 200, 86, 58, 86, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 86, 200, 200, 200, 58, 200, 200, + 200, 200, 200, 200, 200, 86, 34, 34, 34, 34, + 34, 34, 37, 37, 37, 37, 37, 37, 40, 40, + 40, 40, 40, 40, 43, 43, 43, 43, 43, 43, + 47, 47, 49, 49, 70, 200, 200, 70, 74, 74, + 74, 200, 200, 74, 77, 77, 77, 77, 77, 77, + 78, 200, 78, 78, 200, 78, 81, 81, 81, 81, + + 81, 81, 82, 82, 82, 82, 82, 11, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200 } ; -static yyconst flex_int16_t yy_chk[300] = +static yyconst flex_int16_t yy_chk[564] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 4, 5, 6, 7, 8, 3, 4, 13, 13, 14, - 14, 23, 24, 23, 25, 26, 27, 28, 23, 29, - 30, 43, 43, 34, 5, 6, 34, 30, 120, 7, - 8, 24, 96, 25, 26, 27, 28, 23, 29, 30, - 50, 36, 36, 55, 56, 50, 30, 36, 39, 39, - - 52, 39, 53, 54, 53, 52, 54, 57, 58, 53, - 59, 60, 55, 56, 50, 61, 62, 65, 72, 72, - 65, 72, 77, 83, 52, 77, 57, 58, 53, 59, - 60, 68, 68, 78, 61, 62, 79, 68, 78, 79, - 85, 87, 83, 88, 89, 97, 99, 100, 101, 102, - 103, 104, 107, 108, 109, 110, 111, 78, 95, 85, - 87, 94, 88, 89, 97, 99, 100, 101, 102, 103, - 104, 107, 108, 109, 110, 111, 115, 115, 115, 115, - 115, 115, 116, 116, 116, 116, 116, 116, 117, 117, - 117, 117, 117, 117, 118, 118, 118, 118, 118, 118, - - 119, 119, 121, 121, 122, 93, 92, 122, 123, 123, - 123, 81, 80, 123, 124, 124, 124, 124, 124, 124, - 125, 63, 125, 125, 49, 125, 126, 126, 126, 126, - 126, 126, 127, 127, 127, 127, 127, 47, 45, 42, - 31, 22, 21, 20, 19, 16, 11, 10, 9, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114 - + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 4, 5, 6, 7, + 8, 3, 4, 13, 13, 14, 14, 21, 24, 21, + 24, 25, 26, 27, 28, 24, 29, 30, 31, 32, + 31, 29, 206, 5, 6, 198, 32, 36, 7, 8, + 195, 36, 192, 25, 26, 27, 28, 24, 29, 30, + + 31, 32, 31, 29, 38, 38, 41, 41, 32, 41, + 38, 45, 45, 53, 54, 53, 56, 59, 60, 54, + 53, 56, 57, 61, 57, 62, 58, 58, 63, 57, + 58, 64, 65, 66, 67, 68, 69, 189, 186, 59, + 60, 54, 53, 56, 72, 61, 183, 62, 72, 69, + 63, 57, 180, 64, 65, 66, 67, 68, 69, 75, + 75, 79, 79, 94, 79, 75, 85, 88, 85, 96, + 86, 86, 88, 85, 86, 87, 87, 89, 89, 87, + 90, 89, 90, 100, 101, 94, 102, 90, 103, 104, + 104, 96, 115, 117, 88, 85, 108, 114, 108, 114, + + 118, 119, 104, 108, 114, 100, 101, 120, 102, 90, + 103, 104, 104, 121, 115, 117, 122, 123, 127, 177, + 128, 129, 118, 119, 104, 108, 114, 130, 132, 120, + 125, 133, 125, 134, 126, 121, 126, 125, 122, 123, + 127, 126, 128, 129, 136, 137, 136, 137, 139, 130, + 132, 136, 137, 133, 140, 134, 141, 142, 143, 125, + 144, 148, 146, 126, 146, 147, 150, 147, 153, 146, + 139, 173, 147, 136, 137, 157, 140, 159, 141, 142, + 143, 169, 144, 148, 164, 155, 165, 155, 150, 168, + 153, 146, 155, 156, 147, 156, 161, 157, 161, 159, + + 156, 160, 162, 161, 162, 166, 164, 166, 167, 162, + 167, 168, 166, 172, 155, 167, 170, 171, 170, 171, + 154, 145, 156, 170, 171, 161, 174, 135, 174, 124, + 113, 162, 112, 174, 166, 172, 175, 167, 175, 111, + 178, 110, 178, 175, 109, 170, 171, 178, 107, 179, + 181, 179, 181, 92, 91, 174, 179, 181, 84, 182, + 184, 182, 184, 70, 52, 175, 182, 184, 185, 178, + 185, 51, 49, 47, 187, 185, 187, 44, 179, 181, + 188, 187, 188, 190, 191, 190, 191, 188, 182, 184, + 190, 191, 193, 194, 193, 194, 33, 185, 23, 193, + + 194, 22, 20, 187, 196, 19, 196, 16, 197, 188, + 197, 196, 190, 191, 11, 197, 199, 10, 199, 9, + 0, 193, 194, 199, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, + 0, 0, 0, 0, 0, 199, 201, 201, 201, 201, + 201, 201, 202, 202, 202, 202, 202, 202, 203, 203, + 203, 203, 203, 203, 204, 204, 204, 204, 204, 204, + 205, 205, 207, 207, 208, 0, 0, 208, 209, 209, + 209, 0, 0, 209, 210, 210, 210, 210, 210, 210, + 211, 0, 211, 211, 0, 211, 212, 212, 212, 212, + + 212, 212, 213, 213, 213, 213, 213, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200 } ; /* The intent behind this definition is that it'll catch @@ -590,7 +678,8 @@ do {\ -#line 595 "ob_func_expr_parser_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +#line 684 "ob_func_expr_parser_lex.c" #define INITIAL 0 #define in_c_comment 1 @@ -838,9 +927,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 99 "ob_func_expr_parser.l" +#line 102 "ob_func_expr_parser.l" -#line 846 "ob_func_expr_parser_lex.c" +#line 935 "ob_func_expr_parser_lex.c" yylval = yylval_param; @@ -897,13 +986,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 115 ) + if ( yy_current_state >= 201 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 250 ); + while ( yy_base[yy_current_state] != 508 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -929,126 +1018,156 @@ YY_DECL case 1: YY_RULE_SETUP -#line 100 "ob_func_expr_parser.l" +#line 103 "ob_func_expr_parser.l" { return FUNC_SUBSTR; } YY_BREAK case 2: YY_RULE_SETUP -#line 101 "ob_func_expr_parser.l" +#line 104 "ob_func_expr_parser.l" { return FUNC_SUBSTR; } YY_BREAK case 3: YY_RULE_SETUP -#line 102 "ob_func_expr_parser.l" +#line 105 "ob_func_expr_parser.l" { return FUNC_CONCAT; } YY_BREAK case 4: YY_RULE_SETUP -#line 103 "ob_func_expr_parser.l" +#line 106 "ob_func_expr_parser.l" { return FUNC_HASH; } YY_BREAK case 5: YY_RULE_SETUP -#line 104 "ob_func_expr_parser.l" +#line 107 "ob_func_expr_parser.l" { return FUNC_TOINT; } YY_BREAK case 6: YY_RULE_SETUP -#line 105 "ob_func_expr_parser.l" +#line 108 "ob_func_expr_parser.l" { return FUNC_DIV; } YY_BREAK case 7: YY_RULE_SETUP -#line 106 "ob_func_expr_parser.l" +#line 109 "ob_func_expr_parser.l" { return FUNC_ADD; } YY_BREAK case 8: YY_RULE_SETUP -#line 107 "ob_func_expr_parser.l" +#line 110 "ob_func_expr_parser.l" { return FUNC_SUB; } YY_BREAK case 9: YY_RULE_SETUP -#line 108 "ob_func_expr_parser.l" +#line 111 "ob_func_expr_parser.l" { return FUNC_MUL; } YY_BREAK case 10: YY_RULE_SETUP -#line 109 "ob_func_expr_parser.l" +#line 112 "ob_func_expr_parser.l" { return FUNC_TESTLOAD; } YY_BREAK case 11: YY_RULE_SETUP -#line 111 "ob_func_expr_parser.l" -{ return TOKEN_SPECIAL; } +#line 113 "ob_func_expr_parser.l" +{ return FUNC_TO_DATE; } YY_BREAK case 12: YY_RULE_SETUP -#line 113 "ob_func_expr_parser.l" -{ RETURN_INT_VAL(); } +#line 114 "ob_func_expr_parser.l" +{ return FUNC_TO_TIMESTAMP; } YY_BREAK case 13: YY_RULE_SETUP -#line 114 "ob_func_expr_parser.l" -{ RETURN_NUMBER_VAL(); } +#line 115 "ob_func_expr_parser.l" +{ return FUNC_NVL; } YY_BREAK case 14: YY_RULE_SETUP -#line 115 "ob_func_expr_parser.l" -{ RETURN_NAME_OB(); } +#line 116 "ob_func_expr_parser.l" +{ return FUNC_TO_CHAR; } YY_BREAK case 15: YY_RULE_SETUP -#line 116 "ob_func_expr_parser.l" -{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_SINGLE); } +#line 117 "ob_func_expr_parser.l" +{ return FUNC_MOD; } YY_BREAK case 16: YY_RULE_SETUP -#line 117 "ob_func_expr_parser.l" -{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_DOUBLE); } +#line 118 "ob_func_expr_parser.l" +{ return FUNC_SYSDATE; } YY_BREAK case 17: YY_RULE_SETUP -#line 118 "ob_func_expr_parser.l" -{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_BACK); } +#line 120 "ob_func_expr_parser.l" +{ return TOKEN_SPECIAL; } YY_BREAK case 18: -/* rule 18 can match eol */ YY_RULE_SETUP -#line 119 "ob_func_expr_parser.l" -{ } +#line 122 "ob_func_expr_parser.l" +{ RETURN_INT_VAL(); } YY_BREAK case 19: YY_RULE_SETUP -#line 120 "ob_func_expr_parser.l" +#line 123 "ob_func_expr_parser.l" +{ RETURN_NUMBER_VAL(); } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 124 "ob_func_expr_parser.l" +{ RETURN_NAME_OB(); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 125 "ob_func_expr_parser.l" +{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_SINGLE); } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 126 "ob_func_expr_parser.l" +{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_DOUBLE); } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 127 "ob_func_expr_parser.l" +{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_BACK); } + YY_BREAK +case 24: +/* rule 24 can match eol */ +YY_RULE_SETUP +#line 128 "ob_func_expr_parser.l" +{ } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 129 "ob_func_expr_parser.l" { return yytext[0]; } YY_BREAK /* comment */ -case 20: +case 26: YY_RULE_SETUP -#line 123 "ob_func_expr_parser.l" +#line 132 "ob_func_expr_parser.l" { PUSH_STATE(in_c_comment); } YY_BREAK -case 21: +case 27: YY_RULE_SETUP -#line 124 "ob_func_expr_parser.l" +#line 133 "ob_func_expr_parser.l" { POP_STATE(); } YY_BREAK -case 22: -/* rule 22 can match eol */ +case 28: +/* rule 28 can match eol */ YY_RULE_SETUP -#line 125 "ob_func_expr_parser.l" +#line 134 "ob_func_expr_parser.l" {} YY_BREAK -case 23: +case 29: YY_RULE_SETUP -#line 126 "ob_func_expr_parser.l" +#line 135 "ob_func_expr_parser.l" {} YY_BREAK /* quote */ -case 24: +case 30: YY_RULE_SETUP -#line 129 "ob_func_expr_parser.l" +#line 138 "ob_func_expr_parser.l" { PUSH_STATE(sq); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1059,10 +1178,10 @@ YY_RULE_SETUP } } YY_BREAK -case 25: -/* rule 25 can match eol */ +case 31: +/* rule 31 can match eol */ YY_RULE_SETUP -#line 139 "ob_func_expr_parser.l" +#line 148 "ob_func_expr_parser.l" { ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1070,9 +1189,9 @@ YY_RULE_SETUP } } YY_BREAK -case 26: +case 32: YY_RULE_SETUP -#line 146 "ob_func_expr_parser.l" +#line 155 "ob_func_expr_parser.l" { POP_STATE(); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1082,31 +1201,31 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 27: +case 33: YY_RULE_SETUP -#line 155 "ob_func_expr_parser.l" +#line 164 "ob_func_expr_parser.l" {} YY_BREAK -case 28: -/* rule 28 can match eol */ +case 34: +/* rule 34 can match eol */ YY_RULE_SETUP -#line 156 "ob_func_expr_parser.l" +#line 165 "ob_func_expr_parser.l" {} YY_BREAK -case 29: -/* rule 29 can match eol */ +case 35: +/* rule 35 can match eol */ YY_RULE_SETUP -#line 157 "ob_func_expr_parser.l" +#line 166 "ob_func_expr_parser.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 158 "ob_func_expr_parser.l" +#line 167 "ob_func_expr_parser.l" { return ERROR; } YY_BREAK /* dquote */ -case 30: +case 36: YY_RULE_SETUP -#line 162 "ob_func_expr_parser.l" +#line 171 "ob_func_expr_parser.l" { PUSH_STATE(dq); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1117,10 +1236,10 @@ YY_RULE_SETUP } } YY_BREAK -case 31: -/* rule 31 can match eol */ +case 37: +/* rule 37 can match eol */ YY_RULE_SETUP -#line 172 "ob_func_expr_parser.l" +#line 181 "ob_func_expr_parser.l" { ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1128,9 +1247,9 @@ YY_RULE_SETUP } } YY_BREAK -case 32: +case 38: YY_RULE_SETUP -#line 179 "ob_func_expr_parser.l" +#line 188 "ob_func_expr_parser.l" { POP_STATE(); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1140,31 +1259,31 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 33: +case 39: YY_RULE_SETUP -#line 188 "ob_func_expr_parser.l" +#line 197 "ob_func_expr_parser.l" {} YY_BREAK -case 34: -/* rule 34 can match eol */ +case 40: +/* rule 40 can match eol */ YY_RULE_SETUP -#line 189 "ob_func_expr_parser.l" +#line 198 "ob_func_expr_parser.l" {} YY_BREAK -case 35: -/* rule 35 can match eol */ +case 41: +/* rule 41 can match eol */ YY_RULE_SETUP -#line 190 "ob_func_expr_parser.l" +#line 199 "ob_func_expr_parser.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 191 "ob_func_expr_parser.l" +#line 200 "ob_func_expr_parser.l" { return ERROR; } YY_BREAK /* backtick */ -case 36: +case 42: YY_RULE_SETUP -#line 195 "ob_func_expr_parser.l" +#line 204 "ob_func_expr_parser.l" { PUSH_STATE(bt); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1175,9 +1294,9 @@ YY_RULE_SETUP } } YY_BREAK -case 37: +case 43: YY_RULE_SETUP -#line 205 "ob_func_expr_parser.l" +#line 214 "ob_func_expr_parser.l" { ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -1185,10 +1304,10 @@ YY_RULE_SETUP } } YY_BREAK -case 38: -/* rule 38 can match eol */ +case 44: +/* rule 44 can match eol */ YY_RULE_SETUP -#line 212 "ob_func_expr_parser.l" +#line 221 "ob_func_expr_parser.l" { ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -1197,9 +1316,9 @@ YY_RULE_SETUP } } YY_BREAK -case 39: +case 45: YY_RULE_SETUP -#line 220 "ob_func_expr_parser.l" +#line 229 "ob_func_expr_parser.l" { POP_STATE(); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1212,27 +1331,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 231 "ob_func_expr_parser.l" +#line 240 "ob_func_expr_parser.l" { return ERROR; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(in_c_comment): -#line 235 "ob_func_expr_parser.l" +#line 244 "ob_func_expr_parser.l" { return END_P; } YY_BREAK -case 40: +case 46: YY_RULE_SETUP -#line 236 "ob_func_expr_parser.l" +#line 245 "ob_func_expr_parser.l" { return IGNORED_WORD; } YY_BREAK -case 41: +case 47: YY_RULE_SETUP -#line 237 "ob_func_expr_parser.l" +#line 246 "ob_func_expr_parser.l" ECHO; YY_BREAK -#line 1238 "ob_func_expr_parser_lex.c" +#line 1357 "ob_func_expr_parser_lex.c" case YY_END_OF_BUFFER: { @@ -1524,7 +1643,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 115 ) + if ( yy_current_state >= 201 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1553,11 +1672,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 115 ) + if ( yy_current_state >= 201 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 114); + yy_is_jam = (yy_current_state == 200); return yy_is_jam ? 0 : yy_current_state; } @@ -2382,7 +2501,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 237 "ob_func_expr_parser.l" +#line 246 "ob_func_expr_parser.l" @@ -2511,13 +2630,19 @@ extern int obfuncexprdebug; FUNC_SUB = 266, FUNC_MUL = 267, FUNC_TESTLOAD = 268, - END_P = 269, - ERROR = 270, - IGNORED_WORD = 271, - NAME_OB = 272, - STR_VAL = 273, - NUMBER_VAL = 274, - INT_VAL = 275 + FUNC_TO_DATE = 269, + FUNC_TO_TIMESTAMP = 270, + FUNC_NVL = 271, + FUNC_TO_CHAR = 272, + FUNC_MOD = 273, + FUNC_SYSDATE = 274, + END_P = 275, + ERROR = 276, + IGNORED_WORD = 277, + NAME_OB = 278, + STR_VAL = 279, + NUMBER_VAL = 280, + INT_VAL = 281 }; #endif diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.h b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.h index 14f5fb50..3d8a11e8 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.h +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.h @@ -341,7 +341,7 @@ extern int obfuncexprlex \ #undef YY_DECL #endif -#line 237 "ob_func_expr_parser.l" +#line 246 "ob_func_expr_parser.l" #line 348 "ob_func_expr_parser_lex.h" diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.c b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.c index 49ab7202..abb23646 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.c +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.c @@ -138,13 +138,19 @@ extern int obfuncexprdebug; FUNC_SUB = 266, FUNC_MUL = 267, FUNC_TESTLOAD = 268, - END_P = 269, - ERROR = 270, - IGNORED_WORD = 271, - NAME_OB = 272, - STR_VAL = 273, - NUMBER_VAL = 274, - INT_VAL = 275 + FUNC_TO_DATE = 269, + FUNC_TO_TIMESTAMP = 270, + FUNC_NVL = 271, + FUNC_TO_CHAR = 272, + FUNC_MOD = 273, + FUNC_SYSDATE = 274, + END_P = 275, + ERROR = 276, + IGNORED_WORD = 277, + NAME_OB = 278, + STR_VAL = 279, + NUMBER_VAL = 280, + INT_VAL = 281 }; #endif @@ -460,22 +466,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 15 +#define YYFINAL 22 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 46 +#define YYLAST 64 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 24 +#define YYNTOKENS 30 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 7 +#define YYNNTS 8 /* YYNRULES -- Number of rules. */ -#define YYNRULES 22 +#define YYNRULES 29 /* YYNRULES -- Number of states. */ -#define YYNSTATES 30 +#define YYNSTATES 37 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 275 +#define YYMAXUTOK 281 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -487,7 +493,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 21, 22, 2, 2, 23, 2, 2, 2, 2, 2, + 27, 28, 2, 2, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -510,7 +516,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26 }; #if YYDEBUG @@ -519,27 +526,28 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyprhs[] = { 0, 0, 3, 5, 7, 9, 14, 18, 20, 22, - 24, 26, 28, 30, 32, 34, 36, 38, 42, 46, - 48, 50, 52 + 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, + 44, 46, 48, 50, 52, 56, 60, 62, 64, 66 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 25, 0, -1, 26, -1, 27, -1, 1, -1, 28, - 21, 29, 22, -1, 28, 21, 22, -1, 5, -1, - 6, -1, 7, -1, 8, -1, 9, -1, 10, -1, - 11, -1, 12, -1, 13, -1, 30, -1, 29, 23, - 30, -1, 4, 17, 4, -1, 17, -1, 20, -1, - 18, -1, 27, -1 + 31, 0, -1, 32, -1, 33, -1, 1, -1, 34, + 27, 36, 28, -1, 34, 27, 28, -1, 35, -1, + 5, -1, 6, -1, 7, -1, 8, -1, 9, -1, + 10, -1, 11, -1, 12, -1, 13, -1, 14, -1, + 15, -1, 16, -1, 17, -1, 18, -1, 19, -1, + 37, -1, 36, 29, 37, -1, 4, 23, 4, -1, + 23, -1, 26, -1, 24, -1, 33, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 96, 96, 98, 104, 106, 111, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 127, 131, 137, 138, - 139, 140, 141 + 0, 97, 97, 99, 105, 107, 112, 117, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 138, 140, 144, 150, 151, 152, 153, 154 }; #endif @@ -550,10 +558,12 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "DUMMY_FUNCTION_CLAUSE", "TOKEN_SPECIAL", "FUNC_SUBSTR", "FUNC_CONCAT", "FUNC_HASH", "FUNC_TOINT", "FUNC_DIV", - "FUNC_ADD", "FUNC_SUB", "FUNC_MUL", "FUNC_TESTLOAD", "END_P", "ERROR", - "IGNORED_WORD", "NAME_OB", "STR_VAL", "NUMBER_VAL", "INT_VAL", "'('", - "')'", "','", "$accept", "start", "func_root", "func_expr", "func_name", - "param_list", "param", 0 + "FUNC_ADD", "FUNC_SUB", "FUNC_MUL", "FUNC_TESTLOAD", "FUNC_TO_DATE", + "FUNC_TO_TIMESTAMP", "FUNC_NVL", "FUNC_TO_CHAR", "FUNC_MOD", + "FUNC_SYSDATE", "END_P", "ERROR", "IGNORED_WORD", "NAME_OB", "STR_VAL", + "NUMBER_VAL", "INT_VAL", "'('", "')'", "','", "$accept", "start", + "func_root", "func_expr", "func_name", "reserved_func", "param_list", + "param", 0 }; #endif @@ -564,24 +574,24 @@ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 40, 41, 44 + 275, 276, 277, 278, 279, 280, 281, 40, 41, 44 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 24, 25, 26, 26, 27, 27, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 29, 29, 30, 30, - 30, 30, 30 + 0, 30, 31, 32, 32, 33, 33, 33, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 35, 36, 36, 37, 37, 37, 37, 37 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 1, 4, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, - 1, 1, 1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -589,15 +599,16 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 4, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 0, 2, 3, 0, 1, 0, 0, 19, 21, - 20, 6, 22, 0, 16, 0, 5, 0, 18, 17 + 0, 4, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 0, 2, 3, + 0, 7, 1, 0, 0, 26, 28, 27, 6, 29, + 0, 23, 0, 5, 0, 25, 24 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 11, 12, 22, 14, 23, 24 + -1, 17, 18, 29, 20, 21, 30, 31 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing @@ -605,15 +616,16 @@ static const yytype_int8 yydefgoto[] = #define YYPACT_NINF -13 static const yytype_int8 yypact[] = { - 33, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, 12, -13, -13, -6, -13, -4, 0, -13, -13, - -13, -13, -13, -12, -13, 25, -13, 15, -13, -13 + 45, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, 18, -13, -13, + -6, -13, -13, -4, 0, -13, -13, -13, -13, -13, + -12, -13, 37, -13, 21, -13, -13 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -13, -13, -13, 30, -13, -13, 4 + -13, -13, -13, 42, -13, -13, -13, 9 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -623,20 +635,24 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 17, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 26, 27, 15, 18, 19, 16, 20, 25, 21, 17, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 28, - 13, 29, 18, 19, 1, 20, 0, 0, 2, 3, - 4, 5, 6, 7, 8, 9, 10 + 24, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 33, 34, 22, 25, + 26, 23, 27, 32, 28, 24, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 35, 19, 36, 25, 26, 1, 27, 0, 0, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16 }; static const yytype_int8 yycheck[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 22, 23, 0, 17, 18, 21, 20, 17, 22, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, - 0, 27, 17, 18, 1, 20, -1, -1, 5, 6, - 7, 8, 9, 10, 11, 12, 13 + 14, 15, 16, 17, 18, 19, 28, 29, 0, 23, + 24, 27, 26, 23, 28, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 4, 0, 34, 23, 24, 1, 26, -1, -1, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -644,8 +660,9 @@ static const yytype_int8 yycheck[] = static const yytype_uint8 yystos[] = { 0, 1, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 25, 26, 27, 28, 0, 21, 4, 17, 18, - 20, 22, 27, 29, 30, 17, 22, 23, 4, 30 + 13, 14, 15, 16, 17, 18, 19, 31, 32, 33, + 34, 35, 0, 27, 4, 23, 24, 26, 28, 33, + 36, 37, 23, 28, 29, 4, 37 }; #define yyerrok (yyerrstatus = 0) @@ -1528,57 +1545,95 @@ YYLTYPE yylloc; case 7: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; ;} + { + malloc_func_expr_node((yyval.func_node), result, (yyvsp[(1) - (1)].function_type)); + (yyval.func_node)->child_ = NULL; + ;} break; case 8: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_CONCAT; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; ;} break; case 9: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_HASH; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_CONCAT; ;} break; case 10: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TOINT; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_HASH; ;} break; case 11: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_DIV; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TOINT; ;} break; case 12: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_ADD; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_DIV; ;} break; case 13: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SUB; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_ADD; ;} break; case 14: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_MUL; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SUB; ;} break; case 15: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_MUL; ;} break; case 16: + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD; ;} + break; + + case 17: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TO_DATE; ;} + break; + + case 18: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP; ;} + break; + + case 19: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_NVL; ;} + break; + + case 20: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR; ;} + break; + + case 21: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_MOD; ;} + break; + + case 22: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SYSDATE; ;} + break; + + case 23: + { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].param_node)); ;} break; - case 17: + case 24: { add_param_node((yyvsp[(1) - (3)].list), result, (yyvsp[(3) - (3)].param_node)); @@ -1586,27 +1641,27 @@ YYLTYPE yylloc; ;} break; - case 18: + case 25: { malloc_param_node((yyval.param_node), result, PARAM_COLUMN); (yyval.param_node)->col_name_ = (yyvsp[(2) - (3)].str); ;} break; - case 19: + case 26: { malloc_param_node((yyval.param_node), result, PARAM_COLUMN); (yyval.param_node)->col_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 20: + case 27: { malloc_param_node((yyval.param_node), result, PARAM_INT_VAL); (yyval.param_node)->int_value_ = (yyvsp[(1) - (1)].num); ;} break; - case 21: + case 28: { malloc_param_node((yyval.param_node), result, PARAM_STR_VAL); (yyval.param_node)->str_value_ = (yyvsp[(1) - (1)].str); ;} break; - case 22: + case 29: { malloc_param_node((yyval.param_node), result, PARAM_FUNC); (yyval.param_node)->func_expr_node_ = (yyvsp[(1) - (1)].func_node); ;} break; diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.h b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.h index 1eb7984e..4f199b4b 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.h +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.h @@ -67,13 +67,19 @@ extern int obfuncexprdebug; FUNC_SUB = 266, FUNC_MUL = 267, FUNC_TESTLOAD = 268, - END_P = 269, - ERROR = 270, - IGNORED_WORD = 271, - NAME_OB = 272, - STR_VAL = 273, - NUMBER_VAL = 274, - INT_VAL = 275 + FUNC_TO_DATE = 269, + FUNC_TO_TIMESTAMP = 270, + FUNC_NVL = 271, + FUNC_TO_CHAR = 272, + FUNC_MOD = 273, + FUNC_SYSDATE = 274, + END_P = 275, + ERROR = 276, + IGNORED_WORD = 277, + NAME_OB = 278, + STR_VAL = 279, + NUMBER_VAL = 280, + INT_VAL = 281 }; #endif diff --git a/src/obproxy/opsql/func_expr_resolver/ob_func_expr_resolver.cpp b/src/obproxy/opsql/func_expr_resolver/ob_func_expr_resolver.cpp index f586ef93..c8b4dffb 100644 --- a/src/obproxy/opsql/func_expr_resolver/ob_func_expr_resolver.cpp +++ b/src/obproxy/opsql/func_expr_resolver/ob_func_expr_resolver.cpp @@ -50,6 +50,11 @@ int ObFuncExprResolver::recursive_resolve_proxy_expr(const ObProxyParamNode *nod ObProxyExprConst *str_expr = NULL; if(OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_CONST, str_expr))) { LOG_WARN("create proxy expr failed", K(ret)); + } else if (0 == node->str_value_.str_len_) { + ObObj &obj = str_expr->get_object(); + obj.set_varchar(NULL, 0); + obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); + expr = str_expr; } else { ObIAllocator &allocator = *ctx_.allocator_; char *buf = NULL; @@ -103,6 +108,8 @@ int ObFuncExprResolver::recursive_resolve_proxy_expr(const ObProxyParamNode *nod ObProxyFuncExpr *func_expr = NULL; if (OB_FAIL(create_func_expr_by_type(func_expr_node, func_expr))) { LOG_WARN("create func expr by type failed", K(ret)); + } else if (OB_ISNULL(func_expr_node->child_)) { + // do nothing } else { ObProxyParamNodeList *child = func_expr_node->child_; ObProxyParamNode* tmp_param_node = child->head_; @@ -242,6 +249,68 @@ int ObFuncExprResolver::create_func_expr_by_type(const ObFuncExprNode *func_expr } } break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_DATE: + { + ObProxyExprToTimeHandler *todate_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_TO_DATE, todate_expr))) { + LOG_WARN("create proxy to_date failed", K(ret)); + } else { + todate_expr->set_target_type(ObDateTimeType); + func_expr = todate_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP: + { + ObProxyExprToTimeHandler *totimestamp_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP, totimestamp_expr))) { + LOG_WARN("create proxy to_timestamp failed", K(ret)); + } else { + totimestamp_expr->set_target_type(ObTimestampNanoType); + func_expr = totimestamp_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_NVL: + { + ObProxyExprNvl *nvl_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_NVL, nvl_expr))) { + LOG_WARN("create proxy nvl failed", K(ret)); + } else { + func_expr = nvl_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR: + { + ObProxyExprToChar *tochar_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR, tochar_expr))) { + LOG_WARN("create proxy to_char failed", K(ret)); + } else { + func_expr = tochar_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_SYSDATE: + { + ObProxyExprSysdate *sysdate_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_SYSDATE, sysdate_expr))) { + LOG_WARN("create proxy sysdate failed", K(ret)); + } else { + func_expr = sysdate_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_MOD: + { + ObProxyExprMod *mod_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_MOD, mod_expr))) { + LOG_WARN("create proxy mod failed", K(ret)); + } else { + func_expr = mod_expr; + } + } + break; default: ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected type", K(func_expr_node->func_type_), K(ret)); diff --git a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.cpp b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.cpp index 9c3bb18f..323a9a14 100644 --- a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.cpp +++ b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.cpp @@ -12,10 +12,16 @@ #define USING_LOG_PREFIX PROXY -#include "common/ob_obj_cast.h" #include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h" -#include "utils/ob_proxy_utils.h" +#include "common/ob_obj_cast.h" +#include "common/ob_obj_type.h" #include "dbconfig/ob_proxy_db_config_info.h" +#include "lib/time/ob_time_utility.h" +#include "proxy/route/obproxy_expr_calculator.h" +#include "utils/ob_proxy_utils.h" +#include "common/expression/ob_expr_regexp_context.h" +#include "lib/utility/utility.h" +#include namespace oceanbase { @@ -226,10 +232,10 @@ int ObProxyExprColumn::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem } else if (result_obj_array.count() == len && ObProxyExprCalcItem::FROM_SQL_FIELD == calc_item.source_) { bool found = false; for (int64_t i = 0; OB_SUCC(ret) && i < calc_item.sql_result_->field_num_; i++) { - SqlField &field = calc_item.sql_result_->fields_.at(i); - if (0 == field.column_name_.string_.case_compare(column_name_)) { + SqlField* field = calc_item.sql_result_->fields_.at(i); + if (0 == field->column_name_.config_string_.case_compare(column_name_)) { found = true; - common::ObSEArray &column_values = field.column_values_; + common::ObSEArray &column_values = field->column_values_; for (int64_t j = 0; OB_SUCC(ret) && j < column_values.count(); j++) { ObObj result_obj; SqlColumnValue &sql_column_value = column_values.at(j); @@ -240,7 +246,7 @@ int ObProxyExprColumn::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem LOG_WARN("push back obj failed", K(ret), K(result_obj)); } } else if (TOKEN_STR_VAL == sql_column_value.value_type_) { - ObString value = sql_column_value.column_value_.string_; + ObString value = sql_column_value.column_value_.config_string_; result_obj.set_varchar(value); result_obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); if (OB_FAIL(result_obj_array.push_back(result_obj))) { @@ -362,26 +368,19 @@ int ObProxyFuncExpr::calc_param_expr(const ObProxyExprCtx &ctx, return ret; } -int ObProxyFuncExpr::get_int_obj(const ObObj &src, ObObj &dst) +int ObProxyFuncExpr::get_int_obj(const ObObj &src, ObObj &dst, common::ObIAllocator &allocator) { int ret = OB_SUCCESS; - if (src.is_varchar()) { - ObString str; - int64_t val; - if (OB_FAIL(src.get_varchar(str))) { - LOG_WARN("get varchar failed", K(ret)); - } else if (OB_FAIL(get_int_value(str, val))) { - LOG_WARN("get int value failed", K(ret), K(src)); - } else { - dst.set_int(val); + if (!src.is_int()) { + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + ObCastCtx cast_ctx(&allocator, NULL, CM_NULL_ON_WARN, collation); + if (OB_FAIL(ObObjCasterV2::to_type(ObIntType, collation, cast_ctx, src, dst))) { + LOG_WARN("cast obj to varchar obj fail", K(ret)); } - } else if (src.is_int()) { - dst = src; } else { - ret = OB_EXPR_CALC_ERROR; - LOG_WARN("invalid type to int", K(ret)); - } + dst = src; + } return ret; } @@ -389,22 +388,14 @@ int ObProxyFuncExpr::get_int_obj(const ObObj &src, ObObj &dst) int ObProxyFuncExpr::get_varchar_obj(const common::ObObj &src, common::ObObj &dst, common::ObIAllocator &allocator) { int ret = OB_SUCCESS; - if (src.is_int()) { - char *buf = NULL; - const int64_t buf_len = 256; - if (OB_ISNULL(buf = static_cast(allocator.alloc(buf_len)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("alloc buf failed", K(ret), K(buf_len)); - } else { - snprintf(buf, buf_len, "%ld", src.get_int()); - dst.set_varchar(buf, static_cast(strlen(buf))); - dst.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); + if (!src.is_varchar()) { + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + ObCastCtx cast_ctx(&allocator, NULL, CM_NULL_ON_WARN, collation); + if (OB_FAIL(ObObjCasterV2::to_type(ObVarcharType, collation, cast_ctx, src, dst))) { + LOG_WARN("cast obj to varchar obj fail", K(ret)); } } else if (src.is_varchar()) { dst = src; - } else { - ret = OB_EXPR_CALC_ERROR; - LOG_INFO("get varchar obj failed", K(src), K(ret)); } return ret; @@ -456,7 +447,7 @@ int ObProxyExprHash::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -475,7 +466,7 @@ int ObProxyExprHash::calc(const ObProxyExprCtx &ctx, LOG_DEBUG("test load type", K(test_load_obj)); } - if (OB_FAIL(get_int_obj(test_load_obj, obj1))) { + if (OB_FAIL(get_int_obj(test_load_obj, obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret), K(test_load_obj)); } else if (OB_FAIL(obj1.get_int(index))) { LOG_WARN("get int failed", K(ret), K(obj1)); @@ -483,7 +474,7 @@ int ObProxyExprHash::calc(const ObProxyExprCtx &ctx, if (OB_SUCC(ret) && param_array_.count() == 2) { ObObj obj2; - if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(obj2.get_int(num))) { LOG_WARN("get int failed", K(ret)); @@ -507,7 +498,7 @@ int ObProxyExprHash::calc(const ObProxyExprCtx &ctx, } } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -544,7 +535,7 @@ int ObProxyExprSubStr::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -556,6 +547,9 @@ int ObProxyExprSubStr::calc(const ObProxyExprCtx &ctx, int64_t substr_len = -1; ObObj first_obj; + // substr retrun NULL on out of bounds params + bool is_invalid_params = false; + if (OB_FAIL(get_varchar_obj(param_result.at(0), first_obj, *ctx.allocator_))) { LOG_WARN("get varchar obj failed", K(ret)); } else if (OB_FAIL(first_obj.get_varchar(value))) { @@ -567,26 +561,33 @@ int ObProxyExprSubStr::calc(const ObProxyExprCtx &ctx, if (OB_SUCC(ret)) { ObObj obj; - if (OB_FAIL(get_int_obj(param_result.at(1), obj))) { + if (OB_FAIL(get_int_obj(param_result.at(1), obj, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(obj.get_int(start_pos))) { LOG_WARN("get int failed", K(ret)); } } - + if (start_pos == 0) { + if (ctx.is_oracle_mode) { + // 1 and 0 treated as thr first character in oracle + start_pos = 1; + } else { + is_invalid_params = true; + } + } if (OB_SUCC(ret) && 3 == param_result.count()) { ObObj obj; - if (OB_FAIL(get_int_obj(param_result.at(2), obj))) { + if (OB_FAIL(get_int_obj(param_result.at(2), obj, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(obj.get_int(substr_len))) { LOG_WARN("get int failed", K(ret)); } else if (substr_len <= 0) { - ret = OB_INVALID_ARGUMENT_FOR_SUBSTR; - LOG_WARN("substr function param 3 is less than 1", K(ret)); + is_invalid_params = true; + LOG_DEBUG("substr function param 3 is less than 1", K(ret)); } } - if (OB_SUCC(ret)) { + if (OB_SUCC(ret) && !is_invalid_params) { value_length = value.length(); if (start_pos < 0) { start_pos = value_length + start_pos + 1; @@ -597,26 +598,37 @@ int ObProxyExprSubStr::calc(const ObProxyExprCtx &ctx, } if (start_pos <= 0 || start_pos > value_length || substr_len <= 0 || substr_len > value_length || start_pos + substr_len - 1 > value_length) { - ret = OB_INVALID_ARGUMENT_FOR_SUBSTR; - LOG_WARN("column value length does not match", K(start_pos), - K(substr_len), K(value_length), K(value), K(ret)); + is_invalid_params = true; + LOG_DEBUG("invalid substr params", K(start_pos), K(substr_len), K(value_length), K(value), K(ret)); } + } - if (OB_SUCC(ret)) { + if (OB_SUCC(ret)) { + if(is_invalid_params) { + if (ctx.is_oracle_mode) { + result_obj.set_null(); + } else { + result_obj.set_varchar(ObString()); + } + } else { ObString result_str; result_str.assign_ptr(value.ptr() + start_pos - 1, static_cast(substr_len)); result_obj.set_varchar(result_str); result_obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); - if (OB_FAIL(check_varchar_empty(result_obj))) { LOG_WARN("check varchar emtpy failed", K(ret)); - } else if (OB_FAIL(result_obj_array.push_back(result_obj))) { - LOG_WARN("result obj array push back failed", K(ret)); - } + } } } + + if (OB_SUCC(ret)) { + if (OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } + } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -653,7 +665,7 @@ int ObProxyExprConcat::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -709,7 +721,7 @@ int ObProxyExprConcat::calc(const ObProxyExprCtx &ctx, } } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -746,19 +758,19 @@ int ObProxyExprToInt::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } if (OB_SUCC(ret)) { ObObj result_obj; ObObj &obj = param_result.at(0); - if (OB_FAIL(get_int_obj(obj, result_obj))) { + if (OB_FAIL(get_int_obj(obj, result_obj, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(result_obj_array.push_back(result_obj))) { LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -774,7 +786,7 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, common::ObSEArray, 4> param_result_array; int cnt = 0; int64_t len = result_obj_array.count(); - + if (-1 != index_ && ObProxyExprCalcItem::FROM_OBJ_ARRAY == calc_item.source_ && !has_agg_) { if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { LOG_WARN("calc expr failed", K(ret)); @@ -799,7 +811,7 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -810,7 +822,7 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, if (ObDoubleTC == obj1.get_type_class() || ObDoubleTC == obj2.get_type_class()) { if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { LOG_WARN("get double obj failed", K(obj1), K(obj2), K(ret)); - } else if (fabs(obj2.get_double()) == 0.0) { + } else if (fabs(obj2.get_double()) < DBL_EPSILON) { result_obj.set_null(); } else { double obj1_d = obj1.get_double(); @@ -820,6 +832,8 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, } else if (ObFloatTC == obj1.get_type_class() || ObFloatTC == obj2.get_type_class()) { if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { LOG_WARN("get float obj failed", K(obj1), K(obj2), K(ret)); + } else if (fabs(obj2.get_float()) < FLT_EPSILON) { + result_obj.set_null(); } else { float obj1_f = obj1.get_float(); float obj2_f = obj2.get_float(); @@ -846,9 +860,9 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -866,7 +880,7 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -907,7 +921,7 @@ int ObProxyExprAdd::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -950,9 +964,9 @@ int ObProxyExprAdd::calc(const ObProxyExprCtx &ctx, } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -970,7 +984,7 @@ int ObProxyExprAdd::calc(const ObProxyExprCtx &ctx, LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1011,7 +1025,7 @@ int ObProxyExprSub::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -1054,9 +1068,9 @@ int ObProxyExprSub::calc(const ObProxyExprCtx &ctx, } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -1074,7 +1088,7 @@ int ObProxyExprSub::calc(const ObProxyExprCtx &ctx, LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1115,7 +1129,7 @@ int ObProxyExprMul::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -1158,9 +1172,9 @@ int ObProxyExprMul::calc(const ObProxyExprCtx &ctx, } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -1178,7 +1192,7 @@ int ObProxyExprMul::calc(const ObProxyExprCtx &ctx, LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1215,7 +1229,7 @@ int ObProxyExprTestLoad::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -1236,7 +1250,7 @@ int ObProxyExprTestLoad::calc(const ObProxyExprCtx &ctx, } } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1273,7 +1287,7 @@ int ObProxyExprSplit::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -1303,7 +1317,7 @@ int ObProxyExprSplit::calc(const ObProxyExprCtx &ctx, if (OB_SUCC(ret)) { ObObj obj; - if (OB_FAIL(get_int_obj(param_result.at(2), obj))) { + if (OB_FAIL(get_int_obj(param_result.at(2), obj, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(obj.get_int(index))) { LOG_WARN("get int failed", K(ret)); @@ -1374,7 +1388,7 @@ int ObProxyExprSplit::calc(const ObProxyExprCtx &ctx, } } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1404,7 +1418,7 @@ int ObProxyExprAvg::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &c if (ObDoubleTC == obj1.get_type_class() || ObDoubleTC == obj2.get_type_class()) { if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { LOG_WARN("get double obj failed", K(obj1), K(obj2), K(ret)); - } else if (fabs(obj2.get_double()) == 0.0) { + } else if (fabs(obj2.get_double()) < DBL_EPSILON) { result_obj.set_null(); } else { double obj1_d = obj1.get_double(); @@ -1414,6 +1428,8 @@ int ObProxyExprAvg::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &c } else if (ObFloatTC == obj1.get_type_class() || ObFloatTC == obj2.get_type_class()) { if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { LOG_WARN("get float obj failed", K(obj1), K(obj2), K(ret)); + } else if (fabs(obj2.get_float() < FLT_EPSILON)) { + result_obj.set_null(); } else { float obj1_f = obj1.get_float(); float obj2_f = obj2.get_float(); @@ -1440,9 +1456,9 @@ int ObProxyExprAvg::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &c } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -1471,6 +1487,383 @@ int ObProxyExprAvg::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &c return ret; } +/* + * for to_date and to_timestamp, only support at least one param, at most two params + */ +int ObProxyExprToTimeHandler::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + common::ObSEArray, 4> param_result_array; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret), K(param_array_.count())); + } else if (len == result_obj_array.count()) { + if (OB_UNLIKELY(param_array_.count() < 1)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("to_date should have at least one param", K(ret)); + } else if (OB_FAIL(calc_param_expr(ctx, calc_item, param_result_array, cnt))) { + LOG_WARN("calc param expr failed", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + for (int64_t j = 0; OB_SUCC(ret) && j < param_result_array.count(); j++) { + ObObj tmp_obj; + if (param_result_array.at(j).count() == 1) { + tmp_obj = param_result_array.at(j).at(0); + } else { + tmp_obj = param_result_array.at(j).at(i); + } + if (OB_FAIL(param_result.push_back(tmp_obj))) { + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); + } + } + + ObObjTypeClass type = param_result.at(0).get_type_class(); + if (OB_SUCC(ret) && type != ObStringTC && type != ObIntTC && type != ObNumberTC) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("unexpected the first param type of to_date", K(type)); + } + + ObTimeZoneInfo tz_info; + ObDataTypeCastParams dtc_params; + if (OB_SUCC(ret)) { + ObObj second_obj; + ObString nls_format; + + if (2 == param_result.count()) { + if(OB_FAIL(get_varchar_obj(param_result.at(1), second_obj, *ctx.allocator_))){ + LOG_WARN("get varchar obj failed", K(ret)); + } else if (OB_FAIL(second_obj.get_varchar(nls_format))) { + LOG_WARN("get varchar failded", K(ret)); + } else { + if (!nls_format.empty()) { + dtc_params.tz_info_ = &tz_info; + dtc_params.set_nls_format_by_type(target_type_, nls_format); + } else { + dtc_params.tz_info_ = &tz_info; + if (OB_FAIL(proxy::ObExprCalcTool::build_dtc_params( + ctx.client_session_info_, target_type_, dtc_params))) { + LOG_WARN("fail to build dtc params", K(ret), K(target_type_)); + } + } + } + } + } + + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + ObCastCtx cast_ctx(ctx.allocator_, &dtc_params, CM_NULL_ON_WARN, collation); + param_result.at(0).set_collation_type(collation); + if (OB_SUCC(ret) && OB_FAIL(ObObjCasterV2::to_type(target_type_, collation, cast_ctx, + param_result.at(0), param_result.at(0)))) { + LOG_WARN("fail to cast obj", K(ret), K(target_type_), K(collation)); + } + if (OB_SUCC(ret) && OB_FAIL(result_obj_array.push_back(param_result.at(0)))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + +int ObProxyExprNvl::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + common::ObSEArray, 4> param_result_array; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret), K(param_array_.count())); + } else if (len == result_obj_array.count()) { + if (OB_UNLIKELY(param_array_.count() != 2)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("nvl should have two param", K(ret)); + } else if (OB_FAIL(calc_param_expr(ctx, calc_item, param_result_array, cnt))) { + LOG_WARN("calc param expr failed", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + for (int64_t j = 0; OB_SUCC(ret) && j < param_result_array.count(); j++) { + ObObj tmp_obj; + if (param_result_array.at(j).count() == 1) { + tmp_obj = param_result_array.at(j).at(0); + } else { + tmp_obj = param_result_array.at(j).at(i); + } + if (OB_FAIL(param_result.push_back(tmp_obj))) { + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); + } + } + + ObObj result_obj = param_result.at(0); + ObObj second_obj = param_result.at(1); + if (OB_SUCC(ret)) { + // null expr or empty varchar treated as null + if (result_obj.is_null()) { + result_obj = second_obj; + } else if (result_obj.is_string_type()) { + ObString str; + if (OB_FAIL(result_obj.get_string(str))) { + LOG_WARN("get varchar of param failed", K(ret)); + } else if (str.empty()) { + result_obj = second_obj; + } + } + } + + if (OB_SUCC(ret) && OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + +/* + * only support datetime format. + */ +int ObProxyExprToChar::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + common::ObSEArray, 4> param_result_array; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret), K(param_array_.count())); + } else if (len == result_obj_array.count()) { + if (OB_UNLIKELY(param_array_.count() < 1) || OB_UNLIKELY(param_array_.count() > 2)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("to_char should have one or two param", K(ret), K(param_array_.count())); + } else if (OB_FAIL(calc_param_expr(ctx, calc_item, param_result_array, cnt))) { + LOG_WARN("calc param expr failed", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + for (int64_t j = 0; OB_SUCC(ret) && j < param_result_array.count(); j++) { + ObObj tmp_obj; + if (param_result_array.at(j).count() == 1) { + tmp_obj = param_result_array.at(j).at(0); + } else { + tmp_obj = param_result_array.at(j).at(i); + } + if (OB_FAIL(param_result.push_back(tmp_obj))) { + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); + } + } + if (OB_SUCC(ret)) { + ObObjType target_type = ObVarcharType; + ObObj result_obj = param_result.at(0); + ObObj second_obj; + ObString nls_format; + ObTimeZoneInfo tz_info; + ObDataTypeCastParams dtc_params = ObDataTypeCastParams(); + + // to_char(datetime) return NULL when nls_format parmas is '' + bool is_empty_format = false; + + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + dtc_params.tz_info_ = &tz_info; + + if (ObDateTimeTC != param_result.at(0).get_type_class() && ObOTimestampTC != param_result.at(0).get_type_class()) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("unsupported first param type of to_char", K(param_result.at(0).get_type_class())); + } else if (2 == param_result.count()) { + if (OB_FAIL(get_varchar_obj(param_result.at(1), second_obj, *ctx.allocator_))) { + LOG_WARN("get varchar obj failed", K(ret)); + } else if (OB_FAIL(second_obj.get_varchar(nls_format))) { + LOG_WARN("get varchar failed", K(ret)); + } else { + if (!nls_format.empty()) { + // ObObjCasterV2 only support ObOTimestampTC to format by nls_format, here convert ObDateTimeTC to ObTimestampTZType + dtc_params.set_nls_format_by_type(ObTimestampTZType, nls_format); + ObCastCtx cast_ctx_otimestamp(ctx.allocator_, &dtc_params, CM_NULL_ON_WARN, collation); + if (OB_FAIL(ObObjCasterV2::to_type(ObTimestampTZType, collation, cast_ctx_otimestamp, + result_obj, result_obj))) { + LOG_WARN("cast DateTime to ObTimestampTZTType failed", K(ret)); + } + } else { + is_empty_format = true; + } + } + } + + if (OB_SUCC(ret)) { + ObCastCtx cast_ctx(ctx.allocator_, &dtc_params, CM_NULL_ON_WARN, collation); + if (param_array_.count() == 1) { + // do nothing + } else if (is_empty_format) { + result_obj.set_null(); + } else if (OB_FAIL(ObObjCasterV2::to_type(target_type, collation, cast_ctx, result_obj, result_obj))) { + LOG_WARN("fail to cast obj to timestamp", K(ret), K(result_obj), K(target_type), K(collation)); + } + } + + if (OB_SUCC(ret) && OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + +int ObProxyExprSysdate::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret)); + } else if (len == result_obj_array.count()) { + if (OB_UNLIKELY(param_array_.count() > 0)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("sysdate should have no param", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + if (OB_SUCC(ret)) { + ObObjType target_type = ObDateTimeType; + + int64 now = common::ObTimeUtility::current_time(); + // calc timezone offset to correct the time zone info + int64 gm_time_buf = (int64)((time_t)now - mktime(gmtime((time_t *)&now))) * 1000000; + + ObObj result_obj; + result_obj.set_timestamp(now + gm_time_buf); + ObTimeZoneInfo tz_info; + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + if (OB_SUCC(ret)) { + ObCastCtx cast_ctx(ctx.allocator_, NULL, CM_NULL_ON_WARN, collation); + if (OB_FAIL(ObObjCasterV2::to_type(target_type, collation, cast_ctx, result_obj, result_obj))) { + LOG_WARN("fail to cast obj to timestamp", K(ret), K(result_obj), K(target_type), K(collation)); + } else if (OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + +/* + * refer to the implementation of oracle + * mod calculate: MOD(n1, n2) = n1 - n2 * FLOOR(n1/n2) + * when ( n2 = 0 ), return n1 + */ +int ObProxyExprMod::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + common::ObSEArray, 4> param_result_array; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (-1 != index_ && + ObProxyExprCalcItem::FROM_OBJ_ARRAY == calc_item.source_ && !has_agg_) { + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret)); + } + } + + if (OB_SUCC(ret) && len == result_obj_array.count()) { + if (2 != param_array_.count()) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("mod should have two param", K(ret), K(param_array_.count())); + } else if (OB_FAIL( + calc_param_expr(ctx, calc_item, param_result_array, cnt))) { + LOG_WARN("calc param result failed", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + for (int64_t j = 0; OB_SUCC(ret) && j < param_result_array.count(); j++) { + ObObj tmp_obj; + if (param_result_array.at(j).count() == 1) { + tmp_obj = param_result_array.at(j).at(0); + } else { + tmp_obj = param_result_array.at(j).at(i); + } + if (OB_FAIL(param_result.push_back(tmp_obj))) { + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); + } + } + + if (OB_SUCC(ret)) { + ObObj obj1 = param_result.at(0); + ObObj obj2 = param_result.at(1); + ObObj result_obj; + + if (ObDoubleTC == obj1.get_type_class() || + ObDoubleTC == obj2.get_type_class()) { + if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { + LOG_WARN("get double obj failed", K(obj1), K(obj2), K(ret)); + } else if (fabs(obj2.get_double()) < DBL_EPSILON) { + result_obj.set_double(obj1.get_double()); + } else { + double obj1_d = obj1.get_double(); + double obj2_d = obj2.get_double(); + result_obj.set_double(obj1_d - obj2_d * floor(obj1_d / obj1_d)); + } + } else if (ObFloatTC == obj1.get_type_class() || ObFloatTC == obj2.get_type_class()) { + if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { + LOG_WARN("get float obj failed", K(obj1), K(obj2), K(ret)); + } else if (fabs(obj2.get_float()) < FLT_EPSILON) { + result_obj.set_float(obj1.get_float()); + } else { + float obj1_f = obj1.get_float(); + float obj2_f = obj2.get_float(); + result_obj.set_float(obj1_f - obj2_f * floor(obj1_f / obj1_f)); + } + } else { + number::ObNumber res_nmb; + if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { + LOG_WARN("get number obj failed", K(ret), K(obj1), K(obj2)); + } else if (obj2.get_number().is_zero()) { + result_obj.set_number(obj1.get_number()); + } else if (OB_FAIL(obj1.get_number().rem(obj2.get_number(), res_nmb, *ctx.allocator_))) { + LOG_WARN("failed to mod numbers", K(ret), K(obj1), K(obj2)); + } else if (OB_SUCC(ret)) { + result_obj.set_number(res_nmb); + } + } + + if (OB_SUCC(ret) && OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + } // end opsql } // end obproxy } // end oceanbase diff --git a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h index cda8fca6..e7ff0800 100644 --- a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h +++ b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h @@ -13,10 +13,11 @@ #ifndef OB_FUNC_EXPR_PROXY_EXPR_H #define OB_FUNC_EXPR_PROXY_EXPR_H -#include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h" #include "dbconfig/ob_proxy_db_config_info.h" #include "lib/allocator/ob_mod_define.h" #include "lib/ob_define.h" +#include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h" +#include "proxy/mysqllib/ob_proxy_session_info.h" namespace oceanbase { @@ -30,15 +31,26 @@ class ObProxyExprCtx { public: explicit ObProxyExprCtx(const int64_t physical_size, dbconfig::ObTestLoadType type, - bool is_elastic_index, common::ObIAllocator* allocator) + bool is_elastic_index, common::ObIAllocator *allocator) : sharding_physical_size_(physical_size), test_load_type_(type), is_elastic_index_(is_elastic_index), - allocator_(allocator), scale_(-1) {} + allocator_(allocator), scale_(-1), is_oracle_mode(false) {} + explicit ObProxyExprCtx(const int64_t physical_size, + dbconfig::ObTestLoadType type, bool is_elastic_index, + common::ObIAllocator *allocator, + proxy::ObClientSessionInfo *client_session_info) + : sharding_physical_size_(physical_size), test_load_type_(type), + is_elastic_index_(is_elastic_index), allocator_(allocator), scale_(-1), + client_session_info_(client_session_info), is_oracle_mode(false) {} ~ObProxyExprCtx() {} void set_sharding_physical_size(const int64_t physical_size) { sharding_physical_size_ = physical_size; } void set_test_load_type(const dbconfig::ObTestLoadType type) { test_load_type_ = type; } void set_is_elastic_index(const bool is_elastic_index) { is_elastic_index_ = is_elastic_index; } void set_scale(const int64_t scale) { scale_ = scale; }; + void set_client_session_info(proxy::ObClientSessionInfo *client_session_info) + { + client_session_info_ = client_session_info; + } public: int64_t sharding_physical_size_; @@ -46,6 +58,8 @@ class ObProxyExprCtx bool is_elastic_index_; common::ObIAllocator *allocator_; int64_t scale_; + proxy::ObClientSessionInfo *client_session_info_; + bool is_oracle_mode; }; struct ObProxyExprCalcItem { @@ -255,6 +269,8 @@ class ObProxyFuncExpr : public ObProxyExpr virtual ~ObProxyFuncExpr(); int add_param_expr(ObProxyExpr* expr) { return param_array_.push_back(expr); } + int64_t get_param_conut() { return param_array_.count(); } + int calc_param_expr(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, common::ObSEArray, 4> ¶m_result, int &cnt); @@ -263,7 +279,7 @@ class ObProxyFuncExpr : public ObProxyExpr void set_param_array(common::ObSEArray& param_array) { param_array_ = param_array; } public: - static int get_int_obj(const common::ObObj &src, common::ObObj &dst); + static int get_int_obj(const common::ObObj &src, common::ObObj &dst, common::ObIAllocator &allocator); static int get_varchar_obj(const common::ObObj &src, common::ObObj &dst, common::ObIAllocator &allocator); int check_varchar_empty(const common::ObObj& result); @@ -415,6 +431,56 @@ class ObProxyExprSplit : public ObProxyFuncExpr common::ObIArray &result_obj_array); }; +// include to_date and to_timestamp +class ObProxyExprToTimeHandler : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprToTimeHandler() {} + explicit ObProxyExprToTimeHandler(ObObjType &target_type) : target_type_(target_type) {} + ~ObProxyExprToTimeHandler() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); + void set_target_type(ObObjType target_type) { target_type_ = target_type; } +private: + ObObjType target_type_; +}; + +class ObProxyExprNvl : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprNvl() {} + ~ObProxyExprNvl() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); +}; + +class ObProxyExprToChar : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprToChar() {} + ~ObProxyExprToChar() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); +}; + +class ObProxyExprSysdate : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprSysdate() {} + ~ObProxyExprSysdate() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); +}; + +class ObProxyExprMod : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprMod() {} + ~ObProxyExprMod() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); +}; + } // end opsql } // end obproxy } // end oceanbase diff --git a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h index 6554cb50..115929f3 100644 --- a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h +++ b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h @@ -38,6 +38,12 @@ typedef enum ObProxyExprType OB_PROXY_EXPR_TYPE_FUNC_ORDER, OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD, OB_PROXY_EXPR_TYPE_FUNC_SPLIT, + OB_PROXY_EXPR_TYPE_FUNC_TO_DATE, + OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP, + OB_PROXY_EXPR_TYPE_FUNC_NVL, + OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR, + OB_PROXY_EXPR_TYPE_FUNC_SYSDATE, + OB_PROXY_EXPR_TYPE_FUNC_MOD, OB_PROXY_EXPR_TYPE_MAX, }ObProxyExprType; @@ -112,6 +118,24 @@ const char* get_expr_type_name(int expr_type) case OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD: type_name = "OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD"; break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_DATE: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_TO_DATE"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_NVL: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_NVL"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_SYSDATE: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_SYSDATE"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_MOD: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_MOD"; + break; case OB_PROXY_EXPR_TYPE_MAX: type_name = "OB_PROXY_EXPR_TYPE_MAX"; break; diff --git a/src/obproxy/opsql/parser/ob_proxy_parse_result.cpp b/src/obproxy/opsql/parser/ob_proxy_parse_result.cpp index 7c375f3a..97046f70 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parse_result.cpp +++ b/src/obproxy/opsql/parser/ob_proxy_parse_result.cpp @@ -116,9 +116,6 @@ const char* get_print_stmt_name(const ObProxyBasicStmtType type) case OBPROXY_T_SELECT_TX_RO: str_ret = "SELECT_TX_RO"; break; - case OBPROXY_T_SET_AC_0: - str_ret = "SET"; - break; case OBPROXY_T_PING_PROXY: str_ret = "PING"; break; @@ -191,6 +188,25 @@ const char* get_print_stmt_name(const ObProxyBasicStmtType type) str_ret = "DESC"; break; + case OBPROXY_T_SHOW_MASTER_STATUS: + str_ret = "SHOW_MASTER_STATUS"; + break; + case OBPROXY_T_SHOW_BINLOG_EVENTS: + str_ret = "SHOW_BINLOG_EVENTS"; + break; + case OBPROXY_T_PURGE_BINARY_LOGS: + str_ret = "PURGE_BINARY_LOGS"; + break; + case OBPROXY_T_RESET_MASTER: + str_ret = "RESET_MASTER"; + break; + case OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT: + str_ret = "SHOW_BINLOG_SERVER_FOR_TENANT"; + break; + case OBPROXY_T_SHOW_BINARY_LOGS: + str_ret = "SHOW_BINARY_LOGS"; + break; + case OBPROXY_T_INVALID: case OBPROXY_T_MAX: case OBPROXY_T_OTHERS: @@ -348,9 +364,6 @@ const char* get_obproxy_stmt_name(const ObProxyBasicStmtType type) case OBPROXY_T_SELECT_PROXY_VERSION: str_ret = "OBPROXY_T_SELECT_PROXY_VERSION"; break; - case OBPROXY_T_SET_AC_0: - str_ret = "OBPROXY_T_SET_AC_0"; - break; case OBPROXY_T_SHOW_WARNINGS: str_ret = "OBPROXY_T_SHOW_WARNINGS"; break; @@ -411,6 +424,12 @@ const char* get_obproxy_stmt_name(const ObProxyBasicStmtType type) case OBPROXY_T_TEXT_PS_DROP: str_ret = "OBPROXY_T_TEXT_PS_DROP"; break; + case OBPROXY_T_LOGIN: + str_ret = "OBPROXY_T_LOGIN"; + break; + case OBPROXY_T_DESC: + str_ret = "OBPROXY_T_DESC"; + break; case OBPROXY_T_MAX: str_ret = "OBPROXY_T_MAX"; break; @@ -506,6 +525,9 @@ const char* get_obproxy_sub_stmt_name(const ObProxyBasicStmtSubType type) case OBPROXY_T_SUB_ROUTE_ROUTINE: str_ret = "OBPROXY_T_SUB_ROUTE_ROUTINE"; break; + case OBPROXY_T_SUB_SHOW_ELASTIC_ID: + str_ret = "OBPROXY_T_SUB_SHOW_ELASTIC_ID"; + break; case OBPROXY_T_SUB_SHOW_TOPOLOGY: str_ret = "OBPROXY_T_SUB_SHOW_TOPOLOGY"; break; diff --git a/src/obproxy/opsql/parser/ob_proxy_parse_result.h b/src/obproxy/opsql/parser/ob_proxy_parse_result.h index 145532c2..04574905 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parse_result.h +++ b/src/obproxy/opsql/parser/ob_proxy_parse_result.h @@ -87,7 +87,6 @@ typedef enum ObProxyBasicStmtType // internal request OBPROXY_T_BEGIN, OBPROXY_T_SELECT_TX_RO, - OBPROXY_T_SET_AC_0, OBPROXY_T_PING_PROXY, OBPROXY_T_SELECT_ROUTE_ADDR, OBPROXY_T_SET_ROUTE_ADDR, @@ -126,6 +125,14 @@ typedef enum ObProxyBasicStmtType // only for print obproxy_stat log OBPROXY_T_LOGIN, + // binglog related + OBPROXY_T_SHOW_MASTER_STATUS, + OBPROXY_T_SHOW_BINARY_LOGS, + OBPROXY_T_SHOW_BINLOG_EVENTS, + OBPROXY_T_PURGE_BINARY_LOGS, + OBPROXY_T_RESET_MASTER, + OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT, + OBPROXY_T_MAX } ObProxyBasicStmtType; @@ -196,6 +203,7 @@ typedef enum ObProxyBasicStmtSubType OBPROXY_T_SUB_SHOW_FULL_TABLES, OBPROXY_T_SUB_SHOW_TABLE_STATUS, OBPROXY_T_SUB_SHOW_CREATE_TABLE, + OBPROXY_T_SUB_SHOW_ELASTIC_ID, OBPROXY_T_SUB_SHOW_TOPOLOGY, OBPROXY_T_SUB_SHOW_DB_VERSION, OBPROXY_T_SUB_SHOW_COLUMNS, @@ -332,7 +340,7 @@ typedef struct _ObDbMeshRouteInfo typedef enum _ObProxySetValueType { - SET_VALUE_TYPE_ONE = 0, + SET_VALUE_TYPE_NONE = 0, SET_VALUE_TYPE_STR, SET_VALUE_TYPE_INT, SET_VALUE_TYPE_NUMBER, @@ -379,6 +387,7 @@ typedef struct _ObDbpRouteInfo ObProxyParseString table_name_; ObProxyParseString group_idx_str_; bool scan_all_; + bool sticky_session_; bool has_shard_key_; ObDbpShardKeyInfo shard_key_infos_[OBPROXY_MAX_DBP_SHARD_KEY_NUM]; int shard_key_count_; @@ -426,6 +435,9 @@ typedef struct _ObProxyParseResult ObProxyParseString col_name_; ObProxyParseString trace_id_; ObProxyParseString rpc_id_; + + // store the route server address in sql comment + ObProxyParseString target_db_server_; // read_consistency ObProxyReadConsistencyType read_consistency_type_; // db/table name diff --git a/src/obproxy/opsql/parser/ob_proxy_parser.h b/src/obproxy/opsql/parser/ob_proxy_parser.h index ab2436a2..27167a99 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser.h @@ -152,6 +152,7 @@ inline int ObProxyParser::obparse(const common::ObString &sql_string, common::ObString parse_sql_string = sql_string; //set ; ob parse need end with ; bool add_semicolon = false; + char origin_byte = parse_sql_string.ptr()[sql_string.length() - 2]; if (parse_sql_string.ptr()[sql_string.length() - 3] != ';') { parse_sql_string.ptr()[sql_string.length() - 2] = ';'; add_semicolon = true; @@ -169,7 +170,7 @@ inline int ObProxyParser::obparse(const common::ObString &sql_string, } } if (add_semicolon) { - parse_sql_string.ptr()[sql_string.length() - 2] = '\0'; + parse_sql_string.ptr()[sql_string.length() - 2] = origin_byte; } } return ret; diff --git a/src/obproxy/opsql/parser/ob_proxy_parser.l b/src/obproxy/opsql/parser/ob_proxy_parser.l index e01bb139..ef1c29f7 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser.l +++ b/src/obproxy/opsql/parser/ob_proxy_parser.l @@ -269,6 +269,7 @@ do {\ %x prepare %x insert_all_expr %x set_expr +%x show_elastic_id %x show_topology %x show_tables %x proxy_icmd_state @@ -281,8 +282,10 @@ multi_byte_right_parenthesis [\uff09] multi_byte_connect_char /*According to connection character to set by gen_parse.sh*/ space [ \t\n\r\f] identifer (([A-Za-z0-9$_#]|{multi_byte_connect_char})*) -int_num [\-\+]?[0-9]+ -number ([0-9]+E[-+]?[0-9]+)|([0-9]+"."[0-9]*E[-+]?[0-9]+)|("."[0-9]+E[-+]?[0-9]+)|([0-9]+"."[0-9]*)|("."[0-9]+) + +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +int_num [\-\+]?[0-9]{1,17} +number ([\-]?[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*E[-+]?[0-9]+)|([\-]?"."[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*)|([\-]?"."[0-9]+)|([\-\+]?[0-9]{18,}) comment_identifer [\-\+]?{identifer} odp_comment_identifer ([\-\+]?[A-Za-z0-9$_\-]*) @@ -301,7 +304,6 @@ c_cmt_end \*+\/ tx_read_only (@@session{space}*\.{space}*tx_read_only|@@tx_read_only) autocommit (@@session{space}*\.{space}*autocommit|@@autocommit|autocommit) -autocommit_0 ({autocommit}{space}*={space}*0) set_names (set{space}+names{space}+) set_charset (set{space}+charset{space}+|set{space}+character{space}+set{space}+) set_password (set{space}+password{space}+) @@ -357,7 +359,8 @@ show_full_tables (show{space}+full{space}+tables) show_create_table (show{space}+create{space}+table) show_columns (show{space}+(full{space}+)?(columns|fields)) show_index (show{space}+(index|indexes|keys)) -show_topology (show{space}+elastic_id) +show_elastic_id (show{space}+elastic_id) +show_topology (show{space}+topology) show_db_version (show{space}+database_version) select_database (select{space}+database({leftbracket}|{multi_byte_left_parenthesis})({rightbracket}|{multi_byte_right_parenthesis})) alter_proxyconfig (alter{space}+proxyconfig) @@ -369,6 +372,15 @@ select_proxy_version (select{space}+proxy_version{space}*({leftbracket}|{m select_obproxy_route_addr (select{space}+@obproxy_route_addr) set_obproxy_route_addr (set{space}+@obproxy_route_addr) + +/* binlog relate SQL */ +show_master_status (show{space}+master{space}+status) +show_binary_logs (show{space}+binary{space}+logs) +show_binlog_events (show{space}+binlog{space}+events) +purge_binary_logs (purge{space}+binary{space}+logs) +reset_master (reset{space}+master) +show_binlog_server_for_tenant (show{space}+binlog{space}+server{space}+for{space}+tenant) + %% /* basic dml stmt: */ @@ -390,7 +402,7 @@ CALL { SET_BASIC_STMT(OBPROXY_T_CALL); return CALL; } DECLARE { SET_HAS_ANONYMOUS_BLOCK(); PUSH_STATE(in_anonymous_block); } WHEN { ObProxyParseResult *p = yyget_extra(yyscanner); if (OB_NOTNULL(p)) { - if (OBPROXY_T_INSERT == p->cur_stmt_type_) + if (OBPROXY_T_INSERT == p->cur_stmt_type_) PUSH_STATE(insert_all_expr); } return WHEN; } @@ -411,7 +423,7 @@ UNIQUE { return UNIQUE; } USING { return USING; } PREPARE { PUSH_STATE(prepare); return PREPARE; } EXECUTE { return EXECUTE; } -DEALLOCATE { return DEALLOCATE; } +DEALLOCATE { return DEALLOCATE; } /* oracle ddl stmt */ @@ -445,7 +457,7 @@ ALL { return ALL; } LIKE { return LIKE; } PARTITION { return PARTITION; } BINARY { return BINARY; } -GROUP_NAME { return GROUP_NAME; } +GROUP_NAME { RETURN_NON_RESERVED_KEYWORD(GROUP_NAME); } /* to make bison easy, do not return these reserved keyword in non strict mode */ IGNORE { RETURN_IGNORED_WORD(); } @@ -549,13 +561,15 @@ REFRESH { RETURN_NON_RESERVED_KEYWORD(REFRESH); } UPGRADE { RETURN_NON_RESERVED_KEYWORD(UPGRADE); } IDC { RETURN_NON_RESERVED_KEYWORD(IDC); } -{show_topology} { SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_topology); return SHOW_TOPOLOGY; } -"FROM" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } -"WHERE" { POP_STATE(); PUSH_STATE(INITIAL); return WHERE; } -<> { return END_P; } -{whitespace} { } -; { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } -. { return ERROR; } +{show_elastic_id} { SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_elastic_id ); return SHOW_ELASTIC_ID; } +"FROM" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } +"WHERE" { POP_STATE(); PUSH_STATE(INITIAL); return WHERE; } +<> { return END_P; } +{whitespace} { } +; { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } +. { return ERROR; } + +{show_topology} { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_TOPOLOGY; } {show_db_version} { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } {show_databases} { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } @@ -647,7 +661,13 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } return MERGE_HINT_BEGIN; } -{autocommit_0} { return AUTOCOMMIT_0; } +{show_master_status} { SET_BASIC_STMT(OBPROXY_T_SHOW_MASTER_STATUS); return SHOW_MASTER_STATUS; } +{show_binary_logs} { SET_BASIC_STMT(OBPROXY_T_SHOW_BINARY_LOGS); return SHOW_BINARY_LOGS; } +{show_binlog_events} { SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_EVENTS); return SHOW_BINLOG_EVENTS; } +{purge_binary_logs} { SET_BASIC_STMT(OBPROXY_T_PURGE_BINARY_LOGS); return PURGE_BINARY_LOGS; } +{reset_master} { SET_BASIC_STMT(OBPROXY_T_RESET_MASTER); return RESET_MASTER; } +{show_binlog_server_for_tenant} { SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT); return SHOW_BINLOG_SERVER_FOR_TENANT; } + "global" { return GLOBAL; } "session" { return SESSION; } {int_num} { RETURN_INT_NUM(); } @@ -802,6 +822,7 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } {space}*"trace_id" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TRACE_ID); } {space}*{comment_identifer}"." { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT_NAME_OB_DOT(NAME_OB_DOT); } {space}*"rpc_id" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(RPC_ID); } +{space}*"target_db_server" { PUSH_STATE(in_odp_comment_expr); return TARGET_DB_SERVER; } "group_id" { return GROUP_ID; } "table_id" { return TABLE_ID; } @@ -812,6 +833,7 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } "tnt_id" { return TNT_ID; } "trace_id" { return TRACE_ID; } "rpc_id" { return RPC_ID; } +"target_db_server" { return TARGET_DB_SERVER; } {sqbegin} { ENTER_QUOTE_STATE(comment_sq); } {comma}|{multi_byte_comma} { return ','; } {odp_comment_identifer} { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } @@ -882,6 +904,7 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } "$ROUTE" { return ROUTE_TAG; } "$SYS" { return SYS_TAG; } "SCAN_ALL" { return SCAN_ALL; } +"STICKY_SESSION" { return STICKY_SESSION; } "SHARDING_KEY" { return SHARD_KEY; } "table_name" { return TABLE_NAME;} "parallelism" { return PARALL; } @@ -1135,7 +1158,6 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } "last_insert_id" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } "global" { SET_GLOBAL_SET_STMT(); RETURN_IGNORED_WORD(); } {tx_read_only} { RETURN_COL_NAME(TX_READ_ONLY); } -{autocommit_0} { return AUTOCOMMIT_0; } {identifer} { RETURN_IGNORED_WORD(); } <> { return END_P; } {whitespace} { } @@ -1169,7 +1191,7 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } {dquote} { POP_STATE(); } {quote} { POP_STATE(); } -"BEGIN" { POP_STATE(); return BEGI;} +"BEGIN" { POP_STATE(); RETURN_NON_RESERVED_KEYWORD(BEGI);} . {} <> { return END_P; } diff --git a/src/obproxy/opsql/parser/ob_proxy_parser.y b/src/obproxy/opsql/parser/ob_proxy_parser.y index 5e930f58..dbd0eda3 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser.y +++ b/src/obproxy/opsql/parser/ob_proxy_parser.y @@ -39,9 +39,6 @@ static inline void handle_stmt_end(ObProxyParseResult* result) case OBPROXY_T_SELECT_TX_RO: result->stmt_type_ = OBPROXY_T_SELECT; break; - case OBPROXY_T_SET_AC_0: - result->stmt_type_ = OBPROXY_T_OTHERS; - break; case OBPROXY_T_BEGIN: result->stmt_type_ = OBPROXY_T_OTHERS; break; @@ -60,7 +57,7 @@ static inline void handle_stmt_end(ObProxyParseResult* result) } } else { result->stmt_type_ = result->cur_stmt_type_; - } + } if (OBPROXY_T_TEXT_PS_PREPARE == result->text_ps_inner_stmt_type_) { ObProxyBasicStmtType tmp_type = result->cur_stmt_type_; @@ -289,19 +286,19 @@ extern void *obproxy_parse_malloc(const size_t nbyte, void *malloc_pool); %token FROM DUAL %token PREPARE EXECUTE USING DEALLOCATE %token SELECT_HINT_BEGIN UPDATE_HINT_BEGIN DELETE_HINT_BEGIN INSERT_HINT_BEGIN REPLACE_HINT_BEGIN MERGE_HINT_BEGIN HINT_END COMMENT_BEGIN COMMENT_END ROUTE_TABLE ROUTE_PART_KEY QUERY_TIMEOUT READ_CONSISTENCY WEAK STRONG FROZEN PLACE_HOLDER -%token END_P ERROR +%token END_P ERROR %token WHEN /* non-reserved keyword */ %token FLASHBACK AUDIT NOAUDIT %token BEGI START TRANSACTION READ ONLY WITH CONSISTENT SNAPSHOT INDEX XA %token WARNINGS ERRORS TRACE %token QUICK COUNT AS WHERE VALUES ORDER GROUP HAVING INTO UNION FOR -%token TX_READ_ONLY AUTOCOMMIT_0 SELECT_OBPROXY_ROUTE_ADDR SET_OBPROXY_ROUTE_ADDR +%token TX_READ_ONLY SELECT_OBPROXY_ROUTE_ADDR SET_OBPROXY_ROUTE_ADDR %token NAME_OB_DOT NAME_OB EXPLAIN DESC DESCRIBE NAME_STR %token USE HELP SET_NAMES SET_CHARSET SET_PASSWORD SET_DEFAULT SET_OB_READ_CONSISTENCY SET_TX_READ_ONLY GLOBAL SESSION %token NUMBER_VAL -%token GROUP_ID TABLE_ID ELASTIC_ID TESTLOAD ODP_COMMENT TNT_ID DISASTER_STATUS TRACE_ID RPC_ID -%token DBP_COMMENT ROUTE_TAG SYS_TAG TABLE_NAME SCAN_ALL PARALL SHARD_KEY +%token GROUP_ID TABLE_ID ELASTIC_ID TESTLOAD ODP_COMMENT TNT_ID DISASTER_STATUS TRACE_ID RPC_ID TARGET_DB_SERVER +%token DBP_COMMENT ROUTE_TAG SYS_TAG TABLE_NAME SCAN_ALL STICKY_SESSION PARALL SHARD_KEY %token INT_NUM %type right_string_val tracer_right_string_val name_right_string_val %type call_expr @@ -323,12 +320,13 @@ extern void *obproxy_parse_malloc(const size_t nbyte, void *malloc_pool); %token SHOW_PROXYSTAT REFRESH %token SHOW_PROXYTRACE %token SHOW_PROXYINFO BINARY UPGRADE IDC -%token SHOW_TOPOLOGY GROUP_NAME SHOW_DB_VERSION +%token SHOW_ELASTIC_ID SHOW_TOPOLOGY GROUP_NAME SHOW_DB_VERSION %token SHOW_DATABASES SHOW_TABLES SHOW_FULL_TABLES SELECT_DATABASE SHOW_CREATE_TABLE SELECT_PROXY_VERSION SHOW_COLUMNS SHOW_INDEX %token ALTER_PROXYCONFIG %token ALTER_PROXYRESOURCE %token PING_PROXY %token KILL_PROXYSESSION KILL_GLOBALSESSION KILL QUERY +%token SHOW_MASTER_STATUS SHOW_BINARY_LOGS SHOW_BINLOG_EVENTS PURGE_BINARY_LOGS RESET_MASTER SHOW_BINLOG_SERVER_FOR_TENANT %type table_factor non_reserved_keyword var_name %start root @@ -372,6 +370,7 @@ stmt: select_stmt {} | ddl_stmt {} | text_ps_stmt {} | merge_stmt {} + | binlog_stmt {} | other_stmt { result->cur_stmt_type_ = OBPROXY_T_OTHERS; } select_stmt: select_with_opt_hint select_expr_list opt_from @@ -433,7 +432,7 @@ text_ps_prepare_args_stmt : text_ps_prepare_var_list | text_ps_from_stmt -text_ps_prepare_stmt: PREPARE var_name FROM +text_ps_prepare_stmt: PREPARE var_name FROM { result->text_ps_inner_stmt_type_ = OBPROXY_T_TEXT_PS_PREPARE; result->text_ps_name_ = $2; @@ -496,17 +495,14 @@ select_tx_read_only_stmt: SELECT TX_READ_ONLY { result->cur_stmt_type_ = OBPROXY select_proxy_version_stmt: SELECT_PROXY_VERSION | SELECT_PROXY_VERSION AS var_name { result->col_name_ = $3; } -set_autocommit_0_stmt: SET AUTOCOMMIT_0 { result->cur_stmt_type_ = OBPROXY_T_SET_AC_0; } - | SET AUTOCOMMIT_0 expr_list - hooked_stmt: select_tx_read_only_stmt {} | select_proxy_version_stmt {} - | set_autocommit_0_stmt {} | select_obproxy_route_addr_stmt {} | set_obproxy_route_addr_stmt {} | shard_special_stmt {} shard_special_stmt: show_es_id_stmt {} + | show_topology_stmt {} | show_db_version_stmt {} | SELECT_DATABASE { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; } | SHOW_DATABASES { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; } @@ -515,8 +511,9 @@ shard_special_stmt: show_es_id_stmt {} | show_columns_stmt {} | show_index_stmt {} | SHOW_CREATE_TABLE routine_name_stmt { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_CREATE_TABLE; } - | explain_or_desc routine_name_stmt + | explain_or_desc var_name { + result->table_info_.table_name_ = $2; result->cur_stmt_type_ = OBPROXY_T_DESC; result->sub_stmt_type_ = OBPROXY_T_SUB_DESC_TABLE; } @@ -567,21 +564,28 @@ show_table_status_stmt: SHOW TABLE STATUS opt_show_from opt_show_like show_db_version_stmt: SHOW_DB_VERSION { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DB_VERSION; } -show_es_id_stmt: SHOW_TOPOLOGY { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; } - | SHOW_TOPOLOGY FROM NAME_OB +show_es_id_stmt: SHOW_ELASTIC_ID { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; } + | SHOW_ELASTIC_ID FROM NAME_OB { SET_ICMD_ONE_STRING($3); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; } - | SHOW_TOPOLOGY WHERE GROUP_NAME '=' NAME_OB + | SHOW_ELASTIC_ID WHERE GROUP_NAME '=' NAME_OB { SET_ICMD_SECOND_STRING($5); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; } - | SHOW_TOPOLOGY FROM NAME_OB WHERE GROUP_NAME '=' NAME_OB + | SHOW_ELASTIC_ID FROM NAME_OB WHERE GROUP_NAME '=' NAME_OB { SET_ICMD_ONE_STRING($3); SET_ICMD_SECOND_STRING($7); + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; + } + +show_topology_stmt: SHOW_TOPOLOGY { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; } + | SHOW_TOPOLOGY FROM NAME_OB + { + result->table_info_.table_name_ = $3; result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; } @@ -771,7 +775,7 @@ comment_expr: COMMENT_BEGIN comment_list COMMENT_END {} | COMMENT_BEGIN DISASTER_STATUS '=' right_string_val odp_comment_list COMMENT_END { result->dbmesh_route_info_.disaster_status_str_ = $4; } | COMMENT_BEGIN DBP_COMMENT ROUTE_TAG '=' '{' dbp_comment_list '}' COMMENT_END {} | COMMENT_BEGIN DBP_COMMENT SYS_TAG '=' '{' dbp_sys_comment '}' COMMENT_END {} - + | COMMENT_BEGIN TARGET_DB_SERVER '=' right_string_val odp_comment_list COMMENT_END { result->target_db_server_ = $4; } comment_list: /* empty */ {} | comment_list comment @@ -794,6 +798,7 @@ dbp_comment: GROUP_ID '(' right_string_val ')' } | SCAN_ALL '(' ')' { result->dbp_route_info_.scan_all_ = true; } | SCAN_ALL '(' PARALL '=' right_string_val ')' { result->dbp_route_info_.scan_all_ = true; } + | STICKY_SESSION '(' ')' { result->dbp_route_info_.sticky_session_ = true; } | SHARD_KEY '(' dbp_kv_comment_list ')' {result->dbp_route_info_.has_shard_key_ = true;} dbp_sys_comment: TRACE '(' tracer_right_string_val')' { result->trace_id_ = $3; } @@ -822,6 +827,7 @@ odp_comment: GROUP_ID '=' right_string_val { result->dbmesh_route_info_.group_ | RPC_ID '=' tracer_right_string_val { result->rpc_id_ = $3; } | TNT_ID '=' right_string_val { result->dbmesh_route_info_.tnt_id_str_ = $3; } | DISASTER_STATUS '=' right_string_val { result->dbmesh_route_info_.disaster_status_str_ = $3; } + | TARGET_DB_SERVER '=' right_string_val { result->target_db_server_ = $3; } | NAME_OB '.' NAME_OB '=' name_right_string_val { malloc_shard_column_node($$, $1, $3, DBMESH_TOKEN_STR_VAL); @@ -848,10 +854,10 @@ delete_with_opt_hint: DELETE insert_with_opt_hint: INSERT insert_all_when | INSERT_HINT_BEGIN hint_list_with_end insert_all_when -insert_all_when: +insert_all_when: | ALL | ALL WHEN - + replace_with_opt_hint: REPLACE | REPLACE_HINT_BEGIN hint_list_with_end merge_with_opt_hint: MERGE @@ -911,6 +917,13 @@ icmd_stmt: show_proxynet | kill_globalsession | kill_mysql +binlog_stmt: SHOW_MASTER_STATUS {} + | SHOW_BINARY_LOGS {} + | SHOW_BINLOG_EVENTS {} + | PURGE_BINARY_LOGS {} + | RESET_MASTER {} + | SHOW_BINLOG_SERVER_FOR_TENANT {} + /* limit param stmt*/ opt_limit: /*empty*/ @@ -1172,24 +1185,7 @@ non_reserved_keyword: START | UPGRADE | IDC | QUERY - | GROUP_ID - | TABLE_ID - | ELASTIC_ID - | TESTLOAD | GROUP_NAME - | ODP_COMMENT - | TNT_ID - | DISASTER_STATUS - | TRACE_ID - | RPC_ID - | DBP_COMMENT - | ROUTE_TAG - | SYS_TAG - | TABLE_NAME - | PARALL - | SCAN_ALL - | SHARD_KEY - | INDEX | FLASHBACK | AUDIT | NOAUDIT diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.c b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.c index 1deffdef..6e7ce96c 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.c +++ b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 336 -#define YY_END_OF_BUFFER 337 +#define YY_NUM_RULES 344 +#define YY_END_OF_BUFFER 345 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,264 +357,285 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[2327] = +static yyconst flex_int16_t yy_accept[2515] = { 0, - 146, 146, 189, 189, 0, 0, 0, 0, 202, 202, - 230, 230, 0, 0, 0, 0, 0, 0, 258, 258, + 147, 147, 195, 195, 0, 0, 0, 0, 208, 208, + 238, 238, 0, 0, 0, 0, 0, 0, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 307, 307, 0, 0, - 0, 0, 325, 325, 330, 330, 0, 0, 168, 168, - 0, 0, 0, 0, 0, 0, 337, 335, 156, 156, - 152, 282, 146, 146, 271, 153, 152, 144, 335, 152, - 152, 145, 151, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 288, 335, 335, 335, - - 335, 335, 335, 191, 336, 189, 188, 191, 191, 182, - 189, 189, 189, 189, 189, 189, 191, 191, 191, 191, - 191, 191, 195, 194, 195, 197, 197, 336, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 207, 207, 202, 207, - 207, 202, 202, 207, 207, 207, 207, 207, 207, 207, - 234, 233, 233, 230, 228, 234, 230, 229, 230, 232, - 231, 230, 230, 230, 230, 230, 234, 234, 240, 239, - 239, 236, 240, 237, 240, 240, 242, 241, 241, 241, - 242, 242, 242, 260, 257, 257, 258, 252, 253, 260, - - 258, 256, 258, 258, 258, 258, 258, 258, 260, 260, - 262, 261, 336, 336, 268, 267, 267, 265, 263, 264, - 268, 268, 268, 270, 269, 269, 269, 270, 270, 270, - 277, 278, 336, 272, 273, 336, 283, 284, 336, 290, - 291, 293, 294, 310, 308, 308, 298, 307, 307, 299, - 297, 310, 309, 310, 307, 307, 307, 307, 307, 300, - 310, 310, 310, 310, 310, 310, 334, 334, 317, 316, - 316, 314, 316, 315, 312, 313, 317, 317, 317, 317, - 327, 326, 326, 320, 325, 325, 321, 318, 319, 327, - 325, 325, 325, 327, 327, 327, 327, 327, 327, 331, - - 330, 332, 329, 330, 336, 336, 336, 336, 336, 336, - 178, 178, 176, 170, 170, 174, 168, 168, 173, 176, - 167, 176, 176, 166, 172, 171, 171, 168, 168, 168, - 175, 176, 176, 176, 176, 176, 176, 117, 115, 115, - 115, 117, 116, 117, 117, 117, 126, 124, 124, 124, - 126, 125, 126, 126, 126, 336, 336, 336, 156, 0, - 148, 0, 0, 0, 0, 0, 0, 0, 156, 146, - 156, 156, 156, 156, 156, 156, 146, 0, 0, 0, - 0, 0, 0, 0, 147, 0, 0, 0, 0, 0, - 0, 145, 0, 150, 192, 150, 145, 146, 146, 146, - - 44, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 8, 0, 149, 0, 0, 0, 0, - 0, 0, 0, 146, 154, 155, 144, 189, 0, 0, - 0, 0, 0, 0, 0, 190, 182, 182, 189, 189, - 189, 189, 189, 189, 0, 189, 179, 180, 0, 193, - 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, + 0, 0, 0, 0, 0, 0, 315, 315, 0, 0, + 0, 0, 333, 333, 338, 338, 0, 0, 174, 174, + 0, 0, 0, 0, 0, 0, 0, 0, 345, 343, + 157, 157, 153, 291, 147, 147, 280, 154, 153, 145, + 343, 153, 153, 146, 152, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 297, 343, + + 343, 343, 343, 343, 343, 197, 344, 195, 194, 197, + 197, 188, 195, 195, 195, 195, 195, 195, 197, 197, + 197, 197, 197, 197, 201, 200, 201, 203, 203, 344, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 213, 213, + 208, 213, 213, 208, 208, 213, 213, 213, 213, 213, + 213, 213, 242, 241, 241, 238, 236, 242, 238, 237, + 238, 240, 239, 238, 238, 238, 238, 238, 242, 242, + 248, 247, 247, 244, 248, 245, 248, 248, 250, 249, + 249, 249, 250, 250, 250, 269, 266, 266, 267, 261, + + 262, 269, 267, 265, 267, 267, 267, 267, 267, 267, + 269, 269, 271, 270, 344, 344, 277, 276, 276, 274, + 272, 273, 277, 277, 277, 279, 278, 278, 278, 279, + 279, 279, 286, 287, 344, 281, 282, 344, 292, 293, + 344, 299, 300, 302, 303, 318, 316, 316, 307, 315, + 315, 308, 306, 318, 317, 318, 315, 315, 315, 315, + 309, 318, 318, 318, 318, 318, 318, 342, 342, 325, + 324, 324, 322, 324, 323, 320, 321, 325, 325, 325, + 325, 335, 334, 334, 328, 333, 333, 329, 326, 327, + 335, 333, 333, 333, 335, 335, 335, 335, 335, 335, + + 339, 338, 340, 337, 338, 344, 344, 344, 344, 344, + 344, 184, 184, 182, 176, 176, 180, 174, 174, 179, + 182, 173, 182, 182, 172, 178, 177, 174, 174, 181, + 182, 182, 182, 182, 182, 182, 117, 115, 115, 115, + 117, 116, 117, 117, 117, 127, 125, 125, 125, 127, + 126, 127, 127, 127, 344, 344, 344, 157, 0, 149, + 0, 0, 0, 0, 0, 0, 0, 157, 147, 157, + 157, 157, 157, 157, 157, 147, 0, 0, 0, 0, + 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, + 146, 0, 0, 146, 151, 198, 151, 146, 147, 147, + + 147, 44, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 8, 0, 150, 0, 0, 0, + 0, 0, 0, 0, 147, 155, 156, 145, 195, 0, + 0, 0, 0, 0, 0, 0, 196, 188, 188, 195, + 195, 195, 195, 195, 195, 0, 195, 185, 186, 0, + 199, 0, 0, 0, 223, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, - 202, 0, 0, 0, 0, 0, 0, 0, 203, 0, - 0, 0, 0, 0, 0, 0, 206, 202, 202, 0, - 205, 0, 0, 0, 0, 0, 0, 0, 202, 230, - 0, 235, 230, 230, 230, 230, 230, 230, 230, 230, - 233, 229, 0, 238, 239, 237, 0, 241, 241, 258, - 258, 258, 0, 259, 258, 258, 258, 258, 258, 258, - 257, 254, 255, 256, 262, 261, 0, 266, 267, 264, - - 0, 269, 269, 277, 0, 0, 279, 0, 0, 280, - 272, 0, 0, 274, 0, 0, 275, 0, 285, 0, - 0, 0, 286, 290, 289, 293, 292, 308, 0, 308, - 307, 308, 308, 308, 308, 308, 308, 307, 0, 0, - 0, 0, 0, 0, 0, 0, 307, 307, 307, 307, - 307, 307, 0, 307, 297, 0, 316, 0, 316, 0, - 0, 312, 313, 326, 0, 326, 325, 326, 326, 326, - 326, 326, 326, 325, 0, 0, 0, 0, 0, 0, - 0, 325, 325, 325, 0, 325, 318, 319, 330, 0, - 0, 0, 0, 0, 0, 330, 0, 330, 0, 170, - - 0, 170, 168, 170, 170, 170, 170, 170, 170, 168, - 0, 0, 0, 0, 0, 0, 166, 0, 169, 169, - 166, 168, 0, 168, 168, 168, 0, 168, 167, 115, - 0, 115, 0, 0, 0, 124, 0, 124, 0, 0, - 0, 0, 0, 0, 0, 0, 156, 146, 0, 0, - 156, 0, 0, 150, 0, 0, 146, 55, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 42, 146, - 146, 146, 146, 146, 146, 146, 111, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 13, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 53, 146, - 146, 146, 146, 146, 146, 0, 0, 0, 189, 189, - 189, 189, 189, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, + 0, 208, 0, 0, 0, 0, 0, 0, 0, 209, + 0, 0, 0, 0, 0, 0, 0, 212, 208, 208, + 0, 211, 0, 0, 0, 0, 0, 0, 0, 208, + 238, 0, 243, 238, 238, 238, 238, 238, 238, 238, + 238, 241, 237, 0, 246, 247, 245, 0, 249, 249, + 267, 267, 267, 0, 268, 267, 267, 267, 267, 267, + 267, 267, 266, 263, 264, 265, 271, 270, 0, 275, + + 276, 273, 0, 278, 278, 286, 0, 0, 288, 0, + 0, 289, 281, 0, 0, 283, 0, 0, 284, 0, + 294, 0, 0, 0, 295, 299, 298, 302, 301, 316, + 0, 316, 315, 316, 316, 316, 316, 316, 316, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 315, 315, + 315, 315, 315, 0, 315, 306, 0, 324, 0, 324, + 0, 0, 320, 321, 334, 0, 334, 333, 334, 334, + 334, 334, 334, 334, 333, 0, 0, 0, 0, 0, + 0, 0, 333, 333, 333, 0, 333, 326, 327, 338, + 0, 0, 0, 0, 0, 0, 338, 0, 338, 0, + + 176, 0, 176, 174, 176, 176, 176, 176, 176, 176, + 174, 0, 0, 0, 0, 0, 0, 172, 0, 0, + 172, 175, 175, 172, 174, 174, 174, 0, 174, 173, + 115, 0, 115, 0, 0, 0, 125, 0, 125, 0, + 0, 0, 0, 0, 0, 0, 0, 157, 147, 0, + 0, 146, 157, 0, 146, 0, 0, 151, 0, 146, + 0, 147, 55, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 42, 147, 147, 147, 147, 147, 147, + 147, 111, 147, 147, 147, 147, 147, 147, 147, 147, + + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 13, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 53, 147, 147, 147, 147, 147, + 147, 0, 0, 0, 188, 188, 195, 195, 195, 195, + 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 202, 202, 0, 0, 0, 230, 230, 230, 230, - 230, 230, 230, 230, 258, 258, 258, 258, 258, 258, - 258, 258, 281, 0, 281, 0, 276, 0, 276, 0, - 287, 0, 287, 0, 308, 307, 308, 0, 0, 0, - - 0, 307, 307, 307, 307, 307, 307, 0, 0, 316, - 0, 0, 326, 325, 326, 0, 325, 325, 325, 0, - 330, 0, 0, 170, 168, 170, 0, 0, 169, 0, - 0, 168, 0, 0, 168, 168, 168, 0, 115, 0, - 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, - 156, 0, 156, 156, 156, 0, 150, 0, 150, 150, - 146, 146, 146, 146, 146, 146, 14, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 49, 18, 146, 146, - 146, 146, 146, 25, 146, 146, 146, 74, 146, 146, - 146, 146, 61, 137, 146, 56, 146, 146, 146, 146, - - 146, 146, 71, 146, 146, 146, 146, 146, 146, 146, - 51, 146, 146, 146, 146, 146, 146, 146, 146, 0, - 0, 7, 146, 146, 90, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 16, 146, - 52, 0, 189, 189, 189, 189, 189, 184, 0, 0, - 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, - 0, 202, 202, 0, 230, 230, 230, 230, 230, 230, - 230, 230, 258, 245, 258, 258, 258, 258, 258, 258, - 0, 0, 0, 0, 0, 0, 308, 308, 308, 308, - 0, 0, 0, 307, 307, 296, 307, 307, 307, 0, - - 316, 316, 316, 0, 326, 326, 326, 326, 325, 325, - 325, 328, 177, 170, 170, 170, 170, 0, 169, 0, - 169, 169, 0, 0, 168, 168, 168, 115, 115, 115, - 113, 0, 124, 124, 124, 122, 123, 92, 94, 93, - 19, 146, 146, 37, 9, 146, 146, 146, 146, 146, - 66, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 31, 39, 146, 146, 146, 22, 146, 0, - 0, 146, 54, 146, 6, 146, 146, 146, 41, 146, - 0, 0, 146, 34, 138, 65, 146, 146, 146, 146, - 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 146, 10, 146, 23, 146, 69, - 146, 146, 43, 146, 146, 146, 27, 47, 146, 146, - 45, 189, 187, 189, 189, 189, 243, 0, 0, 0, - 0, 0, 198, 0, 0, 0, 202, 200, 230, 230, - 230, 230, 230, 230, 230, 230, 258, 258, 258, 258, - 258, 258, 251, 0, 0, 281, 0, 0, 0, 276, - 0, 0, 0, 287, 0, 0, 0, 0, 307, 307, - 0, 307, 0, 0, 307, 307, 307, 333, 0, 325, - 325, 325, 0, 0, 168, 168, 168, 114, 0, 0, - 146, 146, 58, 146, 11, 146, 146, 17, 146, 146, - - 146, 2, 146, 68, 146, 146, 146, 146, 146, 40, - 146, 60, 3, 0, 0, 0, 146, 146, 0, 0, - 0, 146, 146, 84, 146, 0, 0, 146, 146, 21, - 146, 32, 146, 146, 146, 1, 0, 0, 0, 0, + 208, 208, 0, 0, 0, 238, 238, 238, 238, 238, + 238, 238, 238, 238, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 290, 0, 290, 0, 285, 0, 285, + + 0, 296, 0, 296, 0, 316, 315, 316, 0, 0, + 0, 315, 315, 315, 315, 315, 0, 0, 324, 0, + 0, 334, 333, 334, 0, 333, 333, 333, 0, 338, + 0, 0, 176, 174, 172, 176, 0, 172, 0, 0, + 175, 0, 172, 0, 174, 174, 174, 0, 115, 0, + 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, + 157, 0, 146, 157, 157, 157, 146, 151, 0, 151, + 0, 151, 146, 147, 147, 147, 147, 147, 147, 14, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 49, + 18, 147, 147, 147, 147, 147, 25, 147, 147, 147, + + 74, 147, 147, 147, 147, 61, 138, 147, 56, 147, + 147, 147, 147, 147, 147, 71, 147, 147, 147, 147, + 147, 147, 147, 51, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 0, 0, 7, 147, 147, 90, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 16, 147, 52, 0, 188, 188, 195, 195, + 195, 195, 195, 190, 0, 0, 0, 0, 214, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 208, 208, + 0, 238, 238, 238, 238, 238, 238, 238, 238, 238, + 267, 253, 267, 267, 267, 267, 267, 267, 267, 0, + + 0, 0, 0, 0, 0, 316, 316, 316, 316, 0, + 0, 315, 305, 315, 315, 315, 0, 324, 324, 324, + 0, 334, 334, 334, 334, 333, 333, 333, 336, 183, + 176, 172, 176, 176, 176, 172, 175, 0, 175, 0, + 175, 172, 174, 174, 115, 115, 115, 113, 0, 125, + 125, 125, 123, 124, 92, 94, 93, 146, 146, 146, + 19, 147, 147, 37, 9, 147, 147, 147, 147, 147, + 66, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 31, 39, 147, 147, 147, 22, 147, 0, + 0, 147, 54, 147, 6, 147, 147, 147, 41, 147, + + 0, 0, 147, 34, 139, 65, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 147, 10, 147, 23, 147, + 69, 147, 147, 43, 147, 147, 147, 27, 47, 147, + 147, 45, 188, 188, 195, 193, 195, 195, 195, 251, + 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, + 208, 206, 238, 238, 238, 238, 238, 238, 238, 238, + 238, 267, 267, 267, 267, 267, 267, 267, 260, 0, + 0, 290, 0, 0, 0, 285, 0, 0, 0, 296, + 0, 0, 0, 315, 0, 315, 0, 0, 315, 315, + + 315, 341, 0, 333, 333, 333, 172, 172, 172, 174, + 174, 114, 146, 146, 146, 0, 0, 147, 147, 58, + 147, 11, 147, 147, 17, 147, 147, 147, 2, 147, + 68, 147, 147, 147, 147, 147, 40, 147, 60, 3, + 0, 0, 0, 147, 147, 0, 0, 0, 147, 147, + 84, 147, 0, 0, 147, 0, 0, 147, 21, 147, + 0, 0, 32, 147, 147, 147, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 146, 24, 82, 146, - 146, 26, 4, 146, 46, 146, 146, 186, 189, 189, - 185, 0, 0, 0, 0, 218, 0, 0, 215, 0, - 202, 230, 230, 230, 227, 230, 230, 225, 230, 244, - 258, 258, 258, 258, 258, 0, 0, 0, 307, 307, - - 0, 0, 0, 0, 0, 307, 307, 0, 307, 0, - 0, 0, 0, 0, 0, 0, 304, 307, 307, 311, - 325, 325, 325, 0, 0, 168, 164, 168, 0, 0, - 33, 146, 35, 146, 146, 146, 15, 63, 0, 0, - 0, 146, 29, 48, 146, 146, 146, 146, 0, 0, - 0, 0, 0, 146, 146, 0, 0, 38, 103, 146, - 0, 28, 107, 5, 146, 100, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, + 24, 82, 147, 147, 26, 4, 147, 46, 147, 147, + + 188, 188, 192, 195, 195, 191, 0, 0, 0, 0, + 224, 0, 0, 0, 221, 0, 208, 238, 238, 238, + 234, 238, 238, 238, 232, 238, 252, 267, 267, 267, + 267, 267, 267, 0, 0, 315, 0, 0, 0, 0, + 0, 315, 315, 0, 315, 0, 0, 0, 0, 0, + 0, 0, 313, 315, 315, 319, 333, 333, 333, 172, + 172, 172, 170, 174, 146, 146, 146, 0, 0, 33, + 147, 35, 147, 147, 147, 15, 63, 0, 0, 0, + 147, 29, 48, 147, 147, 147, 147, 0, 0, 0, + 0, 0, 147, 147, 0, 0, 38, 103, 147, 0, + + 28, 0, 0, 107, 5, 0, 0, 147, 100, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 146, 146, 146, 0, 0, 0, 110, - - 146, 146, 189, 189, 0, 0, 0, 0, 0, 0, - 0, 0, 202, 230, 230, 230, 230, 230, 230, 230, - 258, 258, 258, 258, 258, 0, 0, 0, 307, 307, - 0, 0, 0, 0, 0, 307, 0, 307, 0, 307, - 307, 307, 0, 0, 307, 307, 325, 325, 325, 0, - 0, 168, 165, 0, 146, 146, 146, 146, 0, 0, - 50, 146, 146, 146, 146, 0, 0, 0, 0, 146, - 146, 0, 0, 162, 146, 0, 0, 0, 0, 12, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, + 147, 147, 0, 0, 0, 110, 147, 147, 188, 188, + 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 208, 238, 238, 238, 238, 238, 238, 238, 238, + 267, 267, 267, 267, 267, 267, 0, 0, 315, 0, + 0, 0, 0, 0, 315, 0, 315, 0, 315, 315, + 315, 0, 0, 315, 315, 333, 333, 333, 172, 172, + + 172, 171, 146, 146, 146, 0, 147, 147, 147, 147, + 0, 0, 50, 147, 147, 147, 147, 0, 0, 0, + 0, 147, 147, 0, 0, 163, 147, 0, 0, 0, + 0, 0, 0, 12, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, - 146, 20, 0, 0, 146, 67, 189, 189, 0, 0, - 209, 199, 210, 0, 213, 216, 201, 230, 230, 219, - 220, 230, 223, 226, 250, 258, 246, 258, 258, 0, - 0, 0, 307, 307, 0, 0, 0, 0, 0, 307, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 307, - 307, 325, 325, 325, 0, 0, 168, 0, 88, 146, - 146, 146, 0, 0, 159, 36, 146, 146, 146, 0, - 0, 160, 0, 0, 146, 146, 0, 0, 0, 0, - 57, 0, 0, 0, 142, 0, 0, 0, 0, 0, - - 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 0, 146, 0, 0, 158, - 89, 189, 189, 0, 0, 0, 230, 230, 230, 258, - 258, 258, 0, 0, 0, 307, 307, 0, 295, 0, - 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, - 0, 0, 0, 0, 307, 302, 325, 325, 323, 0, - 0, 168, 0, 83, 72, 30, 0, 0, 0, 0, - 141, 59, 146, 0, 0, 0, 0, 0, 0, 146, - 146, 0, 0, 0, 134, 0, 0, 161, 0, 0, - + 0, 0, 0, 0, 0, 0, 73, 147, 20, 0, + 0, 147, 67, 188, 188, 195, 195, 0, 0, 215, + 205, 216, 0, 0, 219, 222, 207, 238, 238, 226, + 227, 238, 238, 230, 233, 259, 267, 254, 267, 267, + + 267, 0, 0, 315, 0, 0, 0, 0, 0, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 315, + 315, 333, 333, 333, 172, 172, 172, 146, 146, 146, + 0, 88, 147, 147, 147, 0, 0, 160, 36, 147, + 147, 147, 0, 0, 161, 0, 0, 147, 147, 0, + 0, 0, 0, 57, 0, 0, 0, 0, 0, 143, + 0, 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, - 0, 146, 0, 0, 0, 0, 189, 189, 0, 212, - 211, 230, 222, 221, 258, 258, 248, 0, 0, 0, - 0, 0, 307, 301, 295, 0, 0, 0, 0, 0, - 0, 0, 0, 307, 322, 325, 0, 0, 0, 0, - 168, 0, 0, 0, 0, 146, 0, 0, 0, 0, - 0, 146, 146, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, + 0, 0, 0, 0, 0, 147, 0, 0, 159, 89, + + 188, 188, 195, 195, 0, 0, 0, 0, 238, 238, + 238, 238, 267, 267, 267, 267, 0, 0, 315, 0, + 304, 0, 0, 0, 0, 0, 0, 0, 304, 0, + 0, 0, 0, 0, 0, 0, 315, 311, 333, 333, + 331, 172, 172, 172, 146, 146, 146, 0, 83, 72, + 30, 0, 0, 0, 0, 142, 59, 147, 0, 0, + 0, 0, 0, 0, 147, 147, 0, 0, 0, 135, + 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, + 0, 0, 147, 0, 0, 0, 0, 188, 188, 195, + 195, 0, 218, 217, 0, 238, 229, 228, 238, 267, + 267, 267, 257, 0, 0, 0, 0, 310, 304, 0, + 0, 0, 0, 0, 0, 0, 0, 315, 330, 333, + 172, 172, 172, 146, 146, 146, 0, 0, 0, 0, + 147, 0, 0, 0, 0, 0, 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 120, 0, 70, 0, 0, 0, - 189, 189, 0, 230, 249, 258, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 295, 307, 325, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, - 0, 0, 0, 146, 62, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, - 78, 0, 0, 0, 0, 127, 0, 0, 0, 0, - 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 95, 0, 0, 0, 0, 105, 0, 189, - 189, 0, 230, 247, 0, 0, 0, 0, 0, 0, - 306, 0, 295, 307, 325, 0, 0, 0, 0, 163, - 0, 0, 0, 0, 64, 0, 0, 0, 146, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, - 0, 101, 104, 0, 181, 189, 0, 230, 0, 0, - 0, 307, 325, 0, 0, 0, 159, 0, 160, 0, - 0, 0, 143, 0, 0, 0, 0, 157, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 119, 0, 0, 0, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 0, 106, 0, 158, 0, 189, 0, - 230, 0, 0, 305, 303, 324, 0, 0, 0, 0, - 0, 161, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, - 0, 0, 0, 0, 0, 0, 0, 99, 0, 108, - 189, 214, 224, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 121, 0, 0, 70, 0, 0, + 0, 188, 188, 195, 195, 0, 0, 238, 238, 258, + 267, 267, 0, 0, 0, 0, 0, 304, 315, 333, + 172, 172, 172, 146, 146, 146, 0, 0, 0, 147, + 0, 0, 0, 147, 62, 0, 0, 0, 0, 0, + 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 76, 0, 78, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, 129, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 95, 0, 0, 0, 0, 0, 105, 0, 188, 188, + 195, 195, 0, 0, 238, 238, 256, 267, 0, 0, + 304, 315, 333, 172, 172, 172, 146, 146, 146, 0, + 0, 0, 64, 0, 0, 0, 147, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 80, 0, 0, 121, 0, 87, 0, 91, 0, - - 102, 0, 0, 183, 0, 0, 0, 132, 0, 0, - 135, 0, 130, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 0, 129, 0, 0, 96, 0, 0, - 86, 0, 0, 0, 0, 136, 0, 0, 0, 0, - 0, 80, 0, 76, 0, 0, 0, 85, 0, 97, - 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, + 0, 0, 0, 0, 0, 101, 104, 118, 0, 188, + 188, 187, 195, 0, 0, 238, 238, 267, 0, 0, + 315, 333, 172, 172, 172, 146, 146, 146, 0, 0, + + 160, 0, 161, 0, 0, 0, 144, 0, 0, 0, + 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 120, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, + 0, 0, 0, 106, 0, 159, 0, 188, 188, 195, + 0, 0, 238, 238, 255, 0, 314, 312, 332, 172, + 172, 172, 146, 146, 146, 0, 0, 0, 0, 0, + 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 118, 0, - 0, 131, 0, 0, 0, 0, 0, 0, 305, 0, + 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 140, 79, 0, 0, 0, 0, 79, - 0, 0, 79, 0, 0, 139, 0, 80, 0, 0, - 0, 0, 0, 0, 79, 0 + 99, 0, 108, 188, 188, 195, 220, 0, 231, 238, + 0, 172, 172, 172, 146, 146, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 80, 165, 0, 0, 0, 0, 122, + 0, 0, 87, 0, 91, 0, 102, 0, 0, 188, + 188, 189, 225, 235, 0, 172, 172, 172, 146, 146, + 146, 133, 0, 0, 136, 167, 0, 131, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, + 0, 130, 0, 0, 0, 96, 0, 0, 86, 188, + 188, 0, 172, 172, 172, 146, 146, 147, 0, 137, + + 0, 0, 0, 0, 0, 80, 0, 76, 0, 0, + 166, 0, 0, 85, 164, 0, 97, 188, 0, 172, + 172, 174, 151, 151, 147, 134, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 175, 175, + 174, 151, 151, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 98, 0, 175, 175, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 119, 0, 0, + 132, 0, 0, 0, 0, 0, 0, 0, 314, 0, + 0, 0, 0, 141, 79, 0, 0, 0, 0, 0, + 0, 79, 0, 0, 0, 79, 0, 0, 0, 140, + + 0, 80, 0, 0, 0, 0, 0, 0, 169, 0, + 0, 0, 79, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -623,2339 +644,2383 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 6, 7, 8, 5, 5, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 20, 21, 1, - 22, 1, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 51, 53, 54, 55, 56, 57, 58, 59, - - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 53, 82, 53, 51, 51, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 84, 85, 86, 87, 87, 87, 87, 88, 89, 90, - 90, 91, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 1 + 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, 20, 1, + 21, 1, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 50, 52, 53, 54, 55, 56, 57, 58, + + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 52, 81, 52, 50, 50, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 83, 84, 85, 86, 86, 86, 86, 87, 88, 89, + 89, 90, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 1 } ; -static yyconst flex_int32_t yy_meta[94] = +static yyconst flex_int32_t yy_meta[93] = { 0, 1, 2, 3, 3, 1, 4, 5, 6, 7, 1, - 1, 1, 8, 1, 9, 10, 1, 11, 11, 12, - 1, 1, 1, 13, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 13, 14, 13, 11, 15, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 13, 16, 16, 16, 16, 16, 17, 18, 16, - 19, 16, 16 + 1, 1, 2, 1, 8, 9, 1, 10, 11, 1, + 1, 1, 12, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, + 13, 12, 10, 14, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 12, 15, 15, 15, 15, 15, 16, 17, 15, 18, + 15, 15 } ; -static yyconst flex_int16_t yy_base[2511] = +static yyconst flex_int16_t yy_base[2700] = { 0, - 0, 0, 93, 0, 184, 185, 197, 0, 290, 0, - 383, 0, 475, 479, 492, 496, 0, 0, 582, 0, - 674, 677, 686, 697, 708, 719, 471, 476, 477, 481, - 486, 491, 3544, 3533, 3529, 3518, 805, 0, 499, 500, - 897, 911, 997, 0, 1090, 0, 504, 506, 1183, 0, - 1275, 1282, 1304, 1311, 486, 491, 3564,15602, 907, 1289, - 15602, 1314, 1407, 649, 1349,15602, 171,15602, 176, 174, - 3549, 1485,15602, 1563, 733, 909, 727, 913, 917, 1319, - 1449, 1492, 1351, 1524, 667, 1571, 1567, 1600, 1457, 1628, - 1633, 1650, 1671, 1326, 1700, 1427, 1682, 1728, 1769, 1777, - - 905, 1784, 493,15602,15602, 1757,15602, 501, 497, 1786, - 1810, 1822, 1840, 1857, 1876, 1892, 1979, 1986, 1993, 1305, - 2000, 502,15602,15602, 518,15602, 2081, 2173, 2265, 529, - 489, 0,15602, 491, 504, 500, 516, 657, 654, 1998, - 2357, 3466, 0, 533, 0, 673,15602, 2015, 2043, 2107, - 537, 2199, 2214, 2238, 2370, 2377, 2395, 684, 2419, 729, - 15602,15602,15602, 0,15602, 552, 0,15602, 0,15602, - 15602, 691, 708, 711, 714, 2018, 3448, 3436,15602,15602, - 15602,15602, 560,15602, 3434, 3422,15602,15602,15602,15602, - 562, 3426, 3402,15602,15602,15602, 722,15602,15602, 756, - - 0,15602, 0, 0, 715, 734, 912, 916, 3394, 688, - 15602,15602, 3372, 3356,15602,15602,15602,15602,15602,15602, - 774, 3349, 3342,15602,15602,15602,15602, 787, 3340, 713, - 0, 2135, 0, 0, 2144, 0,15602, 1747, 0, 0, - 3353, 0, 3349,15602, 1297, 1360,15602, 2501, 2225,15602, - 15602, 3382,15602, 3351, 2397, 2556, 1489, 2181, 877,15602, - 2519, 2526, 2599, 1262, 2606, 944,15602, 738,15602, 1373, - 1387,15602, 0,15602,15602,15602, 3337, 908, 3252, 878, - 15602, 1445, 1451,15602, 2688, 2249,15602,15602,15602, 3301, - 2583, 2474, 2643, 2737, 2744, 2786, 1546, 2793, 1269,15602, - - 2631,15602,15602, 2767, 2854, 2862, 2869, 1276, 2876, 1291, - 15602, 905,15602, 1600, 1610,15602, 2958, 2900,15602, 1298, - 15602, 1312, 1338, 3036,15602,15602, 3287, 1662, 1797, 1973, - 15602, 3007, 3015, 3056, 1445, 3094, 1407,15602, 1796, 1852, - 0, 3294,15602, 903, 917, 3216,15602, 1886, 1951, 0, - 3283,15602, 915, 1269, 3178, 1288, 1321, 1340, 2011, 3175, - 15602, 2912, 3133, 3147, 3154, 1432, 3173, 1451, 0, 3255, - 3348, 3164, 0, 3371, 0, 1461, 3154, 3388, 3395, 3402, - 1466, 3456, 1488, 3199,15602, 3464, 3478, 3516, 1497, 3534, - 1500, 1508, 2061, 2095,15602, 2189, 3601, 2438, 3547, 2475, - - 2193, 3114, 2804, 2211, 2873, 2364, 3563, 2731, 3608, 3234, - 3075, 3636, 3198, 3416, 3586, 3644, 3679, 3382, 3687, 3409, - 3683, 3701, 3717, 3485, 3722, 3708, 3751, 3773, 3778, 3785, - 3790, 3802, 3818, 3835, 2916, 3823, 3851, 3900, 3881, 3918, - 3863, 3926, 3947, 3965, 3971, 3979, 3983, 3999, 4033, 4038, - 4052, 3001, 4057, 4066, 3238,15602, 4084, 4120, 4123, 1519, - 4138, 1528, 4094, 4091,15602,15602,15602, 4123, 4141, 4210, - 4217, 1548, 4224, 1602, 1449,15602, 1635, 4226, 4250, 4167, - 4238, 4276, 4302, 4320, 4263, 4331,15602,15602, 1460,15602, - 4423, 4515, 0,15602, 1448, 1488, 1518, 1570, 1577, 3834, - - 4607, 3146, 0, 1640, 0, 1667, 3138, 1522,15602, 1617, - 1627, 1647, 1656, 1657, 1657, 1685, 1691, 1681, 1683, 1734, - 4357, 0,15602, 4449, 4469, 4537, 4621, 1686, 4628, 1702, - 4479, 4646, 4687, 4700, 1788, 4707, 1793, 4490,15602, 4725, - 4766, 4779, 1799, 4786, 1843, 1638,15602, 4786, 4797, 4808, - 15602, 4895, 4898, 4902, 1849, 4916, 1863, 4873, 4902, 0, - 1722,15602, 1735, 1769, 1788, 1807, 1861, 1861, 1913, 1970, - 15602,15602, 1802,15602,15602,15602, 1922,15602,15602, 0, - 1989, 1993, 2008,15602, 2010, 2008, 2032, 2037, 2060, 2064, - 15602,15602,15602,15602,15602,15602, 2060,15602,15602,15602, - - 2145,15602,15602, 0, 2365, 3210,15602, 3197, 3099,15602, - 0, 2395, 3168,15602, 3155, 3072,15602, 2462,15602, 3144, - 3127, 3050,15602, 0,15602, 0,15602, 2413, 3026, 0, - 4998, 5091, 3014, 0, 5114, 0, 1919, 4940, 4920, 5131, - 5138, 1953, 5145, 1955, 2537, 2791, 4972, 5147, 5171, 5182, - 5202, 5230, 4951, 4983,15602, 2087, 2600, 3008, 0, 2675, - 2143,15602,15602, 2683, 2989, 0, 5323, 5416, 2948, 0, - 5439, 0, 2142, 5087, 5456, 5463, 5470, 2162, 5524, 2164, - 2783, 5265, 5299, 5472, 5213, 5276,15602,15602, 5310, 5562, - 5575, 5583, 2166, 5601, 2207, 5585, 5412, 5601, 2159, 2937, - - 2940, 0, 5694, 5787, 2934, 0, 5810, 0, 2256, 5636, - 5827, 5834, 5841, 2258, 5895, 2276, 2301, 2945, 2415, 2677, - 5962, 4443, 2362, 4783, 4632, 5125, 5647, 4531,15602, 2951, - 2932, 0, 3004, 2166, 2185, 3075, 2928, 0, 3079, 2177, - 2186, 2211, 2410, 2449, 5667, 5784, 5678, 6055, 5841, 5852, - 3083, 2910, 2618, 2789, 2812, 2325, 5872, 5883, 5922, 5949, - 5910, 5998, 6010, 6067, 6082, 6043, 6138, 2887, 3501, 3605, - 4228, 4653, 4426, 3971, 3936, 4782, 4786, 3062, 3144, 3736, - 3884, 3797, 4003, 5179, 4081, 4428, 3991, 4359, 6172, 6173, - 4647, 5549, 4594, 6175, 6145, 4692, 6205, 5173, 4773, 3995, - - 4575, 6216, 5497, 6219, 5949, 6220, 6196, 6228, 6240, 6218, - 4698, 6237, 6257, 6265, 6269, 6267, 6286, 6314, 6290, 6282, - 6327, 6311, 6334, 6292, 6336, 6343, 6366, 6376, 6352, 6354, - 6382, 6373, 6386, 6396, 6398, 6106, 6391, 2327, 6404, 6439, - 6460, 6475, 6499, 6535, 2344, 6613, 6691, 2526, 3119, 2555, - 3028, 2543, 3165, 3276, 2609, 2757, 2372, 6421, 6548, 6488, - 6584, 6571, 6642, 6519, 6653, 2388, 2480, 2499, 2551, 2923, - 2624, 2663, 2908, 2756, 2753, 2800, 2834, 2860, 2874, 2877, - 2890, 3011,15602, 2943, 2914, 3112,15602, 2899, 2892, 3231, - 15602, 2884, 2876, 3315, 6602, 6784, 3331, 2787, 3061, 3191, - - 3201, 6678, 6734, 6765, 6802, 6821, 6666, 2422, 3241, 3496, - 2758, 3252, 6832, 6925, 3545, 2752, 6905, 6955, 6874, 2444, - 6936, 2477, 3335, 6966, 7059, 3552, 2740, 3284, 3476, 3559, - 2501, 7013, 3392, 3452, 7038, 7081, 7110, 2510, 3593, 2737, - 3453, 3449, 3760, 2722, 3469, 3491, 3560, 3574, 3567, 2529, - 2597, 2601, 0, 3883, 2685, 2637, 2735, 2739, 2746, 2784, - 7133, 7155, 7002, 7183, 7194, 7215, 7226, 7291, 3721, 3860, - 7292, 7293, 6780, 7298, 5600, 7356, 7299, 3879, 7300, 7357, - 7305, 4441, 6782, 3959, 7359, 7358, 7366, 4054, 4494, 7364, - 6921, 7372, 4941, 7409, 7125, 5957, 7410, 7411, 6329, 6923, - - 7417, 6584, 6650, 7419, 6869, 7455, 7435, 6942, 7127, 7126, - 7148, 7149, 7443, 7461, 7467, 7472, 7200, 7201, 7477, 7540, - 7538, 7548, 7495, 7532, 7537, 7306, 7592, 7489, 7542, 7600, - 7585, 7597, 7602, 7611, 7608, 7605, 7618, 7626, 7647, 7650, - 7652, 2878, 7634, 7649, 7664, 7675, 7705, 7692, 7753, 7831, - 3606, 4127,15602, 3604, 3784, 5450, 4790, 4090, 5477, 2880, - 2885, 7716, 7792, 2919, 3568, 3584, 3671, 3701, 3796, 3838, - 3842, 3872, 3905, 0, 3992, 4086, 2712, 4140, 4140, 4159, - 4761, 2664, 7130, 2662, 4591, 2658, 2947, 0, 4397, 2641, - 4203, 4206, 2638, 7803, 7842, 7934, 7944, 7813, 7950, 4235, - - 0, 4582, 2599, 4247, 3009, 0, 5075, 2580, 7952, 7901, - 7971, 7982,15602, 3018, 0, 5465, 2578, 3038, 3150, 3175, - 3185, 3192, 4393, 4483, 8019, 8057, 8068, 0, 5659, 2554, - 15602, 4583, 0, 5770, 2551,15602,15602,15602,15602,15602, - 8160, 8252, 5169, 4606, 4607, 4786, 5562, 5523, 7130, 4902, - 4687, 5524, 7439, 7776, 7914, 7916, 5617, 5807, 7034, 6566, - 7918, 4861, 4698, 5228, 6781, 7523, 7921, 4700, 7775, 8134, - 8344, 6920, 4733, 7781, 8116, 6922, 7783, 7785, 4765, 7928, - 8010, 8427, 7782, 4862, 4967, 5067, 7473, 8138, 8141, 8142, - 8145, 8045, 8046, 7929, 5571, 5162, 5251, 5256, 5416, 5461, - - 5465, 2548, 8510, 8593, 5616, 5561, 7784, 5601, 8144, 5663, - 8154, 8156, 5763, 8157, 8161, 8180, 5814, 8041, 8159, 8048, - 5816, 8189, 8200, 8295, 8236, 8327,15602, 8662, 8740, 5851, - 6398, 7840, 6399, 8060, 8064, 7198, 8370, 8220, 5878, 5955, - 2574, 5999, 2558, 5989, 6045, 2555, 6148, 2522, 6150, 6181, - 6220, 2501, 0, 2540, 7287, 2523, 696, 2499, 7341, 2483, - 698, 2463, 6513, 2452, 1404, 6303, 6302, 6572, 8382, 8410, - 8503, 8833, 2420, 8508, 8537, 8549, 8577,15602, 6605, 8596, - 8610, 8634, 6611, 6608, 8674, 8702, 8729,15602, 8230, 8925, - 8341, 8139, 6710, 8317, 6764, 8325, 8327, 6779, 8494, 8343, - - 8496, 8655, 8499, 6780, 8344, 8439, 8309, 8186, 8454, 6782, - 8728, 6851, 8726, 6969, 7163, 2336, 8498, 8898, 8933, 2399, - 9016, 8727, 7360, 7416, 8901, 7530, 2308, 8909, 8907, 7524, - 8911, 7538, 8914, 8913, 8219, 8964, 8957, 7627, 7674, 7670, - 7678, 2332, 7826, 2325, 7869, 7846, 7836, 8952, 7873, 7932, - 7987, 8006, 8008, 8065, 8075, 2263, 8143, 8133, 8179, 8925, - 8730, 8181, 9008, 8924, 8215, 8497, 8971, 8989, 9018, 9044, - 9032, 8927, 9026, 8233, 8997, 8235, 8453, 9030, 8343, 8376, - 9066, 8421, 8461, 8501, 0, 8975, 8533, 0, 8550, 0, - 8585, 8647, 8673, 8672, 8673, 8745, 8742, 8926, 9101, 9122, - - 9168, 8913, 2212, 9214, 9221, 0, 0, 9228, 8953, 9306, - 2195, 0, 9399, 0, 9243, 5836, 9248, 9259, 9284,15602, - 9381, 9408, 9430, 8988, 9021, 9441, 9345, 9466, 9014, 2166, - 9010, 9098, 9015, 9170, 9116, 9118, 9016, 9063, 9236, 2219, - 9558, 9117, 9097, 9152, 9210, 9205, 9229, 9226, 9279, 2175, - 9641, 9187, 9202, 9220, 9238, 2094, 3283, 9214, 9219, 9497, - 9239, 9234, 9242, 9566, 9513, 9272, 9534, 9595, 2110, 9724, - 9328, 9326, 9308, 9384, 9383, 9401, 9416, 9406, 9406, 9408, - 9415, 9424, 9463, 9483, 9481, 9475, 9473, 9512, 9495, 9525, - 9537, 9548, 9544, 9543, 9546, 9572, 9634, 2107, 9807, 9539, - - 9596, 9583, 9597, 9666, 9634, 9575, 9641, 9642, 9675, 9645, - 9682, 9705, 9698, 9558, 2061, 9613, 9640, 9646, 9685, 9686, - 9701, 9694, 9700, 9706, 9715, 9723, 9724, 9740, 9755, 9780, - 9872, 9878, 9892, 9741, 9901, 9745, 9984, 2027, 9910, 0, - 9727, 2008, 9937, 2006, 9918, 9944,10008, 9971,10041, 9734, - 9735,10052,10063, 9759, 9770, 9851, 9877, 9774, 1995, 3301, - 9752, 9876, 9872, 9898, 9897, 1992, 3404, 9795, 9774, 9828, - 10038, 3410, 2146,10020,10119, 9813,10105, 2057,10199, 9847, - 9874, 9863, 9918, 9917, 1982, 3417, 1975, 9921, 1968, 9942, - 10134, 9944, 9974, 9989, 9972,10022,10008,10056,10060,10043, - - 10051,10054,10134,10132,10119,10136,10139,10129,10128,10117, - 10135,10123, 1932, 3439,10131,10128,10142,10179,10191,10147, - 10149,10150,10209,10210,10211,10213,10201, 1955,10215, 0, - 0,10212, 0, 0, 0,10243, 0, 1952,10245,10258, - 10258,10269,10265,10252,10357,10264,10318,10363,10372,10265, - 10386,10392, 1915,10421,10431,10450,10459,10479,10489,10491, - 10510,10539,10558,10577,10266,10278,10607,10333,10334,10348, - 10398,10377, 3453, 2226,10465,10358,10421,10448,10464, 3581, - 2354,10508,10384,10370,10471,10466,10529,10651,10411, 1912, - 10422,10439, 1906, 3600,10472,10499,10482,10488, 3658, 2443, - - 10654,10493,10493,10497,10502,10532,10531,10552, 7702,10564, - 10565,10580,10569,10563,10582,10628,10645, 8003,10649,10627, - 15602,10647,10628,10633,10650,10644,10662, 3697, 3059,10716, - 10632,10673,10703,10704,10711,10712,10641,10657,10692,10679, - 10688,10695,10703, 8526, 1904,10729,10754,10846,15602,10852, - 10861,10868,10884,10914,10891,10951, 0,10967,10974,10981, - 10990,10997,11004,11013,11017,11028,11048,11081,11059,10709, - 10308,11109,10700,10700,10701,10724,10725,10959,10765, 1872, - 10749,10751,10851,11044,11092,10769, 1838,10767,10783,10829, - 10853,11075, 1835,10789,15602, 3710, 3078,11154,10791,10810, - - 10821,11158,11176,10844, 1808,10849,10859,10873,10859,10881, - 10882,10897, 8173, 1800,10921,10961,10985,10976,10992,10998, - 10991,10988,11179, 1779,11000,11008,10995,11237,11011,10999, - 11014,11153,11208,11224,11065, 1754,11232,11253,11171,11066, - 11152,11143, 0, 0,11151,11160, 0,11157,11229,11326, - 1739,11166,11409, 8649,11345,11359,11365,11374,11381,11423, - 11432,11452,11459,11331,11437,11462,11180,11274,11247, 1713, - 11554,11226,11564, 1705,11186,11223,11567, 1702,11192,11214, - 11229,11212,11342,11225,11570,11481,11293, 1698,11313,11338, - 11348,11575, 1677,11376,11392,11380,11412,11392,11413, 8353, - - 8712, 1703,11416, 1690,11403, 9376,11435,11452,15602,11442, - 11453,11478,11461,11465,11488,11524,11495,11530,11546,11554, - 11551,11540,11552,11553,15602,11558,11546,11595, 1657,11562, - 11577,11605,11648,11576, 0,11553,11559,11674,11559,11557, - 1631,11583,10234,11653,11695,11724,11738,11703,11726,11640, - 11718,11640, 1599,11759,11706,11777,11647,11672,11679,11684, - 11692,11709,11701,11718,11705, 9379,11790, 1579,11734,11734, - 11764, 1607,11756,11777,11768,11793, 1568,11781,10685, 1531, - 11123, 1527,11797,11823,11794,15602,11836, 1514,11805, 1504, - 11809,11812,15602,11806,11799,11807,11816,11810,11804,11807, - - 11806,11810,15602,11831,11832,11818,11816,15602,11818,11839, - 11856,11917,11819, 0,11893,11823, 1496,11832, 1464,11899, - 15602, 1460,11906,11933,11918,11950,11825, 1457,11955,15602, - 1448,11895,11895,11902,11906,11972,11917,11919,11935,11976, - 1438,11923,11920,11941,11942,12010, 1342,12019, 1333,11947, - 12022,11957,12026, 1290,11962,11993,11989,12000,12000,11994, - 12005,11997,12011,12005,12006,15602,12007,12003,12005,12006, - 12024,15602,15602,12050,12000,12028,12062,12020,12031,12032, - 12049,12120,12071,12061,12072,12065,12055, 1284,12141, 1265, - 12066,12103,12087,12147,12092,12117,12118,12167, 1262,12125, - - 12171,12178, 1255,12114,12126,12186, 1244,12128,12140,12159, - 15602,12146,12165,12166,12156,12158,12158,12170,12176,15602, - 12164,12163,12180,12177,15602,12182,12210, 1220,12188,12185, - 12176,12194,12198,15602,12241,12199,12208,12205,12219,12232, - 12228,12297, 1214, 1229, 892,12251,12258,12300,12279,12258, - 880,12269,12264,12281,12268,12263,12278,12286,15602,12273, - 12284,12274,12290,12289,12278,12273,12281,15602,12287,15602, - 12306,12294, 0,12290,12305,12292,12301,12291,12295,12297, - 12314, 703, 872,12326,12333, 898, 876,12336,12329,12330, - 12343,12375,12351,12340,15602,12344,15602,12343,15602,12344, - - 15602,12374,12368,12337,12371,12381,12373,15602,12385,12377, - 15602,12378,15602, 816,12385,12388,12391,12392,12386,12407, - 12448,12395,12451, 694,15602,12399,12406,15602,12412,12418, - 15602,12419, 720,12420,12429,15602,12415,12422,12430,12439, - 12441,12477, 717,12480, 666,12427,12439,15602,12435,15602, - 12444,12446,12453,15602,12446,12455,12452,12471,12472,12473, - 12471,12467,12469,12465,12472,12467,12483,12542,12474,12491, - 12492,12494,12485,12487,15602,12511,12498,12555, 662,12564, - 2594, 497, 478,12510, 506, 493,12519,12521,15602,12506, - 12535,15602, 445,12524,12536,12530,12529,12523,15602,12545, - - 12548,12537,12542,15602,12579,12556,12536,12549,12552,12594, - 448,12547,12606,12547,12543,15602,12566,12610,12558,12561, - 12593,12586,12598,12578,12631,15602,12715,12734,12753,12772, - 12791,12810,12829,12848,12867,12886,12905,12924,12943,12962, - 12981,13000,13016,13035,13050,13065,13080,13089,13104,13113, - 13130,13139,13152,13167,13182,13197,13206,13217,13223,13234, - 13253,13272,13291,13310,13329,13348,13367,13382,13391,13408, - 13427,13442,13451,13465,13474,13490,13505,13514,13533,13552, - 13568,13577,13593,13612,13631,13646,13655,13667,13676,13688, - 13697,13709,13718,13733,13742,13755,13764,13776,13785,13797, - - 13806,13818,13827,13838,13844,13855,13874,13893,13912,13931, - 13950,13969,13988,14007,14026,14041,14050,14066,14085,14104, - 14123,14138,14147,14159,14168,14184,14203,14222,14237,14246, - 14262,14281,14297,14316,14335,14350,14369,14384,14399,14414, - 14429,14445,14460,14475,14490,14504,14510,14521,14540,14559, - 14578,14597,14616,14631,14650,14669,14688,14707,14722,14737, - 14756,14775,14794,14809,14828,14847,14866,14885,14900,14915, - 14930,14945,14959,14965,14976,14995,15014,15033,15052,15067, - 15086,15105,15124,15139,15154,15173,15192,15207,15226,15245, - 15263,15278,15293,15308,15322,15328,15339,15358,15377,15392, - - 15411,15430,15449,15468,15487,15506,15525,15544,15563,15582 + 0, 0, 92, 0, 182, 183, 195, 0, 287, 0, + 379, 0, 470, 474, 487, 491, 0, 0, 576, 0, + 667, 670, 679, 690, 701, 712, 466, 471, 472, 476, + 481, 486, 4126, 4121, 4118, 4099, 797, 0, 494, 495, + 888, 902, 987, 0, 1079, 0, 499, 501, 1171, 0, + 1262, 1269, 0, 0, 1290, 1297, 481, 486, 4152,15625, + 898, 1276,15625, 1300, 1392, 643, 1334,15625, 4133,15625, + 172, 4121, 4126, 1469,15625, 1546, 508, 898, 720, 905, + 1295, 1429, 913, 1432, 726, 1478, 721, 1504, 1550, 1583, + 1554, 1508, 1616, 1621, 1632, 1412, 1679, 1413, 1631, 1681, + + 1721, 1729, 669, 1738, 4092,15625,15625, 1738,15625, 494, + 4091, 1749, 1770, 1781, 1799, 1816, 1835, 1851, 1937, 1943, + 1949, 658, 1955, 4077,15625,15625, 495,15625, 2035, 2126, + 2217, 497, 483, 0,15625, 483, 483, 488, 507, 511, + 499, 910, 2308, 4011, 0, 4075, 0, 4074,15625, 1998, + 2088, 2152, 531, 2167, 2205, 2191, 1961, 2050, 2320, 4071, + 2326, 4069,15625,15625,15625, 0,15625, 546, 0,15625, + 0,15625,15625, 510, 640, 637, 650, 1279, 4003, 3995, + 15625,15625,15625,15625, 667,15625, 4001, 3992,15625,15625, + 15625,15625, 683, 3998, 3915,15625,15625,15625, 699,15625, + + 15625, 748, 0,15625, 0, 0, 702, 723, 1734, 894, + 3856, 679,15625,15625, 3852, 3846,15625,15625,15625,15625, + 15625,15625, 751, 3844, 3837,15625,15625,15625,15625, 764, + 3840, 104, 0, 1510, 0, 0, 2025, 0,15625, 2142, + 0, 0, 3868, 0, 3860,15625, 1283, 1366,15625, 2407, + 2179,15625,15625, 3898,15625, 3889, 2462, 1420, 1303, 855, + 15625, 2333, 2387, 2424, 700, 2459, 3892,15625, 723,15625, + 1461, 1501,15625, 0,15625,15625,15625, 3862, 891, 3787, + 703,15625, 1722, 1797,15625, 2554, 2432,15625,15625,15625, + 3852, 2503, 2572, 2583, 2669, 2675, 2681, 892, 2687, 3848, + + 15625, 2527,15625,15625, 2687, 2737, 2774, 2786, 3844, 2792, + 3841,15625, 888,15625, 1810, 1813,15625, 2873, 2815,15625, + 3812,15625, 778, 3809, 2950,15625,15625, 2302, 1337,15625, + 2799, 2858, 2922, 680, 2929, 3808,15625, 1909, 1927, 0, + 3803,15625, 887, 901, 3734,15625, 1950, 1972, 0, 3800, + 15625, 902, 923, 3731, 1251, 1258, 1267, 1978, 3729,15625, + 2905, 2993, 2999, 3006, 3789, 3055, 3783, 0, 3136, 3228, + 3710, 0, 3250, 0, 3774, 3006, 3063, 3111, 3117, 3739, + 3266, 3736, 3090,15625, 3272, 3278, 3291, 3732, 3326, 3730, + 3726, 2067, 3694, 1576, 1480,15625, 1481, 3392, 1735, 3330, + + 2036, 1649, 2428, 2165, 1748, 2007, 2768, 2329, 1931, 3367, + 2684, 2910, 3084, 2805, 3346, 3385, 3401, 3260, 3427, 2724, + 2427, 2916, 3430, 3431, 3297, 3478, 2690, 3482, 3339, 3483, + 2374, 3489, 3173, 3497, 3502, 3049, 3503, 3518, 3566, 3558, + 3571, 3550, 3594, 3622, 3636, 3639, 3642, 3647, 3655, 3656, + 3702, 3705, 3353, 3706, 3710, 3699,15625, 3744, 3748, 3752, + 3684, 3798, 3678, 3120, 3713,15625,15625,15625, 3752, 3801, + 3838, 3850, 3673, 3857, 3671, 771,15625, 3630, 3858, 3882, + 3870, 3904, 3951, 3935, 3973, 3962, 3984,15625,15625, 903, + 15625, 4075, 4166, 0,15625, 1286, 1296, 1307, 1411, 1468, + + 2127, 4257, 3560, 0, 3623, 0, 3611, 3532, 1258,15625, + 1493, 1492, 1521, 1531, 1532, 1544, 1560, 1600, 1553, 1554, + 1599, 4037, 0,15625, 4101, 4090, 4188, 4270, 3589, 4276, + 3561, 4130, 4282, 4294, 4332, 3555, 4346, 3554, 4141,15625, + 4353, 4371, 4408, 3547, 4421, 3533, 1325,15625, 4394, 4408, + 4433,15625, 4519, 4522, 4525, 3517, 4528, 3511, 4421, 4470, + 0, 1359,15625, 1588, 1609, 1613, 1637, 1671, 1628, 1666, + 1730,15625,15625, 1383,15625,15625,15625, 1415,15625,15625, + 0, 1717, 1797, 1421,15625, 1808, 1856, 1891, 1941, 1939, + 1952, 1959,15625,15625,15625,15625,15625,15625, 1422,15625, + + 15625,15625, 1439,15625,15625, 0, 2460, 3500,15625, 3493, + 3409,15625, 0, 2524, 3482,15625, 3472, 3402,15625, 2201, + 15625, 3462, 3438, 3369,15625, 0,15625, 0,15625, 2111, + 3367, 0, 4609, 4701, 3358, 0, 4723, 0, 3417, 4499, + 4589, 4739, 4745, 3409, 4751, 3398, 2396, 1943, 4589, 4566, + 4754, 4774, 4802, 4693, 4785,15625, 1992, 2446, 3331, 0, + 2595, 2006,15625,15625, 2598, 3309, 0, 4894, 4986, 3305, + 0, 5008, 0, 3368, 4836, 4801, 5024, 5030, 3361, 5036, + 3357, 2620, 4868, 5037, 5053, 4847, 4879,15625,15625, 4978, + 5139, 5145, 5151, 3348, 5157, 3342, 5160, 5171, 5182, 2003, + + 2626, 3271, 0, 5274, 5366, 3267, 0, 5388, 0, 3313, + 5216, 5404, 5410, 5416, 3309, 5429, 3294, 3293, 2630, 3292, + 3795, 2088, 2304, 5495, 3856, 3865, 4390, 5227, 3804,15625, + 2647, 3224, 0, 2682, 2029, 2051, 2712, 3221, 0, 2859, + 2065, 2078, 2103, 2101, 2130, 5247, 5442, 5258, 5587, 5416, + 5454, 3285, 2866, 3219, 3878, 1769, 1780, 2689, 2213, 5664, + 3279, 5474, 5531, 5741, 2320, 2773, 2476, 2887, 2943, 2993, + 2780, 3369, 3512, 3406, 3044, 3436, 3408, 2426, 3494, 3631, + 3138, 3532, 2308, 2131, 3564, 2987, 3619, 3057, 3500, 3557, + 3569, 2258, 3666, 2270, 2347, 3704, 3585, 3955, 2453, 3677, + + 2479, 3155, 3340, 3859, 3634, 3699, 2478, 3956, 3247, 4073, + 3949, 3819, 3952, 3499, 3858, 3957, 4071, 2502, 3857, 4175, + 4072, 2752, 2620, 4264, 3751, 4259, 5030, 4307, 2652, 4383, + 4331, 5145, 4149, 4076, 2813, 4382, 4297, 4146, 5151, 5622, + 4536, 5542, 5613, 3276, 3275, 5624, 5642, 5707, 5695, 5761, + 5772, 5800, 3274, 5877, 5954, 3958, 4413, 3684, 4369, 2867, + 4732, 4255, 5157, 3160, 4412, 3273, 5784, 5812, 5823, 5908, + 5897, 5937, 5836, 5976, 3265, 2893, 2935, 3095, 3229, 3286, + 3321, 3357, 3201, 3412, 3508, 3626, 3701, 3881, 3964, 4039, + 4150, 4208, 4280,15625, 3244, 3190, 4000,15625, 3187, 3184, + + 4152,15625, 3154, 3127, 4198, 5847, 6068, 4643, 3048, 4315, + 4323, 5965, 6050, 6087, 6118, 6018, 3112, 4382, 4665, 3045, + 4442, 5866, 6210, 4681, 3044, 6160, 6191, 6231, 3108, 6267, + 3104, 4496, 6098, 6359, 3103, 4747, 3037, 5018, 2565, 2566, + 4776, 2748, 6436, 3093, 6253, 6513, 5058, 3086, 5089, 3001, + 4527, 4527, 5130, 3000, 4577, 4606, 4726, 4772, 4777, 3058, + 3057, 3051, 3050, 0, 5147, 2983, 5166, 3046, 3037, 3030, + 3013, 3012, 6590, 6667, 5372, 5621, 5279, 5378, 4809, 4900, + 6355, 5044, 6345, 5280, 5397, 5120, 5402, 5564, 5443, 4901, + 5115, 5165, 5477, 5611, 6353, 6072, 5373, 5479, 5615, 5700, + + 5400, 5424, 5401, 5698, 5447, 5614, 6387, 5763, 5616, 5699, + 5766, 6213, 6358, 5768, 6360, 5617, 5702, 6361, 6419, 6073, + 6425, 6357, 6366, 5703, 6427, 6057, 6215, 5901, 6422, 6090, + 6363, 6431, 6432, 6758, 6493, 6474, 5904, 6051, 5767, 6433, + 6438, 6489, 6054, 6441, 6126, 5960, 6194, 6508, 6501, 6509, + 6510, 6547, 5902, 6511, 6075, 3009, 3008, 6538, 6550, 6568, + 6613, 6631, 6761, 6642, 6721, 6838, 6122, 6216,15625, 6511, + 6433, 6512, 6513, 6700, 6704, 6589, 3007, 3002, 6777, 6811, + 3001, 6126, 6193, 6218, 6227, 6303, 6304, 6331, 6371, 6378, + 6438, 0, 6444, 6500, 2965, 6509, 6524, 6531, 6532, 5565, + + 2921, 6661, 2903, 6610, 2902, 2952, 0, 5568, 2860, 6665, + 2882, 6849, 6940, 6950, 6772, 6956, 6673, 0, 6664, 2850, + 6686, 2913, 0, 6685, 2838, 6958, 6908, 6977, 6799,15625, + 2900, 2898, 0, 6788, 2831, 6890, 2895, 2859, 2853, 2841, + 2840, 7054, 7131, 6739, 0, 6831, 2773,15625, 6741, 0, + 6834, 2771,15625,15625,15625,15625,15625, 2834, 6948, 7208, + 7299, 7006, 7049, 6975, 7015, 7033, 7081, 7074, 7093, 7088, + 7097, 7100, 7118, 7121, 7106, 7149, 7164, 7170, 7188, 7196, + 7231, 7235, 7203, 7266, 7246, 7238, 7261, 7242, 7279, 7309, + 7324, 7331, 7271, 7354, 7334, 7364, 7395, 7357, 7369, 7399, + + 7406, 7405, 7446, 7416, 7432, 7458, 7463, 7466, 7477, 7481, + 7488, 7493, 7498, 7504, 7508, 6755, 6752, 6758, 6764, 6764, + 6818, 6827, 2765, 7590, 7547, 7528, 7517, 7554, 7520, 7582, + 7524, 7666, 7672, 7575, 7675, 7678, 7639, 7602, 7610, 7684, + 7696, 7708, 2817, 7686, 7698, 7710, 7750, 7786, 7797,15625, + 7874, 7951, 6948, 6941, 6957, 6949, 7400, 7505, 7048, 7122, + 7886, 7731, 6835, 6847, 2778, 6888, 2777, 6876, 6918, 6956, + 2767, 7028, 2766, 7022, 7103, 7097, 7115, 2760, 0, 2803, + 7721, 2793, 1369, 2789, 7741, 2781, 1444, 2758, 7842, 2751, + 901, 7136, 7138, 7809, 7926, 8043, 2736, 8129, 7914, 8106, + + 8117,15625, 7186, 7933, 8150, 8176, 2729, 7643, 7887, 7660, + 7286,15625, 2728, 7673, 8253, 8146, 8266, 8216, 7862, 7826, + 8141, 7848, 8245, 8248, 7851, 8275, 8283, 8294, 7910, 8290, + 7857, 8301, 8304, 8321, 8351, 8331, 8138, 8359, 8160, 8170, + 7195, 7213, 2651, 8376, 8335, 8379, 2712, 8387, 8386, 8367, + 8163, 8404, 7237, 2618, 8417, 8422, 8456, 8449, 8413, 8453, + 8480, 8506, 8486, 8489, 8495, 8499, 8516, 7471, 7321, 7356, + 7364, 7379, 2644, 7380, 2643, 7409, 7667, 7420, 7503, 7684, + 7517, 7571, 7595, 7601, 7590, 7667, 7693, 7696, 2608, 8523, + 8538, 8546, 8562, 8573, 8549, 8577, 8581, 8593, 8599, 8608, + + 2672, 8610, 8621, 8640, 8651, 8662, 7876, 8365, 7697, 7891, + 7793, 7884, 7794, 8377, 7875, 7892, 8727, 7951, 7955, 7950, + 0, 8398, 2600, 7971, 0, 8107, 0, 8114, 8195, 8248, + 8258, 2594, 8272, 8281, 8315, 8715, 8762, 8368, 2548, 8768, + 8820, 0, 0, 8826, 8383, 8903, 2543, 0, 8995, 0, + 8854, 8633, 8803, 8859, 8881,15625, 8977, 9004, 9026, 2607, + 8589, 8602, 8422, 8449, 2602, 8615, 8846, 8413, 2520, 8675, + 8834, 8684, 8776, 8840, 9021, 8757, 8788, 8898, 2570, 9112, + 9077, 8936, 8956, 9095, 9120, 9129, 9071, 9054, 2550, 9163, + 8490, 8493, 9123, 9136, 2475, 1255, 8972, 9024, 9139, 8517, + + 9142, 8535, 2474, 9145, 9165, 8549, 2459, 9153, 9188, 9195, + 9235, 2524, 9233, 8566, 8565, 8561, 8574, 8574, 8599, 8599, + 8600, 8600, 8608, 8613, 8618, 8631, 8714, 8738, 8735, 8786, + 8794, 8807, 8818, 8825, 8835, 8840, 8851, 8843, 8842, 9207, + 9227, 9263, 9251, 2513, 9281, 9257, 9292, 9305, 2483, 9307, + 9318, 9343, 9144, 8899, 9248, 9194, 9285, 9289, 9296, 9297, + 9309, 9364, 8889, 2427, 8993, 8994, 9022, 9146, 9175, 9218, + 9242, 9237, 9291, 9297, 9288, 9313, 9300, 9315, 9375, 9466, + 9472, 9481, 9318, 9487, 9321, 9569, 2390, 9502, 0, 9309, + 2389, 9508, 2377, 9515, 9526, 9551, 9589, 9626, 2433, 9479, + + 9503, 9332, 2422, 9485, 9565, 9345, 9642, 9662, 9665, 9549, + 2353, 1283, 9415, 9685, 9680, 9688, 9701, 2352, 1517, 9360, + 9393, 9693, 9725, 1674, 1531, 9733, 9738, 9394, 9488, 9756, + 2413, 9773, 9486, 9435, 9775, 9496, 9519, 9505, 2332, 1745, + 2358, 9506, 2340, 9549, 9696, 9551, 9577, 9671, 9676, 9695, + 9732, 9690, 9719, 9737, 9720, 9737, 9747, 9758, 9758, 9746, + 9756, 9775, 9776, 9767, 9766, 9768, 9807, 9838, 9841, 2299, + 1756, 9844, 9848, 2351, 9789, 9821, 9850, 9802, 9796, 9797, + 9805, 9806, 9830, 9859, 9831, 9832, 9861, 2311, 9835, 0, + 0, 9847, 9860, 0, 0, 0, 9855, 0, 2301, 9861, + + 9863, 9888, 9899, 9882, 9973, 9894, 9979, 9988,10005, 9919, + 10015,10032, 2270,10050,10065,10072,10079,10098,10107,10110, + 10129,10145,10179,10165, 2334, 9986,10108, 2324,10100,10256, + 9911,10021,10141,10202,10093, 1835, 1591,10275,10238,10278, + 10284,10287, 1838, 1619,10291, 9938, 9931,10294,10297,10300, + 10307, 9964, 2256,10321, 9950, 9989, 2252, 1882,10015,10328, + 10035,10076,10082, 2007, 1656,10344,10086,10087,10094,10101, + 10114,10118,10114,10338,10129,10116,10133,10138,10206,10247, + 10262,10288,10275,10292,10352,10302,10286,15625,10306,10317, + 10314,10319,10340,10336,10337,10382, 2124, 2080,10385,10393, + + 2307,10395,10370,10406,10349,10373,10382,10377,10350,10374, + 10380, 2260,10373,10383,10376,10391,10497, 2232,10432,10523, + 15625,10529,10538,10544,10559,10588,10607,10616, 0,10622, + 10637,10651,10666,10681,10699,10714,10701,10716,10736,10769, + 10747, 2230,10539,10632, 2229,10554,10846,10385,10469,10500, + 10505,10728,10574,10412, 2163,10673,10733,10810,10757,10841, + 10474, 2144,10477,10487,10863,10866,10763, 2123,10517,15625, + 10527, 2189, 2302,10873,10541,10534,10573,10560,10877,10880, + 10584, 2114,10602,10619,10639,10632,10651,10654,10664,10883, + 2105,10685,10672,10688,10671,10692,10690,10712,10724,10731, + + 10805,10887, 2079,10836,10860,10851,10853,10945,10869,10855, + 10862,10863,10948,10951,10970,10875, 2077, 2134,10957,10982, + 11008,10902,10876,10878,10916,10869, 0, 0,10891,10900, + 10934,10927, 0,10993,11034, 2057,10942,11036,11127,11133, + 11142,11148,11169,11175,11205,11211,11232,11213,11234,11263, + 2120,10976,11088, 2093,11140,11201,10957,11058, 2016,10947, + 11289,11084, 1976,10954,10957,10995,11111,11279,10981,10977, + 11184,11076,10994, 1973,10986,10987,11027,11054,11247, 1966, + 11102,11137,11124,11156,11174,11195,11276,11305, 1994,11197, + 1992,11308,11331,11188,11336,11195,11214,15625,11203,11210, + + 11219,11202,11203,11339,11271,11326,11292,11308,11328,11337, + 11338,11327,11337,11338,15625,11341,11343,11374,11381, 1960, + 11342, 2013,11362,11342,11392,11358,11379,11365,11380, 0, + 11361,11404,11456,11390, 1938,11404,11483,11489,11468,11491, + 1980,11479,11487, 1952,11484,11582,11425,11442,11445,11520, + 11446,11478,11467,11529,11523,11532,11560,11585, 1881,11477, + 15625,11479,11541, 1905,11527,11563,11554,11566, 1895,11553, + 11605, 1849,11614, 1833,11569,11625,11566,11628, 1831,11634, + 1809,15625,11642, 1723,11583, 1750,11594,11592,15625,11645, + 1714,11588,11589,11602,11611,11616,11610,11613,11614,11617, + + 15625,11636,11637,11628,11626,11624,15625,11630, 1756,11648, + 11667,11684,11745,11746,11631,11634, 0,11640, 1717,11647, + 11777,11754,11765, 1741,11767,11775, 1731,11804,11862,11658, + 11654,11677,11717,11742,11721,11723,11865,11803, 1647,11868, + 1623,11739,11743,11756,11757,11808, 1645,11871, 1639,11786, + 11812,11793,11879, 1598,11839,11839,11834,11856,11861,11846, + 11857,11858,11852,11853,11865,11856,11871,11864,11866,15625, + 11867,11863,11867,11868,11886,15625,15625,15625,11953, 1661, + 11895,11881,11907,11886,11956,11878,11929,11939,11959,11954, + 11976,11987, 1648,11988,11993, 1639,11992,12021,11983,11975, + + 12024, 1560,12038, 1557,11973,11990,12052,12012,12080,12009, + 12057,12058,12087, 1513,12061,12090,12093, 1497,12060,12061, + 12098, 1467,12066,12073,12080,12083,12071,12088,15625,12069, + 12088,12091,12078,12098,12081,12081,12093,12098,15625,12086, + 12084,12105,12105,15625,12110,12145, 1452, 1513,12114,12126, + 12187,12161,12118,12133, 0,12162,15625,12148,12179, 1505, + 12166,12225, 1503,12226,12270,12163,12183,12213,12208,12217, + 12176, 1432, 1458, 1292,12207,12213,12253,12227,12228, 1412, + 12244,12243,12261,12248,12244,12251,12257,12250,12262,12271, + 15625,12258,12269,12259,12260,12276,12277,12266,12261,12269, + + 15625,12273,15625, 1436,12287,12301,12281,12362, 0,12273, + 12291, 1392,12336,12380, 1381,12340,12398,12286,12276,12281, + 12314,12324,12340, 2261, 1294,12363,12369, 1321, 1307,12372, + 12366,12367,12379,12415,15625,12370,12387,12392,12380,15625, + 12384,12379,15625,12383,15625,12384,15625,12402,12392, 1317, + 12425,12379,12413, 0,12420, 1310,12459,12464, 1306,12467, + 12518,15625,12422,12435,15625,15625,12435,15625, 1200,12442, + 12451,12453,12455,12449,12471,12487,12458,12535, 1198,12459, + 12461,15625,12487,12498,12498,15625,12509,12514,15625, 1256, + 12465, 909, 942,12546,12551, 940,12560,12579,12530,15625, + + 12515,12523,12531,12537,12540,12541, 901,12582, 865,12537, + 15625,12600,12559,15625,15625,12560,15625,15625,12562, 924, + 12597,12612, 922,12598,12630,15625,12565,12575,12578,12597, + 12599,12611,12609,12657, 694,12603,12605,12607, 699,12660, + 12663, 689,12664,12625,12691,12626,12647,12650,12658,12653, + 12658,12660,15625,12663, 678,12686, 632,12722, 2380, 492, + 481,12671, 501, 492,12676,12680,12666,15625,12662,12687, + 15625, 440,12675,12689,12682,12690,12685,12745,15625,12708, + 12710,12701,12707,15625,12750,12753, 110,12723,12710,12722, + 12725,12769, 106,12733,12722,12775,12726,12721,12743,15625, + + 12750,12781,12762,12745,12751,12750,12752,12770,15625,12764, + 12777,12756,12806,15625,12889,12907,12925,12943,12961,12979, + 12997,13015,13033,13051,13069,13087,13105,13123,13141,13159, + 13174,13192,13206,13220,13234,13243,13257,13266,13282,13291, + 13303,13317,13331,13345,13354,13364,13369,13379,13397,13415, + 13433,13451,13469,13487,13505,13519,13528,13544,13562,13576, + 13585,13598,13607,13622,13636,13645,13663,13681,13696,13705, + 13720,13738,13756,13770,13779,13790,13799,13810,13819,13830, + 13839,13853,13862,13874,13883,13894,13903,13914,13923,13934, + 13943,13953,13958,13968,13986,14004,14022,14040,14058,14076, + + 14094,14112,14130,14144,14153,14168,14186,14204,14222,14236, + 14245,14256,14265,14280,14298,14316,14330,14339,14354,14372, + 14387,14405,14423,14437,14455,14469,14483,14497,14511,14526, + 14540,14554,14568,14581,14586,14596,14614,14632,14650,14668, + 14686,14700,14718,14736,14754,14772,14786,14800,14818,14836, + 14854,14868,14886,14904,14922,14940,14954,14968,14982,14996, + 15009,15014,15024,15042,15060,15078,15096,15110,15128,15146, + 15164,15178,15192,15210,15228,15242,15260,15278,15292,15306, + 15320,15334,15347,15352,15362,15380,15398,15412,15426,15444, + 15462,15480,15498,15516,15534,15552,15570,15588,15606 + } ; -static yyconst flex_int16_t yy_def[2511] = +static yyconst flex_int16_t yy_def[2700] = { 0, - 2326, 1, 2326, 3, 2327, 2327, 2326, 7, 2326, 9, - 2326, 11, 2328, 2328, 2329, 2329, 2330, 2330, 2326, 19, - 2330, 2330, 2331, 2331, 2332, 2332, 2333, 2333, 2334, 2334, - 2335, 2335, 2336, 2336, 2337, 2337, 2326, 37, 2338, 2338, - 2339, 2339, 2326, 43, 2326, 45, 2340, 2340, 2326, 49, - 2341, 2341, 2342, 2342, 2330, 2330, 2326, 2326, 2326, 2326, - 2326, 2343, 2344, 2345, 2346, 2326, 2326, 2326, 2326, 2326, - 2326, 2345, 2326, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 2347, 2345, 2345, 2345, - - 2348, 2345, 2326, 2326, 2326, 2349, 2326, 2326, 2326, 2349, - 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2350, - 2349, 2326, 2326, 2326, 2326, 2326, 2351, 2351, 2351, 2326, - 129, 129, 2326, 129, 129, 129, 129, 129, 129, 129, - 2351, 141, 141, 2352, 141, 2326, 2326, 2353, 2354, 2355, - 2326, 2354, 2354, 2356, 2354, 2354, 2354, 2357, 2354, 2326, - 2326, 2326, 2326, 2358, 2326, 2326, 2358, 2326, 2358, 2326, - 2326, 2358, 2358, 2358, 2358, 2358, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2359, 2326, 2326, 2326, - - 2359, 2326, 2359, 2359, 2359, 2359, 2359, 2359, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2360, 2326, 2361, 2362, 2326, 2363, 2326, 2326, 2364, 2365, - 2326, 2366, 2326, 2326, 2326, 2326, 2326, 2367, 2368, 2326, - 2326, 2326, 2326, 2326, 2368, 2368, 256, 256, 256, 2326, - 2368, 2368, 2368, 2369, 2368, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2370, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2371, 2372, 2326, 2326, 2326, 2326, - 2372, 2372, 2372, 2372, 2372, 2372, 2373, 2372, 2326, 2326, - - 2374, 2326, 2326, 2374, 2374, 2374, 2374, 2375, 2374, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2376, 2377, 2326, 2326, - 2326, 2326, 2326, 2377, 2326, 2326, 2326, 324, 324, 324, - 2326, 2377, 2377, 2377, 2378, 2377, 2326, 2326, 2326, 2326, - 2379, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2380, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2381, 2381, 2381, 2381, 2382, 2381, 2326, 2383, 2384, - 2384, 371, 371, 2385, 371, 2383, 2386, 2386, 2386, 2386, - 2387, 2386, 2326, 2388, 2326, 2388, 2388, 2388, 2389, 2388, - 2326, 2326, 2326, 2326, 2326, 2326, 2386, 397, 397, 397, - - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 2390, 2326, 2390, 2390, 2390, 2391, - 2390, 2326, 2326, 397, 2326, 2326, 2326, 2392, 2392, 2392, - 2392, 2393, 2392, 2326, 2326, 2326, 2326, 2392, 2392, 2392, - 2392, 2392, 2392, 2392, 2326, 2392, 2326, 2326, 2326, 2326, - 2394, 2394, 492, 2326, 492, 492, 492, 492, 492, 492, - - 2394, 501, 501, 2395, 501, 2326, 501, 2326, 2326, 492, - 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, - 2326, 492, 2326, 2396, 2396, 2396, 2396, 2397, 2396, 2326, - 2398, 2398, 2398, 2398, 2399, 2398, 2326, 2400, 2326, 2400, - 2400, 2400, 2401, 2400, 2326, 2326, 2326, 2398, 2398, 2402, - 2326, 2402, 2402, 2402, 2403, 2402, 2326, 2326, 2398, 2404, - 2326, 2326, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2405, - 2405, 2405, 2326, 2326, 2405, 2405, 2405, 2405, 2405, 2405, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2406, 2326, 2407, 2326, 2326, 2326, 2326, - 2408, 2326, 2409, 2326, 2326, 2326, 2326, 2326, 2326, 2410, - 2326, 2326, 2326, 2411, 2326, 2412, 2326, 2326, 2326, 2413, - 2414, 2414, 632, 632, 2415, 632, 2413, 2416, 2416, 2416, - 2416, 2417, 2416, 2326, 2326, 2326, 2416, 2416, 2416, 2416, - 2416, 2416, 2326, 2416, 2326, 2326, 2326, 2326, 2418, 2326, - 2326, 2326, 2326, 2326, 2326, 2419, 2420, 2420, 668, 668, - 2421, 668, 2419, 2422, 2422, 2422, 2422, 2423, 2422, 2326, - 2326, 2422, 2422, 2422, 2326, 2422, 2326, 2326, 2424, 2424, - 2424, 2424, 2425, 2424, 2326, 2424, 2326, 2424, 2326, 2326, - - 2326, 2426, 2427, 2427, 704, 704, 2428, 704, 2426, 2429, - 2429, 2429, 2429, 2430, 2429, 2326, 2326, 2326, 2326, 2326, - 2429, 721, 2326, 721, 721, 721, 2326, 721, 2326, 2326, - 2326, 2431, 2326, 2326, 2326, 2326, 2326, 2432, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2433, 2434, 2435, 2326, 2436, - 2437, 2326, 2326, 2326, 2326, 2326, 2438, 2438, 2438, 2438, - 2438, 2438, 2438, 2438, 2438, 2438, 2438, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 2326, 2439, 2326, 2440, 2440, - 2440, 2440, 2440, 2440, 2326, 2441, 2441, 847, 847, 847, - 847, 847, 847, 847, 847, 847, 2326, 2326, 2442, 2326, - 2443, 2444, 2444, 2326, 2445, 2326, 2446, 2446, 2446, 2446, - 2446, 2446, 2446, 2446, 2447, 2447, 2447, 2447, 2447, 2447, - 2447, 2447, 2326, 2448, 2448, 2326, 2326, 2449, 2449, 2326, - 2326, 2450, 2450, 2326, 2451, 2452, 2453, 2326, 2326, 2326, - - 2326, 2454, 2454, 2454, 2454, 2454, 2454, 2326, 2326, 2455, - 2326, 2326, 2456, 2457, 2458, 2326, 2459, 2459, 2459, 2326, - 2460, 2326, 2326, 2461, 2462, 2463, 2326, 2326, 2326, 2326, - 2326, 2464, 2326, 2326, 2464, 2464, 2464, 2326, 2465, 2326, - 2326, 2326, 2466, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2467, 2326, 2468, 2468, 2468, 2326, 2326, 2326, 2326, 2326, - 2469, 2469, 2469, 2469, 2469, 2469, 2469, 2469, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 2326, - 2469, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 2326, 2470, 2470, 2470, 2470, 2470, 2470, 2471, 2471, - 1050, 1050, 2326, 1050, 1050, 1050, 1050, 1050, 1050, 2326, - 2326, 2472, 2472, 2326, 2473, 2473, 2473, 2473, 2473, 2473, - 2473, 2473, 2474, 2474, 2474, 2474, 2474, 2474, 2474, 2474, - 2475, 2326, 2476, 2326, 2477, 2326, 2478, 2479, 2479, 2479, - 2326, 2326, 2326, 2480, 2480, 2480, 1096, 1096, 1096, 2326, - - 2481, 2481, 2481, 2326, 2482, 2483, 2483, 2483, 2484, 2484, - 2484, 2485, 2326, 2486, 2487, 2487, 2487, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2488, 2488, 2488, 2489, 2489, 2489, - 2326, 2326, 2490, 2490, 2490, 2326, 2326, 2326, 2326, 2326, - 2491, 2491, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 2326, - 2491, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 2326, 2491, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2491, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 2492, 2492, 2492, 2492, 2492, 2326, 2493, 2493, 1229, - 1229, 1229, 1229, 1229, 1229, 1229, 2494, 2494, 2495, 2495, - 2495, 2495, 2495, 2495, 2495, 2495, 2496, 2496, 2496, 2496, - 2496, 2496, 2496, 2497, 2497, 2497, 2497, 2498, 2498, 2498, - 2498, 2499, 2499, 2499, 2499, 2326, 2326, 2326, 2500, 2500, - 2326, 2326, 2326, 2500, 2500, 2500, 2500, 2326, 2326, 2484, - 2484, 2484, 2326, 2326, 2488, 2488, 2488, 2326, 2326, 2491, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 2326, 2326, 2326, 1142, 1142, 2326, 2326, - 2491, 1142, 1142, 1142, 1142, 2326, 2326, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 2492, 2492, 2492, - 2492, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, - 2494, 2495, 2495, 2495, 2495, 2495, 2495, 2495, 2495, 2496, - 2496, 2496, 2496, 2496, 2496, 2326, 2326, 2326, 2500, 2500, - - 2501, 2326, 2326, 2501, 2501, 1272, 1272, 2501, 1272, 1272, - 1410, 1410, 2502, 1410, 2501, 2326, 2500, 2500, 2500, 2326, - 2484, 2484, 2484, 2326, 2326, 2488, 2488, 2488, 2326, 2326, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 2326, 2326, - 2491, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 2326, 2326, - 2491, 2326, 2326, 1142, 1142, 2326, 2503, 1142, 1142, 1142, - 2326, 1142, 1142, 1142, 1142, 1142, 1142, 2326, 2326, 2491, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 1142, 1142, 1142, 2326, 2326, 2491, 1142, - - 1142, 1142, 2492, 2492, 1229, 1229, 1229, 1229, 1229, 1229, - 1229, 1229, 2494, 2495, 2495, 2495, 2495, 2495, 2495, 2495, - 2496, 2496, 2496, 2496, 2496, 2326, 2326, 2326, 2500, 2500, - 2501, 2501, 2501, 2326, 2501, 1272, 2501, 1272, 2501, 1272, - 1272, 1272, 2504, 2326, 2500, 2500, 2484, 2484, 2484, 2326, - 2326, 2488, 2488, 2326, 1142, 1142, 1142, 1142, 2326, 2505, - 1142, 1142, 1142, 1142, 1142, 2326, 2506, 2326, 2326, 1142, - 1142, 2503, 2503, 2326, 1142, 2326, 2326, 2326, 2491, 1142, - 1142, 2326, 2326, 2326, 2326, 2507, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 1142, - 1142, 1142, 2326, 2508, 1142, 1142, 2492, 2492, 1229, 1229, - 1229, 1229, 1229, 1229, 1229, 1229, 2494, 2495, 2495, 2495, - 2495, 2495, 2495, 2495, 2496, 2496, 2496, 2496, 2496, 2326, - 2326, 2326, 2500, 2500, 2501, 2326, 2509, 2504, 2501, 1272, - 2501, 2501, 1410, 2504, 2504, 2509, 2504, 2504, 2504, 2500, - 2500, 2484, 2484, 2484, 2326, 2326, 2488, 2326, 1142, 1142, - 1142, 1142, 2505, 2505, 2326, 1142, 1142, 1142, 1142, 2506, - 2506, 2326, 2326, 2326, 1142, 1142, 2326, 2326, 2326, 2326, - 1142, 2326, 2326, 2510, 1142, 2326, 2326, 2326, 2507, 2507, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 1142, 2508, 2508, 2326, - 1142, 2492, 2492, 1229, 1229, 1229, 2495, 2495, 2495, 2496, - 2496, 2496, 2326, 2326, 2326, 2500, 2500, 2501, 2326, 2509, - 2509, 2509, 2509, 2509, 2509, 2509, 1272, 2504, 2504, 2509, - 2509, 2504, 2504, 2504, 2500, 2500, 2484, 2484, 2484, 2326, - 2326, 2488, 2326, 1142, 1142, 1142, 2326, 2326, 2326, 2326, - 1142, 1142, 1142, 2326, 2326, 2326, 2326, 2326, 2326, 1142, - 1142, 2326, 2326, 2326, 2326, 2510, 2510, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 1142, 2326, 2326, 2326, 2326, 2492, 2492, 1229, 1229, - 1229, 2495, 2495, 2495, 2496, 2496, 2496, 2326, 2326, 2326, - 2326, 2326, 2500, 1853, 2501, 2509, 2509, 2509, 2509, 2504, - 2509, 2504, 2504, 1853, 2484, 2484, 2326, 2326, 2326, 2326, - 2488, 2326, 2326, 2326, 2326, 1142, 2326, 2326, 2326, 2326, - 2326, 1142, 1142, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 1142, 2326, 2326, 2326, - 2492, 2492, 1229, 2495, 2496, 2496, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2500, 2509, 2504, 1853, 2484, 2326, - 2326, 2326, 2326, 2326, 2326, 2488, 2326, 2326, 2326, 1142, - 2326, 2326, 2326, 1142, 1142, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2492, - 2492, 1229, 2495, 2496, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2509, 1853, 2484, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 1142, 2326, 2326, 2326, 1142, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2492, 2492, 1229, 2495, 2326, 2326, - 2326, 1853, 2484, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 1142, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2492, 1229, - 2495, 2326, 2326, 2326, 1853, 2484, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2492, 1229, 2495, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2492, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 0, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326 + 2514, 1, 2514, 3, 2515, 2515, 2514, 7, 2514, 9, + 2514, 11, 2516, 2516, 2517, 2517, 2518, 2518, 2514, 19, + 2518, 2518, 2519, 2519, 2520, 2520, 2521, 2521, 2522, 2522, + 2523, 2523, 2524, 2524, 2525, 2525, 2514, 37, 2526, 2526, + 2527, 2527, 2514, 43, 2514, 45, 2528, 2528, 2514, 49, + 2529, 2529, 2518, 2518, 2530, 2530, 2518, 2518, 2514, 2514, + 2514, 2514, 2514, 2531, 2532, 2533, 2534, 2514, 2514, 2514, + 2514, 2514, 2514, 2533, 2514, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 2535, 2533, + + 2533, 2533, 2536, 2533, 2514, 2514, 2514, 2537, 2514, 2514, + 2514, 2537, 2537, 2537, 2537, 2537, 2537, 2537, 2537, 2537, + 2537, 2538, 2537, 2514, 2514, 2514, 2514, 2514, 2539, 2539, + 2539, 2514, 131, 131, 2514, 131, 131, 131, 131, 131, + 131, 131, 2539, 143, 143, 2540, 143, 2514, 2514, 2541, + 2542, 2543, 2514, 2542, 2542, 2544, 2542, 2542, 2542, 2545, + 2542, 2514, 2514, 2514, 2514, 2546, 2514, 2514, 2546, 2514, + 2546, 2514, 2514, 2546, 2546, 2546, 2546, 2546, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2547, 2514, + + 2514, 2514, 2547, 2514, 2547, 2547, 2547, 2547, 2547, 2547, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2548, 2514, 2549, 2550, 2514, 2551, 2514, 2514, + 2552, 2553, 2514, 2554, 2514, 2514, 2514, 2514, 2514, 2555, + 2556, 2514, 2514, 2514, 2514, 2514, 2556, 257, 257, 257, + 2514, 2556, 2556, 2556, 2557, 2556, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2558, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2559, 2560, 2514, 2514, 2514, + 2514, 2560, 2560, 2560, 2560, 2560, 2560, 2561, 2560, 2514, + + 2514, 2562, 2514, 2514, 2562, 2562, 2562, 2562, 2563, 2562, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2564, 2565, 2514, + 2514, 2514, 2514, 2514, 2565, 2514, 2514, 325, 325, 2514, + 2565, 2565, 2565, 2566, 2565, 2514, 2514, 2514, 2514, 2567, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2568, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2569, 2569, 2569, 2569, 2570, 2569, 2514, 2571, 2572, 2572, + 370, 370, 2573, 370, 2571, 2574, 2574, 2574, 2574, 2575, + 2574, 2514, 2576, 2514, 2576, 2576, 2576, 2577, 2576, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2574, 398, 398, + + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 2578, 2514, 2578, 2578, 2578, + 2579, 2578, 2514, 2514, 398, 2514, 2514, 2514, 2580, 2580, + 2580, 2580, 2581, 2580, 2514, 2514, 2514, 2514, 2580, 2580, + 2580, 2580, 2580, 2580, 2580, 2514, 2580, 2514, 2514, 2514, + 2514, 2582, 2582, 493, 2514, 493, 493, 493, 493, 493, + + 493, 2582, 502, 502, 2583, 502, 2514, 502, 2514, 2514, + 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, + 493, 2514, 493, 2514, 2584, 2584, 2584, 2584, 2585, 2584, + 2514, 2586, 2586, 2586, 2586, 2587, 2586, 2514, 2588, 2514, + 2588, 2588, 2588, 2589, 2588, 2514, 2514, 2514, 2586, 2586, + 2590, 2514, 2590, 2590, 2590, 2591, 2590, 2514, 2514, 2586, + 2592, 2514, 2514, 2592, 2592, 2592, 2592, 2592, 2592, 2592, + 2592, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2593, 2593, 2593, 2514, 2514, 2593, 2593, 2593, 2593, 2593, + 2593, 2593, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2594, 2514, 2595, 2514, 2514, + 2514, 2514, 2596, 2514, 2597, 2514, 2514, 2514, 2514, 2514, + 2514, 2598, 2514, 2514, 2514, 2599, 2514, 2600, 2514, 2514, + 2514, 2601, 2602, 2602, 634, 634, 2603, 634, 2601, 2604, + 2604, 2604, 2604, 2605, 2604, 2514, 2514, 2514, 2604, 2604, + 2604, 2604, 2604, 2514, 2604, 2514, 2514, 2514, 2514, 2606, + 2514, 2514, 2514, 2514, 2514, 2514, 2607, 2608, 2608, 669, + 669, 2609, 669, 2607, 2610, 2610, 2610, 2610, 2611, 2610, + 2514, 2514, 2610, 2610, 2610, 2514, 2610, 2514, 2514, 2612, + 2612, 2612, 2612, 2613, 2612, 2514, 2612, 2514, 2612, 2514, + + 2514, 2514, 2614, 2615, 2615, 705, 705, 2616, 705, 2614, + 2617, 2617, 2617, 2617, 2618, 2617, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2617, 724, 724, 724, 2514, 724, 2514, + 2514, 2514, 2619, 2514, 2514, 2514, 2514, 2514, 2620, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2621, 2622, 2623, 2514, + 2624, 2514, 2625, 2514, 2514, 2514, 2514, 2514, 2514, 2626, + 2514, 2626, 2626, 2626, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 2514, 2627, 2514, 2514, 2628, 2628, 2628, 2628, 2628, + 2628, 2628, 2514, 2629, 2629, 855, 855, 855, 855, 855, + 855, 855, 855, 855, 855, 2514, 2514, 2630, 2514, 2631, + 2632, 2632, 2514, 2633, 2514, 2634, 2634, 2634, 2634, 2634, + 2634, 2634, 2634, 2634, 2635, 2635, 2635, 2635, 2635, 2635, + 2635, 2635, 2635, 2514, 2636, 2636, 2514, 2514, 2637, 2637, + + 2514, 2514, 2638, 2638, 2514, 2639, 2640, 2641, 2514, 2514, + 2514, 2642, 2642, 2642, 2642, 2642, 2514, 2514, 2643, 2514, + 2514, 2644, 2645, 2646, 2514, 2647, 2647, 2647, 2514, 2648, + 2514, 2514, 2649, 2650, 2514, 2651, 2514, 2514, 2514, 2514, + 2514, 2514, 2652, 2514, 2652, 2652, 946, 2514, 2653, 2514, + 2514, 2514, 2654, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2655, 2514, 2514, 2656, 2656, 2656, 2514, 2514, 2514, 2514, + 2514, 2514, 2657, 2657, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 2514, 2657, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 2514, 2514, 2658, 2658, 2658, + 2658, 2658, 2658, 2658, 2659, 2659, 1066, 1066, 2514, 1066, + 1066, 1066, 1066, 1066, 1066, 1066, 2514, 2514, 2660, 2660, + 2514, 2661, 2661, 2661, 2661, 2661, 2661, 2661, 2661, 2661, + 2662, 2662, 2662, 2662, 2662, 2662, 2662, 2662, 2662, 2663, + + 2514, 2664, 2514, 2665, 2514, 2666, 2667, 2667, 2667, 2514, + 2514, 2668, 2668, 1113, 1113, 1113, 2514, 2669, 2669, 2669, + 2514, 2670, 2671, 2671, 2671, 2672, 2672, 2672, 2673, 2514, + 2674, 2514, 2675, 2675, 2675, 2514, 2514, 2514, 2514, 2514, + 2514, 2676, 2676, 1143, 2677, 2677, 2677, 2514, 2514, 2678, + 2678, 2678, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2679, + 2679, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 2514, + 2679, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + + 2514, 2679, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2679, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 2514, 2680, 2680, 2680, 2680, 2680, 2680, 2514, + 2681, 2681, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, + 2682, 2682, 2683, 2683, 2683, 2683, 2683, 2683, 2683, 2683, + 2683, 2684, 2684, 2684, 2684, 2684, 2684, 2684, 2684, 2685, + 2685, 2685, 2685, 2686, 2686, 2686, 2686, 2687, 2687, 2687, + 2687, 2514, 2514, 2688, 2514, 2514, 2514, 2688, 2688, 2688, + + 2688, 2514, 2514, 2689, 2689, 2689, 2514, 2514, 1143, 1143, + 1143, 2514, 2514, 2514, 1161, 2514, 2679, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 2514, 2514, 2514, 1161, 1161, 2514, 2514, 2679, 1161, 1161, + 1161, 1161, 2514, 2514, 1161, 2514, 2679, 1161, 1161, 1161, + 2514, 2679, 1161, 1161, 1161, 1161, 1161, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + + 2514, 2680, 2680, 2680, 2680, 2680, 1252, 1252, 1252, 1252, + 1252, 1252, 1252, 1252, 1252, 1252, 2682, 2683, 2683, 2683, + 2683, 2683, 2683, 2683, 2683, 2683, 2684, 2684, 2684, 2684, + 2684, 2684, 2684, 2514, 2514, 2688, 2690, 2514, 2514, 2690, + 2690, 1296, 1296, 2690, 1296, 1296, 1446, 1446, 2691, 1446, + 2690, 2514, 2688, 2688, 2688, 2514, 2689, 2689, 2689, 2514, + 2514, 1143, 1143, 1143, 2514, 2514, 1161, 2514, 2514, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 2514, 2514, 2679, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 2514, 2514, 2679, + 2514, 2514, 1161, 1161, 2514, 2692, 1161, 1161, 1161, 2514, + + 1161, 2514, 2514, 1161, 1161, 2514, 2514, 1161, 1161, 1161, + 2514, 2514, 2679, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1161, + 1161, 1161, 2514, 2514, 2679, 1161, 1161, 1161, 2514, 2680, + 2680, 2680, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, + 1252, 2682, 2683, 2683, 2683, 2683, 2683, 2683, 2683, 2683, + 2684, 2684, 2684, 2684, 2684, 2684, 2514, 2514, 2688, 2690, + 2690, 2690, 2514, 2690, 1296, 2690, 1296, 2690, 1296, 1296, + 1296, 2693, 2514, 2688, 2688, 2689, 2689, 2689, 2514, 2514, + + 1143, 1143, 2514, 2514, 1161, 2514, 1161, 1161, 1161, 1161, + 2514, 2694, 1161, 1161, 1161, 1161, 1161, 2514, 2695, 2514, + 2514, 1161, 1161, 2692, 2692, 2514, 1161, 2514, 2514, 2514, + 2514, 2679, 2514, 1161, 1161, 2514, 2514, 2514, 2514, 2696, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 1161, 1161, 1161, 2514, + 2697, 1161, 1161, 2514, 2680, 2680, 2680, 1252, 1252, 1252, + 1252, 1252, 1252, 1252, 1252, 1252, 2682, 2683, 2683, 2683, + 2683, 2683, 2683, 2683, 2683, 2684, 2684, 2684, 2684, 2684, + + 2684, 2514, 2514, 2688, 2690, 2514, 2698, 2693, 2690, 1296, + 2690, 2690, 1446, 2693, 2693, 2698, 2693, 2693, 2693, 2688, + 2688, 2689, 2689, 2689, 2514, 2514, 1143, 2514, 2514, 1161, + 2514, 1161, 1161, 1161, 1161, 2694, 2694, 2514, 1161, 1161, + 1161, 1161, 2695, 2695, 2514, 2514, 2514, 1161, 1161, 2514, + 2514, 2514, 2514, 1161, 2514, 2514, 2514, 2699, 2514, 1161, + 2514, 2514, 2514, 2696, 2696, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 1161, 2697, 2697, 2514, 1161, + + 2514, 2680, 2680, 2680, 1252, 1252, 1252, 1252, 2683, 2683, + 2683, 2683, 2684, 2684, 2684, 2684, 2514, 2514, 2688, 2690, + 2514, 2698, 2698, 2698, 2698, 2698, 2698, 2698, 1296, 2693, + 2693, 2698, 2698, 2693, 2693, 2693, 2688, 2688, 2689, 2689, + 2689, 2514, 2514, 1143, 2514, 2514, 1161, 2514, 1161, 1161, + 1161, 2514, 2514, 2514, 2514, 1161, 1161, 1161, 2514, 2514, + 2514, 2514, 2514, 2514, 1161, 1161, 2514, 2514, 2514, 2514, + 2514, 2699, 2699, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 1161, 2514, 2514, 2514, 2514, 2514, 2680, 2680, + 2680, 1252, 1252, 1252, 1252, 2683, 2683, 2683, 2683, 2684, + 2684, 2684, 2684, 2514, 2514, 2514, 2514, 2688, 2690, 2698, + 2698, 2698, 2698, 2693, 2698, 2693, 2693, 2688, 2689, 2689, + 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, 2514, + 1161, 2514, 2514, 2514, 2514, 2514, 1161, 1161, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1161, 2514, 2514, + 2514, 2514, 2680, 2680, 2680, 1252, 1252, 2683, 2683, 2684, + 2684, 2684, 2514, 2514, 2514, 2514, 2698, 2693, 2688, 2689, + 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, 1161, + 2514, 2514, 2514, 1161, 1161, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2680, + 2680, 2680, 1252, 1252, 2683, 2683, 2684, 2684, 2514, 2514, + 2698, 2688, 2689, 2514, 2514, 1143, 2514, 2514, 1161, 2514, + 2514, 2514, 1161, 2514, 2514, 2514, 1161, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2680, 2680, 2680, 1252, 1252, 2683, 2683, 2684, 2514, 2514, + 2688, 2689, 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 1161, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2680, 2680, + 1252, 1252, 2683, 2683, 2684, 2514, 2514, 2688, 2689, 2514, + 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2680, 2680, 1252, 1252, 2683, 2683, + 2514, 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2680, 2680, 1252, 2683, 2514, 2514, 2514, 1143, 2514, 2514, + 1161, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2680, 2514, 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 1143, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 0, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514 + } ; -static yyconst flex_int16_t yy_nxt[15696] = +static yyconst flex_int16_t yy_nxt[15718] = { 0, - 58, 59, 60, 59, 61, 62, 63, 64, 65, 66, - 66, 61, 67, 68, 69, 70, 71, 72, 72, 61, - 61, 61, 73, 61, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 64, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 64, 64, - 58, 58, 61, 64, 97, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 64, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 64, - 64, 58, 98, 99, 100, 101, 102, 102, 102, 102, - 102, 102, 103, 104, 104, 105, 104, 104, 104, 106, - - 106, 104, 107, 107, 108, 109, 104, 109, 104, 104, - 110, 110, 104, 104, 104, 104, 104, 106, 106, 106, - 106, 106, 111, 106, 106, 112, 106, 106, 106, 106, - 106, 106, 106, 113, 114, 115, 106, 106, 106, 116, - 106, 106, 106, 104, 104, 104, 106, 104, 106, 106, - 106, 106, 106, 111, 106, 106, 112, 106, 106, 106, - 106, 106, 106, 106, 113, 114, 115, 106, 106, 106, - 116, 106, 106, 106, 104, 117, 118, 119, 120, 121, - 121, 121, 121, 121, 121, 122, 124, 124, 392, 392, - 393, 394, 394, 392, 392, 125, 125, 126, 127, 128, - - 127, 126, 126, 129, 129, 126, 126, 126, 130, 131, - 126, 132, 133, 126, 129, 129, 126, 126, 126, 126, - 126, 129, 129, 129, 134, 135, 129, 136, 129, 129, - 129, 129, 129, 129, 129, 137, 138, 129, 139, 129, - 140, 129, 129, 129, 129, 129, 129, 126, 126, 126, - 129, 126, 129, 129, 129, 134, 135, 129, 136, 129, - 129, 129, 129, 129, 129, 129, 137, 138, 129, 139, - 129, 140, 129, 129, 129, 129, 129, 129, 126, 141, - 142, 143, 144, 145, 145, 145, 145, 145, 145, 146, - 147, 147, 105, 147, 147, 148, 149, 149, 150, 147, - - 147, 151, 147, 147, 147, 147, 147, 149, 149, 147, - 147, 147, 147, 147, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 152, - 149, 149, 149, 153, 149, 149, 149, 149, 149, 149, - 147, 147, 147, 149, 154, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 152, 149, 149, 149, 153, 149, 149, 149, 149, 149, - 149, 147, 155, 156, 157, 158, 159, 159, 159, 159, - 159, 159, 160, 161, 162, 163, 162, 161, 161, 161, - 164, 165, 161, 161, 166, 167, 168, 169, 170, 161, - - 164, 164, 161, 161, 171, 161, 161, 164, 164, 164, - 172, 173, 164, 174, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 175, 164, 176, 164, 164, 164, - 164, 164, 164, 161, 161, 161, 164, 161, 164, 164, - 164, 172, 173, 164, 174, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 175, 164, 176, 164, 164, - 164, 164, 164, 164, 161, 161, 177, 161, 178, 161, - 161, 161, 161, 161, 161, 161, 180, 181, 180, 232, - 180, 181, 180, 182, 232, 235, 183, 182, 184, 235, - 183, 238, 184, 188, 189, 188, 238, 188, 189, 188, - - 190, 105, 105, 191, 190, 190, 105, 191, 105, 190, - 463, 463, 475, 356, 477, 477, 510, 476, 356, 485, - 485, 357, 233, 511, 268, 268, 357, 233, 236, 489, - 358, 2310, 236, 2292, 490, 358, 312, 239, 312, 512, - 508, 513, 239, 514, 356, 509, 2296, 510, 546, 356, - 521, 521, 357, 547, 511, 268, 268, 357, 185, 2295, - 186, 358, 185, 561, 186, 2281, 358, 312, 562, 312, - 512, 573, 513, 577, 514, 192, 574, 193, 578, 192, - 2280, 193, 194, 195, 196, 195, 194, 194, 194, 197, - 198, 199, 199, 200, 201, 202, 203, 194, 194, 204, - - 204, 194, 194, 199, 194, 194, 204, 204, 204, 204, - 204, 204, 205, 204, 204, 204, 204, 204, 204, 204, - 204, 206, 204, 204, 207, 208, 204, 204, 204, 204, - 204, 204, 194, 194, 194, 204, 194, 204, 204, 204, - 204, 204, 204, 205, 204, 204, 204, 204, 204, 204, - 204, 204, 206, 204, 204, 207, 208, 204, 204, 204, - 204, 204, 204, 199, 194, 209, 194, 210, 194, 194, - 194, 194, 194, 194, 194, 211, 211, 211, 211, 211, - 211, 515, 2326, 212, 377, 377, 212, 216, 217, 216, - 521, 521, 218, 516, 219, 427, 220, 221, 216, 217, - - 216, 558, 558, 218, 1256, 219, 1260, 220, 221, 225, - 226, 225, 515, 2213, 227, 2291, 227, 227, 227, 228, - 225, 226, 225, 563, 516, 227, 427, 227, 227, 227, - 228, 378, 379, 380, 381, 382, 382, 382, 382, 382, - 382, 383, 2326, 564, 377, 377, 558, 558, 2326, 2244, - 377, 377, 565, 566, 563, 409, 585, 213, 586, 214, - 213, 404, 214, 581, 582, 405, 656, 583, 410, 222, - 2260, 223, 584, 2252, 564, 592, 593, 2223, 594, 1255, - 222, 1259, 223, 565, 566, 597, 409, 585, 2214, 586, - 598, 229, 404, 230, 581, 582, 405, 656, 601, 410, - - 602, 602, 229, 602, 230, 244, 245, 246, 245, 244, - 247, 248, 249, 250, 251, 244, 244, 244, 244, 252, - 244, 244, 249, 249, 244, 253, 244, 244, 254, 255, - 249, 249, 249, 249, 256, 257, 249, 249, 249, 249, - 258, 249, 249, 249, 249, 249, 259, 249, 249, 249, - 249, 249, 249, 249, 249, 244, 244, 244, 249, 260, - 255, 249, 249, 249, 249, 256, 257, 249, 249, 249, - 249, 258, 249, 249, 249, 249, 249, 259, 249, 249, - 249, 249, 249, 249, 249, 249, 244, 261, 262, 263, - 264, 265, 265, 265, 265, 265, 265, 266, 270, 271, - - 270, 2182, 272, 273, 2213, 274, 275, 276, 359, 359, - 359, 277, 270, 271, 270, 652, 272, 273, 638, 274, - 275, 276, 463, 463, 2326, 277, 377, 377, 2326, 2218, - 377, 377, 2326, 406, 377, 377, 661, 377, 587, 278, - 589, 377, 699, 588, 734, 377, 652, 407, 735, 638, - 408, 2217, 413, 278, 411, 414, 740, 590, 415, 2182, - 412, 653, 653, 2148, 406, 662, 663, 661, 377, 587, - 278, 589, 377, 699, 588, 734, 377, 2183, 407, 735, - 279, 408, 280, 413, 278, 411, 414, 740, 590, 415, - 360, 412, 465, 466, 279, 467, 280, 281, 282, 283, - - 282, 281, 284, 285, 286, 287, 288, 289, 281, 281, - 281, 290, 281, 281, 286, 286, 281, 281, 281, 281, - 281, 286, 286, 286, 286, 286, 291, 286, 286, 286, - 286, 286, 292, 286, 286, 286, 286, 286, 293, 286, - 286, 286, 286, 286, 286, 286, 286, 281, 281, 281, - 286, 281, 286, 286, 286, 286, 286, 291, 286, 286, - 286, 286, 286, 292, 286, 286, 286, 286, 286, 293, - 286, 286, 286, 286, 286, 286, 286, 286, 281, 294, - 295, 296, 297, 298, 298, 298, 298, 298, 298, 299, - 105, 105, 105, 105, 105, 300, 301, 301, 302, 105, - - 105, 105, 105, 105, 105, 105, 105, 301, 301, 105, - 105, 105, 105, 303, 301, 301, 301, 301, 301, 304, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 105, 105, 105, 301, 105, 301, 301, 301, 301, 301, - 304, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 105, 305, 306, 307, 308, 309, 309, 309, 309, - 309, 309, 310, 313, 314, 315, 314, 313, 316, 317, - 318, 319, 313, 313, 313, 320, 321, 322, 323, 313, - - 324, 324, 313, 325, 326, 313, 327, 328, 318, 318, - 318, 318, 318, 329, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 330, 318, 318, 318, 318, - 318, 318, 318, 313, 313, 313, 318, 331, 328, 318, - 318, 318, 318, 318, 329, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 330, 318, 318, 318, - 318, 318, 318, 318, 313, 332, 333, 334, 335, 336, - 336, 336, 336, 336, 336, 337, 339, 340, 339, 653, - 653, 341, 2181, 339, 340, 339, 685, 685, 341, 342, - 359, 359, 359, 697, 697, 343, 342, 2142, 628, 628, - - 628, 741, 343, 2127, 344, 348, 349, 348, 697, 697, - 350, 344, 348, 349, 348, 717, 717, 350, 351, 361, - 742, 345, 485, 485, 352, 351, 718, 2106, 345, 717, - 717, 352, 741, 353, 2326, 344, 377, 377, 2101, 354, - 353, 2326, 344, 377, 377, 2098, 354, 377, 2089, 655, - 450, 742, 345, 743, 377, 719, 719, 385, 346, 345, - 416, 628, 628, 628, 353, 346, 2326, 2087, 377, 377, - 354, 353, 360, 2053, 657, 657, 657, 354, 377, 377, - 629, 450, 744, 423, 743, 377, 2104, 355, 657, 657, - 657, 416, 487, 488, 355, 2100, 363, 364, 365, 366, - - 367, 367, 367, 367, 367, 367, 368, 369, 369, 1264, - 377, 369, 369, 744, 423, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 727, 727, 369, 369, 369, 369, - 369, 386, 387, 388, 389, 390, 390, 390, 390, 390, - 390, 391, 2326, 629, 377, 377, 664, 664, 664, 745, - 745, 454, 664, 664, 664, 377, 658, 369, 369, 369, - 475, 369, 727, 727, 2326, 476, 377, 377, 745, 745, - 658, 489, 2326, 417, 377, 377, 490, 418, 747, 747, - 511, 419, 454, 463, 463, 377, 377, 1263, 369, 371, - 372, 373, 374, 375, 375, 375, 375, 375, 375, 376, - - 396, 437, 397, 397, 417, 463, 463, 2326, 418, 377, - 377, 511, 419, 398, 749, 749, 377, 749, 749, 420, - 377, 2040, 421, 512, 650, 392, 392, 638, 665, 422, - 638, 2029, 437, 508, 665, 729, 836, 836, 509, 2326, - 1954, 377, 377, 2020, 398, 836, 836, 1943, 424, 2080, - 420, 377, 377, 421, 512, 650, 425, 2058, 638, 513, - 422, 638, 426, 685, 685, 485, 485, 378, 379, 380, - 381, 382, 382, 382, 382, 382, 382, 383, 2326, 424, - 377, 377, 2326, 377, 377, 377, 2326, 425, 377, 377, - 513, 377, 429, 426, 515, 377, 430, 1987, 399, 377, - - 400, 700, 700, 700, 431, 401, 402, 403, 432, 428, - 1981, 700, 700, 700, 1979, 2326, 516, 377, 377, 485, - 485, 2050, 377, 429, 433, 515, 377, 430, 377, 399, - 377, 400, 434, 687, 688, 431, 401, 402, 403, 432, - 428, 435, 846, 2326, 436, 377, 377, 516, 2326, 546, - 377, 377, 477, 477, 547, 433, 438, 521, 521, 377, - 2045, 440, 1967, 434, 441, 2326, 439, 377, 377, 847, - 442, 848, 435, 846, 444, 436, 443, 2326, 377, 710, - 710, 445, 1951, 701, 521, 521, 2326, 438, 377, 377, - 710, 446, 440, 701, 849, 441, 850, 439, 851, 377, - - 847, 442, 848, 858, 858, 444, 724, 443, 447, 377, - 448, 852, 445, 449, 1938, 2326, 853, 377, 377, 858, - 858, 710, 446, 854, 451, 849, 855, 850, 377, 851, - 377, 452, 453, 561, 2326, 2326, 456, 724, 562, 447, - 1928, 448, 852, 1985, 449, 463, 463, 853, 618, 618, - 618, 377, 619, 620, 854, 451, 1983, 855, 856, 377, - 1892, 621, 452, 453, 457, 458, 459, 460, 461, 461, - 461, 461, 461, 461, 462, 2326, 2326, 867, 377, 377, - 377, 1886, 377, 2326, 2326, 1877, 463, 463, 1873, 856, - 2326, 2326, 377, 868, 463, 463, 1868, 730, 730, 730, - - 377, 463, 463, 478, 478, 558, 558, 377, 867, 377, - 558, 558, 2326, 573, 710, 710, 860, 860, 574, 377, - 377, 377, 1849, 377, 868, 710, 869, 377, 377, 377, - 622, 377, 725, 870, 377, 377, 377, 1834, 377, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 377, 479, 359, 730, 730, 730, 710, 869, 377, 480, - 860, 860, 1823, 725, 870, 377, 864, 864, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 731, - 864, 864, 479, 1813, 481, 482, 871, 736, 736, 736, - 480, 1803, 469, 470, 471, 472, 473, 473, 473, 473, - - 473, 473, 474, 872, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 481, 482, 871, 1792, 483, - 484, 1785, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 577, 872, 731, 895, 895, 578, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 483, 484, 736, 736, 736, 1778, 873, 1852, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 737, - 653, 653, 653, 653, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 2326, 2326, 873, 2326, 1577, - 710, 710, 2326, 2326, 874, 1688, 485, 485, 1539, 2326, - - 2326, 726, 468, 485, 485, 1741, 2326, 2326, 1737, 468, - 485, 485, 359, 359, 359, 1497, 468, 485, 485, 583, - 523, 1704, 517, 468, 584, 874, 518, 875, 1702, 468, - 468, 468, 726, 468, 737, 519, 468, 468, 468, 520, - 468, 876, 567, 468, 468, 468, 568, 468, 877, 878, - 468, 468, 468, 517, 468, 569, 879, 518, 875, 570, - 468, 880, 751, 751, 751, 1468, 519, 468, 1694, 2326, - 520, 597, 876, 567, 468, 1449, 598, 568, 1439, 877, - 878, 468, 491, 491, 491, 881, 569, 879, 882, 1543, - 570, 1653, 880, 493, 360, 493, 494, 525, 526, 527, - - 528, 529, 529, 529, 529, 529, 529, 530, 495, 496, - 1653, 497, 394, 394, 1629, 539, 881, 909, 1614, 882, - 498, 1586, 499, 753, 500, 532, 533, 534, 535, 536, - 536, 536, 536, 536, 536, 537, 605, 605, 605, 495, - 496, 606, 497, 607, 752, 612, 612, 612, 909, 608, - 613, 498, 614, 499, 753, 500, 601, 1573, 615, 913, - 913, 602, 1687, 501, 502, 503, 504, 505, 505, 505, - 505, 505, 505, 506, 491, 491, 491, 1319, 912, 685, - 685, 685, 685, 697, 697, 493, 1567, 493, 494, 540, - 541, 542, 543, 544, 544, 544, 544, 544, 544, 545, - - 495, 496, 923, 497, 941, 651, 754, 754, 2326, 912, - 377, 377, 498, 942, 499, 945, 500, 755, 609, 638, - 946, 377, 638, 548, 697, 697, 2326, 616, 377, 377, - 1560, 495, 496, 923, 497, 941, 651, 1674, 549, 377, - 947, 763, 1777, 498, 942, 499, 945, 500, 755, 1289, - 638, 946, 377, 638, 548, 501, 502, 503, 504, 505, - 505, 505, 505, 505, 505, 506, 2326, 2326, 2326, 549, - 377, 947, 763, 924, 924, 727, 727, 2326, 1539, 2326, - 494, 532, 533, 534, 535, 536, 536, 536, 536, 536, - 536, 537, 551, 727, 727, 1271, 532, 533, 534, 535, - - 536, 536, 536, 536, 536, 536, 537, 639, 640, 641, - 642, 643, 643, 643, 643, 643, 643, 644, 717, 717, - 552, 553, 554, 555, 556, 556, 556, 556, 556, 556, - 557, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 960, 960, 377, 377, 1203, 501, 507, 503, - 504, 505, 505, 505, 505, 505, 505, 506, 2326, 2326, - 2326, 468, 468, 2326, 2326, 1681, 605, 605, 605, 2326, - 1784, 2326, 2326, 883, 521, 521, 2326, 2326, 1480, 2326, - 492, 377, 377, 2326, 2326, 1478, 933, 558, 558, 492, - 492, 1181, 377, 531, 558, 558, 612, 612, 612, 765, - - 531, 2326, 2326, 887, 934, 531, 531, 492, 492, 492, - 1457, 492, 558, 558, 628, 628, 628, 933, 531, 1170, - 531, 531, 531, 377, 531, 2326, 2326, 531, 531, 531, - 765, 531, 719, 719, 1416, 934, 558, 558, 492, 638, - 638, 647, 531, 928, 948, 531, 531, 531, 609, 531, - 756, 531, 756, 2326, 1700, 757, 757, 1264, 531, 1802, - 2326, 674, 674, 618, 618, 618, 377, 891, 1264, 531, - 531, 531, 647, 531, 928, 948, 531, 949, 616, 639, - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 2326, 1260, 377, 377, 689, 689, 629, 377, 683, 760, - - 531, 630, 630, 377, 1065, 630, 630, 1260, 949, 630, - 630, 630, 630, 630, 630, 630, 630, 630, 1122, 1122, - 630, 630, 630, 630, 630, 2326, 2326, 710, 710, 683, - 760, 1256, 2326, 2326, 377, 1065, 653, 653, 897, 897, - 897, 1066, 638, 653, 653, 622, 362, 362, 1256, 638, - 492, 630, 630, 630, 1395, 630, 675, 676, 677, 678, - 679, 679, 679, 679, 679, 679, 680, 492, 1051, 638, - 638, 638, 1066, 638, 1053, 1391, 638, 638, 638, 492, - 638, 492, 630, 632, 633, 634, 635, 636, 636, 636, - 636, 636, 636, 637, 648, 1067, 1055, 649, 492, 1051, - - 638, 657, 657, 657, 2292, 2326, 2326, 638, 1389, 628, - 492, 1386, 2326, 2326, 370, 370, 653, 653, 384, 384, - 898, 682, 638, 653, 653, 648, 1067, 1384, 649, 638, - 956, 1020, 956, 492, 1134, 957, 957, 1129, 639, 640, - 641, 642, 643, 643, 643, 643, 643, 643, 644, 638, - 638, 638, 682, 638, 957, 957, 638, 638, 638, 1069, - 638, 1116, 1058, 1107, 492, 675, 676, 677, 678, 679, - 679, 679, 679, 679, 679, 680, 910, 910, 910, 2293, - 638, 684, 1102, 658, 664, 664, 664, 638, 666, 666, - 1069, 1268, 666, 666, 929, 929, 666, 666, 666, 666, - - 666, 666, 666, 666, 666, 930, 1070, 666, 666, 666, - 666, 666, 684, 690, 691, 692, 693, 694, 694, 694, - 694, 694, 694, 695, 1089, 675, 676, 677, 678, 679, - 679, 679, 679, 679, 679, 680, 930, 1070, 666, 666, - 666, 1085, 666, 2326, 2326, 1083, 2326, 1081, 377, 377, - 2326, 2326, 957, 957, 685, 685, 959, 959, 911, 769, - 674, 685, 685, 959, 959, 1250, 665, 674, 954, 666, - 668, 669, 670, 671, 672, 672, 672, 672, 672, 672, - 673, 492, 1072, 1059, 915, 915, 915, 674, 674, 674, - 769, 674, 2326, 2326, 674, 674, 674, 1073, 674, 2326, - - 2326, 960, 960, 685, 685, 943, 754, 754, 696, 674, - 685, 685, 492, 1072, 1059, 899, 674, 755, 674, 2326, - 939, 377, 377, 926, 958, 674, 958, 664, 1073, 959, - 959, 762, 377, 900, 901, 915, 674, 674, 674, 696, - 674, 910, 1074, 674, 674, 674, 899, 674, 755, 690, - 691, 692, 693, 694, 694, 694, 694, 694, 694, 695, - 2326, 2326, 762, 377, 900, 901, 916, 674, 2326, 2326, - 897, 697, 697, 1074, 674, 2326, 2326, 689, 1075, 697, - 697, 893, 2326, 2326, 1076, 689, 697, 697, 2326, 893, - 377, 377, 689, 697, 697, 455, 455, 524, 524, 689, - - 889, 377, 538, 538, 689, 689, 689, 889, 689, 1075, - 764, 1077, 689, 689, 689, 1076, 689, 361, 1078, 689, - 689, 689, 885, 689, 971, 1079, 689, 689, 689, 377, - 689, 2326, 377, 377, 377, 689, 550, 550, 700, 700, - 700, 764, 1077, 689, 805, 2326, 926, 926, 926, 1078, - 689, 885, 730, 730, 730, 971, 1079, 689, 702, 702, - 377, 1071, 702, 702, 631, 631, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 805, 1068, 702, 702, 702, - 702, 702, 711, 712, 713, 714, 715, 715, 715, 715, - 715, 715, 716, 751, 363, 364, 365, 366, 367, 367, - - 367, 367, 367, 367, 368, 939, 939, 939, 702, 702, - 702, 736, 702, 2326, 2326, 730, 2326, 702, 377, 377, - 701, 2326, 2326, 700, 727, 727, 667, 667, 927, 834, - 710, 666, 727, 727, 731, 703, 703, 1080, 710, 702, - 704, 705, 706, 707, 708, 708, 708, 708, 708, 708, - 709, 720, 492, 721, 721, 1119, 1119, 710, 710, 710, - 834, 710, 2326, 2326, 722, 710, 710, 710, 1080, 710, - 1729, 1054, 664, 727, 727, 1833, 736, 736, 736, 710, - 943, 943, 943, 492, 954, 751, 751, 940, 710, 1797, - 2326, 657, 377, 377, 1885, 722, 710, 630, 700, 377, - - 2326, 2326, 1054, 377, 982, 1091, 710, 710, 710, 628, - 710, 727, 727, 1081, 1081, 1081, 775, 710, 711, 712, - 713, 714, 715, 715, 715, 715, 715, 715, 716, 2326, - 377, 377, 377, 618, 377, 982, 1091, 710, 2326, 2326, - 2326, 894, 377, 492, 710, 710, 710, 775, 710, 893, - 745, 745, 2326, 2326, 2326, 612, 362, 761, 737, 2326, - 2326, 2326, 944, 1052, 745, 745, 955, 1119, 1119, 890, - 362, 745, 745, 377, 492, 710, 889, 362, 2326, 2326, - 2326, 377, 605, 362, 362, 362, 377, 362, 761, 492, - 745, 745, 1121, 1121, 1052, 1082, 362, 362, 362, 362, - - 1056, 362, 1121, 1121, 362, 362, 362, 385, 362, 1122, - 1122, 886, 377, 2326, 362, 377, 377, 377, 885, 1092, - 492, 2326, 778, 362, 362, 362, 377, 362, 362, 491, - 2326, 1056, 1083, 1083, 1083, 362, 378, 379, 380, 381, - 382, 382, 382, 382, 382, 382, 383, 369, 1093, 2326, - 1092, 377, 377, 778, 362, 369, 369, 377, 359, 369, - 369, 736, 377, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 774, 1100, 369, 369, 369, 369, 369, 1093, - 1104, 386, 387, 388, 389, 390, 390, 390, 390, 390, - 390, 391, 456, 377, 1573, 1574, 1118, 739, 1118, 730, - - 492, 1119, 1119, 774, 1100, 369, 369, 369, 733, 369, - 723, 1104, 1674, 1675, 1084, 681, 1085, 1085, 1085, 1057, - 457, 458, 459, 460, 461, 461, 461, 461, 461, 461, - 462, 492, 1089, 897, 897, 657, 369, 371, 372, 373, - 374, 375, 375, 375, 375, 375, 375, 376, 369, 369, - 1057, 660, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 747, 747, 369, 369, 369, - 369, 369, 369, 1113, 646, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 747, 747, - 369, 369, 369, 369, 2326, 2326, 645, 2326, 1086, 377, - - 377, 2326, 2326, 627, 1113, 463, 463, 625, 2326, 2326, - 377, 377, 463, 463, 1090, 1681, 1682, 785, 377, 463, - 463, 1573, 2326, 603, 2326, 377, 377, 377, 1700, 1701, - 600, 2326, 599, 377, 377, 787, 1123, 377, 377, 377, - 377, 377, 377, 596, 377, 377, 377, 377, 785, 377, - 1729, 1730, 377, 377, 377, 595, 377, 779, 369, 369, - 780, 369, 2326, 2326, 1674, 2326, 787, 1123, 377, 377, - 2326, 2326, 2326, 463, 463, 377, 377, 591, 2326, 377, - 1124, 749, 749, 377, 2326, 2326, 2326, 384, 779, 1131, - 1132, 780, 578, 929, 929, 749, 749, 1102, 910, 910, - - 2326, 384, 377, 377, 930, 1136, 377, 377, 377, 579, - 377, 1124, 576, 377, 384, 384, 384, 575, 384, 1137, - 1131, 1132, 2326, 2326, 2326, 972, 572, 793, 384, 384, - 384, 571, 384, 749, 749, 930, 1136, 377, 377, 384, - 2326, 2326, 2326, 377, 377, 384, 1107, 915, 915, 491, - 1137, 749, 749, 1116, 926, 926, 972, 384, 793, 384, - 395, 2326, 2326, 2326, 377, 377, 384, 384, 384, 377, - 384, 1120, 243, 1120, 377, 377, 1121, 1121, 2326, 1103, - 377, 377, 758, 243, 384, 384, 384, 241, 384, 1138, - 759, 377, 1681, 2326, 1129, 939, 939, 384, 241, 766, - - 767, 2326, 1139, 377, 377, 2326, 377, 768, 1140, 2326, - 1239, 1797, 1798, 758, 377, 384, 396, 2326, 397, 397, - 1138, 759, 377, 2326, 781, 377, 377, 1240, 1108, 398, - 766, 767, 770, 1139, 771, 1117, 377, 2326, 768, 1140, - 973, 1239, 377, 772, 2326, 377, 492, 377, 492, 1229, - 773, 2326, 2326, 377, 377, 781, 2326, 1231, 1240, 2326, - 398, 377, 377, 770, 776, 771, 2326, 377, 782, 1700, - 2326, 973, 377, 377, 772, 777, 1130, 492, 377, 492, - 1229, 773, 783, 378, 379, 380, 381, 382, 382, 382, - 382, 382, 382, 383, 2326, 776, 377, 377, 2326, 782, - - 377, 377, 2326, 377, 377, 377, 777, 377, 1729, 2326, - 1241, 377, 2326, 783, 2326, 377, 2326, 786, 377, 377, - 788, 1797, 2326, 2326, 784, 377, 377, 2326, 789, 377, - 2326, 2326, 2326, 1242, 377, 377, 377, 2326, 377, 377, - 377, 1241, 377, 790, 791, 377, 377, 2326, 786, 1149, - 377, 788, 792, 377, 796, 784, 794, 2326, 795, 789, - 377, 1134, 943, 943, 1242, 2326, 2326, 377, 377, 377, - 2326, 2326, 2326, 983, 790, 791, 377, 2326, 377, 377, - 1149, 377, 2326, 792, 377, 796, 2326, 794, 2326, 795, - 377, 377, 797, 2326, 2326, 377, 377, 798, 2326, 2326, - - 2326, 377, 377, 377, 983, 2326, 377, 377, 377, 377, - 377, 799, 2326, 377, 800, 2326, 1232, 2326, 377, 377, - 377, 2326, 2326, 797, 1243, 801, 492, 2326, 798, 802, - 377, 2326, 377, 2326, 985, 377, 377, 377, 2326, 377, - 377, 377, 799, 1135, 377, 800, 377, 1232, 2326, 377, - 2326, 377, 377, 377, 2326, 1243, 801, 492, 517, 803, - 802, 377, 518, 377, 806, 985, 2326, 2326, 377, 377, - 377, 519, 804, 1244, 1245, 520, 2326, 377, 2326, 807, - 377, 377, 377, 808, 954, 751, 751, 2326, 377, 517, - 803, 377, 1150, 518, 377, 806, 2326, 2326, 377, 377, - - 1246, 819, 519, 804, 1244, 1245, 520, 377, 2326, 377, - 807, 377, 2326, 2326, 808, 2326, 814, 377, 377, 377, - 984, 377, 377, 1150, 809, 815, 377, 816, 377, 810, - 2326, 1246, 819, 2326, 2326, 377, 377, 811, 377, 812, - 377, 2326, 377, 377, 377, 813, 377, 814, 1247, 2326, - 820, 984, 377, 817, 377, 809, 815, 377, 816, 377, - 810, 818, 2326, 2326, 377, 377, 955, 2326, 811, 2326, - 812, 821, 2326, 377, 979, 377, 813, 377, 377, 1247, - 2326, 820, 377, 377, 817, 377, 2326, 377, 377, 377, - 822, 377, 818, 377, 2326, 2326, 377, 377, 2326, 377, - - 377, 377, 821, 824, 377, 979, 377, 377, 377, 377, - 978, 377, 823, 377, 2326, 826, 377, 377, 377, 2326, - 2326, 822, 377, 825, 377, 2326, 827, 377, 377, 828, - 377, 1248, 377, 377, 824, 2326, 2326, 1002, 377, 377, - 377, 978, 377, 823, 377, 377, 826, 986, 2326, 2326, - 377, 377, 2326, 2326, 825, 377, 377, 827, 377, 377, - 828, 829, 1248, 377, 377, 830, 377, 2326, 1002, 377, - 377, 377, 2326, 831, 377, 377, 377, 2326, 986, 832, - 377, 2326, 377, 377, 377, 377, 377, 2326, 2326, 2326, - 2326, 2326, 829, 833, 377, 2326, 830, 377, 2326, 2326, - - 835, 836, 836, 2326, 831, 2326, 2326, 455, 377, 377, - 832, 377, 2326, 377, 2326, 2326, 377, 377, 377, 377, - 988, 1249, 1235, 377, 833, 377, 2326, 2326, 2326, 2326, - 2326, 835, 492, 2326, 455, 455, 455, 836, 836, 2326, - 836, 836, 2326, 455, 2326, 2326, 455, 2326, 2326, 377, - 377, 988, 1249, 1235, 377, 836, 836, 2326, 485, 485, - 2326, 455, 2326, 492, 468, 455, 1230, 1251, 1252, 492, - 455, 455, 455, 455, 455, 455, 838, 838, 838, 838, - 838, 838, 838, 838, 838, 838, 838, 1253, 455, 455, - 455, 468, 468, 468, 840, 468, 2326, 1230, 1251, 1252, - - 492, 455, 2326, 2326, 455, 469, 470, 471, 472, 473, - 473, 473, 473, 473, 473, 474, 2326, 2326, 1253, 455, - 2326, 2326, 468, 2326, 2326, 840, 2326, 485, 485, 2326, - 2326, 2326, 2326, 468, 485, 485, 2326, 2326, 2326, 2326, - 468, 485, 485, 478, 478, 2326, 1266, 468, 1267, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 468, 468, 468, 974, 468, 377, 841, 468, 468, 468, - 377, 468, 1278, 1279, 468, 468, 468, 1266, 468, 1267, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 839, 2326, - 2326, 468, 2326, 2326, 974, 2326, 377, 841, 468, 2326, - - 842, 377, 2326, 1278, 1279, 468, 2326, 2326, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 839, - 469, 470, 471, 472, 473, 473, 473, 473, 473, 473, - 474, 842, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 843, 844, 845, 845, 845, 845, 845, - 845, 845, 845, 845, 845, 845, 2326, 2326, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 2326, - 2326, 2326, 2326, 2326, 843, 844, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 2326, 377, 990, 1089, 897, - - 897, 377, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 469, 470, 471, 472, 473, 473, 473, - 473, 473, 473, 474, 491, 491, 491, 377, 990, 2326, - 2326, 2326, 377, 2326, 2326, 493, 1283, 493, 494, 857, - 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, - 495, 496, 977, 497, 523, 931, 2326, 931, 2326, 989, - 932, 932, 498, 377, 499, 377, 500, 1283, 377, 377, - 377, 710, 1161, 377, 2326, 2326, 2326, 2326, 2326, 2326, - 1090, 495, 496, 977, 497, 2326, 858, 858, 2326, 2326, - 989, 2326, 524, 498, 377, 499, 377, 500, 539, 377, - - 377, 377, 710, 1161, 377, 501, 502, 503, 504, 505, - 505, 505, 505, 505, 505, 506, 2326, 2326, 2326, 524, - 524, 524, 377, 524, 2326, 1284, 377, 2326, 2326, 2326, - 494, 525, 526, 527, 528, 529, 529, 529, 529, 529, - 529, 530, 2326, 2326, 2326, 2326, 2326, 1166, 710, 710, - 524, 2326, 2326, 377, 858, 858, 1284, 377, 2326, 710, - 524, 532, 533, 534, 535, 536, 536, 536, 536, 536, - 536, 537, 540, 541, 542, 543, 544, 544, 544, 544, - 544, 544, 545, 1102, 910, 910, 2326, 524, 524, 524, - 710, 524, 1263, 1085, 1085, 2326, 1264, 501, 507, 503, - - 504, 505, 505, 505, 505, 505, 505, 506, 2326, 2326, - 2326, 1288, 377, 2326, 2326, 2326, 2326, 377, 524, 2326, - 2326, 2326, 2326, 1003, 521, 521, 2326, 2326, 2326, 2326, - 492, 377, 2326, 2326, 2326, 2326, 377, 995, 858, 858, - 2326, 2326, 1288, 377, 524, 858, 858, 2326, 377, 710, - 710, 524, 2326, 2326, 1003, 377, 377, 492, 492, 492, - 710, 492, 377, 558, 558, 1103, 2326, 377, 995, 531, - 936, 524, 524, 524, 1265, 524, 2326, 975, 524, 524, - 524, 976, 524, 2326, 377, 993, 377, 377, 492, 377, - 377, 710, 2326, 2326, 2326, 377, 531, 531, 531, 2326, - - 531, 936, 524, 2326, 558, 558, 2326, 2326, 975, 524, - 531, 2326, 976, 2326, 2326, 377, 993, 558, 558, 2326, - 377, 377, 1013, 531, 558, 558, 377, 531, 2326, 377, - 531, 2326, 2326, 2326, 377, 377, 377, 531, 531, 531, - 377, 531, 860, 860, 2326, 998, 2326, 377, 538, 377, - 531, 531, 531, 1013, 531, 2326, 2326, 531, 531, 531, - 377, 531, 1255, 1081, 1081, 377, 377, 377, 531, 1256, - 2326, 377, 2326, 2326, 2326, 538, 538, 538, 377, 538, - 377, 531, 377, 860, 860, 2326, 2326, 2326, 531, 538, - 2326, 2326, 2326, 2326, 2326, 2326, 860, 860, 2326, 2326, - - 710, 710, 538, 860, 860, 2326, 538, 2326, 980, 538, - 377, 710, 1001, 377, 377, 377, 538, 538, 538, 377, - 538, 981, 863, 377, 377, 1234, 935, 862, 377, 538, - 538, 538, 492, 538, 1293, 377, 538, 538, 538, 980, - 538, 377, 710, 1001, 1257, 377, 377, 538, 2326, 2326, - 377, 2326, 981, 863, 377, 377, 1234, 935, 862, 377, - 538, 2326, 551, 492, 2326, 1293, 377, 538, 532, 533, - 534, 535, 536, 536, 536, 536, 536, 536, 537, 532, - 533, 534, 535, 536, 536, 536, 536, 536, 536, 537, - 552, 553, 554, 555, 556, 556, 556, 556, 556, 556, - - 557, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 377, 377, 864, 864, 1308, 864, 864, 2326, 550, 864, - 864, 550, 2326, 2326, 2326, 550, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 864, 864, 2326, 2326, 653, 653, 550, - 2326, 377, 377, 638, 1297, 550, 550, 550, 550, 550, - 550, 377, 550, 550, 550, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 550, 550, 550, 377, - 638, 638, 638, 377, 638, 1297, 550, 2326, 2326, 550, - 2326, 2326, 377, 550, 532, 533, 534, 535, 536, 536, - 536, 536, 536, 536, 537, 2326, 2326, 550, 630, 630, - - 377, 638, 630, 630, 377, 2326, 630, 630, 630, 630, - 630, 630, 630, 630, 630, 902, 377, 630, 630, 630, - 630, 630, 639, 640, 641, 642, 643, 643, 643, 643, - 643, 643, 644, 908, 908, 908, 908, 908, 908, 908, - 908, 908, 908, 908, 2326, 2326, 902, 377, 630, 630, - 630, 2326, 630, 2326, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 639, 640, 641, 642, 643, - 643, 643, 643, 643, 643, 644, 1107, 915, 915, 630, - 632, 633, 634, 635, 636, 636, 636, 636, 636, 636, - 637, 630, 630, 2326, 2326, 630, 630, 630, 630, 630, - - 630, 630, 630, 630, 630, 630, 630, 630, 895, 895, - 630, 630, 630, 630, 630, 630, 377, 2326, 630, 630, - 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, - 630, 895, 895, 630, 630, 630, 630, 2326, 2326, 2326, - 2326, 2326, 710, 710, 2326, 2326, 2326, 377, 653, 653, - 2326, 2326, 2326, 710, 638, 653, 653, 2326, 1108, 2326, - 2326, 638, 653, 653, 2326, 2326, 2326, 937, 638, 675, - 676, 677, 678, 679, 679, 679, 679, 679, 679, 680, - 2326, 638, 638, 638, 710, 638, 2326, 2326, 638, 638, - 638, 903, 638, 1339, 1292, 638, 638, 638, 937, 638, - - 2326, 630, 630, 2326, 630, 2326, 2326, 2326, 2326, 904, - 377, 987, 638, 2326, 2326, 377, 377, 1000, 377, 638, - 905, 377, 903, 2326, 1339, 1292, 638, 2326, 2326, 639, - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 904, 377, 987, 2326, 906, 2326, 377, 377, 1000, 377, - 2326, 905, 377, 639, 640, 641, 642, 643, 643, 643, - 643, 643, 643, 644, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 906, 907, 377, 2326, 1340, - 1341, 1309, 2326, 2326, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 920, 920, 920, 920, 920, - - 920, 920, 920, 920, 920, 920, 2326, 907, 377, 917, - 1340, 1341, 639, 640, 641, 642, 643, 643, 643, 643, - 643, 643, 644, 666, 666, 2326, 2326, 666, 666, 2326, - 2326, 666, 666, 666, 666, 666, 666, 666, 666, 666, - 917, 918, 666, 666, 666, 666, 666, 675, 676, 677, - 678, 679, 679, 679, 679, 679, 679, 680, 675, 676, - 677, 678, 679, 679, 679, 679, 679, 679, 680, 2326, - 2326, 2326, 918, 666, 666, 666, 2326, 666, 2326, 2326, - 2326, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 690, 691, 692, 693, 694, 694, 694, 694, - - 694, 694, 695, 2326, 666, 668, 669, 670, 671, 672, - 672, 672, 672, 672, 672, 673, 666, 666, 2326, 2326, - 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 913, 913, 666, 666, 666, 666, 666, - 666, 1342, 2326, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 666, 666, 666, 913, 913, 666, 666, - 666, 666, 2326, 2326, 2326, 2326, 1116, 926, 926, 2326, - 2326, 2326, 1342, 685, 685, 2326, 2326, 2326, 1233, 674, - 685, 685, 2326, 2326, 2326, 1343, 674, 685, 685, 2326, - 2326, 2326, 492, 674, 922, 922, 922, 922, 922, 922, - - 922, 922, 922, 922, 922, 1236, 674, 674, 674, 1233, - 674, 2326, 1344, 674, 674, 674, 1343, 674, 919, 492, - 674, 674, 674, 492, 674, 2326, 666, 666, 2326, 666, - 2326, 2326, 2326, 2326, 377, 2326, 1236, 674, 2326, 377, - 1005, 685, 685, 1344, 674, 2326, 2326, 674, 1117, 919, - 492, 674, 1298, 2326, 675, 676, 677, 678, 679, 679, - 679, 679, 679, 679, 680, 377, 1295, 2326, 2326, 2326, - 377, 1005, 377, 377, 674, 674, 674, 2326, 674, 697, - 697, 2326, 2326, 1298, 994, 689, 377, 2326, 2326, 2326, - 2326, 377, 697, 697, 1337, 2326, 2326, 1295, 689, 1294, - - 697, 697, 2326, 377, 377, 674, 689, 2326, 2326, 1338, - 377, 377, 689, 689, 689, 994, 689, 377, 697, 697, - 2326, 2326, 377, 921, 689, 689, 689, 689, 377, 689, - 1294, 2326, 377, 689, 689, 689, 2326, 689, 2326, 2326, - 1338, 377, 377, 689, 2326, 2326, 2326, 1357, 1155, 1303, - 377, 689, 689, 689, 921, 689, 689, 2326, 2326, 377, - 1129, 939, 939, 377, 689, 377, 377, 690, 691, 692, - 693, 694, 694, 694, 694, 694, 694, 695, 1357, 1155, - 1303, 377, 689, 690, 691, 692, 693, 694, 694, 694, - 694, 694, 694, 695, 702, 702, 377, 377, 702, 702, - - 2326, 2326, 702, 702, 702, 702, 702, 702, 702, 702, - 702, 2326, 377, 702, 702, 702, 702, 702, 711, 712, - 713, 714, 715, 715, 715, 715, 715, 715, 716, 938, - 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, - 2326, 2326, 1130, 377, 702, 702, 702, 2326, 702, 950, - 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, - 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, - 951, 1134, 943, 943, 2326, 702, 704, 705, 706, 707, - 708, 708, 708, 708, 708, 708, 709, 702, 702, 361, - 2326, 702, 702, 702, 702, 702, 702, 702, 702, 702, - - 702, 702, 702, 702, 924, 924, 702, 702, 702, 702, - 702, 702, 377, 2326, 702, 702, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 702, 924, 924, 702, - 702, 702, 702, 2326, 2326, 2326, 2326, 1543, 1543, 1543, - 2326, 2326, 2326, 377, 727, 727, 2326, 2326, 2326, 1304, - 710, 727, 727, 1135, 2326, 2326, 377, 710, 727, 727, - 385, 2326, 2326, 377, 710, 377, 363, 364, 365, 366, - 367, 367, 367, 367, 367, 367, 368, 710, 710, 710, - 1304, 710, 2326, 492, 710, 710, 710, 377, 710, 757, - 757, 710, 710, 710, 377, 710, 377, 702, 702, 2326, - - 702, 2326, 2326, 2326, 1374, 2326, 2326, 2326, 710, 2326, - 2326, 2326, 727, 727, 492, 710, 2326, 2326, 710, 1544, - 2326, 1382, 710, 952, 952, 952, 952, 952, 952, 952, - 952, 952, 952, 952, 386, 387, 388, 389, 390, 390, - 390, 390, 390, 390, 391, 710, 710, 710, 2326, 710, - 961, 963, 1382, 2326, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 378, 379, 380, 381, 382, - 382, 382, 382, 382, 382, 383, 710, 720, 2326, 721, - 721, 961, 963, 2326, 962, 377, 377, 1383, 1007, 377, - 722, 377, 378, 379, 380, 381, 382, 382, 382, 382, - - 382, 382, 383, 2326, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 962, 377, 377, 1383, 1007, - 377, 722, 377, 2326, 2326, 2326, 1385, 1387, 2326, 2326, - 964, 378, 379, 380, 381, 382, 382, 382, 382, 382, - 382, 383, 965, 2326, 711, 712, 713, 714, 715, 715, - 715, 715, 715, 715, 716, 369, 369, 1385, 1387, 369, - 369, 964, 2326, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 1388, 965, 369, 369, 369, 369, 369, 968, - 378, 379, 380, 381, 382, 382, 382, 382, 382, 382, - 383, 966, 378, 379, 380, 381, 382, 382, 382, 382, - - 382, 382, 383, 1388, 2326, 369, 369, 369, 2326, 369, - 968, 2326, 2326, 2326, 2326, 2326, 2326, 967, 2326, 2326, - 2326, 2326, 966, 2326, 2326, 378, 379, 380, 381, 382, - 382, 382, 382, 382, 382, 383, 369, 371, 372, 373, - 374, 375, 375, 375, 375, 375, 375, 376, 967, 378, - 379, 380, 381, 382, 382, 382, 382, 382, 382, 383, - 2326, 2326, 2326, 2326, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 969, 1390, 997, 2326, 2326, - 970, 2326, 377, 2326, 2326, 1392, 2326, 377, 1042, 1042, - 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 2326, - - 991, 992, 2326, 996, 2326, 1393, 969, 1390, 997, 377, - 377, 970, 377, 377, 377, 377, 1392, 377, 377, 2326, - 378, 379, 380, 381, 382, 382, 382, 382, 382, 382, - 383, 991, 992, 377, 996, 999, 1393, 1009, 377, 2326, - 377, 377, 377, 377, 1004, 377, 377, 377, 377, 1006, - 1008, 2326, 1394, 377, 1010, 377, 377, 377, 377, 1012, - 377, 377, 377, 2326, 377, 377, 999, 1011, 1009, 377, - 377, 2326, 1014, 377, 377, 1004, 2326, 377, 377, 377, - 1006, 1008, 377, 1394, 377, 1010, 377, 377, 377, 377, - 1012, 377, 377, 377, 377, 1015, 377, 2326, 1011, 377, - - 1016, 377, 377, 1014, 377, 377, 377, 377, 377, 377, - 377, 377, 1017, 377, 1019, 1020, 1020, 1020, 1028, 377, - 1018, 1023, 2326, 377, 377, 377, 1015, 377, 377, 1029, - 377, 1016, 377, 377, 377, 377, 1022, 377, 377, 2326, - 377, 1396, 377, 1017, 1397, 1019, 1026, 2326, 377, 1028, - 377, 377, 1023, 377, 377, 377, 377, 1175, 377, 377, - 1029, 377, 1027, 377, 377, 377, 2326, 1022, 1024, 377, - 1025, 377, 1396, 1030, 2326, 1397, 377, 1026, 377, 377, - 377, 1031, 377, 1032, 377, 377, 2326, 377, 1175, 377, - 1033, 1035, 377, 1027, 377, 377, 377, 1021, 2326, 1024, - - 377, 1025, 377, 377, 1030, 1037, 2326, 377, 377, 377, - 377, 377, 1031, 377, 1032, 377, 377, 1034, 377, 377, - 377, 1033, 1035, 1038, 377, 377, 1036, 377, 377, 1041, - 492, 492, 1375, 1039, 377, 377, 1037, 1040, 377, 377, - 377, 377, 2326, 2326, 377, 456, 377, 2326, 1034, 377, - 377, 2326, 1377, 1043, 1038, 377, 2326, 1036, 2326, 377, - 1041, 492, 492, 1375, 1039, 2326, 377, 1044, 1040, 377, - 2326, 377, 2326, 457, 458, 459, 460, 461, 461, 461, - 461, 461, 461, 462, 1043, 2326, 469, 470, 471, 472, - 473, 473, 473, 473, 473, 473, 474, 2326, 1044, 2326, - - 2326, 1045, 1046, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - 1060, 1060, 1060, 1060, 1263, 1085, 1085, 2326, 1264, 2326, - 2326, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 1045, 1046, 2326, 2326, 2326, 1047, 2326, 2326, - 2326, 2326, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 523, 2326, 2326, 2326, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 1047, 1048, - 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, - 1061, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 539, 2326, 2326, 2326, 1265, 2326, 1306, 2326, - - 1048, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, - 1064, 1064, 1178, 1398, 1062, 377, 377, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 494, 1306, - 525, 526, 527, 528, 529, 529, 529, 529, 529, 529, - 530, 2326, 2326, 1178, 1398, 1062, 377, 377, 1420, 1424, - 1425, 2326, 1049, 532, 533, 534, 535, 536, 536, 536, - 536, 536, 536, 537, 2326, 2326, 540, 541, 542, 543, - 544, 544, 544, 544, 544, 544, 545, 1063, 377, 1420, - 1424, 1425, 377, 1049, 1087, 1087, 1087, 1087, 1087, 1087, - 1087, 1087, 1087, 1087, 1087, 501, 507, 503, 504, 505, - - 505, 505, 505, 505, 505, 506, 494, 551, 1063, 377, - 2326, 2326, 2326, 377, 2326, 1050, 1094, 2326, 2326, 1099, - 2326, 2326, 2326, 2326, 532, 533, 534, 535, 536, 536, - 536, 536, 536, 536, 537, 552, 553, 554, 555, 556, - 556, 556, 556, 556, 556, 557, 1050, 1094, 639, 640, - 641, 642, 643, 643, 643, 643, 643, 643, 644, 377, - 639, 640, 641, 642, 643, 643, 643, 643, 643, 643, - 644, 1095, 2326, 501, 507, 503, 504, 505, 505, 505, - 505, 505, 505, 506, 630, 630, 2326, 2326, 630, 630, - 377, 2326, 630, 630, 630, 630, 630, 630, 630, 630, - - 630, 1096, 1095, 630, 630, 630, 630, 630, 377, 1162, - 377, 1310, 377, 377, 377, 1153, 639, 640, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 1097, 377, 377, - 377, 377, 1096, 2326, 630, 630, 630, 2326, 630, 377, - 1162, 377, 1310, 377, 377, 377, 1153, 639, 640, 641, - 642, 643, 643, 643, 643, 643, 643, 644, 1097, 377, - 377, 377, 377, 2326, 1098, 630, 632, 633, 634, 635, - 636, 636, 636, 636, 636, 636, 637, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 1098, 2326, 377, 2326, 2326, - - 377, 1180, 2326, 639, 640, 641, 642, 643, 643, 643, - 643, 643, 643, 644, 1105, 1105, 1105, 1105, 1105, 1105, - 1105, 1105, 1105, 1105, 1105, 666, 666, 1111, 377, 666, - 666, 377, 1180, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 1109, 2326, 666, 666, 666, 666, 666, 377, - 1176, 377, 1317, 377, 1322, 377, 675, 676, 677, 678, - 679, 679, 679, 679, 679, 679, 680, 2326, 1168, 377, - 1184, 377, 1112, 1109, 377, 666, 666, 666, 2326, 666, - 377, 1176, 377, 1317, 377, 1322, 377, 675, 676, 677, - 678, 679, 679, 679, 679, 679, 679, 680, 1110, 1168, - - 377, 1184, 377, 1112, 1452, 377, 666, 668, 669, 670, - 671, 672, 672, 672, 672, 672, 672, 673, 690, 691, - 692, 693, 694, 694, 694, 694, 694, 694, 695, 1110, - 932, 932, 2326, 2326, 1143, 1452, 2326, 675, 676, 677, - 678, 679, 679, 679, 679, 679, 679, 680, 1114, 1114, - 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 702, - 702, 2326, 2326, 702, 702, 1143, 2326, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 1125, 1305, 702, 702, - 702, 702, 702, 377, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 711, 712, 713, 714, 715, - - 715, 715, 715, 715, 715, 716, 1126, 1125, 1305, 702, - 702, 702, 2326, 702, 377, 2326, 2326, 2326, 2326, 2326, - 711, 712, 713, 714, 715, 715, 715, 715, 715, 715, - 716, 1259, 1083, 1083, 2326, 2326, 2326, 1126, 1260, 2326, - 702, 704, 705, 706, 707, 708, 708, 708, 708, 708, - 708, 709, 1127, 377, 377, 377, 1296, 377, 377, 377, - 1186, 2326, 2326, 711, 712, 713, 714, 715, 715, 715, - 715, 715, 715, 716, 1141, 1185, 377, 1187, 1172, 377, - 377, 377, 2326, 1127, 377, 377, 377, 1296, 377, 377, - 377, 1186, 711, 712, 713, 714, 715, 715, 715, 715, - - 715, 715, 716, 1142, 1453, 1141, 1185, 377, 1187, 2326, - 377, 377, 377, 1261, 2326, 378, 379, 380, 381, 382, - 382, 382, 382, 382, 382, 383, 1144, 1193, 377, 377, - 492, 1145, 1192, 377, 1142, 1453, 2326, 378, 379, 380, - 381, 382, 382, 382, 382, 382, 382, 383, 2326, 2326, - 2326, 1380, 2326, 2326, 2326, 2326, 1146, 1144, 1193, 377, - 377, 492, 1145, 1192, 377, 378, 379, 380, 381, 382, - 382, 382, 382, 382, 382, 383, 378, 379, 380, 381, - 382, 382, 382, 382, 382, 382, 383, 1146, 1255, 1081, - 1081, 2326, 2326, 2326, 2326, 1256, 2326, 378, 379, 380, - - 381, 382, 382, 382, 382, 382, 382, 383, 378, 379, - 380, 381, 382, 382, 382, 382, 382, 382, 383, 1147, - 377, 377, 1154, 1148, 377, 377, 377, 377, 377, 1160, - 377, 377, 377, 377, 1208, 1151, 1152, 377, 377, 2326, - 1157, 1158, 1259, 1083, 1083, 2326, 2326, 2326, 2326, 1260, - 1147, 377, 377, 1154, 1148, 377, 377, 377, 377, 377, - 1160, 377, 377, 377, 377, 1208, 1151, 1152, 377, 377, - 1257, 1157, 1158, 378, 379, 380, 381, 382, 382, 382, - 382, 382, 382, 383, 377, 377, 377, 377, 377, 377, - 377, 377, 377, 2326, 377, 1459, 377, 1164, 377, 1156, - - 377, 1159, 1163, 1165, 377, 1167, 2326, 2326, 2326, 377, - 1170, 1170, 1170, 1169, 2326, 377, 377, 377, 377, 377, - 377, 377, 377, 377, 1261, 377, 1459, 377, 1164, 377, - 1156, 377, 1159, 1163, 1165, 377, 1167, 377, 377, 377, - 377, 377, 377, 377, 1169, 377, 2326, 377, 2326, 377, - 1174, 377, 2326, 1173, 2326, 1177, 1181, 1181, 1181, 1183, - 1179, 2326, 2326, 377, 2326, 377, 2326, 377, 377, 377, - 377, 377, 377, 377, 377, 377, 377, 1299, 377, 1188, - 377, 1174, 377, 377, 1173, 1189, 1177, 377, 377, 377, - 1183, 1179, 1171, 377, 377, 377, 377, 1191, 377, 377, - - 377, 1190, 377, 1194, 377, 377, 377, 2326, 1299, 377, - 1188, 2326, 2326, 2326, 377, 1329, 1189, 1210, 377, 377, - 377, 377, 377, 377, 377, 2326, 377, 377, 1191, 2326, - 377, 377, 1190, 2326, 1194, 377, 377, 1205, 1182, 2326, - 377, 1020, 1020, 1020, 2326, 2326, 1329, 2326, 1210, 1203, - 1203, 1203, 377, 377, 377, 463, 463, 2326, 377, 2326, - 377, 377, 1311, 1195, 377, 377, 1196, 1197, 1205, 377, - 377, 1461, 377, 377, 377, 1206, 377, 1198, 1199, 1200, - 377, 1207, 2326, 1201, 1211, 2326, 2326, 377, 377, 377, - 377, 377, 377, 1311, 2326, 377, 377, 1196, 1197, 2326, - - 377, 377, 1461, 377, 377, 377, 1206, 377, 1198, 1199, - 1200, 377, 1207, 377, 1201, 1211, 1209, 377, 377, 377, - 377, 1020, 1213, 1202, 377, 377, 1212, 2326, 377, 377, - 377, 1204, 377, 1218, 377, 1216, 377, 377, 1217, 377, - 377, 1214, 1219, 377, 377, 1215, 377, 1209, 377, 2326, - 377, 377, 1474, 1213, 377, 377, 377, 1212, 1220, 377, - 377, 377, 1222, 377, 1218, 377, 1216, 377, 377, 1217, - 377, 377, 1214, 1219, 377, 377, 1215, 377, 1221, 377, - 377, 377, 377, 1474, 377, 377, 2326, 2326, 2326, 1220, - 2326, 2326, 2326, 1222, 2326, 2326, 1223, 2326, 1475, 1476, - - 2326, 2326, 2326, 1813, 1813, 1813, 377, 2326, 2326, 1221, - 377, 377, 1224, 377, 1477, 377, 469, 470, 471, 472, - 473, 473, 473, 473, 473, 473, 474, 1223, 1225, 1475, - 1476, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 1226, 1224, 2326, 1477, 469, 470, 471, 472, - 473, 473, 473, 473, 473, 473, 474, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 494, 1237, - 2326, 2326, 1227, 1226, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 1814, 2326, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 532, 533, - - 534, 535, 536, 536, 536, 536, 536, 536, 537, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 1300, 1313, 638, - 1238, 1323, 1318, 1328, 377, 377, 1358, 2326, 1324, 1269, - 377, 377, 377, 377, 377, 501, 507, 503, 504, 505, - 505, 505, 505, 505, 505, 506, 494, 2326, 1300, 1313, - 2326, 1238, 1323, 1318, 1328, 377, 377, 1358, 2326, 1324, - 1269, 377, 377, 377, 377, 377, 1276, 1376, 1479, 1270, - 1483, 1484, 492, 1228, 532, 533, 534, 535, 536, 536, - 536, 536, 536, 536, 537, 639, 640, 641, 642, 643, - 643, 643, 643, 643, 643, 644, 640, 2326, 1376, 1479, - - 1270, 1483, 1484, 492, 1228, 2326, 2326, 1481, 1487, 2326, - 1482, 2326, 2326, 501, 507, 503, 504, 505, 505, 505, - 505, 505, 505, 506, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 1271, 1271, 1271, 1481, 1487, - 1272, 1482, 1301, 1307, 1302, 2326, 2326, 2326, 1273, 1312, - 638, 2326, 2326, 2326, 1281, 2326, 638, 2326, 2326, 2326, - 2326, 2326, 2326, 377, 2326, 377, 2326, 377, 1275, 1488, - 377, 1325, 1336, 1301, 1307, 1302, 1277, 377, 377, 1280, - 1312, 2326, 2326, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 377, 2326, 377, 1282, 377, 1275, - - 1488, 377, 1325, 1336, 1823, 1823, 1823, 1277, 377, 377, - 1280, 1181, 1181, 1181, 2326, 1489, 639, 1274, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 640, 1282, 2326, - 2326, 2326, 2326, 640, 675, 676, 677, 678, 679, 679, - 679, 679, 679, 679, 680, 1285, 1489, 1490, 1491, 1326, - 2326, 2326, 2326, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 690, 691, 692, 693, 694, 694, - 694, 694, 694, 694, 695, 2326, 1285, 2326, 1490, 1491, - 1326, 1286, 1334, 1365, 1335, 1367, 1824, 2326, 2326, 1492, - 377, 1379, 492, 1327, 377, 377, 492, 377, 1378, 1493, - - 1287, 711, 712, 713, 714, 715, 715, 715, 715, 715, - 715, 716, 1286, 1334, 1365, 1335, 1367, 1319, 1319, 1319, - 1492, 377, 1379, 492, 2326, 377, 377, 492, 377, 1378, - 1493, 1287, 1320, 2326, 2326, 1170, 1170, 1170, 2326, 711, - 712, 713, 714, 715, 715, 715, 715, 715, 715, 716, - 711, 712, 713, 714, 715, 715, 715, 715, 715, 715, - 716, 1289, 1289, 1289, 1314, 377, 1330, 1331, 2326, 1333, - 1332, 1359, 2326, 1315, 1813, 1813, 1813, 2326, 1360, 2326, - 1361, 1494, 377, 1432, 1366, 1362, 2326, 377, 377, 1363, - 377, 377, 377, 377, 377, 1314, 377, 1330, 1331, 1321, - - 1333, 1332, 1359, 377, 1315, 377, 377, 1364, 377, 1360, - 377, 1361, 1494, 377, 1432, 1366, 1362, 1316, 377, 377, - 1363, 377, 377, 377, 377, 377, 1368, 1446, 377, 377, - 377, 1289, 1289, 1289, 377, 377, 377, 377, 1364, 377, - 2326, 377, 378, 1290, 380, 381, 382, 382, 382, 382, - 382, 382, 383, 2326, 2326, 2326, 1814, 1368, 1446, 377, - 377, 377, 1370, 1467, 377, 1507, 377, 492, 377, 1429, - 2326, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 1370, 1467, 377, 1507, 2326, 492, 377, - - 1429, 1291, 532, 533, 534, 535, 536, 536, 536, 536, - 536, 536, 537, 1430, 2326, 2326, 2326, 2326, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 2326, - 2326, 2326, 1291, 1445, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 2326, 2326, 2326, 1369, 2326, - 2326, 2326, 2326, 2326, 1979, 1979, 1979, 1371, 377, 2326, - 1433, 463, 463, 2326, 1445, 2326, 377, 377, 1434, 1431, - 1435, 1437, 1443, 2326, 377, 492, 377, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 1371, 377, - 377, 1433, 377, 377, 377, 377, 377, 377, 377, 1434, - - 1431, 1435, 1437, 1443, 1381, 377, 492, 377, 1512, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 1399, 377, 2326, 377, 377, 377, 2326, 1170, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 1381, 1980, 2326, 2326, 1512, - 2326, 2326, 2326, 2326, 463, 463, 2326, 2326, 2326, 1514, - 377, 1399, 532, 533, 534, 535, 536, 536, 536, 536, - 536, 536, 537, 1400, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 2326, 1444, 377, 377, 377, - 1514, 377, 2326, 2326, 2326, 1509, 2326, 1515, 377, 2326, - 1510, 1447, 639, 640, 641, 642, 643, 643, 643, 643, - - 643, 643, 644, 377, 1271, 1271, 1271, 1444, 377, 1401, - 1181, 1203, 1203, 1203, 2326, 2326, 1509, 1273, 1515, 377, - 1436, 1510, 1447, 1438, 1442, 653, 653, 1849, 1849, 1849, - 1402, 638, 1501, 1516, 377, 1454, 1345, 1346, 1347, 1348, - 1349, 1850, 1350, 377, 1351, 377, 377, 377, 377, 1352, - 2326, 1436, 1353, 1354, 1438, 1442, 1355, 1519, 638, 638, - 638, 1402, 638, 1501, 1516, 2326, 1454, 1345, 1346, 1347, - 1348, 1349, 1417, 1350, 377, 1351, 377, 377, 377, 377, - 1352, 1418, 1520, 1353, 1354, 2326, 1403, 1355, 1519, 638, - 2326, 1271, 2326, 1356, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 1417, 2326, 2326, 2326, 2326, 2326, 1851, - 463, 463, 1418, 1520, 2326, 1419, 377, 1521, 2326, 639, - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 2326, 639, 640, 641, 642, 643, 643, 643, 643, 643, - 643, 644, 1422, 377, 377, 377, 1419, 377, 1521, 1421, - 2326, 2326, 2326, 2326, 2326, 2326, 1439, 1439, 1439, 639, - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 2326, 1440, 1423, 1422, 377, 1522, 1203, 494, 675, 676, - 677, 678, 679, 679, 679, 679, 679, 679, 680, 2326, - 2326, 2326, 675, 676, 677, 678, 679, 679, 679, 679, - - 679, 679, 680, 1423, 377, 1372, 1522, 2326, 1523, 1524, - 1525, 2326, 1426, 1981, 1981, 1981, 675, 676, 677, 678, - 679, 679, 679, 679, 679, 679, 680, 1449, 1449, 1449, - 2326, 2326, 640, 2326, 2326, 377, 1372, 1427, 1441, 1523, - 1524, 1525, 1450, 1426, 501, 507, 503, 504, 505, 505, - 505, 505, 505, 505, 506, 494, 711, 712, 713, 714, - 715, 715, 715, 715, 715, 715, 716, 1428, 1427, 1448, - 1458, 1526, 1373, 1496, 1527, 377, 377, 377, 2326, 377, - 2326, 2326, 2326, 2326, 711, 712, 713, 714, 715, 715, - 715, 715, 715, 715, 716, 1982, 2326, 2326, 1428, 2326, - - 1448, 1458, 1526, 1373, 1496, 1527, 377, 377, 377, 1451, - 377, 711, 712, 713, 714, 715, 715, 715, 715, 715, - 715, 716, 501, 507, 503, 504, 505, 505, 505, 505, - 505, 505, 506, 1404, 1405, 1271, 1271, 1404, 1404, 1406, - 1407, 1404, 1404, 1404, 1404, 1404, 1404, 1408, 1404, 1404, - 1407, 1407, 1404, 1404, 1404, 1404, 1404, 1407, 1407, 1407, - 1409, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, - 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, - 1407, 1407, 1407, 1404, 1404, 1404, 1407, 1404, 1407, 1407, - 1407, 1409, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, - - 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, - 1407, 1407, 1407, 1407, 1404, 1410, 1411, 1412, 1413, 1414, - 1414, 1414, 1414, 1414, 1414, 1415, 2326, 2326, 2326, 2326, - 1455, 2326, 2326, 1460, 1319, 1319, 1319, 1462, 1463, 1464, - 1465, 1466, 463, 463, 2326, 2326, 2326, 377, 377, 1320, - 377, 1495, 1500, 2326, 1528, 1505, 377, 1534, 377, 492, - 377, 1455, 377, 377, 1460, 1468, 1468, 1468, 1462, 1463, - 1464, 1465, 1466, 377, 377, 377, 377, 377, 377, 377, - 1469, 377, 1495, 1500, 1485, 1528, 1505, 377, 1534, 377, - 492, 377, 2326, 377, 377, 1471, 1486, 1536, 2326, 1472, - - 1473, 1502, 2326, 2326, 377, 377, 377, 1517, 1289, 1497, - 1497, 1497, 1518, 377, 1550, 1485, 1456, 2326, 2326, 2326, - 377, 2326, 2326, 2326, 1498, 1508, 1471, 1486, 1536, 492, - 1472, 1473, 1502, 463, 463, 2326, 2326, 2326, 1517, 377, - 2326, 2326, 2326, 1518, 377, 1550, 2326, 1470, 2326, 2326, - 2326, 377, 1506, 1551, 1511, 1554, 1508, 377, 492, 377, - 492, 1503, 492, 2326, 377, 377, 377, 377, 377, 2326, - 377, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 1504, 1506, 1551, 1511, 1554, 2326, 377, 492, - 377, 1499, 1503, 492, 1513, 377, 377, 377, 2326, 1319, - - 469, 470, 471, 472, 473, 473, 473, 473, 473, 473, - 474, 2326, 377, 1504, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 1513, 469, 470, 471, 472, - 473, 473, 473, 473, 473, 473, 474, 1529, 2326, 2326, - 2326, 1555, 1558, 377, 1557, 1561, 377, 377, 532, 533, - 534, 535, 536, 536, 536, 536, 536, 536, 537, 2326, - 2326, 2326, 2326, 1530, 2326, 377, 377, 377, 1529, 1405, - 1271, 1271, 1555, 1558, 1531, 1557, 1561, 377, 377, 2326, - 2326, 2326, 1408, 639, 640, 641, 642, 643, 643, 643, - 643, 643, 643, 644, 1530, 1532, 377, 377, 377, 2326, - - 2326, 377, 1556, 2326, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 1405, 1271, 1271, 2326, 377, - 1531, 2326, 1405, 1271, 1271, 1568, 1532, 1531, 1408, 1405, - 1271, 1271, 377, 1556, 1531, 1408, 1562, 1439, 1439, 1439, - 1569, 1532, 1535, 1563, 1405, 1271, 1271, 2326, 1532, 1531, - 377, 1533, 1440, 1564, 377, 1532, 1568, 1408, 1565, 377, - 1537, 1537, 1570, 377, 2326, 2326, 2326, 1562, 377, 377, - 1532, 1569, 1532, 2326, 1563, 377, 1571, 1576, 377, 1532, - 1449, 1449, 1449, 377, 1564, 377, 1532, 377, 2326, 1565, - 377, 377, 2326, 1570, 377, 1450, 1545, 1533, 2326, 377, - - 377, 1532, 2326, 2326, 1533, 2326, 377, 1571, 1576, 377, - 2326, 1533, 1531, 1404, 377, 2326, 2326, 2326, 377, 1559, - 2326, 377, 377, 1537, 1537, 2326, 1533, 1545, 1546, 1407, - 639, 640, 641, 642, 643, 643, 643, 643, 643, 643, - 644, 639, 640, 641, 642, 643, 643, 643, 643, 643, - 643, 644, 377, 1587, 1588, 1589, 1407, 1407, 1407, 1546, - 1407, 2326, 1566, 2326, 2326, 2326, 639, 640, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 1987, 1987, 1987, - 2040, 2040, 2040, 2326, 1587, 1588, 1589, 1407, 1407, 1538, - 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1404, - - 1405, 1271, 1271, 1404, 1404, 1531, 1404, 1404, 1404, 1404, - 1404, 1404, 1404, 1408, 1404, 1404, 1537, 1537, 1404, 1404, - 1404, 1404, 1547, 1590, 1591, 1592, 1541, 711, 712, 713, - 714, 715, 715, 715, 715, 715, 715, 716, 2326, 2326, - 2326, 2326, 2326, 2326, 1593, 1548, 2326, 1594, 1595, 1596, - 1597, 2326, 1598, 1547, 1590, 1591, 1592, 1541, 2326, 1988, - 2326, 2326, 2041, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 1549, 1593, 1548, 1552, 1594, 1595, - 1596, 1597, 1542, 1598, 2326, 2326, 1404, 1404, 2326, 1404, - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - - 680, 2326, 2326, 1553, 2326, 1549, 1599, 1600, 1552, 1601, - 1602, 1603, 675, 676, 677, 678, 679, 679, 679, 679, - 679, 679, 680, 711, 712, 713, 714, 715, 715, 715, - 715, 715, 715, 716, 1553, 1575, 2326, 1599, 1600, 1604, - 1601, 1602, 1603, 1605, 2326, 2326, 377, 1580, 711, 712, - 713, 714, 715, 715, 715, 715, 715, 715, 716, 2326, - 2326, 2326, 377, 1606, 2326, 2326, 1575, 1577, 1577, 1577, - 1604, 1581, 1607, 1608, 1605, 463, 463, 377, 1580, 2326, - 2326, 377, 1578, 377, 2326, 1609, 1610, 2326, 377, 1611, - 2326, 2326, 377, 377, 1606, 377, 1468, 1468, 1468, 1628, - - 1612, 2326, 1581, 1607, 1608, 2326, 2326, 492, 377, 377, - 377, 1469, 377, 2326, 377, 377, 1609, 1610, 1582, 377, - 1611, 377, 1583, 377, 1615, 1616, 377, 2326, 1620, 1617, - 1628, 1612, 377, 2326, 1584, 1497, 1497, 1497, 492, 377, - 1630, 1439, 2326, 2326, 2326, 377, 377, 2326, 2326, 1579, - 1498, 2326, 377, 1583, 2326, 1615, 1616, 2326, 463, 463, - 1617, 2326, 2326, 377, 377, 1584, 492, 1631, 1621, 1624, - 1632, 1630, 2326, 492, 492, 1619, 377, 492, 1585, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 1622, 377, 377, 377, 2326, 377, 2326, 492, 1631, 1621, - - 1624, 1632, 1623, 1618, 492, 492, 1619, 492, 492, 1625, - 2326, 2326, 1633, 1634, 492, 2326, 2326, 1613, 2326, 2326, - 2326, 1622, 377, 2326, 1449, 2326, 2326, 2326, 1635, 1636, - 2326, 2326, 1626, 1623, 1618, 1637, 1638, 492, 492, 1639, - 1625, 463, 463, 1633, 1634, 492, 1627, 377, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 1635, - 1636, 1640, 1641, 1626, 1642, 1646, 1637, 1638, 492, 1650, - 1639, 1536, 1665, 1666, 377, 377, 377, 1627, 377, 2326, - 532, 533, 534, 535, 536, 536, 536, 536, 536, 536, - 537, 1643, 1640, 1641, 2326, 1642, 1646, 1668, 1669, 2326, - - 1650, 377, 1536, 1665, 1666, 377, 2326, 1468, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 1672, 1644, 377, - 1683, 1684, 1643, 377, 463, 463, 2326, 2326, 1668, 1669, - 377, 2326, 377, 2326, 2326, 2326, 2326, 639, 640, 641, - 642, 643, 643, 643, 643, 643, 643, 644, 1672, 1644, - 377, 1683, 1684, 2326, 377, 2326, 1685, 377, 377, 377, - 1692, 377, 639, 640, 641, 642, 643, 643, 643, 643, - 643, 643, 644, 1405, 1271, 1271, 2326, 377, 1531, 1405, - 1271, 1271, 2326, 2326, 1531, 2326, 1408, 1685, 377, 1670, - 1497, 1692, 1408, 1405, 1271, 1271, 377, 2326, 1531, 1532, - - 377, 1696, 1647, 1648, 1648, 1532, 1408, 1531, 377, 2326, - 1676, 1405, 1271, 1271, 1671, 1535, 1531, 1695, 1677, 1532, - 1670, 377, 1645, 377, 1408, 377, 377, 377, 1532, 2326, - 1532, 377, 1696, 2326, 1678, 1679, 1532, 1532, 1655, 1648, - 1648, 1676, 1697, 1656, 2326, 1671, 377, 377, 1695, 1677, - 1532, 1657, 377, 1645, 377, 1533, 377, 377, 1698, 1532, - 1660, 1533, 2326, 1703, 1658, 1678, 1679, 2326, 1532, 2326, - 2326, 2326, 2326, 1697, 2326, 1539, 2326, 377, 377, 2326, - 2326, 1661, 2326, 1705, 1649, 1405, 1271, 1271, 1708, 1698, - 1531, 1660, 2326, 1539, 1703, 1658, 2326, 2326, 1408, 2326, - - 639, 640, 641, 642, 643, 643, 643, 643, 643, 643, - 644, 1532, 1661, 1663, 1705, 2326, 1709, 1710, 1711, 1708, - 1659, 1688, 1688, 1688, 2326, 2326, 639, 640, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 2326, 2326, 2326, - 2326, 2326, 1532, 2326, 1663, 2326, 1662, 1709, 1710, 1711, - 1712, 1689, 1713, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 2326, 2326, 1651, 1652, 1651, 1651, - 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1662, 1664, 1686, - 1714, 1712, 1689, 1713, 1715, 1716, 1717, 377, 1667, 1718, - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - - 680, 2326, 2326, 1690, 2326, 2326, 1577, 1577, 1577, 1664, - 1686, 1714, 2326, 2326, 2326, 1715, 1716, 1717, 377, 1667, - 1718, 1578, 2326, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 711, 712, 713, 714, 715, 715, - 715, 715, 715, 715, 716, 711, 712, 713, 714, 715, - 715, 715, 715, 715, 715, 716, 1691, 2326, 1706, 1719, - 1720, 1721, 1722, 1724, 1725, 1726, 377, 1727, 377, 2326, - 2326, 2326, 377, 1731, 2326, 2326, 1707, 377, 1732, 1735, - 377, 492, 492, 1723, 377, 2326, 2326, 1691, 1693, 1706, - 1719, 1720, 1721, 1722, 1724, 1725, 1726, 377, 1727, 377, - - 2326, 2326, 2326, 377, 1731, 2326, 2326, 1707, 377, 1732, - 1735, 377, 492, 492, 1723, 377, 463, 463, 2326, 2326, - 2326, 1733, 377, 492, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 1943, 1943, 1943, 2326, 2326, - 2326, 492, 492, 492, 1734, 492, 1736, 1738, 1739, 377, - 377, 377, 1733, 377, 492, 1944, 2326, 2326, 2326, 2326, - 2326, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 492, 492, 492, 1740, 492, 1736, 1738, 1739, - 377, 1742, 1577, 532, 533, 534, 535, 536, 536, 536, - 536, 536, 536, 537, 1743, 1744, 1745, 1746, 1747, 1749, - - 1757, 2326, 1770, 2326, 2326, 2326, 1740, 2326, 2326, 1868, - 1868, 1868, 1742, 2326, 2326, 1771, 2326, 2019, 2326, 1751, - 1648, 1648, 2326, 1869, 1752, 1743, 1744, 1745, 1746, 1747, - 1749, 1757, 1753, 1770, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 1754, 1771, 639, 640, 641, - 642, 643, 643, 643, 643, 643, 643, 644, 1405, 1271, - 1271, 2326, 2326, 1531, 1655, 1648, 1648, 2326, 2326, 1656, - 2326, 1408, 2326, 1405, 1271, 1271, 1754, 1657, 1531, 2326, - 1773, 1748, 2326, 377, 1532, 1774, 1408, 1405, 1271, 1271, - 1658, 1870, 1531, 1405, 1271, 1271, 2326, 377, 1531, 1532, - - 1408, 1755, 2326, 1407, 1407, 1776, 1408, 377, 1788, 1407, - 1407, 1773, 1748, 1532, 377, 1532, 1774, 2326, 1789, 1532, - 2326, 1658, 1758, 1271, 1271, 2326, 377, 1656, 377, 2326, - 1532, 2326, 1655, 1648, 1648, 1657, 1776, 1656, 377, 1788, - 1533, 1775, 2326, 1794, 1532, 1657, 1659, 377, 1658, 1789, - 1532, 1760, 1271, 1271, 2326, 1756, 1752, 377, 1658, 2326, - 1758, 1271, 1271, 1781, 1753, 1656, 1778, 1778, 1778, 1533, - 377, 377, 1775, 1762, 1794, 1539, 1782, 1754, 377, 1658, - 1758, 1271, 1271, 2326, 2326, 1656, 1658, 1795, 2326, 1658, - 1758, 1271, 1271, 1657, 1781, 1656, 1779, 377, 1791, 2326, - - 2326, 377, 377, 1657, 1759, 1783, 1658, 1782, 1754, 1785, - 1785, 1785, 1790, 377, 1659, 377, 1658, 1658, 1795, 1765, - 377, 377, 2326, 1763, 1799, 1800, 1801, 1779, 377, 1791, - 1792, 1792, 1792, 1761, 1806, 1807, 1783, 1658, 1808, 1786, - 1809, 2326, 1759, 1790, 377, 1320, 377, 1658, 1780, 2326, - 1765, 377, 377, 1766, 1763, 1799, 1800, 1801, 1810, 1811, - 2326, 2326, 1759, 2326, 2326, 1806, 1807, 2326, 2326, 1808, - 1786, 1809, 1764, 639, 640, 641, 642, 643, 643, 643, - 643, 643, 643, 644, 1766, 1767, 1768, 1812, 1815, 1810, - 1811, 1787, 639, 640, 641, 642, 643, 643, 643, 643, - - 643, 643, 644, 1816, 1817, 1818, 1819, 1820, 2326, 2326, - 2326, 2326, 1793, 2326, 2326, 2326, 1767, 1768, 1812, 1815, - 1769, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 2326, 2326, 1816, 1817, 1818, 1819, 1820, 1772, - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - 680, 1769, 1688, 1688, 1688, 1803, 1803, 1803, 2326, 675, - 676, 677, 678, 679, 679, 679, 679, 679, 679, 680, - 1772, 1821, 1822, 1825, 1826, 1827, 1828, 1829, 1830, 1831, - 2326, 377, 1689, 1842, 1843, 1804, 1979, 1979, 1979, 711, - 712, 713, 714, 715, 715, 715, 715, 715, 715, 716, - - 1832, 1837, 1821, 1822, 1825, 1826, 1827, 1828, 1829, 1830, - 1831, 377, 377, 1689, 1842, 1843, 1804, 1834, 1834, 1834, - 1844, 1845, 1846, 1847, 2326, 2326, 1873, 1873, 1873, 2326, - 2326, 1832, 1837, 2326, 1690, 1838, 492, 1805, 1840, 1848, - 1841, 1440, 377, 492, 492, 1867, 1839, 1835, 1872, 377, - 377, 1844, 1845, 1846, 1847, 469, 470, 471, 472, 473, - 473, 473, 473, 473, 473, 474, 1838, 492, 1980, 1840, - 1848, 1841, 1853, 377, 492, 492, 1867, 1839, 1835, 1872, - 377, 377, 2326, 2326, 2326, 469, 470, 471, 472, 473, - 473, 473, 473, 473, 473, 474, 1854, 1875, 377, 1836, - - 377, 1879, 1880, 1853, 377, 2326, 2326, 2326, 1874, 2326, - 2326, 639, 640, 641, 642, 643, 643, 643, 643, 643, - 643, 644, 2326, 2326, 2326, 1881, 1884, 1854, 1875, 377, - 1889, 377, 1879, 1880, 1890, 2326, 639, 640, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 1405, 1271, 1271, - 2326, 2326, 1531, 1760, 1271, 1271, 1881, 1884, 1752, 2326, - 1408, 1889, 1751, 1648, 1648, 1890, 1753, 1752, 1891, 1760, - 1271, 1271, 1882, 1532, 1752, 1753, 1894, 1895, 377, 1754, - 2326, 1855, 1753, 1876, 2326, 1760, 1271, 1271, 1754, 2326, - 1752, 1896, 1760, 1271, 1271, 1754, 1883, 1752, 1856, 1891, - - 377, 1897, 377, 1882, 1532, 1753, 1898, 1894, 1895, 377, - 1754, 1754, 1855, 2326, 1876, 1760, 1271, 1271, 1754, 1754, - 1752, 2326, 1896, 2326, 1899, 1900, 1754, 1883, 1753, 1533, - 2326, 377, 1897, 377, 2326, 1761, 2326, 1898, 2326, 2326, - 1901, 1754, 1754, 2326, 1755, 2326, 2326, 2326, 1902, 1754, - 2326, 1761, 1751, 1648, 1648, 1899, 1900, 1752, 1857, 2326, - 1778, 1778, 1778, 2326, 2326, 1753, 2326, 1761, 1758, 1271, - 1271, 1901, 1754, 1656, 1858, 1758, 1271, 1271, 1754, 1902, - 1656, 1657, 1760, 1271, 1271, 2326, 2326, 1752, 1657, 1857, - 1779, 1760, 1271, 1271, 1658, 1753, 1752, 1761, 1655, 1648, - - 1648, 1658, 1903, 1656, 1753, 1758, 1271, 1271, 1754, 1754, - 1656, 1762, 1904, 1905, 1655, 1648, 1648, 1754, 1657, 1656, - 1906, 1779, 1907, 1908, 1658, 1658, 2326, 1657, 1862, 2326, - 1909, 1658, 1658, 1903, 1859, 1913, 1914, 1915, 1924, 1754, - 1658, 1925, 1780, 1904, 1905, 1877, 1877, 1877, 1754, 2326, - 1759, 1906, 1926, 1907, 1908, 1658, 2326, 1860, 1864, 1862, - 1450, 1909, 1658, 2326, 1761, 2326, 1913, 1914, 1915, 1924, - 2326, 1658, 1925, 1861, 2326, 2326, 1792, 1792, 1792, 2326, - 1659, 2326, 2326, 1926, 2326, 2326, 2326, 1759, 2326, 1864, - 1865, 1320, 2326, 1785, 1785, 1785, 1863, 1930, 492, 639, - - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 639, 640, 641, 642, 643, 643, 643, 643, 643, 643, - 644, 1865, 1866, 1786, 1981, 1981, 1981, 1878, 1930, 492, - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - 680, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 1871, 1866, 1786, 1886, 1886, 1886, 1793, 1892, - 1892, 1892, 2326, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 1469, 1787, 2326, 1803, 1803, 1803, - 1823, 1823, 1823, 1871, 492, 1887, 1934, 1935, 1936, 1937, - 1927, 711, 712, 713, 714, 715, 715, 715, 715, 715, - - 715, 716, 377, 492, 1942, 1910, 1982, 1804, 1911, 1928, - 1928, 1928, 1950, 2326, 1933, 492, 1887, 1934, 1935, 1936, - 1937, 1927, 1912, 1959, 1498, 1834, 1834, 1834, 2326, 1961, - 1849, 1849, 1849, 377, 492, 1942, 1910, 1888, 1804, 1911, - 2326, 1893, 2326, 1950, 1850, 1933, 2326, 2326, 1951, 1951, - 1951, 2326, 1957, 1912, 1959, 1835, 1962, 1963, 2326, 1805, - 1961, 377, 1824, 1916, 2326, 1964, 1960, 1958, 1966, 1917, - 1931, 1952, 377, 1918, 1919, 1868, 1868, 1868, 1920, 1921, - 1922, 2326, 1923, 1957, 2326, 2326, 1835, 1962, 1963, 1869, - 2326, 1929, 377, 2326, 1916, 1932, 2326, 1960, 1958, 1966, - - 1917, 1931, 1952, 377, 1918, 1919, 2326, 1836, 2326, 1920, - 1921, 1922, 1851, 1923, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 1969, 1932, 1938, 1938, 1938, - 1953, 2326, 2326, 2326, 2326, 469, 470, 471, 472, 473, - 473, 473, 473, 473, 473, 474, 1405, 1271, 1271, 2326, - 1939, 1531, 2326, 2326, 1970, 2326, 1969, 1870, 2326, 1408, - 1751, 1648, 1648, 1971, 2326, 1752, 1760, 1271, 1271, 1940, - 2326, 1752, 1532, 1856, 1948, 1751, 1648, 1648, 2326, 1753, - 1752, 1939, 1760, 1271, 1271, 1970, 1754, 1752, 1753, 1946, - 1965, 377, 1754, 2326, 1971, 1753, 1972, 2326, 2326, 2326, - - 1940, 1754, 2326, 1532, 2326, 1948, 2326, 2326, 1754, 1941, - 1943, 1943, 1943, 1973, 640, 2326, 1974, 1754, 1975, 2326, - 1946, 1965, 377, 1754, 1758, 1271, 1271, 1972, 1533, 1656, - 1944, 2326, 1754, 1760, 1271, 1271, 1976, 1657, 1752, 1754, - 1977, 1978, 1755, 1984, 1973, 1986, 1753, 1974, 1761, 1975, - 1658, 2326, 2326, 1758, 1271, 1271, 2326, 1859, 1656, 1754, - 1758, 1271, 1271, 2326, 1858, 1656, 1657, 1976, 2326, 2326, - 2326, 1977, 1978, 1657, 1984, 2326, 1986, 1989, 1990, 1658, - 1481, 1658, 1886, 1886, 1886, 1485, 1658, 1947, 2326, 2326, - 1754, 639, 1945, 641, 642, 643, 643, 643, 643, 643, - - 643, 644, 1991, 1992, 2326, 1949, 1860, 1993, 1989, 1990, - 1658, 1481, 1887, 2326, 2326, 1861, 1485, 1658, 1947, 675, - 676, 677, 678, 679, 679, 679, 679, 679, 679, 680, - 1994, 2326, 1997, 1991, 1992, 1759, 1949, 2326, 1993, 2326, - 2326, 2326, 1764, 1887, 675, 676, 677, 678, 679, 679, - 679, 679, 679, 679, 680, 1954, 1954, 1954, 1998, 1995, - 2326, 1994, 1996, 1997, 1888, 1873, 1873, 1873, 1877, 1877, - 1877, 1967, 1967, 1967, 1999, 1955, 1892, 1892, 1892, 2002, - 1440, 2005, 2000, 1450, 2006, 2007, 1578, 2003, 2008, 1998, - 1995, 1469, 2001, 1996, 2004, 377, 1928, 1928, 1928, 2009, - - 2013, 2014, 2015, 2016, 2017, 1999, 2326, 2326, 2326, 2326, - 2002, 1498, 2005, 2000, 2326, 2006, 2007, 2326, 2003, 2008, - 2018, 2010, 2326, 2001, 2326, 2004, 377, 2326, 2326, 2326, - 2009, 2013, 2014, 2015, 2016, 2017, 711, 1956, 713, 714, - 715, 715, 715, 715, 715, 715, 716, 1874, 2011, 2326, - 1878, 2018, 2010, 1968, 2020, 2020, 2020, 2326, 1893, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 2021, 2326, 2012, 2326, 2326, 1938, 1938, 1938, 1929, 2011, - 492, 2326, 2326, 2026, 2027, 2032, 2326, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 1939, 2326, - - 2033, 2326, 2326, 2012, 2326, 2326, 2326, 2029, 2029, 2029, - 2326, 492, 653, 653, 2026, 2027, 2032, 1940, 638, 1951, - 1951, 1951, 2034, 2030, 2326, 1760, 1271, 1271, 2326, 1939, - 1752, 2033, 2035, 377, 2326, 2036, 2022, 2037, 1753, 1758, - 1271, 1271, 1952, 2038, 1656, 638, 638, 638, 1940, 638, - 2039, 1754, 1657, 2034, 377, 2326, 2024, 1941, 2326, 2023, - 1954, 1954, 1954, 2035, 377, 1658, 2036, 377, 2037, 2326, - 2326, 2042, 2043, 1952, 2038, 2326, 638, 2326, 1943, 2025, - 1955, 2039, 1754, 2326, 2326, 377, 640, 2326, 2044, 2031, - 2023, 1967, 1967, 1967, 727, 727, 1658, 2326, 377, 2046, - - 710, 1953, 2042, 2043, 2047, 2048, 1578, 1761, 675, 676, - 677, 678, 679, 679, 679, 679, 679, 679, 680, 2044, - 2049, 1759, 2051, 2052, 2053, 2053, 2053, 710, 710, 710, - 2046, 710, 2055, 2057, 2059, 2047, 2048, 1987, 1987, 1987, - 2060, 2061, 2028, 2062, 2063, 2064, 2065, 2066, 2326, 2067, - 2068, 2049, 2069, 2051, 2052, 2070, 2071, 2072, 710, 2073, - 1954, 2074, 2078, 2055, 2057, 2059, 2079, 2081, 2084, 2326, - 2326, 2060, 2061, 1968, 2062, 2063, 2064, 2065, 2066, 2056, - 2067, 2068, 2075, 2069, 2076, 2326, 2070, 2071, 2072, 2326, - 2073, 2326, 2074, 2078, 1943, 1943, 1943, 2079, 2081, 2084, - - 2020, 2020, 2020, 2087, 2087, 2087, 2054, 1760, 1271, 1271, - 2056, 2326, 1752, 2075, 1944, 2076, 2021, 2326, 2326, 1988, - 1753, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 2085, 1754, 2326, 2326, 2326, 2086, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 492, - 2083, 1954, 1954, 1954, 2326, 377, 2029, 2029, 2029, 2091, - 2077, 2092, 2093, 2085, 1754, 2082, 2094, 2095, 2086, 2326, - 2326, 1955, 2030, 2089, 2089, 2089, 2019, 2040, 2040, 2040, - 492, 2083, 2022, 2096, 377, 2088, 377, 2097, 2105, 1761, - 2091, 2077, 2092, 2093, 2326, 2108, 2082, 2094, 2095, 2109, - - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - 680, 2098, 2098, 2098, 2096, 377, 640, 2110, 2097, 2105, - 2101, 2101, 2101, 2106, 2106, 2106, 2108, 2053, 2053, 2053, - 2109, 2111, 2113, 2028, 2102, 2114, 2115, 2116, 2031, 2117, - 2118, 2119, 2112, 2120, 2121, 2122, 2123, 2124, 2110, 2125, - 2126, 2127, 2127, 2127, 2326, 2090, 2087, 2087, 2087, 2041, - 2326, 2326, 2111, 2113, 2131, 2129, 2114, 2115, 2116, 2132, - 2117, 2118, 2119, 2133, 2120, 2121, 2122, 2123, 2124, 2326, - 2125, 2126, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 2099, 492, 2131, 2129, 2134, 2136, 2137, - - 2132, 2138, 2103, 2139, 2133, 2107, 2130, 2326, 2140, 2054, - 469, 470, 471, 472, 473, 473, 473, 473, 473, 473, - 474, 2326, 2326, 2326, 2326, 492, 2326, 2326, 2134, 2136, - 2137, 2326, 2138, 2128, 2139, 2141, 377, 2130, 2088, 2140, - 2144, 2326, 2089, 2089, 2089, 2145, 2146, 2135, 2142, 2142, - 2142, 2147, 2152, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 2153, 2155, 2141, 377, 2098, 2098, - 2098, 2144, 2101, 2101, 2101, 2156, 2145, 2146, 2135, 2148, - 2148, 2148, 2147, 2152, 2157, 2326, 2102, 2106, 2106, 2106, - 2326, 2158, 2159, 2326, 2160, 2153, 2155, 2326, 2161, 2326, - - 2162, 2163, 2164, 640, 2165, 2166, 2156, 2167, 2168, 2169, - 2170, 2127, 2127, 2127, 2171, 2157, 2149, 492, 2173, 2326, - 2174, 2150, 2158, 2159, 2090, 2160, 2175, 2172, 2154, 2161, - 2143, 2162, 2163, 2164, 2176, 2165, 2166, 2177, 2167, 2168, - 2169, 2170, 2326, 2326, 2326, 2171, 2326, 2149, 492, 2173, - 2099, 2174, 2150, 2326, 2103, 2326, 2326, 2175, 2172, 2154, - 2326, 2151, 2326, 2178, 2179, 2176, 2180, 2326, 2177, 2107, - 469, 470, 471, 472, 473, 473, 473, 473, 473, 473, - 474, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 2184, 2128, 2178, 2179, 2185, 2180, 2142, 2142, - - 2142, 2148, 2148, 2148, 2186, 2187, 2188, 2326, 2189, 2190, - 2191, 2192, 2326, 2193, 2194, 2195, 2196, 2197, 2198, 2199, - 2200, 2201, 2202, 2184, 640, 2203, 492, 2185, 2205, 2206, - 2207, 2208, 2209, 2210, 2211, 2186, 2187, 2188, 2149, 2189, - 2190, 2191, 2192, 2150, 2193, 2194, 2195, 2196, 2197, 2198, - 2199, 2200, 2201, 2202, 2204, 2212, 2203, 492, 2326, 2205, - 2206, 2207, 2208, 2209, 2210, 2211, 2326, 2326, 2215, 2149, - 2216, 2219, 2220, 2221, 2150, 2222, 2223, 2223, 2223, 2225, - 2143, 2226, 2227, 2151, 2228, 2204, 2212, 2229, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 2215, - - 2230, 2216, 2219, 2220, 2221, 2231, 2222, 2232, 2233, 2234, - 2225, 2235, 2226, 2227, 2236, 2228, 2237, 2238, 2229, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 2239, 2230, 2240, 2241, 2242, 2243, 2231, 2246, 2232, 2233, - 2234, 2247, 2235, 2248, 2249, 2236, 2250, 2237, 2238, 2244, - 2244, 2244, 2223, 2223, 2223, 2251, 2253, 2254, 2224, 2255, - 2256, 2239, 2257, 2240, 2241, 2242, 2243, 2258, 2246, 2259, - 2261, 2262, 2247, 2263, 2248, 2249, 2264, 2250, 2223, 2223, - 2223, 2244, 2244, 2244, 2265, 2266, 2251, 2253, 2254, 2267, - 2255, 2256, 2268, 2257, 2269, 2270, 2271, 2272, 2258, 2273, - - 2259, 2261, 2262, 2326, 2263, 2274, 2275, 2264, 2276, 2277, - 2278, 2279, 1943, 1943, 1943, 2265, 2266, 2284, 2285, 2286, - 2267, 2287, 2288, 2268, 2289, 2269, 2270, 2271, 2272, 2326, - 2273, 2245, 1944, 2290, 2224, 2326, 2274, 2275, 2294, 2276, - 2277, 2278, 2279, 2280, 2280, 2280, 2297, 2298, 2284, 2285, - 2286, 2281, 2287, 2288, 2299, 2289, 1954, 1954, 1954, 2300, - 2224, 2301, 2302, 2245, 2290, 2280, 2280, 2280, 2303, 2294, - 2304, 2305, 2306, 2281, 2307, 2308, 1955, 2297, 2298, 2309, - 2310, 2310, 2310, 2312, 2313, 2299, 2314, 2315, 2316, 2317, - 2300, 2318, 2301, 2302, 2019, 2310, 2310, 2310, 2319, 2303, - - 2320, 2304, 2305, 2306, 2321, 2307, 2308, 2310, 2310, 2310, - 2309, 2223, 2223, 2223, 2312, 2313, 2326, 2314, 2315, 2316, - 2317, 2322, 2318, 2323, 2324, 2282, 2325, 2283, 2326, 2319, - 2326, 2320, 2310, 2310, 2310, 2321, 2326, 2326, 2028, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2282, 2326, 2283, - 2326, 2326, 2322, 2326, 2323, 2324, 2326, 2325, 2326, 2326, - 2326, 2326, 2311, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2311, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2311, - 2326, 2326, 2326, 2224, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2311, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 215, 215, 215, 215, 215, 215, 215, 215, 215, - - 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 237, 237, 237, - 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, - 237, 237, 237, 237, 237, 237, 240, 240, 240, 240, - 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - - 240, 240, 240, 240, 240, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 338, 338, 338, 338, 338, 338, 338, 338, 338, - 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - - 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, - 347, 347, 347, 347, 347, 347, 347, 347, 347, 362, - 362, 362, 2326, 2326, 2326, 2326, 362, 2326, 2326, 2326, - 2326, 362, 362, 362, 362, 370, 370, 2326, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 377, 377, 2326, 2326, 2326, 2326, - 377, 2326, 2326, 2326, 2326, 377, 377, 377, 377, 384, - 384, 384, 2326, 2326, 2326, 384, 2326, 2326, 2326, 2326, - 384, 384, 384, 384, 455, 455, 2326, 2326, 2326, 2326, - 455, 2326, 2326, 2326, 455, 455, 455, 455, 455, 464, - - 2326, 464, 464, 464, 464, 464, 464, 464, 468, 468, - 2326, 2326, 2326, 2326, 468, 2326, 2326, 2326, 2326, 468, - 468, 468, 468, 486, 2326, 486, 486, 486, 486, 486, - 486, 492, 492, 2326, 492, 492, 2326, 492, 492, 492, - 492, 2326, 2326, 2326, 2326, 492, 492, 492, 492, 522, - 2326, 522, 522, 522, 522, 524, 524, 524, 2326, 2326, - 2326, 2326, 524, 2326, 2326, 2326, 2326, 524, 524, 524, - 524, 531, 531, 2326, 2326, 2326, 2326, 531, 2326, 2326, - 2326, 2326, 531, 531, 531, 531, 538, 538, 538, 2326, - 2326, 2326, 538, 2326, 2326, 2326, 2326, 538, 538, 538, - - 538, 550, 550, 2326, 2326, 2326, 2326, 550, 2326, 2326, - 2326, 550, 550, 550, 550, 550, 559, 2326, 559, 559, - 559, 559, 560, 2326, 2326, 560, 2326, 560, 580, 2326, - 2326, 580, 2326, 580, 604, 604, 604, 604, 604, 604, - 2326, 604, 604, 604, 604, 604, 604, 2326, 604, 604, - 604, 604, 604, 610, 610, 610, 610, 610, 610, 610, - 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, - 610, 610, 611, 611, 611, 611, 611, 611, 2326, 611, - 611, 611, 611, 611, 611, 2326, 611, 611, 611, 611, - 611, 617, 617, 617, 617, 617, 617, 617, 617, 617, - - 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 624, - 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, - 624, 624, 624, 2326, 624, 624, 624, 624, 626, 626, - 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, - 626, 626, 2326, 626, 626, 626, 626, 631, 631, 2326, - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 631, 638, 638, 2326, 2326, - 2326, 2326, 638, 2326, 2326, 2326, 2326, 638, 638, 638, - - 638, 654, 2326, 654, 654, 654, 654, 654, 659, 659, - 2326, 659, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 659, 659, 659, 659, 659, 659, 667, 667, 2326, + 60, 61, 62, 61, 63, 64, 65, 66, 67, 68, + 68, 63, 69, 70, 71, 72, 73, 74, 63, 63, + 63, 75, 63, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 66, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 66, 66, 60, + 60, 63, 66, 99, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 66, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 66, 66, + 60, 100, 101, 102, 103, 104, 104, 104, 104, 104, + 104, 105, 106, 106, 107, 106, 106, 106, 108, 108, + + 106, 109, 109, 110, 111, 106, 111, 106, 106, 112, + 106, 106, 106, 106, 106, 108, 108, 108, 108, 108, + 113, 108, 108, 114, 108, 108, 108, 108, 108, 108, + 108, 115, 116, 117, 108, 108, 108, 118, 108, 108, + 108, 106, 106, 106, 108, 106, 108, 108, 108, 108, + 108, 113, 108, 108, 114, 108, 108, 108, 108, 108, + 108, 108, 115, 116, 117, 108, 108, 108, 118, 108, + 108, 108, 106, 119, 120, 121, 122, 123, 123, 123, + 123, 123, 123, 124, 126, 126, 392, 393, 2492, 394, + 604, 604, 2486, 127, 127, 128, 129, 130, 129, 128, + + 128, 131, 131, 128, 128, 128, 132, 133, 128, 134, + 135, 128, 131, 128, 128, 128, 128, 128, 131, 131, + 131, 136, 137, 131, 138, 131, 131, 131, 131, 131, + 131, 131, 139, 140, 131, 141, 131, 142, 131, 131, + 131, 131, 131, 131, 128, 128, 128, 131, 128, 131, + 131, 131, 136, 137, 131, 138, 131, 131, 131, 131, + 131, 131, 131, 139, 140, 131, 141, 131, 142, 131, + 131, 131, 131, 131, 131, 128, 143, 144, 145, 146, + 147, 147, 147, 147, 147, 147, 148, 149, 149, 107, + 149, 149, 150, 151, 151, 152, 149, 149, 153, 149, + + 149, 149, 149, 149, 151, 149, 149, 149, 149, 149, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 154, 151, 151, 151, 155, + 151, 151, 151, 151, 151, 151, 149, 149, 149, 151, + 156, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 154, 151, 151, 151, + 155, 151, 151, 151, 151, 151, 151, 149, 157, 158, + 159, 160, 161, 161, 161, 161, 161, 161, 162, 163, + 164, 165, 164, 163, 163, 163, 166, 167, 163, 163, + 168, 169, 170, 171, 172, 163, 166, 163, 163, 173, + + 163, 163, 166, 166, 166, 174, 175, 166, 176, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 177, + 166, 178, 166, 166, 166, 166, 166, 166, 163, 163, + 163, 166, 163, 166, 166, 166, 174, 175, 166, 176, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 177, 166, 178, 166, 166, 166, 166, 166, 166, 163, + 163, 179, 163, 180, 163, 163, 163, 163, 163, 163, + 163, 182, 183, 182, 234, 182, 183, 182, 184, 234, + 237, 185, 184, 186, 237, 185, 240, 186, 190, 191, + 190, 240, 190, 191, 190, 192, 107, 107, 193, 192, + + 192, 107, 193, 107, 192, 476, 490, 355, 509, 511, + 477, 491, 355, 510, 512, 356, 235, 513, 269, 269, + 356, 235, 238, 2514, 357, 376, 238, 2471, 514, 357, + 313, 241, 313, 515, 516, 405, 241, 517, 355, 406, + 511, 564, 547, 355, 2475, 512, 356, 548, 513, 269, + 269, 356, 187, 2474, 188, 357, 187, 562, 188, 514, + 357, 313, 563, 313, 515, 516, 405, 2459, 517, 194, + 406, 195, 564, 194, 2458, 195, 196, 197, 198, 197, + 196, 196, 196, 199, 200, 201, 201, 202, 203, 204, + 205, 196, 196, 206, 196, 196, 201, 196, 196, 206, + + 206, 206, 206, 206, 206, 207, 206, 206, 206, 206, + 206, 206, 206, 206, 208, 206, 206, 209, 210, 206, + 206, 206, 206, 206, 206, 196, 196, 196, 206, 196, + 206, 206, 206, 206, 206, 206, 207, 206, 206, 206, + 206, 206, 206, 206, 206, 208, 206, 206, 209, 210, + 206, 206, 206, 206, 206, 206, 201, 196, 211, 196, + 212, 196, 196, 196, 196, 196, 196, 196, 213, 213, + 213, 213, 213, 213, 565, 486, 214, 566, 574, 214, + 218, 219, 218, 575, 2470, 220, 464, 221, 567, 222, + 223, 218, 219, 218, 578, 2455, 220, 728, 221, 579, + + 222, 223, 227, 228, 227, 565, 2442, 229, 566, 229, + 229, 229, 230, 227, 228, 227, 2455, 654, 229, 567, + 229, 229, 229, 230, 377, 378, 379, 380, 381, 381, + 381, 381, 381, 381, 382, 2514, 2514, 376, 376, 582, + 583, 2514, 586, 376, 488, 489, 587, 410, 428, 215, + 657, 216, 215, 376, 216, 466, 467, 424, 468, 584, + 411, 224, 599, 225, 585, 594, 595, 600, 596, 730, + 582, 583, 224, 586, 225, 603, 2434, 587, 410, 428, + 604, 657, 476, 231, 376, 232, 656, 477, 424, 663, + 664, 411, 719, 720, 231, 721, 232, 246, 247, 248, + + 247, 246, 249, 250, 251, 252, 253, 246, 246, 246, + 246, 254, 246, 246, 251, 246, 255, 246, 246, 256, + 251, 251, 251, 251, 251, 257, 258, 251, 251, 251, + 251, 259, 251, 251, 251, 251, 251, 260, 251, 251, + 251, 251, 251, 251, 251, 251, 246, 246, 246, 251, + 261, 251, 251, 251, 251, 251, 257, 258, 251, 251, + 251, 251, 259, 251, 251, 251, 251, 251, 260, 251, + 251, 251, 251, 251, 251, 251, 251, 246, 262, 263, + 264, 265, 266, 266, 266, 266, 266, 266, 267, 271, + 272, 271, 653, 273, 274, 640, 275, 276, 277, 358, + + 358, 358, 278, 271, 272, 271, 1290, 273, 274, 686, + 275, 276, 277, 2514, 490, 376, 278, 591, 662, 491, + 2514, 407, 376, 653, 700, 376, 640, 735, 2514, 279, + 376, 736, 376, 518, 592, 408, 418, 519, 409, 2442, + 419, 2439, 741, 279, 420, 412, 520, 2408, 591, 662, + 521, 413, 407, 2432, 742, 700, 376, 2423, 735, 2420, + 279, 2419, 736, 376, 518, 592, 408, 418, 519, 409, + 280, 419, 281, 741, 279, 420, 412, 520, 688, 689, + 359, 521, 413, 1289, 280, 742, 281, 282, 283, 284, + 283, 282, 285, 286, 287, 288, 289, 290, 282, 282, + + 282, 291, 282, 282, 287, 282, 282, 282, 282, 282, + 287, 287, 287, 287, 287, 292, 287, 287, 287, 287, + 287, 293, 287, 287, 287, 287, 287, 294, 287, 287, + 287, 287, 287, 287, 287, 287, 282, 282, 282, 287, + 282, 287, 287, 287, 287, 287, 292, 287, 287, 287, + 287, 287, 293, 287, 287, 287, 287, 287, 294, 287, + 287, 287, 287, 287, 287, 287, 287, 282, 295, 296, + 297, 298, 299, 299, 299, 299, 299, 299, 300, 107, + 107, 107, 107, 107, 301, 302, 302, 303, 107, 107, + 107, 107, 107, 107, 107, 107, 302, 107, 107, 107, + + 107, 304, 302, 302, 302, 302, 302, 305, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 107, 107, + 107, 302, 107, 302, 302, 302, 302, 302, 305, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 107, + 306, 307, 308, 309, 310, 310, 310, 310, 310, 310, + 311, 314, 315, 316, 315, 314, 317, 318, 319, 320, + 314, 314, 314, 321, 322, 323, 324, 314, 325, 314, + 326, 327, 314, 327, 319, 319, 319, 319, 319, 319, + + 328, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 329, 319, 319, 319, 319, 319, 319, 319, + 314, 314, 314, 319, 330, 319, 319, 319, 319, 319, + 319, 328, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 329, 319, 319, 319, 319, 319, 319, + 319, 314, 331, 332, 333, 334, 335, 335, 335, 335, + 335, 335, 336, 338, 339, 338, 1625, 1626, 340, 509, + 338, 339, 338, 2418, 510, 340, 341, 358, 358, 358, + 2378, 342, 743, 341, 630, 630, 630, 2368, 342, 744, + 343, 347, 348, 347, 1737, 1738, 349, 343, 347, 348, + + 347, 2324, 568, 349, 350, 360, 569, 344, 745, 351, + 2514, 350, 376, 743, 344, 570, 351, 512, 352, 571, + 744, 343, 376, 2396, 353, 352, 652, 2393, 343, 414, + 513, 353, 415, 568, 2390, 416, 547, 569, 344, 745, + 640, 548, 384, 640, 345, 344, 570, 514, 512, 352, + 571, 345, 2514, 376, 711, 353, 352, 652, 359, 2373, + 414, 513, 353, 415, 727, 631, 416, 630, 630, 630, + 562, 640, 354, 2372, 640, 563, 2325, 1282, 514, 354, + 2324, 362, 363, 364, 365, 366, 366, 366, 366, 366, + 366, 367, 368, 368, 574, 727, 368, 368, 2359, 575, + + 368, 368, 368, 368, 368, 368, 368, 368, 368, 2356, + 368, 368, 368, 368, 368, 385, 386, 387, 388, 389, + 389, 389, 389, 389, 389, 390, 578, 2514, 2514, 376, + 376, 579, 584, 599, 516, 451, 455, 585, 600, 376, + 376, 368, 368, 368, 2514, 368, 376, 2514, 631, 376, + 603, 1281, 1286, 2350, 651, 604, 376, 640, 421, 376, + 640, 422, 658, 658, 658, 516, 451, 455, 423, 417, + 376, 376, 368, 370, 371, 372, 373, 374, 374, 374, + 374, 374, 374, 375, 397, 651, 398, 376, 640, 421, + 376, 640, 422, 2514, 2277, 376, 399, 395, 758, 423, + + 417, 425, 658, 658, 658, 376, 517, 757, 759, 426, + 2323, 607, 607, 607, 2271, 427, 608, 854, 609, 2514, + 2315, 376, 2312, 2514, 610, 376, 1285, 399, 1744, 1745, + 2304, 376, 425, 855, 2246, 439, 376, 517, 757, 759, + 426, 429, 1625, 659, 856, 440, 427, 1750, 854, 2221, + 377, 378, 379, 380, 381, 381, 381, 381, 381, 381, + 382, 2514, 376, 376, 855, 2514, 439, 376, 857, 2514, + 858, 376, 429, 376, 430, 856, 440, 376, 431, 2216, + 400, 376, 401, 659, 859, 860, 432, 402, 403, 404, + 433, 397, 611, 755, 863, 2213, 864, 438, 2514, 857, + + 376, 858, 1737, 756, 376, 430, 434, 1852, 376, 431, + 376, 400, 376, 401, 435, 859, 860, 432, 402, 403, + 404, 433, 865, 436, 861, 863, 437, 864, 438, 876, + 1744, 2514, 877, 376, 756, 1859, 2514, 434, 376, 2203, + 862, 376, 2201, 441, 445, 435, 442, 2514, 376, 376, + 878, 446, 443, 865, 436, 861, 2263, 437, 444, 376, + 876, 447, 879, 877, 2514, 2260, 376, 1765, 448, 882, + 449, 862, 1879, 450, 441, 445, 376, 442, 2248, 376, + 2153, 878, 446, 443, 457, 1625, 2514, 2514, 2514, 444, + 376, 2219, 447, 879, 2514, 880, 376, 2215, 464, 448, + + 882, 449, 452, 376, 450, 2140, 376, 376, 883, 453, + 454, 881, 458, 459, 460, 461, 462, 462, 462, 462, + 462, 462, 463, 665, 665, 665, 880, 2514, 2514, 2138, + 376, 376, 376, 452, 376, 2514, 2514, 376, 464, 883, + 453, 454, 881, 376, 2514, 2514, 464, 761, 2196, 761, + 2514, 376, 762, 884, 885, 464, 1765, 1766, 2193, 588, + 376, 376, 376, 2514, 589, 376, 479, 1798, 1799, 2189, + 376, 376, 376, 2180, 376, 376, 590, 768, 376, 376, + 376, 761, 376, 761, 884, 885, 968, 376, 376, 376, + 588, 376, 969, 376, 969, 589, 2090, 970, 665, 665, + + 665, 376, 2161, 358, 666, 2083, 376, 590, 768, 376, + 480, 701, 701, 701, 701, 701, 701, 481, 376, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 470, 471, 472, 473, 474, 474, 474, 474, 474, 474, + 475, 480, 482, 483, 886, 887, 1737, 2514, 481, 1744, + 2514, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 482, 483, 886, 887, 484, 485, 666, + 470, 471, 472, 473, 474, 474, 474, 474, 474, 474, + 475, 2080, 702, 1873, 1874, 702, 888, 470, 471, 472, + + 473, 474, 474, 474, 474, 474, 474, 475, 484, 485, + 731, 731, 731, 2078, 889, 2073, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 888, 731, 731, + 731, 2071, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 2514, 2514, 889, 2514, 2150, 376, 2514, + 2514, 737, 737, 737, 486, 2514, 2514, 2145, 774, 469, + 486, 2514, 2514, 2058, 890, 469, 486, 2514, 2514, 2127, + 891, 469, 486, 737, 737, 737, 892, 469, 559, 358, + 358, 358, 893, 532, 910, 911, 469, 469, 469, 774, + 469, 732, 469, 469, 469, 890, 469, 2124, 469, 469, + + 469, 891, 469, 524, 469, 469, 469, 892, 469, 732, + 532, 532, 532, 893, 532, 910, 911, 469, 1765, 2514, + 2033, 918, 2514, 469, 376, 2514, 614, 614, 614, 469, + 2109, 615, 738, 616, 376, 469, 492, 492, 492, 617, + 921, 532, 2019, 769, 2077, 932, 2075, 494, 1979, 494, + 495, 2514, 918, 376, 738, 1972, 2514, 2514, 1962, 765, + 359, 496, 497, 376, 498, 376, 951, 559, 753, 753, + 753, 921, 532, 499, 769, 500, 932, 501, 952, 526, + 527, 528, 529, 530, 530, 530, 530, 530, 530, 531, + 765, 1798, 496, 497, 376, 498, 1914, 951, 1958, 532, + + 532, 532, 955, 532, 499, 722, 500, 618, 501, 952, + 2044, 956, 630, 630, 630, 940, 502, 503, 504, 505, + 506, 506, 506, 506, 506, 506, 507, 492, 492, 492, + 532, 957, 2514, 955, 958, 1798, 2514, 2041, 494, 1934, + 494, 495, 956, 620, 620, 620, 940, 621, 622, 754, + 518, 2022, 496, 497, 519, 498, 623, 959, 376, 1915, + 540, 1902, 957, 520, 499, 958, 500, 521, 501, 533, + 534, 535, 536, 537, 537, 537, 537, 537, 537, 538, + 2514, 518, 376, 496, 497, 519, 498, 1890, 959, 376, + 549, 767, 376, 631, 520, 499, 1880, 500, 521, 501, + + 1873, 2514, 620, 620, 620, 1867, 902, 502, 503, 504, + 505, 506, 506, 506, 506, 506, 506, 507, 2514, 2514, + 2514, 549, 767, 376, 624, 971, 1860, 971, 550, 2514, + 972, 2514, 495, 541, 542, 543, 544, 545, 545, 545, + 545, 545, 545, 546, 552, 1853, 1954, 1951, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 550, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 2368, 553, 554, 555, 556, 557, 557, 557, 557, + 557, 557, 558, 624, 1937, 376, 533, 534, 535, 536, + 537, 537, 537, 537, 537, 537, 538, 1004, 502, 508, + + 504, 505, 506, 506, 506, 506, 506, 506, 507, 2514, + 2514, 2514, 1929, 1873, 2514, 2514, 376, 2514, 1971, 711, + 2514, 941, 2514, 2514, 1918, 522, 2514, 2514, 1004, 711, + 493, 942, 2514, 2514, 1630, 376, 726, 559, 1751, 2514, + 2514, 1845, 532, 559, 2514, 2369, 376, 376, 532, 995, + 654, 1842, 1588, 1814, 975, 640, 376, 493, 493, 493, + 711, 493, 942, 1809, 771, 772, 376, 726, 1801, 532, + 532, 532, 773, 532, 1005, 532, 532, 532, 376, 532, + 995, 1543, 640, 640, 640, 975, 640, 376, 493, 2514, + 2471, 376, 1769, 2514, 2514, 771, 772, 908, 908, 908, + + 532, 376, 805, 773, 654, 1005, 532, 632, 632, 640, + 1767, 632, 632, 640, 1511, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 1758, 632, 632, 632, 632, 632, + 2514, 2514, 376, 805, 1488, 1478, 640, 640, 640, 1728, + 640, 654, 2514, 2514, 376, 376, 640, 658, 658, 658, + 1725, 990, 792, 376, 376, 376, 632, 632, 632, 1592, + 632, 607, 607, 607, 2472, 2514, 2514, 640, 894, 630, + 766, 1713, 1713, 640, 640, 640, 654, 640, 909, 1689, + 1009, 640, 990, 792, 376, 376, 376, 632, 634, 635, + 636, 637, 638, 638, 638, 638, 638, 638, 639, 649, + + 1674, 766, 650, 376, 640, 1017, 376, 977, 640, 640, + 640, 1009, 640, 676, 677, 678, 679, 680, 680, 680, + 680, 680, 680, 681, 1671, 614, 614, 614, 659, 1028, + 649, 1011, 898, 650, 376, 1640, 1017, 376, 977, 640, + 683, 1361, 611, 641, 642, 643, 644, 645, 645, 645, + 645, 645, 645, 646, 667, 667, 1356, 1346, 667, 667, + 1028, 1619, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 683, 667, 667, 667, 667, 667, 944, 1138, 944, + 1138, 1612, 1137, 1139, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 684, 919, 919, 919, 665, + + 665, 665, 1316, 667, 667, 667, 618, 667, 691, 692, + 693, 694, 695, 695, 695, 695, 695, 695, 696, 1603, + 685, 924, 924, 924, 1599, 1588, 684, 701, 701, 701, + 1295, 936, 936, 936, 667, 669, 670, 671, 672, 673, + 673, 673, 673, 673, 673, 674, 1575, 1033, 731, 731, + 731, 685, 1568, 676, 677, 678, 679, 680, 680, 680, + 680, 680, 680, 681, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 2514, 2514, 920, 1033, 1041, + 666, 2514, 2514, 949, 949, 949, 686, 2514, 2514, 1549, + 1224, 675, 686, 2514, 2514, 1523, 1521, 675, 686, 2514, + + 1201, 376, 925, 675, 686, 2514, 758, 376, 702, 675, + 1041, 376, 937, 737, 737, 737, 759, 376, 675, 675, + 675, 779, 675, 1496, 675, 675, 675, 697, 675, 732, + 675, 675, 675, 1190, 675, 801, 675, 675, 675, 2514, + 675, 376, 376, 2514, 2514, 1465, 1460, 759, 376, 675, + 1452, 376, 779, 791, 698, 675, 1290, 665, 697, 690, + 1140, 675, 1140, 1290, 950, 1141, 801, 675, 691, 692, + 693, 694, 695, 695, 695, 695, 695, 695, 696, 376, + 2514, 2514, 376, 2514, 791, 376, 690, 690, 690, 1286, + 690, 698, 2514, 2514, 738, 376, 690, 1286, 2514, 2514, + + 376, 1282, 770, 698, 1032, 2514, 2514, 376, 690, 698, + 376, 1282, 1433, 976, 690, 981, 728, 690, 1428, 1426, + 2514, 711, 376, 690, 690, 690, 376, 690, 783, 1422, + 1420, 376, 376, 770, 1401, 690, 690, 690, 376, 690, + 376, 690, 690, 690, 976, 690, 981, 1034, 711, 711, + 711, 1313, 711, 1151, 690, 1146, 2514, 1141, 1141, 783, + 953, 953, 953, 376, 2514, 2514, 690, 965, 753, 753, + 1139, 376, 690, 703, 703, 728, 1139, 703, 703, 711, + 711, 703, 703, 703, 703, 703, 703, 703, 703, 703, + 493, 703, 703, 703, 703, 703, 712, 713, 714, 715, + + 716, 716, 716, 716, 716, 716, 717, 711, 711, 711, + 360, 711, 1137, 1134, 376, 1307, 1082, 704, 978, 1071, + 1124, 493, 703, 703, 703, 2514, 703, 376, 2514, 2514, + 668, 2514, 1119, 376, 1293, 2514, 2514, 376, 711, 728, + 701, 954, 1108, 376, 711, 376, 728, 1082, 966, 978, + 780, 711, 793, 703, 705, 706, 707, 708, 709, 709, + 709, 709, 709, 709, 710, 723, 979, 724, 376, 633, + 376, 711, 711, 711, 376, 711, 1083, 725, 711, 711, + 711, 780, 711, 793, 1104, 1102, 362, 363, 364, 365, + 366, 366, 366, 366, 366, 366, 367, 979, 2514, 2514, + + 2514, 376, 711, 1100, 2514, 2514, 2514, 1083, 725, 711, + 746, 2514, 2514, 2514, 376, 361, 746, 1275, 551, 539, + 376, 361, 997, 746, 525, 1243, 456, 980, 361, 972, + 972, 712, 713, 714, 715, 716, 716, 716, 716, 716, + 716, 717, 361, 361, 361, 376, 361, 970, 361, 361, + 361, 376, 361, 997, 970, 361, 361, 361, 980, 361, + 2514, 2514, 2514, 968, 2514, 965, 376, 1158, 383, 2514, + 2514, 376, 746, 361, 369, 361, 810, 361, 986, 361, + 464, 2514, 953, 949, 376, 376, 361, 377, 378, 379, + 380, 381, 381, 381, 381, 381, 381, 382, 384, 2514, + + 999, 376, 376, 711, 361, 361, 361, 810, 361, 986, + 1137, 781, 376, 376, 376, 376, 376, 2514, 2514, 936, + 1132, 690, 782, 2514, 2514, 675, 924, 919, 464, 640, + 908, 999, 904, 376, 464, 361, 368, 368, 1084, 376, + 368, 368, 781, 376, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 782, 368, 368, 368, 368, 368, 904, + 376, 376, 376, 993, 376, 376, 376, 376, 376, 1084, + 376, 385, 386, 387, 388, 389, 389, 389, 389, 389, + 389, 390, 376, 493, 1012, 368, 368, 368, 2514, 368, + 376, 376, 900, 2514, 993, 900, 376, 376, 896, 807, + + 376, 844, 844, 844, 844, 844, 844, 844, 844, 844, + 844, 844, 1075, 376, 493, 1012, 368, 370, 371, 372, + 373, 374, 374, 374, 374, 374, 374, 375, 368, 368, + 807, 376, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 748, 368, 368, 368, 368, + 368, 368, 896, 1089, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 748, 368, 368, + 368, 368, 2514, 2514, 376, 2514, 1019, 376, 2514, 2514, + 2514, 1085, 532, 464, 2514, 2514, 2514, 376, 376, 750, + 493, 469, 1057, 376, 383, 750, 968, 2514, 2514, 2514, + + 383, 753, 963, 737, 789, 376, 731, 1019, 750, 722, + 935, 728, 2514, 383, 376, 376, 376, 376, 376, 376, + 1086, 383, 383, 383, 376, 383, 728, 383, 383, 383, + 933, 383, 2514, 2514, 2514, 789, 368, 368, 798, 368, + 383, 383, 383, 750, 383, 2514, 376, 376, 383, 703, + 1087, 1086, 383, 701, 2514, 376, 376, 376, 383, 698, + 2514, 2514, 803, 376, 763, 698, 376, 376, 2514, 798, + 376, 383, 764, 376, 686, 383, 383, 383, 686, 383, + 840, 1087, 2514, 1013, 376, 922, 784, 667, 376, 785, + 775, 665, 776, 803, 376, 763, 376, 376, 376, 1088, + + 2514, 777, 376, 764, 376, 982, 383, 397, 778, 760, + 983, 840, 376, 658, 1013, 654, 2514, 784, 376, 399, + 785, 775, 786, 776, 787, 376, 654, 376, 376, 985, + 1088, 988, 777, 376, 906, 989, 982, 1090, 788, 778, + 632, 983, 2514, 376, 376, 2514, 2514, 376, 376, 630, + 399, 620, 905, 786, 376, 787, 794, 376, 376, 376, + 985, 790, 988, 376, 376, 797, 989, 904, 1090, 788, + 987, 795, 796, 377, 378, 379, 380, 381, 381, 381, + 381, 381, 381, 382, 614, 376, 901, 794, 376, 376, + 900, 607, 790, 2514, 376, 376, 797, 2514, 2514, 376, + + 376, 987, 795, 796, 2514, 376, 376, 897, 896, 376, + 376, 799, 2514, 800, 376, 804, 376, 2514, 2514, 376, + 376, 376, 802, 806, 376, 1024, 376, 376, 873, 376, + 376, 1000, 991, 2514, 873, 376, 376, 808, 809, 376, + 376, 376, 799, 811, 800, 812, 804, 376, 984, 813, + 869, 1091, 376, 802, 806, 376, 1024, 376, 376, 376, + 376, 376, 1000, 991, 869, 2514, 994, 376, 808, 809, + 376, 559, 559, 2514, 811, 376, 812, 376, 867, 984, + 813, 2514, 1091, 376, 376, 376, 2514, 825, 376, 814, + 376, 376, 820, 376, 815, 1001, 376, 994, 376, 1002, + + 996, 821, 816, 822, 817, 823, 867, 818, 376, 2514, + 819, 376, 376, 824, 2514, 376, 376, 826, 825, 1007, + 814, 376, 376, 820, 376, 815, 1001, 376, 522, 376, + 1002, 996, 821, 816, 822, 817, 823, 2514, 818, 376, + 522, 819, 492, 376, 824, 827, 376, 845, 826, 376, + 1007, 2514, 376, 376, 2514, 998, 376, 2514, 376, 376, + 828, 376, 2514, 376, 376, 830, 376, 1092, 992, 376, + 2514, 2514, 376, 376, 376, 1015, 827, 376, 832, 829, + 376, 833, 376, 835, 834, 831, 998, 836, 486, 376, + 486, 828, 376, 376, 376, 842, 830, 376, 1092, 992, + + 376, 842, 1069, 1003, 376, 376, 1015, 493, 1010, 832, + 829, 395, 833, 376, 835, 834, 831, 2514, 836, 376, + 2514, 2514, 376, 376, 376, 2514, 376, 376, 2514, 376, + 376, 376, 376, 376, 1003, 376, 837, 376, 493, 1010, + 376, 1006, 838, 752, 1093, 839, 1016, 750, 841, 750, + 2514, 2514, 457, 464, 2514, 2514, 464, 376, 2514, 2514, + 376, 842, 376, 376, 376, 842, 456, 837, 376, 842, + 456, 376, 1006, 838, 456, 1093, 839, 1016, 376, 841, + 458, 459, 460, 461, 462, 462, 462, 462, 462, 462, + 463, 748, 368, 456, 456, 456, 1036, 456, 456, 456, + + 746, 456, 456, 456, 2514, 2514, 746, 2514, 2514, 376, + 723, 358, 938, 737, 740, 842, 731, 734, 486, 2514, + 456, 711, 939, 469, 456, 728, 722, 1036, 456, 718, + 2514, 711, 456, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 2514, 2514, 376, 456, 456, 456, + 469, 469, 469, 939, 469, 486, 2514, 2514, 698, 1022, + 469, 698, 711, 2514, 2514, 686, 682, 486, 944, 658, + 944, 2514, 469, 945, 486, 846, 661, 376, 456, 469, + 2514, 469, 711, 711, 376, 376, 376, 469, 469, 469, + 1022, 469, 711, 397, 1029, 967, 848, 1014, 1025, 469, + + 469, 469, 946, 469, 1094, 756, 469, 469, 469, 654, + 469, 648, 647, 629, 711, 376, 376, 376, 469, 847, + 2514, 627, 605, 711, 602, 1029, 601, 848, 1014, 1025, + 469, 849, 598, 946, 597, 1094, 756, 469, 593, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 847, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 849, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 850, 851, 376, 1023, 1021, 376, + 1026, 493, 376, 376, 376, 470, 471, 472, 473, 474, + 474, 474, 474, 474, 474, 475, 852, 1008, 1018, 1067, + + 1095, 1100, 1100, 1100, 579, 850, 851, 376, 1023, 1021, + 376, 1026, 493, 376, 376, 376, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 852, 1008, 1018, + 1067, 1095, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 853, 853, 853, 853, 853, 853, 853, + 853, 853, 853, 853, 470, 471, 472, 473, 474, 474, + 474, 474, 474, 474, 475, 470, 471, 472, 473, 474, + 474, 474, 474, 474, 474, 475, 492, 492, 492, 1096, + 580, 577, 1101, 576, 573, 572, 559, 494, 559, 494, + 495, 522, 522, 492, 486, 2514, 2514, 2514, 376, 376, + + 376, 496, 497, 376, 498, 1027, 524, 867, 478, 464, + 1096, 1020, 525, 499, 1031, 500, 1048, 501, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 376, + 376, 376, 496, 497, 376, 498, 1027, 396, 395, 525, + 525, 525, 1020, 525, 499, 1031, 500, 1048, 501, 540, + 391, 2514, 245, 1102, 1102, 1102, 502, 503, 504, 505, + 506, 506, 506, 506, 506, 506, 507, 2514, 2514, 2514, + 525, 245, 1047, 376, 243, 1097, 376, 1051, 2514, 243, + 2514, 495, 526, 527, 528, 529, 530, 530, 530, 530, + 530, 530, 531, 2514, 2514, 2514, 2514, 2514, 2514, 1104, + + 1104, 1104, 376, 1047, 376, 867, 1097, 376, 1051, 1030, + 525, 533, 534, 535, 536, 537, 537, 537, 537, 537, + 537, 538, 541, 542, 543, 544, 545, 545, 545, 545, + 545, 545, 546, 376, 1103, 2514, 2514, 525, 525, 525, + 1030, 525, 1098, 2514, 2514, 2514, 2514, 502, 508, 504, + 505, 506, 506, 506, 506, 506, 506, 507, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 1034, 1034, 1034, 525, 2514, + 2514, 2514, 2514, 1098, 522, 2514, 2514, 2514, 493, 493, + 1105, 2514, 2514, 2514, 1073, 2514, 376, 867, 2514, 2514, + 2514, 376, 525, 867, 2514, 2514, 2514, 1037, 525, 559, + + 2514, 2514, 2514, 2514, 532, 1099, 493, 493, 493, 493, + 493, 559, 2514, 2514, 2514, 1073, 532, 376, 2514, 525, + 525, 525, 376, 525, 376, 525, 525, 525, 1037, 525, + 2514, 532, 532, 532, 376, 532, 1099, 493, 2514, 2514, + 1050, 1040, 1110, 532, 532, 532, 1035, 532, 2514, 559, + 525, 2514, 2514, 2514, 532, 376, 525, 2514, 376, 2514, + 2514, 2514, 532, 559, 2514, 376, 2514, 1044, 532, 1111, + 869, 1050, 1040, 1110, 532, 539, 2514, 2514, 2514, 2514, + 2514, 532, 532, 532, 2514, 532, 2514, 2514, 869, 376, + 2514, 2514, 493, 539, 2514, 532, 532, 532, 1044, 532, + + 1111, 2514, 539, 539, 539, 2514, 539, 711, 1042, 376, + 376, 1070, 532, 1117, 2514, 2514, 2514, 711, 1049, 1043, + 539, 539, 539, 493, 539, 869, 532, 2514, 2514, 2514, + 539, 947, 872, 539, 871, 493, 493, 1076, 869, 1042, + 376, 376, 1070, 539, 1117, 2514, 2514, 2514, 711, 1049, + 1043, 539, 2514, 2514, 2514, 2514, 1068, 539, 539, 539, + 2514, 539, 947, 872, 2514, 871, 493, 493, 1076, 1121, + 539, 539, 539, 2514, 539, 533, 534, 535, 536, 537, + 537, 537, 537, 537, 537, 538, 552, 1068, 539, 533, + 534, 535, 536, 537, 537, 537, 537, 537, 537, 538, + + 1121, 539, 875, 875, 875, 875, 875, 875, 875, 875, + 875, 875, 875, 2514, 553, 554, 555, 556, 557, 557, + 557, 557, 557, 557, 558, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 1130, 2514, 2514, 873, 2514, 2514, 873, + 2514, 551, 873, 2514, 551, 873, 2514, 551, 2514, 2514, + 551, 533, 534, 535, 536, 537, 537, 537, 537, 537, + 537, 538, 1148, 376, 1130, 2514, 1055, 1149, 551, 551, + 551, 551, 551, 551, 551, 551, 551, 551, 551, 551, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 2514, 2514, 1148, 376, 2514, 2514, 1055, 1149, 551, + + 2514, 2514, 551, 913, 2514, 551, 654, 2514, 551, 632, + 632, 640, 1153, 632, 632, 2514, 2514, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 2514, 632, 632, 632, + 632, 632, 912, 1154, 913, 2514, 2514, 2514, 640, 640, + 640, 2514, 640, 1153, 1108, 908, 908, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 632, 632, + 632, 2514, 632, 912, 1154, 2514, 1119, 919, 919, 640, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 2514, 1124, 924, 924, 2514, 2514, 2514, 2514, 632, + 634, 635, 636, 637, 638, 638, 638, 638, 638, 638, + + 639, 632, 632, 2514, 2514, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, 632, 906, 632, + 632, 632, 632, 632, 632, 1109, 2514, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, + 906, 632, 632, 632, 632, 2514, 2514, 1120, 1134, 936, + 936, 2514, 2514, 2514, 1155, 493, 654, 2514, 2514, 2514, + 2514, 640, 654, 1125, 2514, 2514, 1072, 640, 654, 2514, + 2514, 2514, 2514, 640, 917, 917, 917, 917, 917, 917, + 917, 917, 917, 917, 917, 1155, 493, 2514, 640, 640, + 640, 914, 640, 941, 640, 640, 640, 1072, 640, 1156, + + 640, 640, 640, 942, 640, 2514, 2514, 2514, 2514, 632, + 632, 2514, 632, 2514, 2514, 915, 2514, 1157, 686, 640, + 2514, 2514, 914, 675, 2514, 640, 2514, 2514, 2514, 1135, + 1156, 640, 2514, 2514, 942, 641, 642, 643, 644, 645, + 645, 645, 645, 645, 645, 646, 915, 916, 1157, 1166, + 675, 675, 675, 2514, 675, 641, 642, 643, 644, 645, + 645, 645, 645, 645, 645, 646, 641, 642, 643, 644, + 645, 645, 645, 645, 645, 645, 646, 2514, 916, 2514, + 1166, 675, 2514, 641, 642, 643, 644, 645, 645, 645, + 645, 645, 645, 646, 667, 667, 2514, 2514, 667, 667, + + 2514, 2514, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 926, 667, 667, 667, 667, 667, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 929, 929, + 929, 929, 929, 929, 929, 929, 929, 929, 929, 2514, + 376, 1177, 926, 667, 667, 667, 2514, 667, 2514, 676, + 677, 678, 679, 680, 680, 680, 680, 680, 680, 681, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 376, 1177, 2514, 667, 669, 670, 671, 672, 673, + 673, 673, 673, 673, 673, 674, 667, 667, 2514, 2514, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, - 667, 667, 667, 667, 667, 667, 674, 674, 2326, 2326, - 2326, 2326, 674, 2326, 2326, 2326, 2326, 674, 674, 674, - 674, 686, 2326, 686, 686, 686, 686, 686, 686, 689, - 689, 2326, 2326, 2326, 2326, 689, 2326, 2326, 2326, 2326, - 689, 689, 689, 689, 698, 2326, 698, 698, 698, 698, - 703, 703, 2326, 703, 703, 703, 703, 703, 703, 703, - - 703, 703, 703, 703, 703, 703, 703, 703, 703, 710, - 710, 2326, 2326, 2326, 2326, 710, 2326, 2326, 2326, 2326, - 710, 710, 710, 710, 728, 2326, 728, 728, 728, 728, - 2326, 2326, 728, 732, 732, 2326, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 738, 738, 2326, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, - 738, 362, 362, 362, 2326, 2326, 2326, 2326, 362, 2326, - 2326, 2326, 2326, 362, 362, 362, 362, 746, 2326, 746, - 746, 746, 746, 369, 369, 2326, 369, 369, 369, 369, + + 667, 667, 667, 922, 667, 667, 667, 667, 667, 667, + 2514, 2514, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 667, 922, 667, 667, 667, 667, + 2514, 2514, 2514, 723, 2514, 1136, 2514, 2514, 2514, 2514, + 2514, 686, 2514, 2514, 2514, 939, 675, 686, 2514, 2514, + 2514, 2514, 675, 686, 2514, 2514, 2514, 376, 675, 691, + 692, 693, 694, 695, 695, 695, 695, 695, 695, 696, + 1038, 1169, 1039, 675, 675, 675, 939, 675, 927, 675, + 675, 675, 711, 675, 376, 675, 675, 675, 376, 675, + 1146, 949, 949, 2514, 667, 667, 2514, 667, 928, 1144, + + 2514, 1038, 1169, 1039, 675, 2514, 2514, 2514, 2514, 927, + 675, 2514, 2514, 711, 2514, 376, 675, 2514, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 928, + 1144, 1151, 953, 953, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 2514, 2514, 2514, 965, 753, + 753, 2514, 2514, 2514, 1173, 376, 698, 2514, 2514, 2514, + 376, 690, 698, 2514, 2514, 2514, 2514, 690, 698, 2514, + 2514, 1147, 376, 690, 698, 2514, 2514, 2514, 376, 690, + 493, 397, 1045, 1159, 1046, 1173, 376, 1052, 690, 690, + 690, 376, 690, 756, 690, 690, 690, 930, 690, 1074, + + 690, 690, 690, 376, 690, 1178, 690, 690, 690, 376, + 690, 493, 1152, 1045, 2514, 1046, 2514, 2514, 1052, 690, + 2514, 2514, 2514, 2514, 756, 690, 2514, 2514, 930, 966, + 1074, 690, 2514, 2514, 2514, 2514, 1178, 690, 2514, 2514, + 2514, 691, 692, 693, 694, 695, 695, 695, 695, 695, + 695, 696, 931, 931, 931, 931, 931, 931, 931, 931, + 931, 931, 931, 691, 692, 693, 694, 695, 695, 695, + 695, 695, 695, 696, 703, 703, 2514, 2514, 703, 703, + 2514, 2514, 703, 703, 703, 703, 703, 703, 703, 703, + 703, 2514, 703, 703, 703, 703, 703, 712, 713, 714, + + 715, 716, 716, 716, 716, 716, 716, 717, 948, 948, + 948, 948, 948, 948, 948, 948, 948, 948, 948, 376, + 376, 1164, 1171, 703, 703, 703, 2514, 703, 960, 960, + 960, 960, 960, 960, 960, 960, 960, 960, 960, 961, + 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, + 376, 376, 1164, 1171, 703, 705, 706, 707, 708, 709, + 709, 709, 709, 709, 709, 710, 703, 703, 2514, 2514, + 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 933, 703, 703, 703, 703, 703, 703, + 2514, 2514, 703, 703, 703, 703, 703, 703, 703, 703, + + 703, 703, 703, 703, 703, 933, 703, 703, 703, 703, + 2514, 2514, 376, 376, 1165, 2514, 2514, 2514, 376, 1162, + 2514, 728, 2514, 2514, 2514, 1174, 711, 728, 2514, 2514, + 2514, 2514, 711, 728, 2514, 2514, 2514, 376, 711, 1172, + 376, 1187, 376, 376, 376, 1165, 728, 360, 2514, 376, + 1162, 711, 2514, 711, 711, 711, 1174, 711, 2514, 711, + 711, 711, 384, 711, 376, 711, 711, 711, 376, 711, + 1172, 376, 1187, 376, 703, 703, 1186, 703, 711, 711, + 711, 2514, 711, 376, 711, 1176, 2514, 1189, 2514, 2514, + 711, 762, 2514, 2514, 2514, 376, 711, 962, 962, 962, + + 962, 962, 962, 962, 962, 962, 962, 962, 2514, 711, + 723, 2514, 943, 2514, 376, 2514, 1176, 376, 1189, 376, + 1179, 1183, 725, 362, 363, 364, 365, 366, 366, 366, + 366, 366, 366, 367, 2514, 385, 386, 387, 388, 389, + 389, 389, 389, 389, 389, 390, 2514, 2514, 376, 2514, + 376, 1179, 1183, 725, 2514, 377, 378, 379, 380, 381, + 381, 381, 381, 381, 381, 382, 1281, 1100, 1100, 1108, + 908, 908, 2514, 1282, 2514, 2514, 712, 713, 714, 715, + 716, 716, 716, 716, 716, 716, 717, 368, 368, 2514, + 2514, 368, 368, 2514, 2514, 368, 368, 368, 368, 368, + + 368, 368, 368, 368, 376, 368, 368, 368, 368, 368, + 2514, 1175, 377, 378, 379, 380, 381, 381, 381, 381, + 381, 381, 382, 1056, 1056, 1056, 1056, 1056, 1056, 1056, + 1056, 1056, 1056, 1056, 1180, 376, 368, 368, 368, 2514, + 368, 1058, 1175, 2514, 2514, 2514, 2514, 1283, 2514, 376, + 1109, 376, 1163, 1184, 376, 376, 376, 376, 1053, 2514, + 2514, 376, 1054, 2514, 2514, 1180, 457, 368, 370, 371, + 372, 373, 374, 374, 374, 374, 374, 374, 375, 397, + 376, 973, 376, 1163, 1184, 376, 376, 376, 376, 1053, + 1059, 399, 376, 1054, 458, 459, 460, 461, 462, 462, + + 462, 462, 462, 462, 463, 470, 471, 472, 473, 474, + 474, 474, 474, 474, 474, 475, 2514, 2514, 2514, 2514, + 2514, 1059, 399, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1060, 1061, 1185, 2514, 376, 376, + 376, 1193, 1199, 376, 1188, 377, 378, 379, 380, 381, + 381, 381, 381, 381, 381, 382, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 1060, 1061, 1185, 974, 376, + 376, 376, 1193, 1199, 376, 1188, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 1062, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 974, + + 2514, 2514, 2514, 376, 1194, 1197, 376, 376, 376, 1063, + 1228, 2514, 2514, 2514, 2514, 1192, 2514, 524, 1062, 2514, + 2514, 2514, 377, 378, 379, 380, 381, 381, 381, 381, + 381, 381, 382, 1064, 376, 1194, 1197, 376, 376, 376, + 1063, 1228, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1064, 1077, 1077, 1077, 1077, 1077, + 1077, 1077, 1077, 1077, 1077, 1077, 2514, 2514, 2514, 2514, + 2514, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 495, 526, 527, 528, 529, 530, 530, 530, + + 530, 530, 530, 531, 1078, 1078, 1078, 1078, 1078, 1078, + 1078, 1078, 1078, 1078, 1078, 1065, 540, 1081, 1081, 1081, + 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1079, + 2514, 376, 376, 1210, 376, 1226, 1065, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 502, 508, + 504, 505, 506, 506, 506, 506, 506, 506, 507, 495, + 1079, 1080, 376, 376, 1210, 376, 1226, 1066, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 541, + 542, 543, 544, 545, 545, 545, 545, 545, 545, 546, + + 376, 1112, 1080, 1235, 2514, 2514, 2514, 2514, 1066, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 552, + 2514, 376, 1112, 2514, 1235, 502, 508, 504, 505, 506, + 506, 506, 506, 506, 506, 507, 641, 642, 643, 644, + 645, 645, 645, 645, 645, 645, 646, 553, 554, 555, + 556, 557, 557, 557, 557, 557, 557, 558, 632, 632, + 1116, 2514, 632, 632, 2514, 2514, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 1113, 632, 632, 632, 632, + 632, 376, 1208, 1227, 376, 1232, 1203, 376, 1182, 641, + + 642, 643, 644, 645, 645, 645, 645, 645, 645, 646, + 2514, 1114, 376, 376, 1212, 376, 1113, 632, 632, 632, + 2514, 632, 376, 1208, 1227, 376, 1232, 1203, 376, 1182, + 376, 641, 642, 643, 644, 645, 645, 645, 645, 645, + 645, 646, 1114, 376, 376, 1212, 376, 2514, 632, 634, + 635, 636, 637, 638, 638, 638, 638, 638, 638, 639, + 1115, 376, 1234, 493, 1252, 2514, 376, 1263, 641, 642, + 643, 644, 645, 645, 645, 645, 645, 645, 646, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 2514, 1115, 2514, 1234, 493, 1252, 1126, 376, 1263, 641, + + 642, 643, 644, 645, 645, 645, 645, 645, 645, 646, + 667, 667, 2514, 2514, 667, 667, 2514, 2514, 667, 667, + 667, 667, 667, 667, 667, 667, 667, 1126, 667, 667, + 667, 667, 667, 1127, 376, 1264, 1236, 2514, 1209, 2514, + 1195, 676, 677, 678, 679, 680, 680, 680, 680, 680, + 680, 681, 2514, 376, 1253, 376, 1265, 493, 1266, 667, + 667, 667, 2514, 667, 1127, 376, 1264, 1236, 2514, 1209, + 945, 1195, 676, 677, 678, 679, 680, 680, 680, 680, + 680, 680, 681, 1128, 376, 1253, 376, 1265, 493, 1266, + 667, 669, 670, 671, 672, 673, 673, 673, 673, 673, + + 673, 674, 1129, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 676, 677, 678, 679, 680, 680, 680, 680, + 680, 680, 681, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 1267, 1268, 2514, 1129, 712, 713, 714, 715, 716, 716, + 716, 716, 716, 716, 717, 2514, 2514, 2514, 691, 692, + 693, 694, 695, 695, 695, 695, 695, 695, 696, 703, + 703, 1267, 1268, 703, 703, 1269, 2514, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 1170, 703, 703, 703, + 703, 703, 1167, 1181, 1196, 376, 1168, 1198, 1190, 1190, + 1190, 2514, 1200, 376, 1213, 376, 1269, 376, 376, 1206, + + 376, 376, 1270, 376, 1205, 1271, 376, 1170, 703, 703, + 703, 2514, 703, 1167, 1181, 1196, 376, 1168, 1198, 2514, + 1201, 1201, 1201, 1200, 376, 1213, 376, 376, 376, 376, + 1206, 376, 376, 1270, 376, 1205, 1271, 376, 2514, 703, + 705, 706, 707, 708, 709, 709, 709, 709, 709, 709, + 710, 723, 1204, 1142, 1207, 1211, 1214, 1215, 376, 376, + 1229, 1230, 376, 725, 1255, 376, 1233, 376, 2514, 1191, + 2514, 376, 376, 376, 493, 1224, 1224, 1224, 376, 2514, + 1272, 376, 1273, 1204, 2514, 1207, 1211, 1214, 1215, 2514, + 376, 1229, 1230, 376, 725, 1255, 376, 1233, 376, 2514, + + 2514, 1202, 376, 376, 376, 493, 2514, 2514, 2514, 376, + 464, 1272, 376, 1273, 376, 376, 1231, 712, 713, 714, + 715, 716, 716, 716, 716, 716, 716, 717, 2514, 376, + 1238, 1237, 2514, 1240, 1274, 1276, 1239, 1143, 1242, 1256, + 1257, 376, 376, 376, 376, 376, 376, 1231, 376, 376, + 376, 376, 493, 493, 493, 1244, 1225, 1277, 1278, 1279, + 376, 1238, 1237, 1254, 1240, 1274, 1276, 1239, 1143, 1242, + 1256, 1257, 376, 376, 2514, 1034, 2514, 1245, 1241, 376, + 376, 376, 376, 493, 493, 493, 2514, 376, 1277, 1278, + 1279, 2514, 2514, 2514, 712, 713, 714, 715, 716, 716, + + 716, 716, 716, 716, 717, 397, 2514, 1160, 1245, 1241, + 2514, 1289, 1104, 1104, 1246, 1290, 1260, 399, 376, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 493, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 2514, 2514, 2514, 1246, 2514, 1260, 399, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 1247, 493, 1285, 1102, 1102, 1119, 919, 919, 2514, 1286, + 2514, 377, 378, 379, 380, 381, 381, 381, 381, 381, + 381, 382, 2514, 1248, 2514, 2514, 1124, 924, 924, 2514, + 2514, 1247, 1291, 2514, 470, 471, 472, 473, 474, 474, + + 474, 474, 474, 474, 475, 2514, 1292, 1161, 2514, 1302, + 2514, 1303, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1258, 1259, 495, 1292, 1161, 1250, + 1302, 493, 1303, 1287, 2514, 493, 1120, 2514, 377, 378, + 379, 380, 381, 381, 381, 381, 381, 381, 382, 1034, + 1034, 1034, 711, 2514, 2514, 1258, 1259, 1125, 1312, 2514, + 1311, 2514, 493, 2514, 2514, 2514, 493, 1368, 640, 2514, + 1216, 2514, 1370, 1217, 1218, 1371, 2514, 1372, 1373, 1134, + 936, 936, 1369, 711, 1219, 1220, 1221, 1249, 2514, 1312, + + 1222, 1311, 502, 508, 504, 505, 506, 506, 506, 506, + 506, 506, 507, 1370, 1217, 1218, 1371, 2514, 1372, 1373, + 2514, 2514, 2514, 1369, 1300, 1219, 1220, 1221, 1249, 1261, + 2514, 1222, 1146, 949, 949, 1151, 953, 953, 1262, 2514, + 1223, 1374, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 495, 642, 2514, 2514, 2514, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 1262, + 1135, 2514, 1374, 1375, 2514, 1294, 2514, 1418, 1419, 1251, + 691, 692, 693, 694, 695, 695, 695, 695, 695, 695, + 696, 2514, 533, 534, 535, 536, 537, 537, 537, 537, + + 537, 537, 538, 2514, 1375, 723, 1294, 1308, 1418, 1419, + 1251, 2514, 2514, 1147, 1421, 2514, 1152, 939, 1423, 502, + 508, 504, 505, 506, 506, 506, 506, 506, 506, 507, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 1295, 1295, 1295, 2514, 1421, 1296, 2514, 939, 1423, + 2514, 2514, 2514, 2514, 1297, 1424, 640, 2514, 2514, 2514, + 1305, 2514, 640, 397, 2514, 1314, 2514, 2514, 2514, 2514, + 2514, 2514, 493, 1299, 1410, 756, 2514, 2514, 2514, 493, + 493, 1301, 1425, 1411, 1304, 2514, 1424, 2514, 493, 676, + 677, 678, 679, 680, 680, 680, 680, 680, 680, 681, + + 1409, 1412, 1306, 493, 1299, 1410, 756, 2514, 2514, 2514, + 493, 493, 1301, 1425, 1411, 1304, 2514, 2514, 2514, 493, + 2514, 641, 1298, 643, 644, 645, 645, 645, 645, 645, + 645, 646, 642, 1306, 2514, 2514, 2514, 2514, 642, 676, + 677, 678, 679, 680, 680, 680, 680, 680, 680, 681, + 2514, 2514, 2514, 2514, 1318, 1427, 1429, 378, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 723, + 2514, 1309, 2514, 1319, 1415, 2514, 2514, 2514, 2514, 493, + 1320, 725, 2514, 2514, 2514, 1318, 1427, 1429, 378, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 378, 2514, 2514, + + 2514, 2514, 2514, 2514, 1319, 1415, 2514, 2514, 2514, 2514, + 493, 1320, 725, 2514, 2514, 378, 1322, 1321, 1323, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 1430, 1325, 1431, 1324, + 2514, 378, 2514, 1328, 2514, 712, 713, 714, 715, 716, + 716, 716, 716, 716, 716, 717, 2514, 1322, 1321, 1323, + 2514, 2514, 2514, 493, 1310, 1326, 378, 1430, 1325, 1431, + 1324, 1327, 1432, 378, 1328, 2514, 2514, 2514, 2514, 2514, + 378, 2514, 2514, 2514, 1416, 378, 1329, 1434, 1435, 378, + 2514, 2514, 378, 2514, 493, 1310, 1326, 2514, 378, 2514, + 2514, 2514, 1327, 1432, 2514, 1330, 2514, 2514, 2514, 2514, + + 378, 2514, 2514, 378, 2514, 2514, 2514, 1329, 1434, 1435, + 2514, 1331, 712, 713, 714, 715, 716, 716, 716, 716, + 716, 716, 717, 397, 2514, 1315, 1330, 1333, 1456, 1491, + 1332, 378, 2514, 2514, 2514, 399, 2514, 2514, 2514, 2514, + 2514, 2514, 1331, 2514, 2514, 2514, 378, 2514, 2514, 2514, + 2514, 2514, 378, 1492, 2514, 1334, 2514, 2514, 1333, 1456, + 1491, 1332, 2514, 2514, 2514, 2514, 399, 2514, 2514, 2514, + 378, 2514, 2514, 2514, 2514, 1337, 1338, 1500, 378, 2514, + 2514, 2514, 2514, 2514, 1492, 378, 1334, 1335, 1339, 377, + 378, 379, 380, 381, 381, 381, 381, 381, 381, 382, + + 1316, 1316, 1316, 2514, 2514, 2514, 1337, 1338, 1500, 711, + 1190, 1190, 1190, 378, 2514, 2514, 2514, 378, 1336, 1339, + 378, 1340, 2514, 1464, 378, 2514, 2514, 2514, 378, 2514, + 2514, 2514, 2514, 2514, 2514, 1346, 1346, 1346, 1341, 2514, + 711, 464, 2514, 378, 2514, 1517, 376, 1342, 378, 2514, + 1347, 2514, 1340, 378, 1464, 2514, 2514, 2514, 2514, 2514, + 2514, 378, 1344, 2514, 2514, 2514, 2514, 2514, 2514, 1341, + 2514, 2514, 2514, 376, 376, 376, 1517, 376, 1342, 1518, + 377, 1317, 379, 380, 381, 381, 381, 381, 381, 381, + 382, 1343, 1519, 1344, 1345, 1349, 2514, 2514, 2514, 1351, + + 2514, 2514, 2514, 2514, 376, 2514, 1190, 1201, 1201, 1201, + 1518, 2514, 2514, 378, 1520, 2514, 1348, 1356, 1356, 1356, + 2514, 1522, 464, 1519, 2514, 1345, 1349, 376, 2514, 2514, + 1351, 493, 1350, 2514, 2514, 2514, 378, 2514, 2514, 378, + 1524, 1352, 1413, 1527, 1353, 1520, 378, 2514, 2514, 2514, + 2514, 378, 1522, 2514, 376, 376, 376, 2514, 376, 2514, + 2514, 2514, 493, 1350, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 1524, 1352, 1413, 1527, 1353, 2514, 378, 2514, 2514, + 2514, 378, 1361, 1361, 1361, 376, 1355, 1201, 1354, 2514, + 2514, 2514, 2514, 1359, 2514, 2514, 2514, 2514, 1357, 2514, + + 2514, 2514, 1360, 2514, 1358, 2514, 2514, 2514, 1514, 2514, + 2514, 2514, 1515, 1516, 378, 1363, 1364, 1355, 2514, 2514, + 2514, 2514, 2514, 2514, 1359, 2514, 2514, 2514, 378, 2514, + 2514, 2514, 2514, 1360, 1365, 1358, 493, 1528, 2514, 1514, + 378, 1366, 1414, 1515, 1516, 378, 1363, 1364, 378, 2514, + 1367, 1531, 2514, 2514, 2514, 2514, 2514, 2514, 1390, 378, + 2514, 2514, 2514, 1362, 464, 1365, 2514, 493, 1528, 376, + 378, 2514, 1366, 1414, 2514, 378, 2514, 2514, 2514, 2514, + 378, 1367, 1531, 2514, 2514, 2514, 378, 2514, 2514, 1390, + 378, 1224, 1224, 1224, 2514, 1391, 376, 376, 376, 378, + + 376, 2514, 378, 2514, 2514, 2514, 378, 1532, 1392, 2514, + 378, 2514, 2514, 2514, 1376, 1377, 1378, 1379, 1380, 1381, + 2514, 1382, 1533, 1383, 1534, 1384, 1391, 376, 1385, 1224, + 1535, 1386, 1387, 2514, 2514, 1388, 378, 2514, 1532, 1392, + 2514, 2514, 2514, 2514, 2514, 1376, 1377, 1378, 1379, 1380, + 1381, 1398, 1382, 1533, 1383, 1534, 1384, 378, 723, 1385, + 1461, 1535, 1386, 1387, 378, 1397, 1388, 2514, 2514, 2514, + 939, 2514, 1389, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 1398, 711, 378, 2514, 2514, 2514, 397, 1393, + 1466, 2514, 378, 2514, 1463, 1394, 1397, 2514, 2514, 2514, + + 756, 939, 1395, 1402, 1525, 1396, 1536, 1526, 1399, 2514, + 2514, 2514, 2514, 2514, 711, 1529, 1537, 2514, 2514, 1539, + 1393, 378, 1281, 1100, 1100, 1463, 1394, 1530, 1555, 1282, + 1538, 756, 1400, 1395, 1403, 1525, 1396, 1536, 1526, 1399, + 2514, 2514, 1285, 1102, 1102, 2514, 1529, 1537, 378, 1286, + 1539, 2514, 2514, 2514, 378, 2514, 2514, 378, 1530, 1555, + 378, 1538, 2514, 1400, 2514, 1403, 378, 470, 471, 472, + 473, 474, 474, 474, 474, 474, 474, 475, 378, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 378, 470, 471, 472, 473, 474, 474, 474, 474, 474, + + 474, 475, 1404, 1283, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 1405, 533, 534, 535, 536, 537, 537, 537, 537, + 537, 537, 538, 1287, 493, 493, 1406, 2514, 2514, 2514, + 2514, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 1405, 1289, 1104, 1104, 1559, 1290, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 493, 493, 1406, 2514, 2514, + 2514, 1436, 2514, 2514, 2514, 2514, 2514, 470, 471, 472, + 473, 474, 474, 474, 474, 474, 474, 475, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 495, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + + 646, 2514, 723, 1553, 1462, 1471, 493, 493, 378, 2514, + 711, 1478, 1478, 1478, 725, 1557, 1407, 2514, 1556, 1417, + 1558, 2514, 493, 1561, 1291, 2514, 1479, 1295, 1295, 1295, + 378, 2514, 1437, 378, 1553, 2514, 1471, 493, 493, 378, + 1297, 711, 2514, 2514, 378, 725, 1557, 1407, 1453, 1556, + 1417, 1558, 1438, 493, 1561, 502, 508, 504, 505, 506, + 506, 506, 506, 506, 506, 507, 495, 533, 534, 535, + 536, 537, 537, 537, 537, 537, 537, 538, 1563, 1453, + 1564, 1565, 1408, 1438, 2514, 1457, 2514, 2514, 2514, 2514, + 2514, 2514, 1480, 2514, 1569, 641, 642, 643, 644, 645, + + 645, 645, 645, 645, 645, 646, 2514, 2514, 1439, 1563, + 2514, 1564, 1565, 1408, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 1569, 2514, 2514, 2514, 2514, + 2514, 2514, 502, 508, 504, 505, 506, 506, 506, 506, + 506, 506, 507, 1440, 1441, 1295, 1295, 1440, 1440, 1442, + 1443, 1440, 1440, 1440, 1440, 1440, 1440, 1444, 1440, 1440, + 1443, 1440, 1440, 1440, 1440, 1440, 1443, 1443, 1443, 1445, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1440, 1440, 1440, 1443, 1440, 1443, 1443, 1443, + + 1445, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1440, 1446, 1447, 1448, 1449, 1450, 1450, + 1450, 1450, 1450, 1450, 1451, 2514, 2514, 1454, 1570, 2514, + 2514, 2514, 2514, 2514, 2514, 1571, 654, 1316, 1316, 1316, + 2514, 640, 2514, 2514, 1455, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1454, 1570, + 2514, 1488, 1488, 1488, 2514, 2514, 1571, 2514, 640, 640, + 640, 1458, 640, 1472, 1468, 1455, 1489, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 641, 642, + + 643, 644, 645, 645, 645, 645, 645, 645, 646, 640, + 2514, 1295, 1458, 1459, 1472, 1468, 2514, 2514, 2514, 2514, + 378, 2514, 1572, 378, 2514, 2514, 2514, 2514, 1469, 2514, + 2514, 676, 677, 678, 679, 680, 680, 680, 680, 680, + 680, 681, 378, 1470, 1459, 378, 2514, 2514, 2514, 2514, + 2514, 2514, 1490, 1572, 2514, 2514, 2514, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 397, 2514, + 1467, 2514, 2514, 2514, 1470, 2514, 2514, 2514, 2514, 2514, + 399, 2514, 1573, 464, 2514, 2514, 2514, 1473, 376, 2514, + 1474, 2514, 2514, 2514, 1574, 2514, 2514, 2514, 378, 2514, + + 1475, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1576, 2514, + 1476, 399, 1577, 1573, 1481, 376, 376, 376, 1473, 376, + 1477, 1474, 2514, 2514, 2514, 1574, 2514, 378, 1482, 2514, + 378, 1475, 2514, 2514, 2514, 378, 2514, 2514, 2514, 1576, + 1483, 1476, 1578, 1577, 1484, 1481, 376, 2514, 1316, 2514, + 2514, 1477, 2514, 2514, 2514, 2514, 2514, 378, 2514, 1482, + 2514, 2514, 2514, 2514, 2514, 378, 1494, 1486, 2514, 2514, + 2514, 1483, 378, 1578, 2514, 1484, 378, 2514, 2514, 2514, + 1346, 1346, 1346, 378, 2514, 2514, 378, 2514, 2514, 2514, + 1554, 1485, 2514, 2514, 2514, 1347, 493, 1494, 1486, 1487, + + 1560, 1498, 2514, 378, 464, 2514, 2514, 2514, 493, 376, + 2514, 1583, 1493, 378, 2514, 2514, 2514, 378, 2514, 2514, + 2514, 1554, 1485, 1356, 1356, 1356, 1585, 493, 1497, 1566, + 1487, 1560, 1498, 378, 1567, 1499, 376, 376, 376, 493, + 376, 378, 1583, 1493, 1501, 711, 1502, 2514, 2514, 378, + 2514, 2514, 2514, 1606, 2514, 2514, 2514, 1585, 378, 1497, + 1566, 1495, 2514, 2514, 2514, 1567, 1499, 376, 378, 1346, + 2514, 2514, 711, 464, 2514, 1501, 711, 1502, 376, 1504, + 1505, 1361, 1361, 1361, 1606, 1602, 378, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 378, 2514, 2514, 2514, 378, + + 2514, 2514, 2514, 711, 1503, 376, 376, 376, 2514, 376, + 1504, 1505, 2514, 2514, 1508, 1506, 1602, 1511, 1511, 1511, + 2514, 2514, 1509, 464, 2514, 2514, 2514, 1620, 376, 2514, + 1621, 378, 1512, 2514, 2514, 378, 376, 2514, 1356, 2514, + 2514, 2514, 1510, 2514, 2514, 1508, 1506, 2514, 2514, 2514, + 2514, 2514, 2514, 1509, 1628, 376, 376, 376, 1620, 376, + 1540, 1621, 1507, 2514, 2514, 2514, 1629, 2514, 378, 2514, + 2514, 378, 1633, 1510, 2514, 2514, 2514, 378, 1543, 1543, + 1543, 378, 2514, 2514, 2514, 1628, 376, 1541, 1361, 2514, + 1641, 1540, 1642, 1544, 2514, 2514, 2514, 1629, 1513, 2514, + + 2514, 2514, 2514, 1633, 723, 378, 1600, 1643, 1546, 2514, + 2514, 2514, 1644, 2514, 1645, 1542, 939, 723, 1541, 1601, + 378, 1641, 1646, 1642, 2514, 711, 1647, 1550, 378, 725, + 397, 378, 1604, 1547, 1592, 1592, 1592, 1548, 1643, 1546, + 1648, 1649, 756, 1644, 378, 1645, 1542, 939, 1650, 1651, + 2514, 2514, 1652, 1646, 2514, 378, 711, 1647, 1653, 1545, + 725, 2514, 2514, 378, 1547, 2514, 2514, 2514, 1548, 2514, + 2514, 1648, 1649, 756, 2514, 378, 2514, 2514, 2514, 1650, + 1651, 378, 1551, 1652, 2514, 2514, 2514, 2514, 1552, 1653, + 378, 470, 471, 472, 473, 474, 474, 474, 474, 474, + + 474, 475, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 1551, 2514, 1593, 2514, 2514, 2514, 1552, + 2514, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1562, 1579, 1654, 378, 2514, 2514, + 2514, 1655, 1656, 1441, 1295, 1295, 378, 2514, 1580, 1441, + 1295, 1295, 2514, 2514, 1580, 2514, 1444, 2514, 2514, 2514, + 2514, 2514, 1444, 2514, 2514, 1562, 1579, 1654, 1581, 2514, + 2514, 2514, 1655, 1656, 1581, 2514, 641, 642, 643, 644, + + 645, 645, 645, 645, 645, 645, 646, 1608, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 1581, + 1657, 1441, 1295, 1295, 2514, 1581, 1580, 1441, 1295, 1295, + 2514, 1658, 1580, 1659, 1444, 2514, 2514, 2514, 1608, 378, + 1584, 2514, 2514, 2514, 1582, 2514, 1581, 2514, 2514, 2514, + 1582, 1657, 1581, 2514, 2514, 1441, 1295, 1295, 378, 2514, + 1580, 397, 1658, 1605, 1659, 1660, 1661, 1609, 1444, 2514, + 378, 1586, 1662, 399, 1663, 1664, 1607, 1581, 2514, 2514, + 1581, 1665, 1666, 1581, 641, 642, 643, 644, 645, 645, + 645, 645, 645, 645, 646, 1594, 1660, 1661, 1609, 1478, + + 1478, 1478, 1582, 1662, 399, 1663, 1664, 1607, 1582, 1580, + 1440, 1581, 1665, 1666, 1479, 2514, 378, 2514, 2514, 2514, + 1586, 2514, 378, 2514, 1595, 1443, 1594, 2514, 378, 1688, + 493, 2514, 2514, 2514, 2514, 2514, 1582, 2514, 2514, 2514, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 1679, 1443, 1443, 1443, 1595, 1443, 2514, 2514, 2514, + 1688, 493, 641, 642, 643, 644, 645, 645, 645, 645, + 645, 645, 646, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 1611, 2514, 2514, 1443, 1443, 1587, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1440, 1441, 1295, 1295, 1440, + + 1440, 1580, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1444, + 1440, 1440, 1586, 1440, 1440, 1440, 1440, 1596, 378, 1690, + 1691, 1590, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 378, 2514, + 1597, 2514, 2514, 2514, 1610, 1692, 2514, 2514, 1596, 2514, + 1690, 1691, 1590, 2514, 378, 1488, 1488, 1488, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 1598, + 1489, 1597, 2514, 2514, 2514, 1610, 1692, 1591, 2514, 2514, + 2514, 1440, 1440, 2514, 1440, 676, 677, 678, 679, 680, + 680, 680, 680, 680, 680, 681, 2514, 2514, 2514, 2514, + + 1598, 2514, 1617, 378, 1613, 2514, 378, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 2514, 2514, + 1614, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 464, + 2514, 2514, 2514, 1617, 376, 1613, 1618, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 1614, 1616, 378, 2514, 2514, 2514, 1615, 2514, 378, + 2514, 376, 376, 376, 1622, 376, 1630, 1630, 1630, 2514, + 2514, 2514, 1693, 1623, 2514, 493, 1627, 378, 2514, 2514, + 464, 1631, 2514, 1616, 1678, 376, 1634, 2514, 1615, 2514, + 2514, 2514, 376, 2514, 1478, 1622, 2514, 2514, 2514, 2514, + + 2514, 1694, 378, 1693, 1623, 378, 493, 1627, 2514, 2514, + 2514, 378, 376, 376, 376, 1678, 376, 1634, 378, 2514, + 2514, 378, 2514, 2514, 378, 493, 2514, 378, 2514, 2514, + 2514, 1635, 1694, 2514, 2514, 378, 1511, 1511, 1511, 2514, + 2514, 1681, 2514, 376, 1695, 1488, 2514, 1632, 2514, 1667, + 464, 1512, 1543, 1543, 1543, 376, 493, 1636, 2514, 2514, + 2514, 1637, 1635, 2514, 2514, 2514, 2514, 1544, 1696, 1668, + 378, 1697, 1681, 1638, 1680, 1695, 2514, 378, 2514, 493, + 1667, 2514, 376, 376, 376, 2514, 376, 2514, 2514, 378, + 1669, 2514, 1637, 2514, 2514, 2514, 2514, 2514, 464, 1696, + + 1668, 2514, 1697, 376, 1638, 1680, 2514, 2514, 2514, 378, + 493, 1682, 1683, 376, 2514, 1511, 493, 1639, 2514, 1672, + 493, 1669, 1684, 1685, 1675, 1698, 1699, 493, 493, 1700, + 376, 376, 376, 1670, 376, 1686, 1701, 1702, 1703, 378, + 493, 1706, 1682, 1683, 1710, 378, 1673, 493, 2514, 1676, + 1672, 493, 1585, 1684, 1685, 711, 1698, 1699, 493, 493, + 1700, 376, 2514, 1543, 2514, 2514, 1686, 1701, 1702, 1703, + 2514, 493, 1706, 2514, 378, 1710, 2514, 1673, 2514, 1677, + 1676, 2514, 1731, 1585, 1746, 2514, 711, 378, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 470, + + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 1677, 1687, 1704, 1731, 2514, 1746, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 470, 471, 472, 473, 474, 474, + 474, 474, 474, 474, 475, 2514, 2514, 2514, 2514, 1747, + 1755, 2514, 1687, 1704, 2514, 533, 534, 535, 536, 537, + 537, 537, 537, 537, 537, 538, 641, 642, 643, 644, + 645, 645, 645, 645, 645, 645, 646, 1441, 1295, 1295, + 1747, 1755, 1580, 1441, 1295, 1295, 2514, 2514, 1580, 2514, + 1444, 2514, 1441, 1295, 1295, 2514, 1444, 1580, 1707, 1708, + 1708, 2514, 1581, 1580, 723, 1444, 1726, 378, 1581, 2514, + + 397, 1584, 1729, 1441, 1295, 1295, 939, 1581, 1580, 1715, + 1708, 1708, 756, 1581, 1716, 1705, 1444, 378, 723, 2514, + 1727, 2514, 1717, 1581, 1756, 2514, 711, 1759, 1581, 1581, + 725, 2514, 2514, 1761, 1718, 2514, 2514, 939, 1581, 2514, + 2514, 2514, 1762, 756, 1581, 1763, 1705, 1768, 1582, 2514, + 2514, 2514, 2514, 2514, 1582, 1756, 1720, 711, 1759, 1581, + 2514, 725, 1721, 1588, 1761, 1718, 2514, 2514, 2514, 1709, + 1441, 1295, 1295, 1762, 2514, 1580, 1763, 2514, 1768, 2514, + 397, 2514, 1730, 1444, 1588, 2514, 2514, 1720, 1722, 1770, + 1719, 1735, 399, 1721, 1773, 1581, 641, 642, 643, 644, + + 645, 645, 645, 645, 645, 645, 646, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 1774, 1722, + 1770, 2514, 1735, 399, 2514, 1773, 1581, 2514, 2514, 2514, + 1723, 378, 676, 677, 678, 679, 680, 680, 680, 680, + 680, 680, 681, 2514, 2514, 2514, 2514, 378, 2514, 1774, + 1711, 1712, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, + 1711, 1723, 1724, 2514, 2514, 2514, 2514, 2514, 2514, 1732, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 1724, 2514, 2514, 2514, 2514, 1775, 1733, + + 1732, 1734, 2514, 2514, 2514, 2514, 2514, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 1739, 1771, + 1748, 1776, 1777, 1741, 378, 1740, 2514, 2514, 2514, 1775, + 1733, 2514, 1734, 1780, 1751, 1751, 1751, 1772, 1742, 2514, + 2514, 2514, 1781, 2514, 378, 2514, 2514, 378, 2514, 1739, + 1771, 1748, 1776, 1777, 1741, 1778, 1740, 1630, 1630, 1630, + 1782, 1783, 378, 1752, 1780, 1749, 1779, 378, 1772, 1742, + 378, 1784, 1631, 1781, 1754, 378, 2514, 2514, 2514, 2514, + 2514, 1785, 1786, 378, 2514, 1787, 1778, 1788, 2514, 2514, + 464, 1782, 1783, 2514, 1752, 376, 1749, 1779, 1789, 1792, + + 1790, 1793, 1784, 1794, 1795, 1754, 1802, 378, 2514, 2514, + 2514, 2514, 1785, 1786, 2514, 1753, 1787, 1760, 1788, 2514, + 378, 1791, 376, 376, 376, 2514, 376, 1806, 493, 1789, + 1792, 1790, 1793, 493, 1794, 1795, 493, 493, 1757, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1760, 2514, + 2514, 2514, 1791, 376, 1805, 1630, 1803, 378, 1806, 493, + 2514, 493, 493, 493, 493, 1807, 1810, 493, 493, 1796, + 470, 471, 472, 473, 474, 474, 474, 474, 474, 474, + 475, 2514, 1811, 1808, 1812, 1800, 1813, 1803, 1815, 378, + 493, 1804, 493, 493, 493, 2514, 1807, 1810, 1816, 2514, + + 1796, 2514, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 1811, 1808, 1812, 1800, 1813, 2514, 1815, + 378, 493, 1804, 378, 1817, 1818, 378, 1819, 1821, 1816, + 378, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 533, 534, 535, 536, 537, 537, 537, 537, + 537, 537, 538, 1829, 2514, 1817, 1818, 1848, 1819, 1821, + 2514, 1863, 2514, 641, 642, 643, 644, 645, 645, 645, + 645, 645, 645, 646, 1441, 1295, 1295, 2514, 1864, 1580, + 1823, 1708, 1708, 2514, 1829, 1824, 2514, 1444, 1848, 1715, + 1708, 1708, 1863, 1825, 1716, 1869, 1820, 1870, 2514, 1581, + + 2514, 723, 1717, 1843, 2514, 1826, 1441, 1295, 1295, 1864, + 2514, 1580, 1871, 939, 1718, 2514, 1441, 1295, 1295, 1444, + 2514, 1580, 2514, 2514, 2514, 2514, 1869, 1820, 1870, 1444, + 1581, 1581, 1443, 1441, 1295, 1295, 1826, 2514, 1580, 2514, + 2514, 1581, 2514, 1871, 939, 1718, 1444, 2514, 2514, 1443, + 2514, 1830, 1295, 1295, 2514, 1582, 1716, 1875, 1581, 1876, + 2514, 1827, 1581, 2514, 1717, 2514, 1715, 1708, 1708, 2514, + 1719, 1716, 1581, 1832, 1295, 1295, 1718, 2514, 1824, 1717, + 1830, 1295, 1295, 2514, 2514, 1716, 1825, 1828, 1875, 1581, + 1876, 1718, 2514, 1834, 2514, 2514, 2514, 1582, 1826, 1830, + + 1295, 1295, 2514, 378, 1716, 1718, 2514, 1718, 1830, 1295, + 1295, 2514, 1717, 1716, 1588, 397, 2514, 1846, 1877, 1878, + 1851, 1717, 1718, 723, 1718, 1844, 1883, 756, 1884, 1826, + 2514, 711, 1831, 1718, 1885, 725, 1718, 1837, 1886, 1887, + 2514, 1835, 2514, 2514, 2514, 1888, 2514, 1719, 1889, 1877, + 1878, 1851, 1892, 1893, 1833, 1718, 1894, 1883, 756, 1884, + 2514, 1831, 711, 2514, 1718, 1885, 725, 2514, 1837, 1886, + 1887, 1838, 1835, 2514, 2514, 378, 1888, 1849, 1895, 1889, + 1831, 2514, 2514, 1892, 1893, 2514, 2514, 1894, 2514, 1836, + 1839, 641, 642, 643, 644, 645, 645, 645, 645, 645, + + 645, 646, 1838, 2514, 2514, 2514, 1840, 1841, 1849, 1895, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 1839, 2514, 378, 2514, 2514, 676, 677, 678, 679, + 680, 680, 680, 680, 680, 680, 681, 1840, 1841, 2514, + 2514, 2514, 2514, 1896, 1850, 2514, 676, 677, 678, 679, + 680, 680, 680, 680, 680, 680, 681, 2514, 2514, 2514, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 397, 2514, 1847, 1896, 1850, 1853, 1853, 1853, 2514, + 2514, 2514, 1897, 399, 378, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 1860, 1860, 1860, 2514, 2514, 2514, 2514, 2514, + + 2514, 1867, 1867, 1867, 1898, 1854, 2514, 2514, 1751, 1751, + 1751, 1857, 1899, 1897, 399, 2514, 1347, 1900, 1901, 1856, + 378, 1861, 2514, 2514, 2514, 1904, 2514, 1858, 1866, 2514, + 2514, 2514, 1905, 1906, 1865, 1898, 1854, 1752, 378, 1890, + 1890, 1890, 1857, 1899, 1907, 1880, 1880, 1880, 1900, 1901, + 1856, 2514, 1861, 1902, 1902, 1902, 1904, 1855, 1858, 1866, + 378, 1908, 1909, 1905, 1906, 1865, 378, 1910, 1752, 378, + 1911, 1912, 2514, 1862, 1881, 1907, 378, 2514, 2514, 378, + 493, 2514, 1868, 2514, 2514, 2514, 1915, 1915, 1915, 1753, + 1922, 1926, 1908, 1909, 2514, 2514, 2514, 1920, 1910, 1923, + + 1927, 1911, 1912, 378, 493, 1881, 2514, 1928, 493, 1924, + 378, 493, 1919, 493, 1930, 1916, 1931, 1932, 1933, 1913, + 1891, 1922, 1926, 2514, 2514, 2514, 1882, 2514, 1920, 1925, + 1923, 1927, 1957, 2514, 1903, 493, 2514, 1921, 1928, 493, + 1924, 2514, 2514, 1960, 493, 1930, 1916, 1931, 1932, 1933, + 1913, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 2514, 1957, 378, 2514, 2514, 1917, 1921, 2514, + 2514, 2514, 2514, 1938, 1960, 378, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 470, 471, 472, + 473, 474, 474, 474, 474, 474, 474, 475, 1934, 1934, + + 1934, 2514, 2514, 2514, 1938, 1964, 2514, 2514, 2514, 2514, + 2514, 1965, 1935, 641, 642, 643, 644, 645, 645, 645, + 645, 645, 645, 646, 1441, 1295, 1295, 2514, 1966, 1580, + 1832, 1295, 1295, 2514, 2514, 1824, 1964, 1444, 2514, 1823, + 1708, 1708, 1965, 1825, 1824, 1832, 1295, 1295, 2514, 1581, + 1824, 378, 1825, 1969, 723, 1826, 1952, 1939, 1825, 1966, + 1832, 1295, 1295, 2514, 1826, 1824, 939, 1970, 1975, 397, + 1826, 1955, 1976, 1940, 2514, 1853, 1853, 1853, 2514, 1936, + 1581, 756, 378, 2514, 1969, 1826, 1826, 378, 1939, 1832, + 1295, 1295, 2514, 2514, 1824, 1826, 1977, 939, 1970, 1975, + + 2514, 1826, 1825, 1976, 1854, 1582, 1978, 2514, 1832, 1295, + 1295, 1833, 756, 1824, 1826, 1981, 1826, 1823, 1708, 1708, + 1827, 1825, 1824, 1830, 1295, 1295, 1833, 1977, 1716, 1982, + 1825, 1941, 2514, 1826, 2514, 1854, 1717, 1978, 1830, 1295, + 1295, 1833, 1826, 1716, 2514, 1826, 1981, 723, 1718, 1953, + 1983, 1717, 1832, 1295, 1295, 711, 1855, 1824, 2514, 725, + 1982, 2514, 1941, 1718, 1826, 1825, 1984, 1832, 1295, 1295, + 1833, 2514, 1824, 1826, 2514, 2514, 2514, 1826, 1985, 1718, + 1825, 1983, 1715, 1708, 1708, 2514, 711, 1716, 2514, 1942, + 725, 2514, 1826, 1986, 1718, 1834, 1987, 1984, 1943, 2514, + + 1830, 1295, 1295, 2514, 1831, 1716, 1988, 1718, 1826, 1985, + 2514, 1989, 1990, 1717, 1991, 1715, 1708, 1708, 1992, 1944, + 1716, 1993, 1946, 1826, 1986, 1718, 1994, 1987, 1717, 1958, + 1958, 1958, 2514, 1833, 2514, 2514, 2514, 1988, 1718, 1995, + 1718, 1948, 1989, 1990, 1479, 1991, 2514, 1996, 1945, 1992, + 2514, 2514, 1993, 1946, 2514, 378, 1718, 1994, 1962, 1962, + 1962, 2514, 1997, 1719, 1867, 1867, 1867, 2514, 2514, 2514, + 1995, 1718, 1948, 1489, 2514, 2514, 2514, 1949, 1996, 1347, + 2514, 1831, 641, 642, 643, 644, 645, 645, 645, 645, + 645, 645, 646, 1997, 2514, 2514, 1947, 641, 642, 643, + + 644, 645, 645, 645, 645, 645, 645, 646, 1949, 1950, + 1959, 2514, 2514, 2514, 2514, 378, 2514, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 1963, + 1950, 1961, 1860, 1860, 1860, 1868, 1998, 2514, 2514, 2514, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 397, 2514, 1956, 2514, 2514, 2514, 2514, 2514, 2514, + 2002, 1861, 1961, 399, 1972, 1972, 1972, 1998, 1979, 1979, + 1979, 1880, 1880, 1880, 1890, 1890, 1890, 2003, 1902, 1902, + 1902, 2004, 378, 1512, 2005, 2014, 2015, 2514, 2514, 2016, + + 2017, 2002, 1861, 1973, 399, 1967, 2021, 493, 1968, 493, + 1881, 2028, 1999, 2514, 2514, 2000, 2514, 2514, 2003, 2514, + 2514, 2514, 2004, 1862, 2514, 2005, 2014, 2015, 378, 2001, + 2016, 2017, 2029, 493, 1973, 2030, 1967, 2021, 493, 1968, + 493, 1881, 2028, 1999, 2026, 378, 2000, 493, 378, 2514, + 2514, 2514, 2019, 2019, 2019, 1974, 2514, 2027, 2514, 1980, + 2001, 2031, 1882, 2029, 493, 1891, 2030, 1544, 2032, 1903, + 2006, 1915, 1915, 1915, 2023, 2026, 2007, 2514, 493, 2036, + 2008, 2009, 2047, 2049, 2018, 2010, 2011, 2012, 2027, 2013, + 2051, 723, 2031, 2042, 1934, 1934, 1934, 2048, 2052, 2032, + + 1916, 2006, 2514, 939, 2514, 2514, 2514, 2007, 1935, 2514, + 2036, 2008, 2009, 2047, 2049, 2018, 2010, 2011, 2012, 2024, + 2013, 2051, 2053, 2056, 2057, 2060, 2061, 2062, 2048, 2052, + 378, 1916, 2514, 2020, 939, 2033, 2033, 2033, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 2025, + 2024, 2063, 1917, 2053, 2056, 2057, 2060, 2061, 2062, 1958, + 1958, 1958, 2514, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1479, 1936, 2034, 1972, 1972, 1972, + 2025, 2514, 2063, 2514, 2514, 1962, 1962, 1962, 2514, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + + 1489, 2064, 2514, 723, 2514, 2043, 1973, 2034, 2514, 2514, + 2514, 711, 2514, 2514, 2514, 725, 2035, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 1441, 1295, + 1295, 2514, 2064, 1580, 1823, 1708, 1708, 1973, 2065, 1824, + 1959, 1444, 711, 1832, 1295, 1295, 725, 1940, 1824, 1823, + 1708, 1708, 2514, 1581, 1824, 397, 1825, 2045, 1974, 1826, + 2066, 2067, 1825, 2054, 2514, 2037, 1963, 756, 1826, 2065, + 1832, 1295, 1295, 2514, 1826, 1824, 1830, 1295, 1295, 2068, + 2514, 1716, 2514, 1825, 1581, 2058, 2058, 2058, 2514, 1717, + 1826, 2066, 2067, 378, 2514, 1826, 2037, 2514, 756, 1826, + + 1631, 1718, 2514, 2514, 2514, 1826, 1832, 1295, 1295, 1582, + 2068, 1824, 1830, 1295, 1295, 1827, 397, 1716, 2046, 1825, + 2514, 2069, 2070, 2076, 1833, 1717, 1826, 2514, 399, 2082, + 1943, 1826, 1718, 1830, 1295, 1295, 2085, 1718, 1716, 2086, + 1525, 1529, 2087, 2088, 2089, 2038, 1717, 2514, 1979, 1979, + 1979, 1942, 2069, 2070, 2076, 2039, 2514, 1944, 1718, 399, + 2082, 2514, 1826, 1512, 2514, 2514, 2059, 2085, 1718, 2514, + 2086, 1525, 1529, 2087, 2088, 2089, 2038, 2071, 2071, 2071, + 2514, 2514, 2514, 378, 2514, 2514, 2039, 1945, 2514, 1718, + 2514, 2514, 2514, 1831, 641, 642, 643, 644, 645, 645, + + 645, 645, 645, 645, 646, 2040, 2073, 2073, 2073, 2078, + 2078, 2078, 2092, 2514, 1836, 676, 677, 678, 679, 680, + 680, 680, 680, 680, 680, 681, 2055, 2514, 2095, 1980, + 2514, 2050, 2080, 2080, 2080, 2096, 2040, 2083, 2083, 2083, + 2090, 2090, 2090, 2092, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 2097, 2514, 2055, 2072, 2095, + 2093, 378, 2050, 2094, 2098, 2100, 2096, 2103, 2104, 2105, + 2106, 378, 2107, 2101, 2099, 2514, 2514, 2514, 2108, 2110, + 2102, 2113, 2019, 2019, 2019, 2111, 2097, 2074, 2115, 493, + 2079, 2093, 2514, 2514, 2094, 2098, 2100, 1544, 2103, 2104, + + 2105, 2106, 2514, 2107, 2101, 2099, 2114, 2116, 2117, 2108, + 493, 2102, 2113, 2081, 2514, 2514, 2111, 2514, 2084, 2115, + 493, 2091, 2514, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 2112, 2118, 2119, 2114, 2116, 2117, + 2120, 493, 2514, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 2514, 2514, 378, 2033, 2033, 2033, + 2514, 2514, 2130, 2020, 2514, 2112, 2118, 2119, 2514, 2131, + 2514, 2120, 2514, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1832, 1295, 1295, 2132, 2134, 1824, + 1830, 1295, 1295, 2130, 723, 1716, 2125, 1825, 2034, 397, + + 2131, 2128, 723, 1717, 2126, 2135, 939, 2514, 2136, 1826, + 711, 756, 2514, 2142, 725, 1718, 2143, 2121, 2132, 2134, + 2122, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2034, + 2514, 2514, 2514, 2138, 2138, 2138, 2135, 939, 2035, 2136, + 1826, 711, 756, 2123, 2142, 725, 1718, 2143, 2121, 641, + 642, 643, 644, 645, 645, 645, 645, 645, 645, 646, + 2137, 2140, 2140, 2140, 2144, 1833, 2514, 2133, 2514, 2146, + 2514, 1831, 676, 677, 678, 679, 680, 680, 680, 680, + 680, 680, 681, 2514, 2514, 2514, 2058, 2058, 2058, 2147, + 2148, 2137, 2149, 2151, 2152, 2144, 2514, 397, 2133, 2129, + + 2146, 1631, 378, 2155, 2514, 378, 2071, 2071, 2071, 399, + 2160, 378, 2514, 2514, 2139, 2073, 2073, 2073, 2162, 2163, + 2147, 2148, 2165, 2149, 2151, 2152, 2153, 2153, 2153, 2078, + 2078, 2078, 2166, 2514, 2155, 2080, 2080, 2080, 2167, 2168, + 399, 2160, 2141, 2083, 2083, 2083, 2090, 2090, 2090, 2162, + 2163, 2169, 2170, 2165, 2171, 2514, 2514, 2172, 2173, 2174, + 2175, 2157, 2156, 2166, 378, 2181, 2176, 2059, 2177, 2167, + 2168, 2178, 2179, 2186, 2187, 2158, 2514, 2188, 2201, 2201, + 2201, 2190, 2169, 2170, 2159, 2171, 2164, 2072, 2172, 2173, + 2174, 2175, 2157, 2156, 2199, 2200, 2074, 2176, 2514, 2177, + + 2514, 2514, 2178, 2179, 2186, 2187, 2158, 2154, 2188, 2182, + 2079, 2183, 2190, 2514, 2514, 2159, 2081, 2164, 2514, 2514, + 2514, 2514, 2514, 2514, 2084, 2199, 2200, 2091, 2514, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 2182, 2514, 2183, 2203, 2203, 2203, 2514, 2514, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 2202, + 2514, 2514, 2205, 2514, 2206, 470, 471, 472, 473, 474, + 474, 474, 474, 474, 474, 475, 493, 493, 1832, 1295, + 1295, 2209, 723, 1824, 2194, 2191, 2185, 2184, 2514, 2210, + 723, 1825, 2195, 2205, 939, 2206, 2192, 2211, 711, 378, + + 2514, 2212, 725, 1826, 2138, 2138, 2138, 493, 493, 2213, + 2213, 2213, 2209, 2221, 2221, 2221, 2191, 2185, 2184, 397, + 2210, 2197, 2514, 2514, 2204, 939, 2220, 2192, 2211, 711, + 2223, 756, 2212, 725, 1826, 641, 642, 643, 644, 645, + 645, 645, 645, 645, 645, 646, 676, 677, 678, 679, + 680, 680, 680, 680, 680, 680, 681, 2220, 2514, 1833, + 2514, 2223, 756, 2514, 2514, 2514, 2514, 2514, 2514, 2140, + 2140, 2140, 2216, 2216, 2216, 2224, 2225, 397, 2226, 2198, + 2153, 2153, 2153, 2227, 2228, 2139, 2217, 2229, 2231, 399, + 2214, 2207, 2232, 2233, 2222, 2234, 2235, 2236, 2230, 2237, + + 2238, 2239, 2208, 2240, 2241, 2242, 2224, 2225, 2243, 2226, + 2244, 2245, 2249, 2514, 2227, 2228, 2514, 493, 2229, 2231, + 399, 2253, 2207, 2232, 2233, 2514, 2234, 2235, 2236, 2251, + 2237, 2238, 2239, 2208, 2240, 2241, 2242, 2514, 2514, 2243, + 2514, 2244, 2245, 2250, 378, 2514, 2514, 378, 493, 2514, + 2141, 2514, 2253, 2218, 2246, 2246, 2246, 2514, 2514, 2514, + 2251, 2154, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 2254, 2250, 2255, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 493, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 2256, + + 2252, 2257, 2258, 723, 2254, 2261, 2255, 397, 723, 2264, + 2262, 2266, 2267, 2259, 2268, 939, 711, 2514, 493, 756, + 725, 2269, 2514, 2514, 2514, 2201, 2201, 2201, 2514, 2514, + 2256, 2252, 2257, 2258, 2514, 2247, 397, 2514, 2265, 2203, + 2203, 2203, 2266, 2267, 2259, 2268, 939, 711, 399, 2270, + 756, 725, 2269, 2514, 2514, 2514, 2273, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 399, + 2270, 2271, 2271, 2271, 2274, 2275, 2276, 2273, 2213, 2213, + 2213, 2216, 2216, 2216, 2277, 2277, 2277, 2281, 2282, 2221, + + 2221, 2221, 2284, 378, 2514, 2217, 2202, 2285, 2514, 2286, + 2287, 2288, 2289, 2290, 2291, 2274, 2275, 2276, 2292, 2293, + 2204, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2281, 2282, + 2278, 2305, 2301, 2284, 378, 2279, 2302, 2303, 2285, 2283, + 2286, 2287, 2288, 2289, 2290, 2291, 2246, 2246, 2246, 2292, + 2293, 2306, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2309, + 2310, 2278, 2272, 2301, 2514, 2514, 2279, 2302, 2303, 2214, + 2283, 2514, 2218, 2514, 2514, 2280, 2514, 2271, 2271, 2271, + 2222, 723, 2306, 2313, 2514, 2514, 2514, 2514, 2308, 2311, + 2309, 2310, 493, 939, 2318, 470, 471, 472, 473, 474, + + 474, 474, 474, 474, 474, 475, 2514, 470, 471, 472, + 473, 474, 474, 474, 474, 474, 474, 475, 493, 2308, + 2311, 2514, 2514, 493, 939, 2318, 2319, 2247, 2307, 641, + 642, 643, 644, 645, 645, 645, 645, 645, 645, 646, + 723, 397, 2314, 2316, 2320, 2321, 2322, 2326, 711, 493, + 2327, 2328, 725, 756, 2277, 2277, 2277, 2319, 2272, 2307, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 2514, 2514, 2514, 2329, 2320, 2321, 2322, 2326, 711, + 2330, 2327, 2328, 725, 756, 397, 2331, 2317, 2332, 2333, + 2278, 2334, 2335, 2336, 2337, 2279, 2338, 399, 2339, 2340, + + 2341, 2342, 2343, 2344, 2351, 2329, 2345, 2346, 2347, 2348, + 2349, 2330, 493, 2354, 2355, 2362, 2363, 2331, 2364, 2332, + 2333, 2278, 2334, 2335, 2336, 2337, 2279, 2338, 399, 2339, + 2340, 2341, 2342, 2343, 2344, 2280, 2514, 2345, 2346, 2347, + 2348, 2349, 2514, 493, 2354, 2355, 2362, 2363, 2352, 2364, + 2365, 723, 378, 2357, 2514, 397, 2514, 2360, 2514, 2514, + 2514, 2514, 2514, 939, 2514, 2366, 2514, 756, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 2352, + 2367, 2365, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 493, 939, 723, 2366, 2358, 756, 2514, + + 2514, 2514, 2353, 711, 2370, 2371, 2374, 725, 2375, 2376, + 2377, 2367, 2380, 397, 2381, 2361, 2378, 2378, 2378, 2382, + 2383, 2384, 2385, 2386, 493, 399, 2387, 2388, 2389, 2514, + 2514, 2514, 2514, 2353, 711, 2370, 2371, 2374, 725, 2375, + 2376, 2377, 2391, 2380, 493, 2381, 2392, 2399, 2514, 2514, + 2382, 2383, 2384, 2385, 2386, 2514, 399, 2387, 2388, 2389, + 470, 471, 472, 473, 474, 474, 474, 474, 474, 474, + 475, 2400, 2401, 2402, 723, 493, 2394, 2392, 2399, 723, + 378, 2395, 397, 2514, 2397, 2514, 939, 711, 2408, 2408, + 2408, 725, 2403, 2404, 756, 2405, 2406, 2379, 2407, 2410, + + 2411, 2412, 2400, 2401, 2402, 2514, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 939, 711, 2514, + 2514, 2514, 725, 2403, 2404, 756, 2405, 2406, 2413, 2407, + 2410, 2411, 2412, 397, 2414, 2398, 2378, 2378, 2378, 2415, + 2416, 2417, 2378, 2378, 2378, 399, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 2426, 2427, 2413, + 2428, 723, 2429, 2421, 2430, 2414, 723, 2431, 2422, 2409, + 2415, 2416, 2417, 939, 711, 397, 399, 2424, 725, 2433, + 2514, 2514, 2514, 2408, 2408, 2408, 2514, 756, 2426, 2427, + 2436, 2428, 2514, 2429, 397, 2430, 2425, 2437, 2431, 2438, + + 378, 2434, 2434, 2434, 939, 711, 399, 2444, 2514, 725, + 2433, 2445, 723, 397, 2440, 2443, 2514, 2379, 756, 2446, + 2447, 2436, 2448, 2379, 939, 756, 2514, 723, 2437, 2441, + 2438, 2514, 2514, 2514, 2449, 711, 2450, 399, 2444, 725, + 2452, 2453, 2445, 2454, 2514, 397, 2514, 2425, 2514, 2514, + 2446, 2447, 2457, 2448, 2514, 939, 756, 399, 2434, 2434, + 2434, 378, 2514, 2514, 2409, 2449, 711, 2450, 2462, 2514, + 725, 2452, 2453, 2463, 2454, 723, 2464, 2456, 723, 397, + 2441, 2443, 2435, 2457, 2465, 2451, 711, 939, 399, 2466, + 725, 756, 2458, 2458, 2458, 2467, 2468, 2469, 2473, 2462, + + 2459, 723, 2476, 2456, 2463, 2477, 2478, 2464, 2514, 2479, + 2480, 2481, 378, 939, 2482, 2465, 2451, 711, 939, 2483, + 2466, 725, 756, 2458, 2458, 2458, 2467, 2468, 2469, 2473, + 2484, 2459, 2485, 2476, 2488, 2489, 2477, 2478, 2490, 2435, + 2479, 2480, 2481, 2491, 939, 2482, 2486, 2486, 2486, 2495, + 2483, 2492, 2492, 2492, 2486, 2486, 2486, 2496, 2497, 2498, + 2499, 2484, 2500, 2485, 2514, 2488, 2489, 2501, 2502, 2490, + 2492, 2492, 2492, 2460, 2491, 2461, 2492, 2492, 2492, 2503, + 2495, 2504, 2378, 2378, 2378, 2505, 2506, 2507, 2496, 2497, + 2498, 2499, 2508, 2500, 2509, 2494, 2514, 2510, 2501, 2502, + + 2511, 2514, 2512, 2513, 2460, 2514, 2461, 2492, 2492, 2492, + 2503, 2514, 2504, 2514, 2514, 2514, 2505, 2506, 2507, 2514, + 2514, 2514, 2514, 2508, 2514, 2509, 2494, 2487, 2510, 2514, + 2514, 2511, 2493, 2512, 2513, 2487, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2493, 2514, 2514, 2514, 2514, 2514, 2493, 2514, 2514, + 2514, 2514, 2514, 2379, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2493, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + + 125, 125, 125, 125, 125, 125, 125, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 217, 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, 217, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 233, 233, 233, + + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, + 239, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 268, 268, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, + 312, 337, 337, 337, 337, 337, 337, 337, 337, 337, + 337, 337, 337, 337, 337, 337, 337, 337, 337, 346, + 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 361, 361, 361, + 2514, 2514, 2514, 361, 2514, 2514, 2514, 2514, 361, 361, + 361, 361, 369, 369, 2514, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 370, 370, 2326, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 370, 748, 748, 2326, 748, 748, 748, 748, 748, 748, - 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, - 377, 377, 2326, 2326, 2326, 2326, 377, 2326, 2326, 2326, - 2326, 377, 377, 377, 377, 464, 2326, 464, 464, 464, - 464, 384, 384, 384, 2326, 2326, 2326, 384, 2326, 2326, - 2326, 2326, 384, 384, 384, 384, 750, 2326, 750, 750, - 750, 750, 455, 455, 2326, 2326, 2326, 2326, 455, 2326, - - 2326, 2326, 455, 455, 455, 455, 455, 837, 2326, 837, - 837, 837, 837, 468, 468, 2326, 2326, 2326, 2326, 468, - 2326, 2326, 2326, 2326, 468, 468, 468, 468, 486, 2326, - 486, 486, 486, 486, 492, 492, 2326, 492, 492, 2326, - 492, 492, 492, 492, 2326, 2326, 2326, 2326, 492, 492, - 492, 492, 522, 2326, 522, 522, 522, 522, 524, 524, - 524, 2326, 2326, 2326, 2326, 524, 2326, 2326, 2326, 2326, - 524, 524, 524, 524, 859, 2326, 859, 859, 859, 859, - 531, 531, 2326, 2326, 2326, 2326, 531, 2326, 2326, 2326, - 2326, 531, 531, 531, 531, 559, 2326, 559, 559, 559, - - 559, 538, 538, 538, 2326, 2326, 2326, 538, 2326, 2326, - 2326, 2326, 538, 538, 538, 538, 861, 2326, 861, 861, - 861, 861, 550, 550, 2326, 2326, 2326, 2326, 550, 2326, - 2326, 2326, 550, 550, 550, 550, 550, 865, 2326, 865, - 865, 865, 865, 560, 2326, 2326, 560, 2326, 560, 580, - 2326, 2326, 580, 2326, 580, 604, 604, 604, 604, 604, - 604, 2326, 604, 604, 604, 604, 604, 604, 2326, 604, - 604, 604, 604, 604, 884, 884, 2326, 884, 884, 884, - 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, - 884, 884, 884, 611, 611, 611, 611, 611, 611, 2326, - - 611, 611, 611, 611, 611, 611, 2326, 611, 611, 611, - 611, 611, 888, 888, 2326, 888, 888, 888, 888, 888, - 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, - 888, 892, 892, 2326, 892, 892, 892, 892, 892, 892, - 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, - 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, - 624, 624, 624, 624, 2326, 624, 624, 624, 624, 626, + 376, 376, 2514, 2514, 2514, 376, 2514, 2514, 2514, 2514, + 376, 376, 376, 376, 383, 383, 383, 2514, 2514, 383, + 2514, 2514, 2514, 2514, 383, 383, 383, 383, 456, 456, + 2514, 2514, 2514, 456, 2514, 2514, 2514, 456, 456, 456, + 456, 456, 465, 2514, 465, 465, 465, 465, 465, 465, + 465, 469, 469, 2514, 2514, 2514, 469, 2514, 2514, 2514, + 2514, 469, 469, 469, 469, 487, 2514, 487, 487, 487, + 487, 487, 487, 493, 493, 2514, 493, 493, 2514, 493, + 493, 493, 2514, 2514, 2514, 2514, 493, 493, 493, 493, + + 523, 2514, 523, 523, 523, 523, 525, 525, 525, 2514, + 2514, 2514, 525, 2514, 2514, 2514, 2514, 525, 525, 525, + 525, 532, 532, 2514, 2514, 2514, 532, 2514, 2514, 2514, + 2514, 532, 532, 532, 532, 539, 539, 539, 2514, 2514, + 539, 2514, 2514, 2514, 2514, 539, 539, 539, 539, 551, + 551, 2514, 2514, 2514, 551, 2514, 2514, 2514, 551, 551, + 551, 551, 551, 560, 2514, 560, 560, 560, 560, 561, + 2514, 561, 2514, 561, 581, 2514, 581, 2514, 581, 606, + 606, 606, 606, 606, 606, 2514, 606, 606, 606, 606, + 606, 2514, 606, 606, 606, 606, 606, 612, 612, 612, + + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 613, 613, 613, 613, 613, + 613, 2514, 613, 613, 613, 613, 613, 2514, 613, 613, + 613, 613, 613, 619, 619, 619, 619, 619, 619, 619, + 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, + 619, 625, 625, 625, 625, 625, 625, 625, 625, 625, + 625, 625, 625, 625, 625, 625, 625, 625, 625, 626, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 2514, 626, 626, 626, 626, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, + + 2514, 628, 628, 628, 628, 633, 633, 2514, 633, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 633, 633, 640, 640, 2514, 2514, 2514, 640, 2514, + 2514, 2514, 2514, 640, 640, 640, 640, 655, 2514, 655, + 655, 655, 655, 655, 660, 660, 2514, 660, 660, 660, + 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, + 660, 660, 668, 668, 2514, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 675, 675, 2514, 2514, 2514, 675, 2514, 2514, 2514, 2514, + 675, 675, 675, 675, 687, 2514, 687, 687, 687, 687, + + 687, 687, 690, 690, 2514, 2514, 2514, 690, 2514, 2514, + 2514, 2514, 690, 690, 690, 690, 699, 2514, 699, 699, + 699, 699, 704, 704, 2514, 704, 704, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, + 711, 711, 2514, 2514, 2514, 711, 2514, 2514, 2514, 2514, + 711, 711, 711, 711, 729, 2514, 729, 729, 729, 729, + 2514, 2514, 729, 733, 733, 2514, 733, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 739, 739, 2514, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 739, 361, + + 361, 361, 2514, 2514, 2514, 361, 2514, 2514, 2514, 2514, + 361, 361, 361, 361, 747, 2514, 747, 747, 747, 747, + 368, 368, 2514, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 369, 369, + 2514, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 749, 749, 2514, 749, + 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, + 749, 749, 749, 749, 376, 376, 2514, 2514, 2514, 376, + 2514, 2514, 2514, 2514, 376, 376, 376, 376, 465, 2514, + 465, 465, 465, 465, 383, 383, 383, 2514, 2514, 383, + + 2514, 2514, 2514, 2514, 383, 383, 383, 383, 751, 2514, + 751, 751, 751, 751, 456, 456, 2514, 2514, 2514, 456, + 2514, 2514, 2514, 456, 456, 456, 456, 456, 843, 2514, + 843, 843, 843, 843, 469, 469, 2514, 2514, 2514, 469, + 2514, 2514, 2514, 2514, 469, 469, 469, 469, 487, 2514, + 487, 487, 487, 487, 493, 493, 2514, 493, 493, 2514, + 493, 493, 493, 2514, 2514, 2514, 2514, 493, 493, 493, + 493, 523, 2514, 523, 523, 523, 523, 525, 525, 525, + 2514, 2514, 2514, 525, 2514, 2514, 2514, 2514, 525, 525, + 525, 525, 868, 2514, 868, 868, 868, 868, 532, 532, + + 2514, 2514, 2514, 532, 2514, 2514, 2514, 2514, 532, 532, + 532, 532, 560, 2514, 560, 560, 560, 560, 539, 539, + 539, 2514, 2514, 539, 2514, 2514, 2514, 2514, 539, 539, + 539, 539, 870, 2514, 870, 870, 870, 870, 551, 551, + 2514, 2514, 2514, 551, 2514, 2514, 2514, 551, 551, 551, + 551, 551, 874, 2514, 874, 874, 874, 874, 561, 2514, + 561, 2514, 561, 581, 2514, 581, 2514, 581, 606, 606, + 606, 606, 606, 606, 2514, 606, 606, 606, 606, 606, + 2514, 606, 606, 606, 606, 606, 895, 895, 2514, 895, + 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, + + 895, 895, 895, 895, 613, 613, 613, 613, 613, 613, + 2514, 613, 613, 613, 613, 613, 2514, 613, 613, 613, + 613, 613, 899, 899, 2514, 899, 899, 899, 899, 899, + 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + 903, 903, 2514, 903, 903, 903, 903, 903, 903, 903, + 903, 903, 903, 903, 903, 903, 903, 903, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, - 626, 626, 626, 2326, 626, 626, 626, 626, 630, 630, - 2326, 630, 630, 630, 630, 630, 630, 630, 630, 630, - - 630, 630, 630, 630, 630, 630, 630, 631, 631, 2326, - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 631, 896, 896, 2326, 896, - 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, - 896, 896, 896, 896, 896, 638, 638, 2326, 2326, 2326, - 2326, 638, 2326, 2326, 2326, 2326, 638, 638, 638, 638, - 654, 2326, 654, 654, 654, 654, 659, 659, 2326, 659, - 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 659, 659, 659, 659, 666, 666, 2326, 666, 666, - 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, - - 666, 666, 666, 666, 667, 667, 2326, 667, 667, 667, + 626, 2514, 626, 626, 626, 626, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, 628, 2514, + 628, 628, 628, 628, 632, 632, 2514, 632, 632, 632, + + 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 633, 633, 2514, 633, 633, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 907, 907, 2514, 907, 907, 907, 907, 907, 907, 907, + 907, 907, 907, 907, 907, 907, 907, 907, 640, 640, + 2514, 2514, 2514, 640, 2514, 2514, 2514, 2514, 640, 640, + 640, 640, 655, 2514, 655, 655, 655, 655, 660, 660, + 2514, 660, 660, 660, 660, 660, 660, 660, 660, 660, + 660, 660, 660, 660, 660, 660, 667, 667, 2514, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, - 667, 667, 667, 914, 914, 2326, 914, 914, 914, 914, - 914, 914, 914, 914, 914, 914, 914, 914, 914, 914, - 914, 914, 674, 674, 2326, 2326, 2326, 2326, 674, 2326, - 2326, 2326, 2326, 674, 674, 674, 674, 686, 2326, 686, - 686, 686, 686, 689, 689, 2326, 2326, 2326, 2326, 689, - 2326, 2326, 2326, 2326, 689, 689, 689, 689, 698, 2326, - 698, 698, 698, 698, 702, 702, 2326, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - - 702, 702, 702, 703, 703, 2326, 703, 703, 703, 703, - 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, - 703, 703, 925, 925, 2326, 925, 925, 925, 925, 925, - 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, - 925, 710, 710, 2326, 2326, 2326, 2326, 710, 2326, 2326, - 2326, 2326, 710, 710, 710, 710, 728, 2326, 728, 728, - 728, 728, 732, 732, 2326, 732, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 738, 738, 2326, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, - - 362, 362, 362, 2326, 2326, 2326, 2326, 362, 2326, 2326, - 2326, 2326, 362, 362, 362, 362, 369, 369, 2326, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 370, 370, 2326, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 384, 384, 384, 2326, 2326, 2326, - 384, 2326, 2326, 2326, 2326, 384, 384, 384, 384, 953, - 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, - 953, 953, 953, 953, 953, 953, 953, 953, 377, 377, - 2326, 2326, 2326, 2326, 377, 2326, 2326, 2326, 2326, 377, - - 377, 377, 377, 455, 455, 2326, 2326, 2326, 2326, 455, - 2326, 2326, 2326, 455, 455, 455, 455, 455, 468, 468, - 2326, 2326, 2326, 2326, 468, 2326, 2326, 2326, 2326, 468, - 468, 468, 468, 492, 492, 2326, 2326, 2326, 492, 492, - 2326, 2326, 2326, 2326, 492, 492, 492, 492, 524, 524, - 524, 2326, 2326, 2326, 2326, 524, 2326, 2326, 2326, 2326, - 524, 524, 524, 524, 538, 538, 538, 2326, 2326, 2326, - 538, 2326, 2326, 2326, 2326, 538, 538, 538, 538, 531, - 531, 2326, 2326, 2326, 2326, 531, 2326, 2326, 2326, 2326, - 531, 531, 531, 531, 550, 550, 2326, 2326, 2326, 2326, - - 550, 2326, 2326, 2326, 550, 550, 550, 550, 550, 560, - 2326, 2326, 560, 2326, 560, 580, 2326, 2326, 580, 2326, - 580, 884, 884, 2326, 884, 884, 884, 884, 884, 884, - 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, - 888, 888, 2326, 888, 888, 888, 888, 888, 888, 888, - 888, 888, 888, 888, 888, 888, 888, 888, 888, 892, - 892, 2326, 892, 892, 892, 892, 892, 892, 892, 892, - 892, 892, 892, 892, 892, 892, 892, 892, 630, 630, - 2326, 630, 630, 630, 630, 630, 630, 630, 630, 630, - 630, 630, 630, 630, 630, 630, 630, 631, 631, 2326, - - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 631, 1088, 1088, 1088, 1088, - 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, - 1088, 1088, 1088, 1088, 1088, 638, 638, 2326, 2326, 2326, - 2326, 638, 2326, 2326, 2326, 2326, 638, 638, 638, 638, - 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, - 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 666, - 666, 2326, 666, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 666, 666, 666, 666, 666, 667, 667, - 2326, 667, 667, 667, 667, 667, 667, 667, 667, 667, - - 667, 667, 667, 667, 667, 667, 667, 1106, 1106, 1106, - 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, - 1106, 1106, 1106, 1106, 1106, 1106, 674, 674, 2326, 2326, - 2326, 2326, 674, 2326, 2326, 2326, 2326, 674, 674, 674, - 674, 689, 689, 2326, 2326, 2326, 2326, 689, 2326, 2326, - 2326, 2326, 689, 689, 689, 689, 702, 702, 2326, 702, - 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 703, 703, 2326, 703, 703, - 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, - 703, 703, 703, 703, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 1115, 1115, 710, 710, 2326, 2326, 2326, 2326, 710, - 2326, 2326, 2326, 2326, 710, 710, 710, 710, 1128, 1128, - 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, - 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1133, 1133, 1133, - 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, - 1133, 1133, 1133, 1133, 1133, 1133, 369, 369, 2326, 369, + 667, 667, 667, 667, 668, 668, 2514, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 923, 923, 2514, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 675, 675, 2514, 2514, 2514, 675, 2514, 2514, 2514, 2514, + 675, 675, 675, 675, 687, 2514, 687, 687, 687, 687, + 690, 690, 2514, 2514, 2514, 690, 2514, 2514, 2514, 2514, + 690, 690, 690, 690, 699, 2514, 699, 699, 699, 699, + 703, 703, 2514, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 703, 703, 704, 704, + + 2514, 704, 704, 704, 704, 704, 704, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 934, 934, 2514, 934, + 934, 934, 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 711, 711, 2514, 2514, 2514, 711, + 2514, 2514, 2514, 2514, 711, 711, 711, 711, 729, 2514, + 729, 729, 729, 729, 733, 733, 2514, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 739, 739, 2514, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, + 361, 361, 361, 2514, 2514, 2514, 361, 2514, 2514, 2514, + + 2514, 361, 361, 361, 361, 368, 368, 2514, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 369, 369, 2514, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 953, 953, 2326, 953, 953, - 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, - - 953, 953, 953, 953, 377, 377, 2326, 2326, 2326, 2326, - 377, 2326, 2326, 2326, 2326, 377, 377, 377, 377, 468, - 468, 2326, 2326, 2326, 2326, 468, 2326, 2326, 2326, 2326, - 468, 468, 468, 468, 492, 492, 2326, 2326, 2326, 492, - 492, 492, 2326, 2326, 2326, 492, 492, 492, 492, 531, - 531, 2326, 2326, 2326, 2326, 531, 2326, 2326, 2326, 2326, - 531, 531, 531, 531, 560, 2326, 2326, 560, 2326, 560, - 580, 2326, 2326, 580, 2326, 580, 1254, 1254, 1254, 1254, - 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - 1254, 1254, 1254, 1254, 1254, 1258, 1258, 1258, 1258, 1258, - - 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - 1258, 1258, 1258, 1258, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 630, 630, 2326, 630, 630, 630, 630, - 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, - 630, 630, 1088, 1088, 2326, 1088, 1088, 1088, 1088, 1088, - 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, - 1088, 638, 638, 2326, 2326, 2326, 2326, 638, 2326, 2326, - 2326, 2326, 638, 638, 638, 638, 1101, 1101, 2326, 1101, - 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, - - 1101, 1101, 1101, 1101, 1101, 666, 666, 2326, 666, 666, - 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 666, 1106, 1106, 2326, 1106, 1106, 1106, - 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, - 1106, 1106, 1106, 674, 674, 2326, 2326, 2326, 2326, 674, - 2326, 2326, 2326, 2326, 674, 674, 674, 674, 689, 689, - 2326, 2326, 2326, 2326, 689, 2326, 2326, 2326, 2326, 689, - 689, 689, 689, 702, 702, 2326, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - 702, 702, 1115, 1115, 2326, 1115, 1115, 1115, 1115, 1115, - - 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 710, 710, 2326, 2326, 2326, 2326, 710, 2326, 2326, - 2326, 2326, 710, 710, 710, 710, 1128, 1128, 2326, 1128, - 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, - 1128, 1128, 1128, 1128, 1128, 1133, 1133, 2326, 1133, 1133, + 369, 383, 383, 383, 2514, 2514, 383, 2514, 2514, 2514, + 2514, 383, 383, 383, 383, 964, 964, 964, 964, 964, + 964, 964, 964, 964, 964, 964, 964, 964, 964, 964, + 964, 964, 964, 376, 376, 2514, 2514, 376, 376, 2514, + 2514, 2514, 2514, 376, 376, 376, 376, 456, 456, 2514, + 2514, 2514, 456, 2514, 2514, 2514, 456, 456, 456, 456, + + 456, 469, 469, 2514, 2514, 2514, 469, 2514, 2514, 2514, + 2514, 469, 469, 469, 469, 493, 493, 2514, 2514, 493, + 493, 2514, 2514, 2514, 2514, 493, 493, 493, 493, 525, + 525, 525, 2514, 2514, 2514, 525, 2514, 2514, 2514, 2514, + 525, 525, 525, 525, 539, 539, 539, 2514, 2514, 539, + 2514, 2514, 2514, 2514, 539, 539, 539, 539, 532, 532, + 2514, 2514, 2514, 532, 2514, 2514, 2514, 2514, 532, 532, + 532, 532, 551, 551, 2514, 2514, 2514, 551, 2514, 2514, + 2514, 551, 551, 551, 551, 551, 561, 2514, 561, 2514, + 561, 581, 2514, 581, 2514, 581, 895, 895, 2514, 895, + + 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 899, 899, 2514, 899, 899, 899, + 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + 899, 899, 903, 903, 2514, 903, 903, 903, 903, 903, + 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, + 632, 632, 2514, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, 632, 633, 633, + 2514, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 1107, 1107, 1107, 1107, + 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, + + 1107, 1107, 1107, 1107, 640, 640, 2514, 2514, 2514, 640, + 2514, 2514, 2514, 2514, 640, 640, 640, 640, 1118, 1118, + 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, + 1118, 1118, 1118, 1118, 1118, 1118, 667, 667, 2514, 667, + 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 668, 668, 2514, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 675, 675, 2514, 2514, 2514, 675, 2514, 2514, 2514, 2514, + + 675, 675, 675, 675, 690, 690, 2514, 2514, 2514, 690, + 2514, 2514, 2514, 2514, 690, 690, 690, 690, 703, 703, + 2514, 703, 703, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 704, 704, 2514, 704, + 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, + 704, 704, 704, 704, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, - 1133, 1133, 1133, 1133, 377, 377, 2326, 377, 377, 2326, - 2326, 2326, 2326, 377, 2326, 2326, 2326, 2326, 377, 377, - 377, 377, 468, 468, 2326, 2326, 2326, 2326, 468, 2326, - 2326, 2326, 2326, 468, 468, 468, 468, 492, 492, 2326, - - 2326, 2326, 492, 492, 2326, 2326, 2326, 2326, 492, 492, - 492, 492, 531, 531, 2326, 2326, 2326, 2326, 531, 2326, - 2326, 2326, 2326, 531, 531, 531, 531, 560, 2326, 2326, - 560, 2326, 560, 580, 2326, 2326, 580, 2326, 580, 1254, - 1254, 2326, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1258, 1258, - 2326, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1262, 1262, 2326, - 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 638, 638, 2326, 2326, - - 2326, 2326, 638, 2326, 2326, 2326, 2326, 638, 638, 638, - 638, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, - 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, - 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, - 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1572, - 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, - 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1654, 1654, - 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, - 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1673, 1673, 1673, - 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, - - 1673, 1673, 1673, 1673, 1673, 1673, 1680, 1680, 1680, 1680, - 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, - 1680, 1680, 1680, 1680, 1680, 1699, 1699, 1699, 1699, 1699, - 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, - 1699, 1699, 1699, 1699, 1728, 1728, 1728, 1728, 1728, 1728, - 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, - 1728, 1728, 1728, 1750, 1750, 1750, 1750, 1750, 1750, 1750, - 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, - 1750, 1750, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, - 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, - - 1796, 57, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326 - + 1133, 1133, 711, 711, 2514, 2514, 711, 711, 2514, 2514, + 2514, 2514, 711, 711, 711, 711, 1145, 1145, 1145, 1145, + 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, + + 1145, 1145, 1145, 1145, 1150, 1150, 1150, 1150, 1150, 1150, + 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, + 1150, 1150, 368, 368, 2514, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 964, 964, 2514, 964, 964, 964, 964, 964, 964, 964, + 964, 964, 964, 964, 964, 964, 964, 964, 376, 376, + 2514, 2514, 376, 376, 2514, 2514, 2514, 2514, 376, 376, + 376, 376, 469, 469, 2514, 2514, 2514, 469, 2514, 2514, + 2514, 2514, 469, 469, 469, 469, 493, 493, 2514, 2514, + 493, 493, 493, 2514, 2514, 2514, 493, 493, 493, 493, + + 532, 532, 2514, 2514, 2514, 532, 2514, 2514, 2514, 2514, + 532, 532, 532, 532, 561, 2514, 561, 2514, 561, 581, + 2514, 581, 2514, 581, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, + 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, + 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, + 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 632, 632, + 2514, 632, 632, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 1107, 1107, 2514, 1107, + + 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, + 1107, 1107, 1107, 1107, 640, 640, 2514, 2514, 2514, 640, + 2514, 2514, 2514, 2514, 640, 640, 640, 640, 1118, 1118, + 2514, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, + 1118, 1118, 1118, 1118, 1118, 1118, 667, 667, 2514, 667, + 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 1123, 1123, 2514, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 675, 675, 2514, 2514, 2514, 675, 2514, 2514, + 2514, 2514, 675, 675, 675, 675, 690, 690, 2514, 2514, + + 2514, 690, 2514, 2514, 2514, 2514, 690, 690, 690, 690, + 703, 703, 2514, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 703, 703, 1133, 1133, + 2514, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, + 1133, 1133, 1133, 1133, 1133, 1133, 711, 711, 2514, 2514, + 711, 711, 2514, 2514, 2514, 2514, 711, 711, 711, 711, + 1145, 1145, 2514, 1145, 1145, 1145, 1145, 1145, 1145, 1145, + 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1150, 1150, + 2514, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, + 1150, 1150, 1150, 1150, 1150, 1150, 376, 376, 2514, 2514, + + 376, 376, 2514, 2514, 2514, 2514, 376, 376, 376, 376, + 469, 469, 2514, 2514, 2514, 469, 2514, 2514, 2514, 2514, + 469, 469, 469, 469, 493, 493, 2514, 2514, 493, 493, + 2514, 2514, 2514, 2514, 493, 493, 493, 493, 532, 532, + 2514, 2514, 2514, 532, 2514, 2514, 2514, 2514, 532, 532, + 532, 532, 561, 2514, 561, 2514, 561, 581, 2514, 581, + 2514, 581, 1280, 1280, 2514, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1284, 1284, 2514, 1284, 1284, 1284, 1284, 1284, 1284, 1284, + 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1288, 1288, + + 2514, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, + 1288, 1288, 1288, 1288, 1288, 1288, 640, 640, 2514, 2514, + 2514, 640, 2514, 2514, 2514, 2514, 640, 640, 640, 640, + 675, 675, 2514, 2514, 2514, 675, 2514, 2514, 2514, 2514, + 675, 675, 675, 675, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, + 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, + 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, + 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1714, 1714, + + 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, + 1714, 1714, 1714, 1714, 1714, 1714, 1736, 1736, 1736, 1736, + 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, + 1736, 1736, 1736, 1736, 1743, 1743, 1743, 1743, 1743, 1743, + 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, + 1743, 1743, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, + 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, + 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, + 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1822, 1822, + 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, + + 1822, 1822, 1822, 1822, 1822, 1822, 1872, 1872, 1872, 1872, + 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, + 1872, 1872, 1872, 1872, 59, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514 } ; -static yyconst flex_int16_t yy_chk[15696] = +static yyconst flex_int16_t yy_chk[15718] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -2966,7 +3031,7 @@ static yyconst flex_int16_t yy_chk[15696] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -2976,8 +3041,8 @@ static yyconst flex_int16_t yy_chk[15696] = 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 5, 6, 67, 67, - 69, 70, 70, 69, 69, 5, 6, 7, 7, 7, + 3, 3, 3, 3, 5, 6, 71, 71, 2493, 71, + 232, 232, 2487, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -2987,7 +3052,7 @@ static yyconst flex_int16_t yy_chk[15696] = 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -2997,8 +3062,8 @@ static yyconst flex_int16_t yy_chk[15696] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 11, 11, 11, 11, 11, 11, 11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, @@ -3008,44 +3073,43 @@ static yyconst flex_int16_t yy_chk[15696] = 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 13, 13, 13, 27, - 14, 14, 14, 13, 28, 29, 13, 14, 13, 30, - 14, 31, 14, 15, 15, 15, 32, 16, 16, 16, - - 15, 39, 40, 15, 16, 15, 47, 16, 48, 16, - 103, 103, 108, 55, 109, 109, 131, 108, 56, 122, - 122, 55, 27, 134, 39, 40, 56, 28, 29, 125, - 55, 2311, 30, 2293, 125, 56, 47, 31, 48, 135, - 130, 136, 32, 137, 55, 130, 2286, 131, 151, 56, - 144, 144, 55, 151, 134, 39, 40, 56, 13, 2285, - 13, 55, 14, 166, 14, 2283, 56, 47, 166, 48, - 135, 183, 136, 191, 137, 15, 183, 15, 191, 16, - 2282, 16, 19, 19, 19, 19, 19, 19, 19, 19, + 11, 13, 13, 13, 27, 14, 14, 14, 13, 28, + 29, 13, 14, 13, 30, 14, 31, 14, 15, 15, + 15, 32, 16, 16, 16, 15, 39, 40, 15, 16, + + 15, 47, 16, 48, 16, 110, 127, 57, 132, 133, + 110, 127, 58, 132, 136, 57, 27, 137, 39, 40, + 58, 28, 29, 77, 57, 77, 30, 2472, 138, 58, + 47, 31, 48, 139, 140, 77, 32, 141, 57, 77, + 133, 174, 153, 58, 2464, 136, 57, 153, 137, 39, + 40, 58, 13, 2463, 13, 57, 14, 168, 14, 138, + 58, 47, 168, 48, 139, 140, 77, 2461, 141, 15, + 77, 15, 174, 16, 2460, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 21, 21, 21, 22, 22, - 22, 138, 85, 21, 85, 85, 22, 23, 23, 23, - 146, 146, 23, 139, 23, 85, 23, 23, 24, 24, - - 24, 158, 158, 24, 1257, 24, 1261, 24, 24, 25, - 25, 25, 138, 2182, 25, 2279, 25, 25, 25, 25, - 26, 26, 26, 172, 139, 26, 85, 26, 26, 26, - 26, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 77, 173, 77, 77, 160, 160, 75, 2245, - 75, 75, 174, 175, 172, 77, 205, 21, 206, 21, - 22, 75, 22, 197, 197, 75, 268, 200, 77, 23, - 2243, 23, 200, 2233, 173, 210, 210, 2224, 210, 1257, - 24, 1261, 24, 174, 175, 221, 77, 205, 2182, 206, - 221, 25, 75, 25, 197, 197, 75, 268, 228, 77, - - 230, 230, 26, 228, 26, 37, 37, 37, 37, 37, + 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, + 21, 22, 22, 22, 175, 122, 21, 176, 185, 22, + 23, 23, 23, 185, 2457, 23, 103, 23, 177, 23, + 23, 24, 24, 24, 193, 2455, 24, 334, 24, 193, + + 24, 24, 25, 25, 25, 175, 2442, 25, 176, 25, + 25, 25, 25, 26, 26, 26, 2439, 265, 26, 177, + 26, 26, 26, 26, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 79, 87, 79, 87, 199, + 199, 85, 207, 85, 122, 122, 208, 79, 87, 21, + 269, 21, 22, 85, 22, 103, 103, 85, 103, 202, + 79, 23, 223, 23, 202, 212, 212, 223, 212, 334, + 199, 199, 24, 207, 24, 230, 2435, 208, 79, 87, + 230, 269, 476, 25, 85, 25, 265, 476, 85, 281, + 281, 79, 323, 323, 26, 323, 26, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, @@ -3054,21 +3118,20 @@ static yyconst flex_int16_t yy_chk[15696] = 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 41, 41, - - 41, 2145, 41, 41, 2214, 41, 41, 41, 59, 59, - 59, 41, 42, 42, 42, 259, 42, 42, 259, 42, - 42, 42, 101, 101, 76, 42, 76, 76, 78, 2187, - 78, 78, 79, 76, 79, 79, 278, 76, 207, 41, - 208, 78, 312, 207, 344, 79, 259, 76, 345, 259, - 76, 2186, 79, 42, 78, 79, 353, 208, 79, 2183, - 78, 266, 266, 2151, 76, 280, 280, 278, 76, 207, - 41, 208, 78, 312, 207, 344, 79, 2145, 76, 345, - 41, 76, 41, 79, 42, 78, 79, 353, 208, 79, - 59, 78, 101, 101, 42, 101, 42, 43, 43, 43, - - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 41, + 41, 41, 260, 41, 41, 260, 41, 41, 41, 61, + + 61, 61, 41, 42, 42, 42, 1291, 42, 42, 298, + 42, 42, 42, 78, 490, 78, 42, 210, 279, 490, + 80, 78, 80, 260, 313, 78, 260, 343, 83, 41, + 83, 344, 80, 142, 210, 78, 83, 142, 78, 2423, + 83, 2420, 352, 42, 83, 80, 142, 2409, 210, 279, + 142, 80, 78, 2407, 353, 313, 78, 2396, 343, 2393, + 41, 2392, 344, 80, 142, 210, 78, 83, 142, 78, + 41, 83, 41, 352, 42, 83, 80, 142, 298, 298, + 61, 142, 80, 1291, 42, 353, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, @@ -3076,9 +3139,10 @@ static yyconst flex_int16_t yy_chk[15696] = 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, @@ -3086,1604 +3150,1607 @@ static yyconst flex_int16_t yy_chk[15696] = 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 49, 49, 49, 49, 49, 49, 49, + 45, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 51, 51, 51, 264, - 264, 51, 2144, 52, 52, 52, 299, 299, 52, 51, - 60, 60, 60, 308, 308, 51, 52, 2143, 245, 245, - - 245, 354, 52, 2128, 51, 53, 53, 53, 310, 310, - 53, 52, 54, 54, 54, 320, 320, 54, 53, 62, - 356, 51, 120, 120, 53, 54, 322, 2107, 52, 322, - 322, 54, 354, 53, 80, 51, 80, 80, 2103, 53, - 54, 94, 52, 94, 94, 2099, 54, 80, 2090, 264, - 94, 356, 51, 357, 94, 323, 323, 65, 51, 52, - 80, 246, 246, 246, 53, 52, 83, 2088, 83, 83, - 53, 54, 60, 2054, 270, 270, 270, 54, 80, 83, - 245, 94, 358, 83, 357, 94, 2049, 53, 271, 271, - 271, 80, 120, 120, 54, 2047, 62, 62, 62, 62, - - 62, 62, 62, 62, 62, 62, 62, 63, 63, 1265, - 83, 63, 63, 358, 83, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 337, 337, 63, 63, 63, 63, - 63, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 96, 246, 96, 96, 282, 282, 282, 366, - 366, 96, 283, 283, 283, 96, 270, 63, 63, 63, - 475, 63, 335, 335, 81, 475, 81, 81, 368, 368, - 271, 489, 89, 81, 89, 89, 489, 81, 376, 376, - 495, 81, 96, 381, 381, 89, 96, 1265, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - - 72, 89, 72, 72, 81, 383, 383, 82, 81, 82, - 82, 495, 81, 72, 389, 389, 89, 391, 391, 82, - 82, 2041, 82, 496, 257, 392, 392, 257, 282, 82, - 257, 2031, 89, 508, 283, 335, 460, 460, 508, 84, - 2028, 84, 84, 2022, 72, 462, 462, 2019, 84, 2017, - 82, 82, 84, 82, 496, 257, 84, 1990, 257, 497, - 82, 257, 84, 297, 297, 472, 472, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 74, 84, - 74, 74, 87, 84, 87, 87, 86, 84, 86, 86, - 497, 74, 87, 84, 498, 87, 87, 1988, 74, 86, - - 74, 314, 314, 314, 87, 74, 74, 74, 87, 86, - 1982, 315, 315, 315, 1980, 88, 499, 88, 88, 474, - 474, 1977, 74, 87, 88, 498, 87, 87, 88, 74, - 86, 74, 88, 297, 297, 87, 74, 74, 74, 87, - 86, 88, 510, 90, 88, 90, 90, 499, 91, 546, - 91, 91, 477, 477, 546, 88, 90, 504, 504, 88, - 1972, 91, 1968, 88, 91, 92, 90, 92, 92, 511, - 91, 512, 88, 510, 92, 88, 91, 328, 92, 328, - 328, 92, 1953, 314, 506, 506, 93, 90, 93, 93, - 328, 92, 91, 315, 513, 91, 514, 90, 515, 93, - - 511, 91, 512, 528, 528, 92, 328, 91, 93, 92, - 93, 516, 92, 93, 1941, 95, 517, 95, 95, 530, - 530, 328, 92, 518, 95, 513, 519, 514, 95, 515, - 93, 95, 95, 561, 98, 98, 97, 328, 561, 93, - 1929, 93, 516, 1904, 93, 98, 98, 517, 238, 238, - 238, 98, 238, 238, 518, 95, 1902, 519, 520, 95, - 1893, 238, 95, 95, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 99, 99, 563, 98, 98, - 98, 1888, 98, 100, 100, 1878, 99, 99, 1874, 520, - 102, 102, 99, 564, 100, 100, 1870, 339, 339, 339, - - 100, 102, 102, 110, 110, 535, 535, 102, 563, 98, - 537, 537, 329, 573, 329, 329, 543, 543, 573, 99, - 99, 99, 1851, 99, 564, 329, 565, 100, 100, 100, - 238, 100, 329, 566, 102, 102, 102, 1836, 102, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 99, 111, 99, 340, 340, 340, 329, 565, 100, 112, - 545, 545, 1824, 329, 566, 102, 555, 555, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 339, - 557, 557, 111, 1814, 113, 114, 567, 348, 348, 348, - 112, 1805, 111, 111, 111, 111, 111, 111, 111, 111, - - 111, 111, 111, 568, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 113, 114, 567, 1793, 115, - 116, 1787, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 577, 568, 340, 637, 637, 577, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 115, 116, 349, 349, 349, 1780, 569, 1745, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 348, - 642, 642, 644, 644, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 117, 117, 569, 330, 1693, - 330, 330, 118, 118, 570, 1690, 117, 117, 1653, 119, - - 119, 330, 117, 118, 118, 1638, 121, 121, 1628, 118, - 119, 119, 359, 359, 359, 1613, 119, 121, 121, 583, - 148, 1589, 140, 121, 583, 570, 140, 581, 1587, 117, - 117, 117, 330, 117, 349, 140, 118, 118, 118, 140, - 118, 582, 176, 119, 119, 119, 176, 119, 585, 586, - 121, 121, 121, 140, 121, 176, 587, 140, 581, 176, - 117, 588, 393, 393, 393, 1585, 140, 118, 1578, 118, - 140, 597, 582, 176, 119, 1566, 597, 176, 1559, 585, - 586, 121, 127, 127, 127, 589, 176, 587, 590, 1544, - 176, 1542, 588, 127, 359, 127, 127, 148, 148, 148, - - 148, 148, 148, 148, 148, 148, 148, 148, 127, 127, - 1538, 127, 394, 394, 1515, 150, 589, 656, 1498, 590, - 127, 1469, 127, 394, 127, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 232, 232, 232, 127, - 127, 232, 127, 232, 393, 235, 235, 235, 656, 232, - 235, 127, 235, 127, 394, 127, 601, 1573, 235, 673, - 673, 601, 1573, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 128, 128, 128, 1456, 661, 678, - 678, 680, 680, 693, 693, 128, 1450, 128, 128, 150, + 49, 49, 49, 51, 51, 51, 1496, 1496, 51, 509, + 52, 52, 52, 2390, 509, 52, 51, 62, 62, 62, + 2379, 51, 355, 52, 247, 247, 247, 2369, 52, 356, + 51, 55, 55, 55, 1612, 1612, 55, 52, 56, 56, + + 56, 2274, 178, 56, 55, 64, 178, 51, 357, 55, + 81, 56, 81, 355, 52, 178, 56, 496, 55, 178, + 356, 51, 81, 2359, 55, 56, 259, 2356, 52, 81, + 497, 56, 81, 178, 2350, 81, 547, 178, 51, 357, + 259, 547, 67, 259, 51, 52, 178, 498, 496, 55, + 178, 52, 329, 81, 329, 55, 56, 259, 62, 2329, + 81, 497, 56, 81, 329, 247, 81, 248, 248, 248, + 562, 259, 55, 2328, 259, 562, 2274, 1283, 498, 56, + 2325, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 65, 65, 574, 329, 65, 65, 2315, 574, + + 65, 65, 65, 65, 65, 65, 65, 65, 65, 2312, + 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 578, 96, 98, 96, + 98, 578, 584, 599, 499, 96, 98, 584, 599, 96, + 98, 65, 65, 65, 82, 65, 82, 84, 248, 84, + 603, 1283, 1287, 2304, 258, 603, 82, 258, 84, 84, + 258, 84, 271, 271, 271, 499, 96, 98, 84, 82, + 96, 98, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 74, 258, 74, 82, 258, 84, + 84, 258, 84, 86, 2280, 86, 74, 395, 397, 84, + + 82, 86, 272, 272, 272, 86, 500, 395, 397, 86, + 2273, 234, 234, 234, 2272, 86, 234, 511, 234, 88, + 2263, 88, 2260, 92, 234, 92, 1287, 74, 1619, 1619, + 2248, 88, 86, 512, 2247, 92, 86, 500, 395, 397, + 86, 88, 1625, 271, 513, 92, 86, 1625, 511, 2222, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 76, 88, 76, 512, 89, 92, 89, 514, 91, + 515, 91, 88, 76, 89, 513, 92, 89, 89, 2218, + 76, 91, 76, 272, 516, 517, 89, 76, 76, 76, + 89, 394, 234, 394, 519, 2214, 520, 91, 90, 514, + + 90, 515, 1737, 394, 76, 89, 90, 1737, 89, 89, + 90, 76, 91, 76, 90, 516, 517, 89, 76, 76, + 76, 89, 521, 90, 518, 519, 90, 520, 91, 564, + 1744, 93, 565, 93, 394, 1744, 94, 90, 94, 2204, + 518, 90, 2202, 93, 94, 90, 93, 95, 94, 95, + 566, 94, 93, 521, 90, 518, 2196, 90, 93, 95, + 564, 94, 567, 565, 402, 2193, 402, 1765, 95, 569, + 95, 518, 1765, 95, 93, 94, 402, 93, 2180, 94, + 2154, 566, 94, 93, 99, 1624, 1624, 100, 100, 93, + 95, 2149, 94, 567, 97, 568, 97, 2147, 100, 95, + + 569, 95, 97, 100, 95, 2141, 97, 402, 570, 97, + 97, 568, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 283, 283, 283, 568, 101, 101, 2139, + 100, 100, 100, 97, 100, 102, 102, 97, 101, 570, + 97, 97, 568, 101, 104, 104, 102, 399, 2127, 399, + 399, 102, 399, 571, 582, 104, 1640, 1640, 2124, 209, + 104, 100, 399, 405, 209, 405, 112, 1671, 1671, 2119, + 101, 101, 101, 2109, 101, 405, 209, 405, 102, 102, + 102, 756, 102, 756, 571, 582, 756, 104, 104, 104, + 209, 104, 757, 399, 757, 209, 2091, 757, 284, 284, + + 284, 101, 2086, 101, 283, 2084, 405, 209, 405, 102, + 113, 315, 315, 315, 316, 316, 316, 114, 104, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 113, 115, 116, 583, 586, 1736, 1736, 114, 1743, + 1743, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 115, 116, 583, 586, 117, 118, 284, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 2081, 315, 1758, 1758, 316, 587, 116, 116, 116, + + 116, 116, 116, 116, 116, 116, 116, 116, 117, 118, + 338, 338, 338, 2079, 588, 2074, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 587, 339, 339, + 339, 2072, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 119, 119, 588, 409, 2069, 409, 120, + 120, 347, 347, 347, 119, 121, 121, 2064, 409, 119, + 120, 123, 123, 2059, 589, 120, 121, 157, 157, 2044, + 590, 121, 123, 348, 348, 348, 591, 123, 157, 358, + 358, 358, 592, 157, 648, 648, 119, 119, 119, 409, + 119, 338, 120, 120, 120, 589, 120, 2041, 121, 121, + + 121, 590, 121, 150, 123, 123, 123, 591, 123, 339, + 157, 157, 157, 592, 157, 648, 648, 119, 1764, 1764, + 2035, 657, 406, 120, 406, 120, 237, 237, 237, 121, + 2022, 237, 347, 237, 406, 123, 129, 129, 129, 237, + 662, 157, 2020, 406, 1991, 700, 1989, 129, 1980, 129, + 129, 401, 657, 401, 348, 1974, 158, 158, 1963, 401, + 358, 129, 129, 401, 129, 406, 735, 158, 392, 392, + 392, 662, 158, 129, 406, 129, 700, 129, 736, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - - 128, 128, 699, 128, 734, 258, 396, 396, 401, 661, - 401, 401, 128, 735, 128, 740, 128, 396, 232, 258, - 741, 401, 258, 152, 695, 695, 404, 235, 404, 404, - 1440, 128, 128, 699, 128, 734, 258, 1674, 153, 404, - 742, 404, 1674, 128, 735, 128, 740, 128, 396, 1430, - 258, 741, 401, 258, 152, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 129, 129, 129, 153, - 404, 742, 404, 709, 709, 714, 714, 129, 1411, 129, - 129, 152, 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 154, 716, 716, 1403, 153, 153, 153, 153, - - 153, 153, 153, 153, 153, 153, 153, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 717, 717, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 286, 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 756, 756, 838, 838, 1356, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 141, 141, - 141, 845, 845, 141, 141, 1681, 605, 605, 605, 141, - 1681, 141, 141, 605, 141, 141, 155, 155, 1344, 406, - 141, 406, 406, 156, 156, 1342, 723, 155, 155, 857, - 857, 1327, 406, 155, 156, 156, 612, 612, 612, 406, - - 156, 157, 157, 612, 723, 866, 866, 141, 141, 141, - 1320, 141, 157, 157, 628, 628, 628, 723, 157, 1316, - 155, 155, 155, 406, 155, 159, 159, 156, 156, 156, - 406, 156, 719, 719, 1273, 723, 159, 159, 141, 908, - 908, 255, 159, 719, 743, 157, 157, 157, 605, 157, - 398, 155, 398, 398, 1700, 398, 398, 1264, 156, 1700, - 156, 920, 920, 618, 618, 618, 398, 618, 1262, 159, - 159, 159, 255, 159, 719, 743, 157, 744, 612, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 400, 1260, 400, 400, 922, 922, 628, 398, 292, 400, - - 159, 248, 248, 400, 867, 248, 248, 1258, 744, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 931, 931, - 248, 248, 248, 248, 248, 261, 261, 938, 938, 292, - 400, 1256, 262, 262, 400, 867, 261, 261, 645, 645, - 645, 868, 261, 262, 262, 618, 950, 950, 1254, 262, - 848, 248, 248, 248, 1252, 248, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 852, 848, 261, - 261, 261, 868, 261, 850, 1248, 262, 262, 262, 850, - 262, 848, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 256, 869, 852, 256, 852, 848, - - 261, 657, 657, 657, 2281, 263, 263, 262, 1246, 262, - 850, 1243, 265, 265, 951, 951, 263, 263, 952, 952, - 645, 291, 263, 265, 265, 256, 869, 1241, 256, 265, - 753, 1202, 753, 855, 1135, 753, 753, 1130, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 263, - 263, 263, 291, 263, 956, 956, 265, 265, 265, 871, - 265, 1117, 855, 1108, 855, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 660, 660, 660, 2281, - 263, 293, 1103, 657, 664, 664, 664, 265, 285, 285, - 871, 1093, 285, 285, 720, 720, 285, 285, 285, 285, - - 285, 285, 285, 285, 285, 720, 872, 285, 285, 285, - 285, 285, 293, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 1090, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 720, 872, 285, 285, - 285, 1086, 285, 294, 294, 1084, 408, 1082, 408, 408, - 295, 295, 957, 957, 294, 294, 958, 958, 660, 408, - 294, 295, 295, 959, 959, 1077, 664, 295, 955, 285, - 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, - 285, 856, 874, 856, 681, 681, 681, 294, 294, 294, - 408, 294, 296, 296, 295, 295, 295, 875, 295, 298, - - 298, 960, 960, 296, 296, 944, 754, 754, 304, 296, - 298, 298, 856, 874, 856, 646, 298, 754, 294, 403, - 940, 403, 403, 927, 755, 295, 755, 295, 875, 755, - 755, 403, 403, 646, 646, 916, 296, 296, 296, 304, - 296, 911, 876, 298, 298, 298, 646, 298, 754, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 305, 305, 403, 403, 646, 646, 681, 296, 306, 306, - 898, 305, 305, 876, 298, 307, 307, 305, 877, 306, - 306, 893, 309, 309, 878, 306, 307, 307, 405, 892, - 405, 405, 307, 309, 309, 1042, 1042, 1060, 1060, 309, - - 889, 405, 1061, 1061, 305, 305, 305, 888, 305, 877, - 405, 879, 306, 306, 306, 878, 306, 362, 880, 307, - 307, 307, 885, 307, 768, 881, 309, 309, 309, 768, - 309, 435, 405, 435, 435, 305, 1064, 1064, 700, 700, - 700, 405, 879, 306, 435, 306, 718, 718, 718, 880, - 307, 884, 730, 730, 730, 768, 881, 309, 317, 317, - 768, 873, 317, 317, 1087, 1087, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 435, 870, 317, 317, 317, - 317, 317, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 752, 362, 362, 362, 362, 362, 362, - - 362, 362, 362, 362, 362, 733, 733, 733, 317, 317, - 317, 737, 317, 332, 332, 731, 452, 705, 452, 452, - 700, 333, 333, 701, 332, 332, 1105, 1105, 718, 452, - 332, 669, 333, 333, 730, 1114, 1114, 882, 333, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 324, 851, 324, 324, 1118, 1118, 332, 332, 332, - 452, 332, 334, 334, 324, 333, 333, 333, 882, 333, - 1729, 851, 665, 334, 334, 1729, 736, 736, 736, 334, - 739, 739, 739, 851, 751, 751, 751, 733, 332, 1797, - 411, 658, 411, 411, 1797, 324, 333, 633, 333, 778, - - 336, 336, 851, 411, 778, 899, 334, 334, 334, 629, - 334, 336, 336, 886, 886, 886, 411, 336, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 402, - 778, 402, 402, 622, 411, 778, 899, 334, 363, 363, - 363, 621, 402, 849, 336, 336, 336, 411, 336, 620, - 363, 363, 364, 364, 364, 616, 363, 402, 736, 365, - 365, 365, 739, 849, 364, 364, 751, 1119, 1119, 615, - 364, 365, 365, 402, 849, 336, 613, 365, 367, 367, - 367, 779, 609, 363, 363, 363, 779, 363, 402, 853, - 367, 367, 1120, 1120, 849, 886, 367, 364, 364, 364, - - 853, 364, 1121, 1121, 365, 365, 365, 384, 365, 1122, - 1122, 608, 779, 413, 363, 413, 413, 779, 606, 900, - 853, 507, 413, 367, 367, 367, 413, 367, 364, 502, - 364, 853, 890, 890, 890, 365, 377, 377, 377, 377, - 377, 377, 377, 377, 377, 377, 377, 372, 901, 410, - 900, 410, 410, 413, 367, 370, 370, 413, 360, 370, - 370, 355, 410, 370, 370, 370, 370, 370, 370, 370, - 370, 370, 410, 909, 370, 370, 370, 370, 370, 901, - 912, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 455, 410, 1457, 1457, 928, 351, 928, 346, - - 854, 928, 928, 410, 909, 370, 370, 370, 342, 370, - 327, 912, 1560, 1560, 890, 290, 894, 894, 894, 854, - 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, - 455, 854, 897, 897, 897, 279, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 371, 371, - 854, 277, 371, 371, 371, 371, 371, 371, 371, 371, - 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, - 371, 374, 374, 923, 254, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 378, 378, 252, 418, 894, 418, - - 418, 379, 379, 243, 923, 378, 378, 241, 380, 380, - 418, 378, 379, 379, 897, 1567, 1567, 418, 379, 380, - 380, 1572, 1572, 229, 420, 380, 420, 420, 1586, 1586, - 223, 414, 222, 414, 414, 420, 933, 420, 378, 378, - 378, 418, 378, 214, 414, 379, 379, 379, 418, 379, - 1614, 1614, 380, 380, 380, 213, 380, 414, 374, 374, - 414, 374, 382, 382, 1673, 1673, 420, 933, 420, 378, - 386, 386, 386, 382, 382, 414, 379, 209, 379, 382, - 934, 386, 386, 380, 387, 387, 387, 386, 414, 941, - 942, 414, 193, 929, 929, 387, 387, 910, 910, 910, - - 424, 387, 424, 424, 929, 945, 382, 382, 382, 192, - 382, 934, 186, 424, 386, 386, 386, 185, 386, 946, - 941, 942, 388, 388, 388, 769, 178, 424, 387, 387, - 387, 177, 387, 388, 388, 929, 945, 382, 769, 388, - 390, 390, 390, 769, 424, 386, 915, 915, 915, 142, - 946, 390, 390, 926, 926, 926, 769, 390, 424, 387, - 71, 387, 399, 57, 399, 399, 388, 388, 388, 769, - 388, 930, 36, 930, 769, 399, 930, 930, 407, 910, - 407, 407, 399, 35, 390, 390, 390, 34, 390, 947, - 399, 407, 1680, 1680, 939, 939, 939, 388, 33, 407, - - 407, 415, 948, 415, 415, 0, 399, 407, 949, 0, - 1065, 1694, 1694, 399, 415, 390, 397, 0, 397, 397, - 947, 399, 407, 409, 415, 409, 409, 1066, 915, 397, - 407, 407, 409, 948, 409, 926, 409, 0, 407, 949, - 770, 1065, 770, 409, 0, 415, 1054, 770, 1051, 1051, - 409, 412, 0, 412, 412, 415, 0, 1054, 1066, 416, - 397, 416, 416, 409, 412, 409, 0, 409, 416, 1699, - 1699, 770, 416, 770, 409, 412, 939, 1054, 770, 1051, - 1051, 409, 416, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 417, 412, 417, 417, 421, 416, - - 421, 421, 419, 416, 419, 419, 412, 417, 1728, 1728, - 1067, 421, 0, 416, 0, 419, 422, 419, 422, 422, - 421, 1796, 1796, 426, 417, 426, 426, 0, 422, 422, - 0, 0, 423, 1068, 423, 423, 426, 425, 417, 425, - 425, 1067, 421, 422, 422, 423, 419, 0, 419, 969, - 425, 421, 423, 969, 426, 417, 425, 0, 425, 422, - 422, 943, 943, 943, 1068, 0, 427, 426, 427, 427, - 0, 0, 0, 780, 422, 422, 423, 0, 780, 427, - 969, 425, 0, 423, 969, 426, 0, 425, 428, 425, - 428, 428, 427, 429, 0, 429, 429, 428, 0, 0, - - 430, 428, 430, 430, 780, 431, 429, 431, 431, 780, - 427, 429, 0, 430, 430, 0, 1055, 432, 431, 432, - 432, 0, 0, 427, 1069, 431, 1055, 0, 428, 432, - 432, 0, 428, 433, 782, 433, 433, 429, 436, 782, - 436, 436, 429, 943, 430, 430, 433, 1055, 0, 431, - 434, 436, 434, 434, 0, 1069, 431, 1055, 500, 433, - 432, 432, 500, 434, 436, 782, 437, 0, 437, 437, - 782, 500, 434, 1070, 1071, 500, 0, 433, 441, 437, - 441, 441, 436, 437, 954, 954, 954, 0, 970, 500, - 433, 441, 970, 500, 434, 436, 439, 0, 439, 439, - - 1072, 441, 500, 434, 1070, 1071, 500, 978, 0, 439, - 437, 978, 0, 0, 437, 438, 439, 438, 438, 970, - 781, 781, 441, 970, 438, 439, 781, 439, 438, 438, - 0, 1072, 441, 440, 0, 440, 440, 438, 978, 438, - 439, 442, 978, 442, 442, 438, 440, 439, 1073, 0, - 442, 781, 781, 440, 442, 438, 439, 781, 439, 438, - 438, 440, 443, 0, 443, 443, 954, 0, 438, 0, - 438, 443, 0, 775, 775, 443, 438, 440, 775, 1073, - 444, 442, 444, 444, 440, 442, 445, 984, 445, 445, - 444, 984, 440, 444, 446, 0, 446, 446, 447, 445, - - 447, 447, 443, 446, 775, 775, 443, 446, 774, 775, - 774, 447, 445, 774, 448, 447, 448, 448, 984, 0, - 0, 444, 984, 446, 444, 0, 448, 448, 787, 448, - 445, 1075, 800, 787, 446, 0, 0, 800, 446, 774, - 783, 774, 447, 445, 774, 783, 447, 783, 449, 0, - 449, 449, 0, 450, 446, 450, 450, 448, 448, 787, - 448, 449, 1075, 800, 787, 449, 450, 451, 800, 451, - 451, 783, 453, 450, 453, 453, 783, 0, 783, 450, - 451, 454, 988, 454, 454, 453, 988, 0, 0, 0, - 457, 457, 449, 451, 454, 0, 449, 450, 0, 0, - - 453, 457, 457, 0, 450, 0, 464, 457, 464, 464, - 450, 451, 0, 988, 0, 0, 453, 988, 785, 464, - 785, 1076, 1058, 785, 451, 454, 458, 458, 0, 459, - 459, 453, 1058, 0, 457, 457, 457, 458, 458, 0, - 459, 459, 0, 458, 461, 461, 459, 469, 469, 785, - 464, 785, 1076, 1058, 785, 461, 461, 0, 469, 469, - 0, 461, 0, 1058, 469, 457, 1052, 1078, 1079, 1052, - 458, 458, 458, 459, 459, 459, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 1080, 461, 461, - 461, 469, 469, 469, 480, 469, 0, 1052, 1078, 1079, - - 1052, 458, 0, 458, 459, 468, 468, 468, 468, 468, - 468, 468, 468, 468, 468, 468, 470, 470, 1080, 461, - 0, 0, 469, 471, 471, 480, 0, 470, 470, 0, - 473, 473, 0, 470, 471, 471, 0, 0, 0, 0, - 471, 473, 473, 478, 478, 0, 1091, 473, 1092, 480, - 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, - 470, 470, 470, 771, 470, 771, 481, 471, 471, 471, - 771, 471, 1100, 1104, 473, 473, 473, 1091, 473, 1092, - 0, 0, 0, 0, 0, 0, 0, 0, 479, 0, - 0, 470, 0, 470, 771, 0, 771, 481, 471, 0, - - 482, 771, 0, 1100, 1104, 473, 0, 0, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 479, - 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, - 481, 482, 479, 479, 479, 479, 479, 479, 479, 479, - 479, 479, 479, 483, 484, 485, 485, 485, 485, 485, - 485, 485, 485, 485, 485, 485, 0, 0, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, 482, 0, - 0, 0, 0, 0, 483, 484, 0, 0, 0, 0, - 0, 0, 0, 0, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 0, 788, 788, 1089, 1089, - - 1089, 788, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 486, 486, 486, 486, 486, 486, 486, - 486, 486, 486, 486, 491, 491, 491, 788, 788, 0, - 0, 0, 788, 0, 0, 491, 1123, 491, 491, 521, - 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, - 491, 491, 773, 491, 524, 722, 0, 722, 722, 786, - 722, 722, 491, 773, 491, 786, 491, 1123, 773, 982, - 786, 722, 982, 982, 525, 525, 525, 0, 0, 0, - 1089, 491, 491, 773, 491, 0, 525, 525, 0, 0, - 786, 0, 525, 491, 773, 491, 786, 491, 538, 773, - - 982, 786, 722, 982, 982, 491, 491, 491, 491, 491, - 491, 491, 491, 491, 491, 491, 492, 492, 492, 525, - 525, 525, 989, 525, 0, 1124, 989, 492, 0, 492, - 492, 524, 524, 524, 524, 524, 524, 524, 524, 524, - 524, 524, 526, 526, 526, 0, 728, 989, 728, 728, - 525, 0, 0, 989, 526, 526, 1124, 989, 0, 728, - 526, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 538, 538, 538, 538, 538, 538, 538, 538, - 538, 538, 538, 1102, 1102, 1102, 0, 526, 526, 526, - 728, 526, 1085, 1085, 1085, 0, 1085, 492, 492, 492, - - 492, 492, 492, 492, 492, 492, 492, 492, 501, 501, - 501, 1132, 801, 501, 501, 0, 0, 801, 526, 501, - 526, 501, 501, 801, 501, 501, 527, 527, 527, 0, - 501, 793, 0, 529, 529, 529, 793, 793, 527, 527, - 0, 0, 1132, 801, 527, 529, 529, 725, 801, 725, - 725, 529, 532, 532, 801, 1144, 1145, 501, 501, 501, - 725, 501, 793, 532, 532, 1102, 0, 793, 793, 532, - 725, 527, 527, 527, 1085, 527, 0, 772, 529, 529, - 529, 772, 529, 0, 791, 791, 1144, 1145, 501, 791, - 772, 725, 0, 533, 533, 772, 532, 532, 532, 0, - - 532, 725, 527, 0, 533, 533, 534, 534, 772, 529, - 533, 0, 772, 536, 536, 791, 791, 534, 534, 0, - 791, 772, 811, 534, 536, 536, 772, 532, 0, 796, - 536, 540, 540, 540, 796, 811, 1151, 533, 533, 533, - 811, 533, 540, 540, 0, 796, 0, 1163, 540, 1168, - 534, 534, 534, 811, 534, 0, 0, 536, 536, 536, - 796, 536, 1081, 1081, 1081, 796, 811, 1151, 533, 1081, - 533, 811, 541, 541, 541, 540, 540, 540, 1163, 540, - 1168, 534, 1173, 541, 541, 542, 542, 542, 536, 541, - 0, 0, 544, 544, 544, 0, 542, 542, 724, 0, - - 724, 724, 542, 544, 544, 0, 540, 0, 776, 544, - 799, 724, 799, 1173, 1179, 799, 541, 541, 541, 776, - 541, 777, 549, 777, 776, 1057, 724, 548, 777, 542, - 542, 542, 1057, 542, 1146, 1146, 544, 544, 544, 776, - 544, 799, 724, 799, 1081, 1179, 799, 541, 0, 541, - 776, 0, 777, 549, 777, 776, 1057, 724, 548, 777, - 542, 0, 550, 1057, 0, 1146, 1146, 544, 548, 548, - 548, 548, 548, 548, 548, 548, 548, 548, 548, 549, - 549, 549, 549, 549, 549, 549, 549, 549, 549, 549, + 401, 1798, 129, 129, 401, 129, 1798, 735, 1959, 158, + + 158, 158, 741, 158, 129, 722, 129, 237, 129, 736, + 1954, 742, 630, 630, 630, 722, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 130, 130, 130, + 158, 743, 158, 741, 744, 1797, 1797, 1951, 130, 1936, + 130, 130, 742, 240, 240, 240, 722, 240, 240, 392, + 501, 1918, 130, 130, 501, 130, 240, 745, 784, 1917, + 152, 1903, 743, 501, 130, 744, 130, 501, 130, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 404, 501, 404, 130, 130, 501, 130, 1891, 745, 784, + 154, 404, 404, 630, 501, 130, 1882, 130, 501, 130, + + 1872, 1872, 620, 620, 620, 1868, 620, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, + 131, 154, 404, 404, 240, 759, 1862, 759, 155, 131, + 759, 131, 131, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 156, 1855, 1845, 1842, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 155, + 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, + 251, 2324, 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 620, 1818, 792, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 794, 131, 131, + + 131, 131, 131, 131, 131, 131, 131, 131, 131, 143, + 143, 143, 1812, 1873, 143, 143, 792, 328, 1873, 328, + 143, 723, 143, 143, 1801, 143, 159, 159, 794, 328, + 143, 723, 161, 161, 1757, 783, 328, 159, 1753, 262, + 262, 1728, 159, 161, 408, 2324, 408, 765, 161, 783, + 262, 1725, 1713, 1699, 765, 262, 408, 143, 143, 143, + 328, 143, 723, 1688, 408, 408, 783, 328, 1674, 159, + 159, 159, 408, 159, 795, 161, 161, 161, 765, 161, + 783, 1670, 262, 262, 262, 765, 262, 408, 143, 431, + 2459, 431, 1643, 263, 263, 408, 408, 647, 647, 647, + + 159, 431, 431, 408, 263, 795, 161, 250, 250, 263, + 1641, 250, 250, 262, 1639, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 1631, 250, 250, 250, 250, 250, + 264, 264, 431, 431, 1618, 1611, 263, 263, 263, 1603, + 263, 264, 421, 403, 421, 403, 264, 658, 658, 658, + 1599, 778, 421, 778, 421, 403, 250, 250, 250, 1593, + 250, 607, 607, 607, 2459, 266, 266, 263, 607, 263, + 403, 1591, 1587, 264, 264, 264, 266, 264, 647, 1564, + 799, 266, 778, 421, 778, 421, 403, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 257, + + 1549, 403, 257, 767, 264, 807, 801, 767, 266, 266, + 266, 799, 266, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 1544, 614, 614, 614, 658, 818, + 257, 801, 614, 257, 767, 1512, 807, 801, 767, 266, + 292, 1507, 607, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 286, 286, 1503, 1495, 286, 286, + 818, 1489, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 292, 286, 286, 286, 286, 286, 939, 940, 939, + 940, 1479, 939, 940, 292, 292, 292, 292, 292, 292, + 292, 292, 292, 292, 292, 293, 661, 661, 661, 665, + + 665, 665, 1469, 286, 286, 286, 614, 286, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 1465, + 294, 682, 682, 682, 1460, 1447, 293, 701, 701, 701, + 1439, 719, 719, 719, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 1432, 823, 731, 731, + 731, 294, 1423, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 294, 294, 294, 294, 294, 294, + 294, 294, 294, 294, 294, 295, 295, 661, 823, 829, + 665, 296, 296, 734, 734, 734, 295, 297, 297, 1401, + 1389, 295, 296, 299, 299, 1375, 1373, 296, 297, 411, + + 1354, 411, 682, 297, 299, 427, 758, 427, 701, 299, + 829, 411, 719, 737, 737, 737, 758, 427, 295, 295, + 295, 411, 295, 1347, 296, 296, 296, 305, 296, 731, + 297, 297, 297, 1343, 297, 427, 299, 299, 299, 420, + 299, 420, 411, 306, 306, 1313, 1307, 758, 427, 295, + 1297, 420, 411, 420, 306, 296, 1290, 296, 305, 306, + 942, 297, 942, 1288, 734, 942, 427, 299, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 822, + 307, 307, 420, 407, 420, 407, 306, 306, 306, 1286, + 306, 307, 308, 308, 737, 407, 307, 1284, 310, 310, + + 766, 1282, 407, 308, 822, 331, 331, 771, 308, 310, + 822, 1280, 1278, 766, 310, 771, 331, 306, 1273, 1271, + 414, 331, 414, 307, 307, 307, 407, 307, 414, 1267, + 1265, 766, 414, 407, 1243, 308, 308, 308, 771, 308, + 835, 310, 310, 310, 766, 310, 771, 1223, 331, 331, + 331, 1158, 331, 1152, 307, 1147, 307, 1141, 1140, 414, + 740, 740, 740, 414, 332, 332, 308, 753, 753, 753, + 1139, 835, 310, 318, 318, 332, 1138, 318, 318, 331, + 332, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 860, 318, 318, 318, 318, 318, 319, 319, 319, 319, + + 319, 319, 319, 319, 319, 319, 319, 332, 332, 332, + 361, 332, 1137, 1135, 768, 1132, 876, 1131, 768, 860, + 1125, 860, 318, 318, 318, 412, 318, 412, 333, 333, + 1122, 422, 1120, 422, 1111, 335, 335, 412, 332, 333, + 332, 740, 1109, 422, 333, 768, 335, 876, 753, 768, + 412, 335, 422, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 325, 769, 325, 412, 1106, + 769, 333, 333, 333, 422, 333, 877, 325, 335, 335, + 335, 412, 335, 422, 1105, 1103, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 769, 362, 362, + + 362, 769, 333, 1101, 363, 363, 363, 877, 325, 335, + 362, 364, 364, 364, 786, 362, 363, 1095, 1081, 1078, + 770, 363, 786, 364, 1077, 1057, 1056, 770, 364, 972, + 971, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 362, 362, 362, 786, 362, 970, 363, 363, + 363, 770, 363, 786, 969, 364, 364, 364, 770, 364, + 366, 366, 366, 968, 436, 966, 436, 963, 962, 377, + 377, 775, 366, 362, 961, 960, 436, 366, 775, 363, + 377, 363, 954, 950, 788, 377, 364, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 376, 376, 383, 413, + + 788, 413, 775, 948, 366, 366, 366, 436, 366, 775, + 944, 413, 377, 377, 377, 788, 377, 378, 378, 937, + 935, 931, 413, 379, 379, 929, 925, 920, 378, 917, + 909, 788, 904, 378, 379, 366, 369, 369, 878, 379, + 369, 369, 413, 377, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 413, 369, 369, 369, 369, 369, 903, + 378, 378, 378, 781, 378, 781, 379, 379, 379, 878, + 379, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 802, 864, 802, 369, 369, 369, 433, 369, + 433, 378, 900, 378, 781, 899, 781, 379, 896, 433, + + 433, 464, 464, 464, 464, 464, 464, 464, 464, 464, + 464, 464, 864, 802, 864, 802, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 370, 370, + 433, 433, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 373, 373, 895, 883, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 381, 381, 809, 418, 809, 418, 385, 385, + 385, 879, 875, 381, 386, 386, 386, 418, 381, 385, + 866, 853, 845, 844, 385, 386, 761, 387, 387, 387, + + 386, 754, 752, 738, 418, 809, 732, 809, 387, 720, + 718, 717, 425, 387, 425, 381, 381, 381, 418, 381, + 880, 385, 385, 385, 425, 385, 715, 386, 386, 386, + 710, 386, 389, 389, 389, 418, 373, 373, 425, 373, + 387, 387, 387, 389, 387, 400, 381, 400, 389, 706, + 881, 880, 385, 702, 429, 425, 429, 400, 386, 696, + 386, 415, 429, 415, 400, 694, 429, 803, 453, 425, + 453, 387, 400, 415, 681, 389, 389, 389, 679, 389, + 453, 881, 410, 803, 410, 674, 415, 670, 400, 415, + 410, 666, 410, 429, 410, 400, 772, 429, 803, 882, + + 416, 410, 416, 400, 415, 772, 389, 398, 410, 398, + 772, 453, 416, 659, 803, 646, 417, 415, 417, 398, + 415, 410, 416, 410, 417, 410, 644, 772, 417, 774, + 882, 777, 410, 774, 639, 777, 772, 884, 417, 410, + 635, 772, 419, 416, 419, 423, 424, 423, 424, 631, + 398, 624, 623, 416, 419, 417, 423, 423, 424, 417, + 774, 419, 777, 776, 774, 424, 777, 622, 884, 417, + 776, 423, 423, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 618, 419, 617, 423, 423, 424, + 615, 611, 419, 426, 776, 426, 424, 428, 430, 428, + + 430, 776, 423, 423, 432, 426, 432, 610, 608, 428, + 430, 426, 434, 426, 434, 430, 432, 435, 437, 435, + 437, 779, 428, 432, 434, 814, 814, 789, 558, 435, + 437, 789, 779, 438, 556, 438, 426, 434, 435, 773, + 428, 430, 426, 437, 426, 438, 430, 432, 773, 438, + 546, 885, 779, 428, 432, 434, 814, 814, 789, 782, + 435, 437, 789, 779, 544, 442, 782, 442, 434, 435, + 773, 538, 536, 440, 437, 440, 438, 442, 531, 773, + 438, 439, 885, 439, 790, 440, 441, 442, 441, 439, + 782, 785, 440, 439, 439, 790, 791, 782, 441, 791, + + 785, 440, 439, 440, 439, 441, 529, 439, 442, 443, + 439, 443, 797, 441, 508, 790, 440, 443, 442, 797, + 439, 443, 785, 440, 439, 439, 790, 791, 507, 441, + 791, 785, 440, 439, 440, 439, 441, 444, 439, 444, + 505, 439, 503, 797, 441, 444, 787, 478, 443, 444, + 797, 445, 443, 445, 446, 787, 446, 447, 780, 447, + 445, 805, 448, 445, 448, 447, 446, 886, 780, 447, + 449, 450, 449, 450, 448, 805, 444, 787, 448, 446, + 444, 449, 449, 450, 449, 447, 787, 450, 475, 780, + 473, 445, 805, 793, 445, 463, 447, 446, 886, 780, + + 447, 461, 858, 793, 800, 448, 805, 858, 800, 448, + 446, 393, 449, 449, 450, 449, 447, 451, 450, 451, + 452, 454, 452, 454, 793, 455, 806, 455, 465, 451, + 465, 796, 452, 454, 793, 800, 451, 455, 858, 800, + 465, 796, 451, 391, 887, 452, 806, 390, 454, 388, + 458, 458, 456, 382, 459, 459, 380, 806, 460, 460, + 451, 458, 796, 452, 454, 459, 458, 451, 455, 460, + 459, 465, 796, 451, 460, 887, 452, 806, 825, 454, + 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, + 456, 375, 371, 458, 458, 458, 825, 459, 459, 459, + + 367, 460, 460, 460, 462, 462, 365, 470, 470, 825, + 721, 359, 721, 354, 350, 462, 345, 341, 470, 729, + 462, 729, 721, 470, 458, 336, 324, 825, 459, 321, + 459, 729, 460, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 471, 471, 812, 462, 462, 462, + 470, 470, 470, 721, 470, 471, 472, 472, 311, 812, + 471, 309, 729, 474, 474, 300, 291, 472, 725, 280, + 725, 725, 472, 725, 474, 479, 278, 812, 462, 474, + 726, 470, 726, 725, 819, 815, 804, 471, 471, 471, + 812, 471, 726, 755, 819, 755, 481, 804, 815, 472, + + 472, 472, 726, 472, 888, 755, 474, 474, 474, 267, + 474, 256, 254, 245, 725, 819, 815, 804, 471, 480, + 471, 243, 231, 726, 225, 819, 224, 481, 804, 815, + 472, 482, 216, 726, 215, 888, 755, 474, 211, 479, + 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, + 480, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 482, 480, 480, 480, 480, 480, 480, 480, + 480, 480, 480, 480, 483, 484, 811, 813, 811, 813, + 816, 856, 798, 808, 816, 482, 482, 482, 482, 482, + 482, 482, 482, 482, 482, 482, 485, 798, 808, 856, + + 889, 897, 897, 897, 195, 483, 484, 811, 813, 811, + 813, 816, 856, 798, 808, 816, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 485, 798, 808, + 856, 889, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 486, 486, 486, 486, 486, 486, 486, + 486, 486, 486, 486, 485, 485, 485, 485, 485, 485, + 485, 485, 485, 485, 485, 487, 487, 487, 487, 487, + 487, 487, 487, 487, 487, 487, 492, 492, 492, 890, + 194, 188, 897, 187, 180, 179, 162, 492, 160, 492, + 492, 148, 146, 144, 124, 526, 526, 526, 817, 821, + + 810, 492, 492, 834, 492, 817, 525, 526, 111, 105, + 890, 810, 526, 492, 821, 492, 834, 492, 522, 522, + 522, 522, 522, 522, 522, 522, 522, 522, 522, 817, + 821, 810, 492, 492, 834, 492, 817, 73, 72, 526, + 526, 526, 810, 526, 492, 821, 492, 834, 492, 539, + 69, 59, 36, 901, 901, 901, 492, 492, 492, 492, + 492, 492, 492, 492, 492, 492, 492, 493, 493, 493, + 526, 35, 833, 838, 34, 891, 833, 838, 493, 33, + 493, 493, 525, 525, 525, 525, 525, 525, 525, 525, + 525, 525, 525, 527, 527, 527, 0, 0, 0, 905, + + 905, 905, 820, 833, 838, 527, 891, 833, 838, 820, + 527, 532, 532, 532, 532, 532, 532, 532, 532, 532, + 532, 532, 539, 539, 539, 539, 539, 539, 539, 539, + 539, 539, 539, 820, 901, 0, 0, 527, 527, 527, + 820, 527, 892, 0, 0, 0, 0, 493, 493, 493, + 493, 493, 493, 493, 493, 493, 493, 493, 502, 502, + 502, 0, 0, 502, 502, 824, 824, 824, 527, 502, + 527, 502, 502, 892, 502, 528, 528, 528, 862, 502, + 905, 530, 530, 530, 862, 0, 826, 528, 533, 533, + 0, 824, 528, 530, 0, 0, 0, 826, 530, 533, + + 534, 534, 0, 0, 533, 893, 502, 502, 502, 862, + 502, 534, 0, 0, 0, 862, 534, 826, 0, 528, + 528, 528, 824, 528, 837, 530, 530, 530, 826, 530, + 0, 533, 533, 533, 828, 533, 893, 502, 535, 535, + 837, 828, 910, 534, 534, 534, 824, 534, 0, 535, + 528, 0, 537, 537, 535, 837, 530, 0, 831, 541, + 541, 541, 533, 537, 0, 828, 0, 831, 537, 911, + 541, 837, 828, 910, 534, 541, 534, 542, 542, 542, + 0, 535, 535, 535, 0, 535, 0, 0, 542, 831, + 0, 0, 859, 542, 0, 537, 537, 537, 831, 537, + + 911, 0, 541, 541, 541, 727, 541, 727, 830, 836, + 830, 859, 535, 918, 543, 543, 543, 727, 836, 830, + 542, 542, 542, 859, 542, 543, 537, 545, 545, 545, + 543, 727, 550, 541, 549, 865, 857, 865, 545, 830, + 836, 830, 859, 545, 918, 0, 0, 0, 727, 836, + 830, 542, 0, 542, 0, 0, 857, 543, 543, 543, + 0, 543, 727, 550, 0, 549, 865, 857, 865, 921, + 545, 545, 545, 0, 545, 549, 549, 549, 549, 549, + 549, 549, 549, 549, 549, 549, 551, 857, 543, 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, - 550, 552, 552, 0, 553, 553, 0, 0, 554, 554, - 1162, 1184, 552, 552, 1162, 553, 553, 0, 552, 554, - 554, 553, 556, 556, 0, 554, 639, 639, 0, 0, - 0, 0, 0, 556, 556, 0, 0, 639, 639, 556, - 0, 1162, 1184, 639, 1150, 552, 552, 552, 553, 553, - 553, 1150, 554, 554, 554, 558, 558, 558, 558, 558, - 558, 558, 558, 558, 558, 558, 556, 556, 556, 993, - 639, 639, 639, 993, 639, 1150, 552, 0, 0, 553, - 0, 553, 1150, 554, 559, 559, 559, 559, 559, 559, - 559, 559, 559, 559, 559, 0, 0, 556, 631, 631, - - 993, 639, 631, 631, 993, 0, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 647, 1185, 631, 631, 631, - 631, 631, 638, 638, 638, 638, 638, 638, 638, 638, - 638, 638, 638, 653, 653, 653, 653, 653, 653, 653, - 653, 653, 653, 653, 0, 0, 647, 1185, 631, 631, - 631, 0, 631, 0, 647, 647, 647, 647, 647, 647, - 647, 647, 647, 647, 647, 654, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 654, 1107, 1107, 1107, 631, - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 632, 632, 0, 0, 632, 632, 632, 632, 632, - - 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, - 632, 632, 632, 632, 635, 635, 1186, 0, 635, 635, - 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, - 635, 635, 635, 635, 635, 635, 635, 640, 640, 0, - 726, 0, 726, 726, 641, 641, 0, 1186, 640, 640, - 0, 643, 643, 726, 640, 641, 641, 0, 1107, 0, - 0, 641, 643, 643, 0, 0, 0, 726, 643, 674, - 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, - 0, 640, 640, 640, 726, 640, 0, 0, 641, 641, - 641, 648, 641, 1196, 1143, 643, 643, 643, 726, 643, - - 0, 635, 635, 0, 635, 0, 0, 0, 0, 649, - 798, 784, 640, 0, 640, 798, 784, 798, 1143, 641, - 650, 784, 648, 0, 1196, 1143, 643, 0, 0, 648, - 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, - 649, 798, 784, 0, 651, 0, 798, 784, 798, 1143, - 0, 650, 784, 649, 649, 649, 649, 649, 649, 649, - 649, 649, 649, 649, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 651, 652, 1164, 0, 1197, - 1198, 1164, 0, 0, 651, 651, 651, 651, 651, 651, - 651, 651, 651, 651, 651, 685, 685, 685, 685, 685, - - 685, 685, 685, 685, 685, 685, 0, 652, 1164, 682, - 1197, 1198, 652, 652, 652, 652, 652, 652, 652, 652, - 652, 652, 652, 667, 667, 0, 0, 667, 667, 0, - 0, 667, 667, 667, 667, 667, 667, 667, 667, 667, - 682, 683, 667, 667, 667, 667, 667, 682, 682, 682, - 682, 682, 682, 682, 682, 682, 682, 682, 686, 686, + 921, 545, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 559, 0, 551, 551, 551, 551, 551, 551, + 551, 551, 551, 551, 551, 553, 553, 0, 554, 554, + 0, 555, 555, 932, 557, 557, 553, 0, 0, 554, + 0, 553, 555, 0, 554, 557, 0, 555, 0, 0, + 557, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 951, 841, 932, 0, 841, 952, 553, 553, + 553, 554, 554, 554, 555, 555, 555, 557, 557, 557, + 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 0, 0, 951, 841, 641, 641, 841, 952, 553, + + 0, 0, 554, 650, 554, 555, 641, 0, 557, 633, + 633, 641, 955, 633, 633, 0, 0, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 0, 633, 633, 633, + 633, 633, 649, 956, 650, 0, 0, 0, 641, 641, + 641, 0, 641, 955, 908, 908, 908, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 633, 633, + 633, 0, 633, 649, 956, 0, 919, 919, 919, 641, + 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, + 649, 0, 924, 924, 924, 0, 0, 0, 0, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + + 633, 634, 634, 0, 0, 634, 634, 634, 634, 634, + 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, + 634, 634, 634, 637, 637, 908, 0, 637, 637, 637, + 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, + 637, 637, 637, 637, 637, 642, 642, 919, 936, 936, + 936, 643, 643, 0, 957, 861, 642, 645, 645, 0, + 0, 642, 643, 924, 0, 0, 861, 643, 645, 0, + 0, 0, 0, 645, 654, 654, 654, 654, 654, 654, + 654, 654, 654, 654, 654, 957, 861, 0, 642, 642, + 642, 651, 642, 941, 643, 643, 643, 861, 643, 958, + + 645, 645, 645, 941, 645, 0, 0, 676, 676, 637, + 637, 0, 637, 0, 0, 652, 0, 959, 676, 642, + 0, 642, 651, 676, 0, 643, 0, 0, 0, 936, + 958, 645, 0, 0, 941, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 651, 652, 653, 959, 979, + 676, 676, 676, 0, 676, 652, 652, 652, 652, 652, + 652, 652, 652, 652, 652, 652, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 0, 653, 0, + 979, 676, 0, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 668, 668, 0, 0, 668, 668, + + 0, 0, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 683, 668, 668, 668, 668, 668, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 0, - 0, 0, 683, 667, 667, 667, 0, 667, 0, 0, - 0, 683, 683, 683, 683, 683, 683, 683, 683, 683, - 683, 683, 689, 689, 689, 689, 689, 689, 689, 689, - - 689, 689, 689, 0, 667, 667, 667, 667, 667, 667, - 667, 667, 667, 667, 667, 667, 668, 668, 0, 0, - 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, - 668, 668, 668, 668, 668, 668, 668, 668, 668, 671, - 671, 1199, 0, 671, 671, 671, 671, 671, 671, 671, - 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, - 671, 671, 675, 675, 0, 0, 1116, 1116, 1116, 676, - 676, 0, 1199, 675, 675, 0, 677, 677, 1056, 675, - 676, 676, 0, 0, 0, 1200, 676, 677, 677, 0, - 0, 0, 1056, 677, 697, 697, 697, 697, 697, 697, - - 697, 697, 697, 697, 697, 1059, 675, 675, 675, 1056, - 675, 0, 1201, 676, 676, 676, 1200, 676, 684, 1059, - 677, 677, 677, 1056, 677, 0, 671, 671, 0, 671, - 679, 679, 0, 0, 803, 0, 1059, 675, 0, 803, - 803, 679, 679, 1201, 676, 0, 676, 679, 1116, 684, - 1059, 677, 1152, 0, 684, 684, 684, 684, 684, 684, - 684, 684, 684, 684, 684, 803, 1148, 0, 690, 690, - 803, 803, 1148, 1152, 679, 679, 679, 0, 679, 690, - 690, 691, 691, 1152, 792, 690, 792, 0, 0, 692, - 692, 792, 691, 691, 1195, 0, 0, 1148, 691, 1147, - - 692, 692, 0, 1148, 1152, 679, 692, 694, 694, 1195, - 1206, 1147, 690, 690, 690, 792, 690, 792, 694, 694, - 0, 0, 792, 696, 694, 691, 691, 691, 975, 691, - 1147, 0, 975, 692, 692, 692, 0, 692, 0, 0, - 1195, 1206, 1147, 690, 0, 0, 0, 1205, 975, 1157, - 1208, 694, 694, 694, 696, 694, 691, 0, 691, 975, - 1129, 1129, 1129, 975, 692, 1205, 1157, 696, 696, 696, - 696, 696, 696, 696, 696, 696, 696, 696, 1205, 975, - 1157, 1208, 694, 698, 698, 698, 698, 698, 698, 698, - 698, 698, 698, 698, 703, 703, 1205, 1157, 703, 703, - - 0, 0, 703, 703, 703, 703, 703, 703, 703, 703, - 703, 0, 1210, 703, 703, 703, 703, 703, 710, 710, - 710, 710, 710, 710, 710, 710, 710, 710, 710, 727, - 727, 727, 727, 727, 727, 727, 727, 727, 727, 727, - 0, 0, 1129, 1210, 703, 703, 703, 0, 703, 745, - 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, - 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, - 747, 1134, 1134, 1134, 0, 703, 703, 703, 703, 703, - 703, 703, 703, 703, 703, 703, 703, 704, 704, 746, - 0, 704, 704, 704, 704, 704, 704, 704, 704, 704, - - 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, - 707, 707, 1213, 0, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 711, 711, 0, 0, 1416, 1416, 1416, - 712, 712, 0, 1213, 711, 711, 0, 713, 713, 1158, - 711, 712, 712, 1134, 0, 0, 1158, 712, 713, 713, - 750, 0, 0, 1217, 713, 1221, 746, 746, 746, 746, - 746, 746, 746, 746, 746, 746, 746, 711, 711, 711, - 1158, 711, 0, 1230, 712, 712, 712, 1158, 712, 757, - 757, 713, 713, 713, 1217, 713, 1221, 707, 707, 0, - - 707, 715, 715, 0, 1230, 0, 0, 0, 711, 0, - 0, 0, 715, 715, 1230, 712, 0, 712, 715, 1416, - 0, 1239, 713, 749, 749, 749, 749, 749, 749, 749, - 749, 749, 749, 749, 750, 750, 750, 750, 750, 750, - 750, 750, 750, 750, 750, 715, 715, 715, 0, 715, - 759, 761, 1239, 0, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 758, 758, 758, 758, 758, - 758, 758, 758, 758, 758, 758, 715, 721, 0, 721, - 721, 759, 761, 0, 760, 996, 805, 1240, 805, 996, - 721, 805, 761, 761, 761, 761, 761, 761, 761, 761, - - 761, 761, 761, 0, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 760, 996, 805, 1240, 805, - 996, 721, 805, 0, 0, 0, 1242, 1244, 0, 0, - 762, 760, 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 763, 0, 721, 721, 721, 721, 721, 721, - 721, 721, 721, 721, 721, 748, 748, 1242, 1244, 748, - 748, 762, 0, 748, 748, 748, 748, 748, 748, 748, - 748, 748, 1245, 763, 748, 748, 748, 748, 748, 766, - 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, - 762, 764, 763, 763, 763, 763, 763, 763, 763, 763, - - 763, 763, 763, 1245, 0, 748, 748, 748, 0, 748, - 766, 0, 0, 0, 0, 0, 0, 765, 0, 0, - 0, 0, 764, 0, 0, 766, 766, 766, 766, 766, - 766, 766, 766, 766, 766, 766, 748, 748, 748, 748, - 748, 748, 748, 748, 748, 748, 748, 748, 765, 764, - 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, - 0, 0, 0, 0, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 767, 1247, 795, 0, 0, - 767, 0, 795, 0, 0, 1249, 0, 795, 836, 836, - 836, 836, 836, 836, 836, 836, 836, 836, 836, 0, - - 789, 790, 0, 794, 0, 1250, 767, 1247, 795, 789, - 790, 767, 794, 795, 789, 790, 1249, 794, 795, 0, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 789, 790, 807, 794, 797, 1250, 807, 807, 0, - 789, 790, 797, 794, 802, 789, 790, 797, 794, 804, - 806, 0, 1251, 802, 808, 810, 804, 806, 802, 810, - 810, 804, 806, 0, 807, 808, 797, 809, 807, 807, - 808, 0, 812, 797, 812, 802, 0, 809, 797, 812, - 804, 806, 809, 1251, 802, 808, 810, 804, 806, 802, - 810, 810, 804, 806, 813, 813, 808, 0, 809, 813, - - 814, 808, 814, 812, 816, 812, 815, 814, 809, 816, - 812, 815, 815, 809, 817, 818, 818, 818, 824, 820, - 816, 820, 0, 817, 820, 813, 813, 819, 817, 824, - 813, 814, 819, 814, 824, 816, 819, 815, 814, 0, - 816, 1266, 815, 815, 1267, 817, 822, 0, 822, 824, - 820, 818, 820, 822, 817, 820, 818, 999, 819, 817, - 824, 999, 823, 819, 821, 824, 0, 819, 821, 821, - 821, 823, 1266, 825, 0, 1267, 823, 822, 825, 822, - 826, 826, 818, 826, 822, 826, 0, 818, 999, 829, - 827, 830, 999, 823, 829, 821, 830, 818, 0, 821, - - 821, 821, 823, 827, 825, 832, 0, 823, 827, 825, - 832, 826, 826, 828, 826, 832, 826, 828, 828, 831, - 829, 827, 830, 833, 831, 829, 831, 830, 833, 835, - 1231, 1233, 1231, 834, 827, 835, 832, 834, 834, 827, - 835, 832, 0, 0, 828, 837, 832, 0, 828, 828, - 831, 0, 1233, 839, 833, 831, 0, 831, 0, 833, - 835, 1231, 1233, 1231, 834, 0, 835, 840, 834, 834, - 0, 835, 0, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 839, 0, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 0, 840, 0, - - 0, 841, 842, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 1263, 1263, 1263, 0, 1263, 0, - 0, 840, 840, 840, 840, 840, 840, 840, 840, 840, - 840, 840, 841, 842, 0, 0, 0, 843, 0, 0, - 0, 0, 841, 841, 841, 841, 841, 841, 841, 841, - 841, 841, 841, 859, 0, 0, 0, 842, 842, 842, - 842, 842, 842, 842, 842, 842, 842, 842, 843, 844, - 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, - 860, 843, 843, 843, 843, 843, 843, 843, 843, 843, - 843, 843, 861, 0, 0, 0, 1263, 0, 1160, 0, - - 844, 864, 864, 864, 864, 864, 864, 864, 864, 864, - 864, 864, 1002, 1268, 862, 1160, 1002, 844, 844, 844, - 844, 844, 844, 844, 844, 844, 844, 844, 846, 1160, - 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, - 859, 0, 0, 1002, 1268, 862, 1160, 1002, 1279, 1283, - 1284, 0, 846, 862, 862, 862, 862, 862, 862, 862, - 862, 862, 862, 862, 0, 0, 861, 861, 861, 861, - 861, 861, 861, 861, 861, 861, 861, 863, 1003, 1279, - 1283, 1284, 1003, 846, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 846, 846, 846, 846, 846, - - 846, 846, 846, 846, 846, 846, 847, 865, 863, 1003, - 0, 0, 0, 1003, 0, 847, 902, 0, 0, 907, - 0, 0, 0, 0, 863, 863, 863, 863, 863, 863, - 863, 863, 863, 863, 863, 865, 865, 865, 865, 865, - 865, 865, 865, 865, 865, 865, 847, 902, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 1293, - 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, - 902, 903, 0, 847, 847, 847, 847, 847, 847, 847, - 847, 847, 847, 847, 896, 896, 0, 0, 896, 896, - 1293, 0, 896, 896, 896, 896, 896, 896, 896, 896, - - 896, 904, 903, 896, 896, 896, 896, 896, 973, 983, - 983, 1165, 973, 1295, 983, 973, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 905, 1298, 1304, - 1165, 1310, 904, 0, 896, 896, 896, 0, 896, 973, - 983, 983, 1165, 973, 1295, 983, 973, 904, 904, 904, - 904, 904, 904, 904, 904, 904, 904, 904, 905, 1298, - 1304, 1165, 1310, 0, 906, 896, 896, 896, 896, 896, - 896, 896, 896, 896, 896, 896, 896, 0, 0, 0, - 0, 0, 0, 0, 905, 905, 905, 905, 905, 905, - 905, 905, 905, 905, 905, 906, 0, 1005, 0, 0, - - 1312, 1005, 0, 906, 906, 906, 906, 906, 906, 906, - 906, 906, 906, 906, 913, 913, 913, 913, 913, 913, - 913, 913, 913, 913, 913, 914, 914, 919, 1005, 914, - 914, 1312, 1005, 914, 914, 914, 914, 914, 914, 914, - 914, 914, 917, 0, 914, 914, 914, 914, 914, 991, - 1000, 1000, 1172, 991, 1176, 1000, 919, 919, 919, 919, - 919, 919, 919, 919, 919, 919, 919, 0, 991, 1172, - 1008, 1176, 921, 917, 1008, 914, 914, 914, 0, 914, - 991, 1000, 1000, 1172, 991, 1176, 1000, 917, 917, 917, - 917, 917, 917, 917, 917, 917, 917, 917, 918, 991, - - 1172, 1008, 1176, 921, 1314, 1008, 914, 914, 914, 914, - 914, 914, 914, 914, 914, 914, 914, 914, 921, 921, - 921, 921, 921, 921, 921, 921, 921, 921, 921, 918, - 932, 932, 0, 0, 963, 1314, 0, 918, 918, 918, - 918, 918, 918, 918, 918, 918, 918, 918, 924, 924, - 924, 924, 924, 924, 924, 924, 924, 924, 924, 925, - 925, 0, 0, 925, 925, 963, 0, 925, 925, 925, - 925, 925, 925, 925, 925, 925, 935, 1159, 925, 925, - 925, 925, 925, 1159, 963, 963, 963, 963, 963, 963, - 963, 963, 963, 963, 963, 932, 932, 932, 932, 932, - - 932, 932, 932, 932, 932, 932, 936, 935, 1159, 925, - 925, 925, 0, 925, 1159, 0, 0, 0, 0, 0, - 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, - 935, 1083, 1083, 1083, 0, 0, 0, 936, 1083, 0, - 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, - 925, 925, 937, 995, 1010, 1009, 1149, 995, 1010, 1009, - 1010, 0, 0, 936, 936, 936, 936, 936, 936, 936, - 936, 936, 936, 936, 961, 1009, 1011, 1012, 995, 1149, - 1011, 1012, 0, 937, 995, 1010, 1009, 1149, 995, 1010, - 1009, 1010, 937, 937, 937, 937, 937, 937, 937, 937, - - 937, 937, 937, 962, 1315, 961, 1009, 1011, 1012, 0, - 1149, 1011, 1012, 1083, 0, 961, 961, 961, 961, 961, - 961, 961, 961, 961, 961, 961, 964, 1018, 1017, 1018, - 1236, 965, 1017, 1018, 962, 1315, 0, 962, 962, 962, - 962, 962, 962, 962, 962, 962, 962, 962, 0, 0, - 0, 1236, 0, 0, 0, 0, 966, 964, 1018, 1017, - 1018, 1236, 965, 1017, 1018, 964, 964, 964, 964, 964, - 964, 964, 964, 964, 964, 964, 965, 965, 965, 965, - 965, 965, 965, 965, 965, 965, 965, 966, 1255, 1255, - 1255, 0, 0, 0, 0, 1255, 0, 966, 966, 966, - - 966, 966, 966, 966, 966, 966, 966, 966, 967, 967, - 967, 967, 967, 967, 967, 967, 967, 967, 967, 968, - 971, 972, 974, 968, 971, 972, 974, 977, 979, 981, - 974, 977, 979, 981, 1026, 971, 972, 981, 1026, 0, - 977, 979, 1259, 1259, 1259, 0, 0, 0, 0, 1259, - 968, 971, 972, 974, 968, 971, 972, 974, 977, 979, - 981, 974, 977, 979, 981, 1026, 971, 972, 981, 1026, - 1255, 977, 979, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 976, 980, 986, 985, 976, 980, - 986, 985, 990, 0, 987, 1323, 990, 986, 987, 976, - - 992, 980, 985, 987, 992, 990, 0, 0, 0, 1323, - 994, 994, 994, 992, 0, 976, 980, 986, 985, 976, - 980, 986, 985, 990, 1259, 987, 1323, 990, 986, 987, - 976, 992, 980, 985, 987, 992, 990, 994, 997, 998, - 1323, 994, 997, 998, 992, 1001, 0, 1004, 0, 1001, - 998, 1004, 0, 997, 0, 1001, 1006, 1006, 1006, 1007, - 1004, 0, 0, 1007, 0, 1324, 0, 1007, 994, 997, - 998, 1013, 994, 997, 998, 1013, 1001, 1153, 1004, 1013, - 1001, 998, 1004, 1006, 997, 1014, 1001, 1006, 1153, 1014, - 1007, 1004, 994, 1014, 1007, 1015, 1324, 1016, 1007, 1015, - - 1016, 1015, 1013, 1019, 1016, 1019, 1013, 0, 1153, 1019, - 1013, 0, 0, 0, 1006, 1187, 1014, 1028, 1006, 1153, - 1014, 1028, 1187, 1023, 1014, 0, 1015, 1023, 1016, 0, - 1015, 1016, 1015, 0, 1019, 1016, 1019, 1023, 1006, 0, - 1019, 1020, 1020, 1020, 1021, 1021, 1187, 0, 1028, 1022, - 1022, 1022, 1028, 1187, 1023, 1021, 1021, 0, 1023, 0, - 1024, 1021, 1166, 1020, 1024, 1025, 1020, 1020, 1023, 1025, - 1029, 1326, 1166, 1330, 1029, 1024, 1022, 1020, 1020, 1020, - 1022, 1025, 0, 1020, 1029, 0, 0, 1332, 1021, 1021, - 1021, 1024, 1021, 1166, 0, 1024, 1025, 1020, 1020, 0, - - 1025, 1029, 1326, 1166, 1330, 1029, 1024, 1022, 1020, 1020, - 1020, 1022, 1025, 1031, 1020, 1029, 1027, 1031, 1332, 1021, - 1027, 1021, 1031, 1020, 1027, 1032, 1030, 0, 1030, 1032, - 1033, 1022, 1030, 1036, 1033, 1034, 1035, 1036, 1035, 1034, - 1035, 1032, 1037, 1034, 1031, 1033, 1037, 1027, 1031, 0, - 1037, 1027, 1338, 1031, 1038, 1027, 1032, 1030, 1038, 1030, - 1032, 1033, 1043, 1030, 1036, 1033, 1034, 1035, 1036, 1035, - 1034, 1035, 1032, 1037, 1034, 1039, 1033, 1037, 1040, 1039, - 1041, 1037, 1040, 1338, 1041, 1038, 0, 0, 0, 1038, - 0, 0, 0, 1043, 0, 0, 1044, 0, 1339, 1340, - - 0, 0, 0, 1709, 1709, 1709, 1039, 0, 0, 1040, - 1039, 1041, 1045, 1040, 1341, 1041, 1043, 1043, 1043, 1043, - 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1044, 1046, 1339, - 1340, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, - 1044, 1044, 1047, 1045, 0, 1341, 1045, 1045, 1045, 1045, - 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1046, 1046, 1046, - 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1049, 1062, - 0, 0, 1049, 1047, 1048, 1048, 1048, 1048, 1048, 1048, - 1048, 1048, 1048, 1048, 1048, 1709, 0, 1047, 1047, 1047, - 1047, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 1062, 1062, - - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 0, - 0, 0, 0, 0, 1098, 1098, 1098, 1154, 1169, 1098, - 1063, 1177, 1174, 1183, 1169, 1154, 1207, 1098, 1178, 1094, - 1174, 1183, 1177, 1207, 1178, 1049, 1049, 1049, 1049, 1049, - 1049, 1049, 1049, 1049, 1049, 1049, 1050, 0, 1154, 1169, - 1050, 1063, 1177, 1174, 1183, 1169, 1154, 1207, 0, 1178, - 1094, 1174, 1183, 1177, 1207, 1178, 1098, 1232, 1343, 1095, - 1346, 1347, 1232, 1050, 1063, 1063, 1063, 1063, 1063, 1063, - 1063, 1063, 1063, 1063, 1063, 1094, 1094, 1094, 1094, 1094, - 1094, 1094, 1094, 1094, 1094, 1094, 1098, 0, 1232, 1343, - - 1095, 1346, 1347, 1232, 1050, 0, 0, 1345, 1349, 0, - 1345, 0, 0, 1050, 1050, 1050, 1050, 1050, 1050, 1050, - 1050, 1050, 1050, 1050, 1095, 1095, 1095, 1095, 1095, 1095, - 1095, 1095, 1095, 1095, 1095, 1096, 1096, 1096, 1345, 1349, - 1096, 1345, 1155, 1161, 1156, 1097, 1097, 1097, 1096, 1167, - 1097, 1099, 1099, 1099, 1110, 0, 1099, 0, 1097, 0, - 0, 0, 0, 1155, 1099, 1156, 0, 1161, 1097, 1350, - 1167, 1180, 1194, 1155, 1161, 1156, 1099, 1180, 1194, 1109, - 1167, 0, 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, - 1110, 1110, 1110, 1110, 1155, 0, 1156, 1111, 1161, 1097, - - 1350, 1167, 1180, 1194, 1718, 1718, 1718, 1099, 1180, 1194, - 1109, 1181, 1181, 1181, 0, 1351, 1096, 1096, 1096, 1096, - 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1097, 1111, 0, - 0, 0, 0, 1099, 1109, 1109, 1109, 1109, 1109, 1109, - 1109, 1109, 1109, 1109, 1109, 1125, 1351, 1352, 1353, 1181, - 0, 0, 0, 1111, 1111, 1111, 1111, 1111, 1111, 1111, - 1111, 1111, 1111, 1111, 1112, 1112, 1112, 1112, 1112, 1112, - 1112, 1112, 1112, 1112, 1112, 0, 1125, 0, 1352, 1353, - 1181, 1126, 1192, 1218, 1193, 1220, 1718, 0, 0, 1354, - 1218, 1235, 1234, 1181, 1192, 1193, 1235, 1220, 1234, 1355, - - 1127, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - 1125, 1125, 1126, 1192, 1218, 1193, 1220, 1175, 1175, 1175, - 1354, 1218, 1235, 1234, 0, 1192, 1193, 1235, 1220, 1234, - 1355, 1127, 1175, 0, 0, 1170, 1170, 1170, 0, 1126, - 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, + 980, 990, 683, 668, 668, 668, 0, 668, 0, 683, + 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, + 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, + 687, 980, 990, 0, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 669, 669, 0, 0, + 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, + + 669, 669, 669, 669, 669, 669, 669, 669, 672, 672, + 0, 0, 672, 672, 672, 672, 672, 672, 672, 672, + 672, 672, 672, 672, 672, 672, 672, 672, 672, 672, + 677, 677, 0, 938, 0, 938, 678, 678, 0, 0, + 0, 677, 680, 680, 0, 938, 677, 678, 0, 0, + 0, 0, 678, 680, 0, 0, 0, 827, 680, 690, + 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, + 827, 982, 827, 677, 677, 677, 938, 677, 684, 678, + 678, 678, 947, 678, 982, 680, 680, 680, 827, 680, + 949, 949, 949, 0, 672, 672, 0, 672, 685, 947, + + 0, 827, 982, 827, 677, 0, 677, 0, 0, 684, + 678, 0, 0, 947, 0, 982, 680, 0, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 685, + 947, 953, 953, 953, 685, 685, 685, 685, 685, 685, + 685, 685, 685, 685, 685, 691, 691, 0, 965, 965, + 965, 692, 692, 0, 986, 991, 691, 693, 693, 0, + 986, 691, 692, 695, 695, 0, 0, 692, 693, 0, + 0, 949, 832, 693, 695, 0, 0, 0, 839, 695, + 863, 967, 832, 967, 832, 986, 991, 839, 691, 691, + 691, 986, 691, 967, 692, 692, 692, 697, 692, 863, + + 693, 693, 693, 832, 693, 992, 695, 695, 695, 839, + 695, 863, 953, 832, 0, 832, 0, 0, 839, 691, + 0, 0, 0, 0, 967, 692, 0, 692, 697, 965, + 863, 693, 0, 0, 0, 0, 992, 695, 0, 0, + 0, 697, 697, 697, 697, 697, 697, 697, 697, 697, + 697, 697, 698, 698, 698, 698, 698, 698, 698, 698, + 698, 698, 698, 699, 699, 699, 699, 699, 699, 699, + 699, 699, 699, 699, 704, 704, 0, 0, 704, 704, + 0, 0, 704, 704, 704, 704, 704, 704, 704, 704, + 704, 0, 704, 704, 704, 704, 704, 711, 711, 711, + + 711, 711, 711, 711, 711, 711, 711, 711, 728, 728, + 728, 728, 728, 728, 728, 728, 728, 728, 728, 977, + 984, 977, 984, 704, 704, 704, 0, 704, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, 746, 748, + 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, + 977, 984, 977, 984, 704, 704, 704, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 705, 705, 0, 0, + 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, + 705, 705, 705, 705, 705, 705, 705, 705, 708, 708, + 0, 0, 708, 708, 708, 708, 708, 708, 708, 708, + + 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, + 712, 712, 975, 997, 978, 0, 713, 713, 978, 975, + 0, 712, 714, 714, 0, 987, 712, 713, 0, 0, + 0, 0, 713, 714, 0, 716, 716, 985, 714, 985, + 1001, 1003, 987, 975, 997, 978, 716, 747, 0, 978, + 975, 716, 0, 712, 712, 712, 987, 712, 0, 713, + 713, 713, 751, 713, 1002, 714, 714, 714, 985, 714, + 985, 1001, 1003, 987, 708, 708, 1002, 708, 716, 716, + 716, 0, 716, 989, 712, 989, 0, 1005, 0, 762, + 713, 762, 713, 0, 0, 1002, 714, 750, 750, 750, + + 750, 750, 750, 750, 750, 750, 750, 750, 0, 716, + 724, 0, 724, 0, 989, 0, 989, 993, 1005, 998, + 993, 998, 724, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 0, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 763, 0, 993, 0, + 998, 993, 998, 724, 0, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 1100, 1100, 1100, 1108, + 1108, 1108, 0, 1100, 0, 0, 724, 724, 724, 724, + 724, 724, 724, 724, 724, 724, 724, 749, 749, 0, + 0, 749, 749, 0, 0, 749, 749, 749, 749, 749, + + 749, 749, 749, 749, 988, 749, 749, 749, 749, 749, + 0, 988, 763, 763, 763, 763, 763, 763, 763, 763, + 763, 763, 763, 842, 842, 842, 842, 842, 842, 842, + 842, 842, 842, 842, 994, 988, 749, 749, 749, 0, + 749, 846, 988, 0, 0, 0, 0, 1100, 0, 840, + 1108, 994, 976, 999, 1006, 999, 1009, 1016, 840, 0, + 0, 976, 840, 0, 0, 994, 843, 749, 749, 749, + 749, 749, 749, 749, 749, 749, 749, 749, 749, 760, + 840, 760, 994, 976, 999, 1006, 999, 1009, 1016, 840, + 847, 760, 976, 840, 843, 843, 843, 843, 843, 843, + + 843, 843, 843, 843, 843, 846, 846, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 0, 0, 0, 0, + 0, 847, 760, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 848, 849, 1000, 0, 1004, 1010, + 1000, 1010, 1017, 1024, 1004, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 764, 0, 0, 0, + 0, 0, 0, 0, 0, 848, 849, 1000, 764, 1004, + 1010, 1000, 1010, 1017, 1024, 1004, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 850, 848, 848, + 848, 848, 848, 848, 848, 848, 848, 848, 848, 764, + + 0, 0, 0, 1008, 1011, 1014, 1011, 1039, 1014, 851, + 1039, 0, 0, 0, 0, 1008, 0, 868, 850, 0, + 0, 0, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 852, 1008, 1011, 1014, 1011, 1039, 1014, + 851, 1039, 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 851, 851, 851, 851, 851, 851, 851, + 851, 851, 851, 851, 852, 867, 867, 867, 867, 867, + 867, 867, 867, 867, 867, 867, 0, 0, 0, 0, + 0, 852, 852, 852, 852, 852, 852, 852, 852, 852, + 852, 852, 854, 868, 868, 868, 868, 868, 868, 868, + + 868, 868, 868, 868, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 854, 870, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 871, + 0, 1028, 1053, 1028, 1037, 1037, 854, 922, 922, 922, + 922, 922, 922, 922, 922, 922, 922, 922, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 855, + 871, 872, 1028, 1053, 1028, 1037, 1037, 855, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, 871, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + + 1046, 912, 872, 1046, 0, 0, 0, 0, 855, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 872, 872, + 872, 872, 872, 872, 872, 872, 872, 872, 872, 874, + 0, 1046, 912, 0, 1046, 855, 855, 855, 855, 855, + 855, 855, 855, 855, 855, 855, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 874, 874, 874, + 874, 874, 874, 874, 874, 874, 874, 874, 907, 907, + 916, 0, 907, 907, 0, 0, 907, 907, 907, 907, + 907, 907, 907, 907, 907, 913, 907, 907, 907, 907, + 907, 1038, 1026, 1038, 1043, 1043, 1020, 1026, 996, 916, + + 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, + 0, 914, 996, 1020, 1030, 1055, 913, 907, 907, 907, + 0, 907, 1038, 1026, 1038, 1043, 1043, 1020, 1026, 996, + 1030, 913, 913, 913, 913, 913, 913, 913, 913, 913, + 913, 913, 914, 996, 1020, 1030, 1055, 0, 907, 907, + 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, + 915, 1030, 1045, 1067, 1067, 0, 1045, 1082, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, 914, 933, + 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, + 0, 915, 0, 1045, 1067, 1067, 926, 1045, 1082, 915, + + 915, 915, 915, 915, 915, 915, 915, 915, 915, 915, + 923, 923, 0, 0, 923, 923, 0, 0, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 926, 923, 923, + 923, 923, 923, 927, 1047, 1083, 1047, 0, 1027, 0, + 1012, 926, 926, 926, 926, 926, 926, 926, 926, 926, + 926, 926, 0, 1012, 1068, 1027, 1084, 1068, 1085, 923, + 923, 923, 0, 923, 927, 1047, 1083, 1047, 945, 1027, + 945, 1012, 927, 927, 927, 927, 927, 927, 927, 927, + 927, 927, 927, 928, 1012, 1068, 1027, 1084, 1068, 1085, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + + 923, 923, 930, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 928, 928, 928, 928, 928, 928, 928, 928, + 928, 928, 928, 0, 0, 0, 0, 0, 0, 0, + 1086, 1087, 0, 930, 945, 945, 945, 945, 945, 945, + 945, 945, 945, 945, 945, 0, 0, 0, 930, 930, + 930, 930, 930, 930, 930, 930, 930, 930, 930, 934, + 934, 1086, 1087, 934, 934, 1088, 0, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 983, 934, 934, 934, + 934, 934, 981, 995, 1013, 983, 981, 1015, 1007, 1007, + 1007, 0, 1018, 995, 1031, 981, 1088, 1022, 1013, 1023, + + 1015, 1018, 1089, 1031, 1022, 1090, 1023, 983, 934, 934, + 934, 0, 934, 981, 995, 1013, 983, 981, 1015, 0, + 1019, 1019, 1019, 1018, 995, 1031, 981, 1007, 1022, 1013, + 1023, 1015, 1018, 1089, 1031, 1022, 1090, 1023, 0, 934, + 934, 934, 934, 934, 934, 934, 934, 934, 934, 934, + 934, 943, 1021, 943, 1025, 1029, 1032, 1033, 1007, 1019, + 1040, 1041, 1029, 943, 1071, 1021, 1044, 1025, 0, 1007, + 0, 1032, 1033, 1040, 1071, 1036, 1036, 1036, 1041, 0, + 1091, 1044, 1093, 1021, 0, 1025, 1029, 1032, 1033, 0, + 1019, 1040, 1041, 1029, 943, 1071, 1021, 1044, 1025, 1035, + + 1035, 1019, 1032, 1033, 1040, 1071, 0, 0, 1035, 1041, + 1035, 1091, 1044, 1093, 1036, 1035, 1042, 943, 943, 943, + 943, 943, 943, 943, 943, 943, 943, 943, 946, 1042, + 1049, 1048, 0, 1051, 1094, 1096, 1050, 946, 1054, 1072, + 1073, 1049, 1035, 1035, 1035, 1036, 1035, 1042, 1048, 1050, + 1051, 1054, 1070, 1072, 1073, 1058, 1036, 1097, 1098, 1099, + 1042, 1049, 1048, 1070, 1051, 1094, 1096, 1050, 946, 1054, + 1072, 1073, 1049, 1035, 0, 1035, 0, 1059, 1052, 1048, + 1050, 1051, 1054, 1070, 1072, 1073, 0, 1052, 1097, 1098, + 1099, 0, 0, 0, 946, 946, 946, 946, 946, 946, + + 946, 946, 946, 946, 946, 973, 0, 973, 1059, 1052, + 0, 1104, 1104, 1104, 1060, 1104, 1076, 973, 1052, 1058, + 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, + 1076, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, + 1059, 1059, 0, 0, 0, 1060, 0, 1076, 973, 1060, + 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, + 1061, 1076, 1102, 1102, 1102, 1119, 1119, 1119, 0, 1102, + 0, 973, 973, 973, 973, 973, 973, 973, 973, 973, + 973, 973, 974, 1062, 0, 0, 1124, 1124, 1124, 0, + 0, 1061, 1104, 0, 1061, 1061, 1061, 1061, 1061, 1061, + + 1061, 1061, 1061, 1061, 1061, 0, 1110, 974, 0, 1117, + 0, 1121, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, + 1062, 1062, 1062, 1064, 1064, 1064, 1064, 1064, 1064, 1064, + 1064, 1064, 1064, 1064, 1074, 1075, 1065, 1110, 974, 1065, + 1117, 1074, 1121, 1102, 0, 1075, 1119, 0, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 1034, + 1034, 1034, 1144, 0, 0, 1074, 1075, 1124, 1149, 0, + 1144, 0, 1074, 1115, 1115, 1115, 1075, 1216, 1115, 0, + 1034, 0, 1217, 1034, 1034, 1218, 1115, 1219, 1220, 1134, + 1134, 1134, 1216, 1144, 1034, 1034, 1034, 1063, 0, 1149, + + 1034, 1144, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, + 1065, 1065, 1065, 1217, 1034, 1034, 1218, 0, 1219, 1220, + 0, 0, 0, 1216, 1115, 1034, 1034, 1034, 1063, 1079, + 0, 1034, 1146, 1146, 1146, 1151, 1151, 1151, 1080, 0, + 1034, 1221, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1066, 1115, 0, 1066, 0, 1079, 1079, + 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1080, + 1134, 0, 1221, 1222, 0, 1112, 0, 1263, 1264, 1066, + 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + 1129, 0, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, + + 1080, 1080, 1080, 0, 1222, 1136, 1112, 1136, 1263, 1264, + 1066, 0, 0, 1146, 1266, 0, 1151, 1136, 1268, 1066, + 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, + 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, + 1112, 1113, 1113, 1113, 0, 1266, 1113, 0, 1136, 1268, + 0, 1114, 1114, 1114, 1113, 1269, 1114, 1116, 1116, 1116, + 1127, 0, 1116, 1159, 1114, 1159, 0, 0, 0, 0, + 1116, 0, 1254, 1114, 1254, 1159, 1164, 1164, 1164, 1253, + 1256, 1116, 1270, 1255, 1126, 0, 1269, 0, 1255, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, - 1127, 1141, 1141, 1141, 1170, 1175, 1188, 1189, 0, 1191, - 1190, 1209, 0, 1170, 1813, 1813, 1813, 0, 1211, 0, - 1212, 1357, 1358, 1292, 1219, 1214, 0, 1188, 1292, 1215, - 1189, 1190, 1357, 1209, 1191, 1170, 1175, 1188, 1189, 1175, - - 1191, 1190, 1209, 1211, 1170, 1212, 1214, 1216, 1219, 1211, - 1215, 1212, 1357, 1358, 1292, 1219, 1214, 1170, 1188, 1292, - 1215, 1189, 1190, 1357, 1209, 1191, 1222, 1308, 1359, 1216, - 1362, 1289, 1289, 1289, 1211, 1308, 1212, 1214, 1216, 1219, - 0, 1215, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, - 1141, 1141, 1141, 1142, 1142, 1142, 1813, 1222, 1308, 1359, - 1216, 1362, 1225, 1335, 1365, 1374, 1308, 1376, 1335, 1289, - 0, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, - 1222, 1222, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - 1223, 1223, 1223, 1225, 1335, 1365, 1374, 0, 1376, 1335, - - 1289, 1142, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, - 1238, 1238, 1238, 1289, 0, 0, 0, 0, 1225, 1225, - 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 0, - 0, 0, 1142, 1307, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1171, 1171, 1171, 1224, 0, - 1171, 1171, 0, 0, 1900, 1900, 1900, 1226, 1307, 0, - 1294, 1171, 1171, 0, 1307, 0, 1294, 1171, 1296, 1291, - 1297, 1300, 1305, 0, 1296, 1379, 1297, 1224, 1224, 1224, - 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1226, 1307, - 1291, 1294, 1300, 1305, 1171, 1171, 1171, 1294, 1171, 1296, - - 1291, 1297, 1300, 1305, 1237, 1296, 1379, 1297, 1380, 1226, - 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, - 1269, 1291, 0, 1300, 1305, 1171, 0, 1171, 1182, 1182, - 1182, 0, 0, 1182, 1182, 1237, 1900, 0, 0, 1380, - 0, 0, 0, 0, 1182, 1182, 0, 0, 0, 1382, - 1182, 1269, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, - 1237, 1237, 1237, 1270, 1269, 1269, 1269, 1269, 1269, 1269, - 1269, 1269, 1269, 1269, 1269, 0, 1306, 1182, 1182, 1182, - 1382, 1182, 0, 0, 0, 1377, 0, 1383, 1306, 0, - 1377, 1309, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, - - 1270, 1270, 1270, 1309, 1271, 1271, 1271, 1306, 1182, 1271, - 1182, 1203, 1203, 1203, 1274, 1274, 1377, 1271, 1383, 1306, - 1299, 1377, 1309, 1301, 1303, 1274, 1274, 1744, 1744, 1744, - 1271, 1274, 1366, 1384, 1309, 1317, 1203, 1203, 1203, 1203, - 1203, 1744, 1203, 1299, 1203, 1301, 1366, 1317, 1303, 1203, - 0, 1299, 1203, 1203, 1301, 1303, 1203, 1387, 1274, 1274, - 1274, 1271, 1274, 1366, 1384, 0, 1317, 1203, 1203, 1203, - 1203, 1203, 1275, 1203, 1299, 1203, 1301, 1366, 1317, 1303, - 1203, 1276, 1389, 1203, 1203, 0, 1271, 1203, 1387, 1274, - 0, 1274, 0, 1203, 1204, 1204, 1204, 0, 0, 1204, - - 1204, 0, 0, 1275, 0, 0, 0, 0, 0, 1744, - 1204, 1204, 1276, 1389, 0, 1277, 1204, 1391, 0, 1275, - 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, - 0, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, - 1276, 1276, 1281, 1204, 1204, 1204, 1277, 1204, 1391, 1280, - 1854, 1854, 1854, 0, 0, 0, 1302, 1302, 1302, 1277, - 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, - 1854, 1302, 1282, 1281, 1204, 1392, 1204, 1228, 1280, 1280, - 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 0, - 0, 0, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, - - 1281, 1281, 1281, 1282, 1302, 1228, 1392, 0, 1393, 1394, - 1395, 0, 1285, 1901, 1901, 1901, 1282, 1282, 1282, 1282, - 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1313, 1313, 1313, - 0, 0, 1854, 0, 0, 1302, 1228, 1286, 1302, 1393, - 1394, 1395, 1313, 1285, 1228, 1228, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1229, 1285, 1285, 1285, 1285, - 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1287, 1286, 1311, - 1322, 1396, 1229, 1361, 1397, 1313, 1322, 1311, 0, 1361, - 0, 0, 0, 0, 1286, 1286, 1286, 1286, 1286, 1286, - 1286, 1286, 1286, 1286, 1286, 1901, 0, 0, 1287, 0, - - 1311, 1322, 1396, 1229, 1361, 1397, 1313, 1322, 1311, 1313, - 1361, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, - 1287, 1287, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, - 1229, 1229, 1229, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1290, 1290, 1290, 0, - 1318, 1290, 1290, 1325, 1319, 1319, 1319, 1328, 1329, 1331, - 1333, 1334, 1290, 1290, 0, 0, 0, 1318, 1290, 1319, - 1325, 1360, 1364, 0, 1398, 1372, 1329, 1402, 1328, 1372, - 1331, 1318, 1334, 1333, 1325, 1336, 1336, 1336, 1328, 1329, - 1331, 1333, 1334, 1364, 1360, 1290, 1290, 1290, 1318, 1290, - 1336, 1325, 1360, 1364, 1348, 1398, 1372, 1329, 1402, 1328, - 1372, 1331, 0, 1334, 1333, 1337, 1348, 1409, 0, 1337, - - 1337, 1367, 0, 0, 1364, 1360, 1290, 1386, 1290, 1363, - 1363, 1363, 1386, 1336, 1424, 1348, 1319, 1321, 1321, 1321, - 1367, 0, 1321, 1321, 1363, 1375, 1337, 1348, 1409, 1375, - 1337, 1337, 1367, 1321, 1321, 0, 0, 0, 1386, 1321, - 0, 0, 0, 1386, 1336, 1424, 0, 1336, 0, 0, - 0, 1367, 1373, 1425, 1378, 1429, 1375, 1363, 1373, 1431, - 1375, 1369, 1378, 0, 1433, 1437, 1321, 1321, 1321, 0, - 1321, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, - 1368, 1368, 1370, 1373, 1425, 1378, 1429, 0, 1363, 1373, - 1431, 1363, 1369, 1378, 1381, 1433, 1437, 1321, 0, 1321, - - 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, - 1369, 0, 1438, 1370, 1371, 1371, 1371, 1371, 1371, 1371, - 1371, 1371, 1371, 1371, 1371, 1381, 1370, 1370, 1370, 1370, - 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1399, 0, 0, - 0, 1432, 1436, 1438, 1435, 1442, 1443, 1432, 1381, 1381, - 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 0, - 0, 0, 0, 1400, 0, 1435, 1442, 1436, 1399, 1401, - 1401, 1401, 1432, 1436, 1401, 1435, 1442, 1443, 1432, 0, - 0, 0, 1401, 1399, 1399, 1399, 1399, 1399, 1399, 1399, - 1399, 1399, 1399, 1399, 1400, 1401, 1435, 1442, 1436, 0, - - 0, 1444, 1434, 0, 1400, 1400, 1400, 1400, 1400, 1400, - 1400, 1400, 1400, 1400, 1400, 1404, 1404, 1404, 0, 1434, - 1404, 0, 1405, 1405, 1405, 1452, 1401, 1405, 1404, 1408, - 1408, 1408, 1444, 1434, 1408, 1405, 1445, 1439, 1439, 1439, - 1453, 1404, 1408, 1446, 1415, 1415, 1415, 0, 1405, 1415, - 1434, 1401, 1439, 1447, 1446, 1408, 1452, 1415, 1448, 1445, - 1415, 1415, 1454, 1458, 0, 0, 0, 1445, 1459, 1454, - 1415, 1453, 1404, 0, 1446, 1448, 1455, 1461, 1447, 1405, - 1449, 1449, 1449, 1462, 1447, 1446, 1408, 1455, 0, 1448, - 1445, 1463, 0, 1454, 1458, 1449, 1418, 1404, 0, 1459, - - 1454, 1415, 0, 0, 1405, 0, 1448, 1455, 1461, 1447, - 0, 1408, 1410, 1410, 1462, 0, 0, 0, 1455, 1439, - 0, 1466, 1463, 1410, 1410, 0, 1415, 1418, 1419, 1410, - 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, - 1417, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, - 1418, 1418, 1466, 1471, 1472, 1473, 1410, 1410, 1410, 1419, - 1410, 0, 1449, 0, 0, 0, 1419, 1419, 1419, 1419, - 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1906, 1906, 1906, - 1966, 1966, 1966, 0, 1471, 1472, 1473, 1410, 1410, 1410, - 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1413, - - 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, - 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, - 1413, 1413, 1421, 1474, 1475, 1476, 1413, 1427, 1427, 1427, - 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 0, 0, - 0, 0, 0, 0, 1477, 1422, 0, 1478, 1479, 1480, - 1481, 0, 1482, 1421, 1474, 1475, 1476, 1413, 0, 1906, - 0, 0, 1966, 1421, 1421, 1421, 1421, 1421, 1421, 1421, - 1421, 1421, 1421, 1421, 1423, 1477, 1422, 1426, 1478, 1479, - 1480, 1481, 1413, 1482, 0, 0, 1413, 1413, 0, 1413, - 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, - - 1422, 0, 0, 1428, 0, 1423, 1483, 1484, 1426, 1485, - 1486, 1487, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, - 1423, 1423, 1423, 1426, 1426, 1426, 1426, 1426, 1426, 1426, - 1426, 1426, 1426, 1426, 1428, 1460, 0, 1483, 1484, 1488, - 1485, 1486, 1487, 1489, 0, 0, 1460, 1465, 1428, 1428, - 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1441, - 1441, 1441, 1465, 1490, 1441, 1441, 1460, 1464, 1464, 1464, - 1488, 1467, 1491, 1492, 1489, 1441, 1441, 1460, 1465, 0, - 0, 1441, 1464, 1467, 0, 1493, 1494, 0, 1500, 1495, - 0, 0, 1494, 1465, 1490, 1495, 1468, 1468, 1468, 1514, - - 1496, 0, 1467, 1491, 1492, 0, 0, 1506, 1441, 1441, - 1441, 1468, 1441, 0, 1467, 1464, 1493, 1494, 1468, 1500, - 1495, 1496, 1468, 1494, 1501, 1502, 1495, 0, 1506, 1503, - 1514, 1496, 1502, 0, 1468, 1497, 1497, 1497, 1506, 1441, - 1516, 1441, 1451, 1451, 1451, 1501, 1464, 1451, 1451, 1464, - 1497, 0, 1496, 1468, 0, 1501, 1502, 0, 1451, 1451, - 1503, 0, 0, 1502, 1451, 1468, 1505, 1517, 1507, 1510, - 1518, 1516, 0, 1507, 1508, 1505, 1501, 1510, 1468, 1503, - 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, - 1508, 1451, 1451, 1451, 0, 1451, 0, 1505, 1517, 1507, - - 1510, 1518, 1509, 1504, 1507, 1508, 1505, 1509, 1510, 1511, - 0, 0, 1519, 1520, 1511, 0, 0, 1497, 0, 0, - 0, 1508, 1451, 0, 1451, 1470, 1470, 1470, 1521, 1522, - 1470, 1470, 1512, 1509, 1504, 1523, 1524, 1512, 1509, 1525, - 1511, 1470, 1470, 1519, 1520, 1511, 1513, 1470, 1504, 1504, - 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1521, - 1522, 1526, 1527, 1512, 1528, 1534, 1523, 1524, 1512, 1536, - 1525, 1541, 1550, 1551, 1470, 1470, 1470, 1513, 1470, 0, - 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, - 1513, 1529, 1526, 1527, 0, 1528, 1534, 1554, 1555, 0, - - 1536, 1561, 1541, 1550, 1551, 1470, 0, 1470, 1499, 1499, - 1499, 0, 0, 1499, 1499, 0, 0, 1558, 1530, 1555, - 1568, 1569, 1529, 1558, 1499, 1499, 0, 0, 1554, 1555, - 1499, 0, 1561, 0, 0, 0, 0, 1529, 1529, 1529, - 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1558, 1530, - 1555, 1568, 1569, 0, 1558, 0, 1570, 1499, 1499, 1499, - 1576, 1499, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, - 1530, 1530, 1530, 1531, 1531, 1531, 0, 1570, 1531, 1532, - 1532, 1532, 0, 0, 1532, 0, 1531, 1570, 1499, 1556, - 1499, 1576, 1532, 1533, 1533, 1533, 1580, 0, 1533, 1531, - - 1556, 1582, 1535, 1535, 1535, 1532, 1533, 1535, 1570, 0, - 1562, 1539, 1539, 1539, 1557, 1535, 1539, 1581, 1563, 1533, - 1556, 1563, 1532, 1581, 1539, 1562, 1557, 1580, 1535, 0, - 1531, 1556, 1582, 0, 1564, 1565, 1532, 1539, 1543, 1543, - 1543, 1562, 1583, 1543, 0, 1557, 1565, 1564, 1581, 1563, - 1533, 1543, 1563, 1532, 1581, 1531, 1562, 1557, 1584, 1535, - 1545, 1532, 0, 1588, 1543, 1564, 1565, 0, 1539, 0, - 0, 0, 0, 1583, 0, 1533, 0, 1565, 1564, 0, - 0, 1546, 0, 1590, 1535, 1537, 1537, 1537, 1592, 1584, - 1537, 1545, 0, 1539, 1588, 1543, 0, 0, 1537, 0, - - 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, - 1545, 1537, 1546, 1548, 1590, 0, 1593, 1594, 1595, 1592, - 1543, 1574, 1574, 1574, 0, 0, 1546, 1546, 1546, 1546, - 1546, 1546, 1546, 1546, 1546, 1546, 1546, 0, 0, 0, - 0, 0, 1537, 0, 1548, 0, 1547, 1593, 1594, 1595, - 1596, 1574, 1597, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 0, 0, 1537, 1537, 1537, 1537, - 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1547, 1549, 1571, - 1598, 1596, 1574, 1597, 1599, 1600, 1601, 1571, 1552, 1602, - 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, - - 1547, 0, 0, 1574, 0, 0, 1577, 1577, 1577, 1549, - 1571, 1598, 0, 0, 0, 1599, 1600, 1601, 1571, 1552, - 1602, 1577, 0, 1549, 1549, 1549, 1549, 1549, 1549, 1549, - 1549, 1549, 1549, 1549, 1552, 1552, 1552, 1552, 1552, 1552, - 1552, 1552, 1552, 1552, 1552, 1553, 1553, 1553, 1553, 1553, - 1553, 1553, 1553, 1553, 1553, 1553, 1575, 0, 1591, 1603, - 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1575, 0, - 0, 0, 1612, 1615, 0, 0, 1591, 1616, 1617, 1620, - 1615, 1621, 1622, 1606, 1611, 0, 0, 1575, 1577, 1591, - 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1575, - - 1579, 1579, 1579, 1612, 1615, 1579, 1579, 1591, 1616, 1617, - 1620, 1615, 1621, 1622, 1606, 1611, 1579, 1579, 0, 0, - 0, 1618, 1579, 1619, 1617, 1617, 1617, 1617, 1617, 1617, - 1617, 1617, 1617, 1617, 1617, 1943, 1943, 1943, 0, 0, - 0, 1623, 1624, 1625, 1619, 1626, 1624, 1629, 1632, 1579, - 1579, 1579, 1618, 1579, 1619, 1943, 0, 0, 0, 0, - 0, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, - 1618, 1618, 1623, 1624, 1625, 1636, 1626, 1624, 1629, 1632, - 1579, 1639, 1579, 1627, 1627, 1627, 1627, 1627, 1627, 1627, - 1627, 1627, 1627, 1627, 1640, 1641, 1642, 1643, 1644, 1646, - - 1650, 0, 1665, 0, 0, 0, 1636, 0, 0, 1771, - 1771, 1771, 1639, 0, 0, 1666, 0, 1943, 0, 1647, - 1647, 1647, 0, 1771, 1647, 1640, 1641, 1642, 1643, 1644, - 1646, 1650, 1647, 1665, 1644, 1644, 1644, 1644, 1644, 1644, - 1644, 1644, 1644, 1644, 1644, 1647, 1666, 1643, 1643, 1643, - 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1645, 1645, - 1645, 0, 0, 1645, 1648, 1648, 1648, 0, 0, 1648, - 0, 1645, 0, 1649, 1649, 1649, 1647, 1648, 1649, 0, - 1668, 1645, 0, 1669, 1645, 1670, 1649, 1651, 1651, 1651, - 1648, 1771, 1651, 1652, 1652, 1652, 0, 1670, 1652, 1649, - - 1651, 1647, 0, 1651, 1651, 1672, 1652, 1676, 1683, 1652, - 1652, 1668, 1645, 1651, 1669, 1645, 1670, 0, 1684, 1652, - 0, 1648, 1654, 1654, 1654, 0, 1672, 1654, 1670, 0, - 1649, 0, 1655, 1655, 1655, 1654, 1672, 1655, 1676, 1683, - 1645, 1671, 0, 1689, 1651, 1655, 1648, 1671, 1654, 1684, - 1652, 1656, 1656, 1656, 0, 1649, 1656, 1672, 1655, 0, - 1657, 1657, 1657, 1677, 1656, 1657, 1675, 1675, 1675, 1651, - 1677, 1691, 1671, 1657, 1689, 1652, 1678, 1656, 1671, 1654, - 1658, 1658, 1658, 0, 0, 1658, 1657, 1692, 0, 1655, - 1659, 1659, 1659, 1658, 1677, 1659, 1675, 1678, 1686, 0, - - 0, 1677, 1691, 1659, 1654, 1679, 1658, 1678, 1656, 1682, - 1682, 1682, 1685, 1679, 1655, 1686, 1659, 1657, 1692, 1660, - 1685, 1695, 0, 1658, 1696, 1697, 1698, 1675, 1678, 1686, - 1687, 1687, 1687, 1656, 1702, 1703, 1679, 1658, 1704, 1682, - 1705, 0, 1657, 1685, 1679, 1687, 1686, 1659, 1675, 0, - 1660, 1685, 1695, 1661, 1658, 1696, 1697, 1698, 1706, 1707, - 0, 0, 1658, 0, 0, 1702, 1703, 0, 0, 1704, - 1682, 1705, 1659, 1660, 1660, 1660, 1660, 1660, 1660, 1660, - 1660, 1660, 1660, 1660, 1661, 1662, 1663, 1708, 1710, 1706, - 1707, 1682, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, - - 1661, 1661, 1661, 1711, 1712, 1713, 1714, 1715, 0, 0, - 0, 0, 1687, 0, 0, 0, 1662, 1663, 1708, 1710, - 1664, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, - 1662, 1662, 0, 0, 1711, 1712, 1713, 1714, 1715, 1667, - 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, - 1663, 1664, 1688, 1688, 1688, 1701, 1701, 1701, 0, 1664, - 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, - 1667, 1716, 1717, 1719, 1720, 1722, 1723, 1724, 1725, 1726, - 0, 1731, 1688, 1737, 1738, 1701, 1979, 1979, 1979, 1667, - 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, - - 1727, 1732, 1716, 1717, 1719, 1720, 1722, 1723, 1724, 1725, - 1726, 1727, 1731, 1688, 1737, 1738, 1701, 1730, 1730, 1730, - 1739, 1740, 1741, 1742, 0, 0, 1777, 1777, 1777, 0, - 0, 1727, 1732, 0, 1688, 1733, 1734, 1701, 1735, 1743, - 1736, 1777, 1727, 1735, 1736, 1770, 1734, 1730, 1773, 1774, - 1775, 1739, 1740, 1741, 1742, 1732, 1732, 1732, 1732, 1732, - 1732, 1732, 1732, 1732, 1732, 1732, 1733, 1734, 1979, 1735, - 1743, 1736, 1746, 1776, 1735, 1736, 1770, 1734, 1730, 1773, - 1774, 1775, 0, 0, 0, 1733, 1733, 1733, 1733, 1733, - 1733, 1733, 1733, 1733, 1733, 1733, 1747, 1779, 1781, 1730, - - 1782, 1786, 1788, 1746, 1776, 0, 0, 0, 1777, 0, - 0, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, - 1746, 1746, 0, 0, 0, 1789, 1794, 1747, 1779, 1781, - 1799, 1782, 1786, 1788, 1800, 0, 1747, 1747, 1747, 1747, - 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1748, 1748, 1748, - 0, 0, 1748, 1750, 1750, 1750, 1789, 1794, 1750, 0, - 1748, 1799, 1751, 1751, 1751, 1800, 1750, 1751, 1801, 1752, - 1752, 1752, 1790, 1748, 1752, 1751, 1804, 1806, 1790, 1750, - 0, 1748, 1752, 1783, 0, 1753, 1753, 1753, 1751, 0, - 1753, 1807, 1755, 1755, 1755, 1752, 1791, 1755, 1753, 1801, - - 1783, 1808, 1791, 1790, 1748, 1755, 1809, 1804, 1806, 1790, - 1750, 1753, 1748, 0, 1783, 1754, 1754, 1754, 1755, 1751, - 1754, 0, 1807, 0, 1810, 1811, 1752, 1791, 1754, 1748, - 0, 1783, 1808, 1791, 0, 1750, 0, 1809, 0, 0, - 1812, 1754, 1753, 0, 1751, 0, 0, 0, 1815, 1755, - 0, 1752, 1756, 1756, 1756, 1810, 1811, 1756, 1754, 0, - 1778, 1778, 1778, 0, 0, 1756, 0, 1753, 1758, 1758, - 1758, 1812, 1754, 1758, 1755, 1759, 1759, 1759, 1756, 1815, - 1759, 1758, 1760, 1760, 1760, 0, 0, 1760, 1759, 1754, - 1778, 1761, 1761, 1761, 1758, 1760, 1761, 1754, 1762, 1762, - - 1762, 1759, 1816, 1762, 1761, 1763, 1763, 1763, 1760, 1756, - 1763, 1762, 1817, 1818, 1764, 1764, 1764, 1761, 1763, 1764, - 1819, 1778, 1820, 1821, 1762, 1758, 0, 1764, 1763, 0, - 1822, 1763, 1759, 1816, 1756, 1825, 1826, 1827, 1829, 1760, - 1764, 1830, 1778, 1817, 1818, 1784, 1784, 1784, 1761, 0, - 1758, 1819, 1831, 1820, 1821, 1762, 0, 1759, 1765, 1763, - 1784, 1822, 1763, 0, 1760, 0, 1825, 1826, 1827, 1829, - 0, 1764, 1830, 1761, 0, 0, 1792, 1792, 1792, 0, - 1762, 0, 0, 1831, 0, 0, 0, 1763, 0, 1765, - 1767, 1792, 0, 1785, 1785, 1785, 1764, 1835, 1840, 1765, - - 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, - 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, - 1766, 1767, 1768, 1785, 1981, 1981, 1981, 1784, 1835, 1840, - 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, - 1767, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, - 1769, 1769, 1772, 1768, 1785, 1798, 1798, 1798, 1792, 1802, - 1802, 1802, 0, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - 1768, 1768, 1768, 1768, 1802, 1785, 0, 1803, 1803, 1803, - 1823, 1823, 1823, 1772, 1841, 1798, 1842, 1845, 1846, 1848, - 1832, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, - - 1772, 1772, 1832, 1839, 1852, 1823, 1981, 1803, 1823, 1833, - 1833, 1833, 1867, 0, 1839, 1841, 1798, 1842, 1845, 1846, - 1848, 1832, 1823, 1875, 1833, 1834, 1834, 1834, 0, 1879, - 1849, 1849, 1849, 1832, 1839, 1852, 1823, 1798, 1803, 1823, - 0, 1802, 0, 1867, 1849, 1839, 0, 0, 1869, 1869, - 1869, 0, 1872, 1823, 1875, 1834, 1880, 1881, 0, 1803, - 1879, 1882, 1823, 1828, 0, 1882, 1876, 1872, 1884, 1828, - 1837, 1869, 1876, 1828, 1828, 1868, 1868, 1868, 1828, 1828, - 1828, 0, 1828, 1872, 0, 0, 1834, 1880, 1881, 1868, - 0, 1833, 1882, 0, 1828, 1838, 0, 1876, 1872, 1884, - - 1828, 1837, 1869, 1876, 1828, 1828, 0, 1834, 0, 1828, - 1828, 1828, 1849, 1828, 1837, 1837, 1837, 1837, 1837, 1837, - 1837, 1837, 1837, 1837, 1837, 1887, 1838, 1850, 1850, 1850, - 1869, 0, 1864, 1864, 1864, 1838, 1838, 1838, 1838, 1838, - 1838, 1838, 1838, 1838, 1838, 1838, 1855, 1855, 1855, 0, - 1850, 1855, 1864, 0, 1889, 0, 1887, 1868, 0, 1855, - 1856, 1856, 1856, 1890, 0, 1856, 1857, 1857, 1857, 1850, - 0, 1857, 1855, 1856, 1864, 1858, 1858, 1858, 0, 1857, - 1858, 1850, 1859, 1859, 1859, 1889, 1856, 1859, 1858, 1857, - 1883, 1883, 1857, 0, 1890, 1859, 1891, 0, 0, 0, - - 1850, 1858, 0, 1855, 0, 1864, 0, 0, 1859, 1850, - 1853, 1853, 1853, 1894, 1864, 0, 1895, 1856, 1896, 0, - 1857, 1883, 1883, 1857, 1860, 1860, 1860, 1891, 1855, 1860, - 1853, 0, 1858, 1861, 1861, 1861, 1897, 1860, 1861, 1859, - 1898, 1899, 1856, 1903, 1894, 1905, 1861, 1895, 1857, 1896, - 1860, 0, 0, 1862, 1862, 1862, 0, 1858, 1862, 1861, - 1863, 1863, 1863, 0, 1859, 1863, 1862, 1897, 0, 0, - 0, 1898, 1899, 1863, 1903, 0, 1905, 1907, 1908, 1862, - 1910, 1860, 1886, 1886, 1886, 1911, 1863, 1862, 0, 0, - 1861, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, - - 1853, 1853, 1912, 1913, 0, 1866, 1860, 1914, 1907, 1908, - 1862, 1910, 1886, 0, 0, 1861, 1911, 1863, 1862, 1865, - 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, - 1915, 0, 1917, 1912, 1913, 1862, 1866, 0, 1914, 0, - 0, 0, 1863, 1886, 1866, 1866, 1866, 1866, 1866, 1866, - 1866, 1866, 1866, 1866, 1866, 1871, 1871, 1871, 1918, 1916, - 0, 1915, 1916, 1917, 1886, 1873, 1873, 1873, 1877, 1877, - 1877, 1885, 1885, 1885, 1919, 1871, 1892, 1892, 1892, 1921, - 1873, 1922, 1920, 1877, 1923, 1924, 1885, 1921, 1926, 1918, - 1916, 1892, 1920, 1916, 1921, 1927, 1928, 1928, 1928, 1930, - - 1934, 1936, 1937, 1939, 1940, 1919, 0, 0, 0, 0, - 1921, 1928, 1922, 1920, 0, 1923, 1924, 0, 1921, 1926, - 1942, 1931, 0, 1920, 0, 1921, 1927, 0, 0, 0, - 1930, 1934, 1936, 1937, 1939, 1940, 1871, 1871, 1871, 1871, - 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1873, 1932, 0, - 1877, 1942, 1931, 1885, 1944, 1944, 1944, 0, 1892, 1931, - 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, - 1944, 0, 1933, 0, 0, 1938, 1938, 1938, 1928, 1932, - 1933, 0, 0, 1950, 1952, 1957, 0, 1932, 1932, 1932, - 1932, 1932, 1932, 1932, 1932, 1932, 1932, 1932, 1938, 0, - - 1958, 1945, 1945, 1933, 1948, 1948, 1948, 1955, 1955, 1955, - 0, 1933, 1945, 1945, 1950, 1952, 1957, 1938, 1945, 1951, - 1951, 1951, 1959, 1955, 1948, 1946, 1946, 1946, 0, 1938, - 1946, 1958, 1960, 1960, 0, 1961, 1944, 1962, 1946, 1947, - 1947, 1947, 1951, 1963, 1947, 1945, 1945, 1945, 1938, 1945, - 1964, 1946, 1947, 1959, 1965, 0, 1948, 1938, 0, 1946, - 1954, 1954, 1954, 1960, 1960, 1947, 1961, 1964, 1962, 0, - 0, 1969, 1970, 1951, 1963, 0, 1945, 0, 1945, 1949, - 1954, 1964, 1946, 1956, 1956, 1965, 1948, 0, 1971, 1955, - 1946, 1967, 1967, 1967, 1956, 1956, 1947, 0, 1964, 1973, - - 1956, 1951, 1969, 1970, 1974, 1975, 1967, 1946, 1949, 1949, - 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1971, - 1976, 1947, 1978, 1983, 1984, 1984, 1984, 1956, 1956, 1956, - 1973, 1956, 1985, 1989, 1991, 1974, 1975, 1987, 1987, 1987, - 1992, 1994, 1954, 1995, 1996, 1997, 1998, 1999, 0, 2000, - 2001, 1976, 2002, 1978, 1983, 2004, 2005, 2006, 1956, 2007, - 1956, 2009, 2013, 1985, 1989, 1991, 2016, 2018, 2027, 0, - 0, 1992, 1994, 1967, 1995, 1996, 1997, 1998, 1999, 1987, - 2000, 2001, 2010, 2002, 2011, 0, 2004, 2005, 2006, 0, - 2007, 0, 2009, 2013, 2015, 2015, 2015, 2016, 2018, 2027, - - 2020, 2020, 2020, 2034, 2034, 2034, 1984, 2023, 2023, 2023, - 1987, 0, 2023, 2010, 2015, 2011, 2020, 0, 0, 1987, - 2023, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, - 2010, 2010, 2032, 2023, 2024, 2024, 2024, 2033, 2011, 2011, - 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2012, - 2025, 2026, 2026, 2026, 2024, 2035, 2029, 2029, 2029, 2037, - 2012, 2038, 2039, 2032, 2023, 2024, 2042, 2043, 2033, 0, - 0, 2026, 2029, 2036, 2036, 2036, 2015, 2040, 2040, 2040, - 2012, 2025, 2020, 2044, 2039, 2034, 2035, 2045, 2050, 2023, - 2037, 2012, 2038, 2039, 0, 2052, 2024, 2042, 2043, 2055, - - 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, - 2025, 2046, 2046, 2046, 2044, 2039, 2024, 2056, 2045, 2050, - 2048, 2048, 2048, 2051, 2051, 2051, 2052, 2053, 2053, 2053, - 2055, 2057, 2058, 2026, 2048, 2059, 2060, 2061, 2029, 2062, - 2063, 2063, 2057, 2064, 2065, 2067, 2068, 2069, 2056, 2070, - 2071, 2074, 2074, 2074, 0, 2036, 2087, 2087, 2087, 2040, - 0, 0, 2057, 2058, 2078, 2076, 2059, 2060, 2061, 2079, - 2062, 2063, 2063, 2080, 2064, 2065, 2067, 2068, 2069, 0, - 2070, 2071, 2075, 2075, 2075, 2075, 2075, 2075, 2075, 2075, - 2075, 2075, 2075, 2046, 2077, 2078, 2076, 2081, 2083, 2084, - - 2079, 2085, 2048, 2086, 2080, 2051, 2077, 0, 2091, 2053, - 2076, 2076, 2076, 2076, 2076, 2076, 2076, 2076, 2076, 2076, - 2076, 2082, 2082, 2082, 0, 2077, 0, 0, 2081, 2083, - 2084, 0, 2085, 2074, 2086, 2092, 2093, 2077, 2087, 2091, - 2095, 2082, 2089, 2089, 2089, 2096, 2097, 2082, 2094, 2094, - 2094, 2100, 2104, 2083, 2083, 2083, 2083, 2083, 2083, 2083, - 2083, 2083, 2083, 2083, 2105, 2108, 2092, 2093, 2098, 2098, - 2098, 2095, 2101, 2101, 2101, 2109, 2096, 2097, 2082, 2102, - 2102, 2102, 2100, 2104, 2110, 0, 2101, 2106, 2106, 2106, - 0, 2112, 2113, 0, 2114, 2105, 2108, 0, 2115, 0, - - 2116, 2117, 2118, 2082, 2119, 2121, 2109, 2122, 2123, 2124, - 2126, 2127, 2127, 2127, 2129, 2110, 2102, 2130, 2131, 0, - 2132, 2102, 2112, 2113, 2089, 2114, 2133, 2130, 2106, 2115, - 2094, 2116, 2117, 2118, 2137, 2119, 2121, 2138, 2122, 2123, - 2124, 2126, 2135, 2135, 2135, 2129, 0, 2102, 2130, 2131, - 2098, 2132, 2102, 0, 2101, 0, 0, 2133, 2130, 2106, - 0, 2102, 2135, 2139, 2140, 2137, 2141, 0, 2138, 2106, - 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, - 2129, 2136, 2136, 2136, 2136, 2136, 2136, 2136, 2136, 2136, - 2136, 2136, 2146, 2127, 2139, 2140, 2147, 2141, 2142, 2142, - - 2142, 2148, 2148, 2148, 2149, 2150, 2152, 0, 2153, 2154, - 2155, 2156, 0, 2157, 2158, 2160, 2161, 2162, 2163, 2164, - 2165, 2166, 2167, 2146, 2135, 2169, 2172, 2147, 2174, 2175, - 2176, 2177, 2178, 2179, 2180, 2149, 2150, 2152, 2148, 2153, - 2154, 2155, 2156, 2148, 2157, 2158, 2160, 2161, 2162, 2163, - 2164, 2165, 2166, 2167, 2171, 2181, 2169, 2172, 0, 2174, - 2175, 2176, 2177, 2178, 2179, 2180, 0, 0, 2184, 2148, - 2185, 2188, 2189, 2190, 2148, 2191, 2192, 2192, 2192, 2193, - 2142, 2194, 2196, 2148, 2198, 2171, 2181, 2200, 2171, 2171, - 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2184, - - 2202, 2185, 2188, 2189, 2190, 2203, 2191, 2205, 2206, 2207, - 2193, 2209, 2194, 2196, 2210, 2198, 2212, 2215, 2200, 2204, - 2204, 2204, 2204, 2204, 2204, 2204, 2204, 2204, 2204, 2204, - 2216, 2202, 2217, 2218, 2219, 2220, 2203, 2222, 2205, 2206, - 2207, 2226, 2209, 2227, 2229, 2210, 2230, 2212, 2215, 2221, - 2221, 2221, 2223, 2223, 2223, 2232, 2234, 2235, 2192, 2237, - 2238, 2216, 2239, 2217, 2218, 2219, 2220, 2240, 2222, 2241, - 2246, 2247, 2226, 2249, 2227, 2229, 2251, 2230, 2242, 2242, - 2242, 2244, 2244, 2244, 2252, 2253, 2232, 2234, 2235, 2255, - 2237, 2238, 2256, 2239, 2257, 2258, 2259, 2260, 2240, 2261, - - 2241, 2246, 2247, 0, 2249, 2262, 2263, 2251, 2264, 2265, - 2266, 2267, 2276, 2276, 2276, 2252, 2253, 2269, 2270, 2271, - 2255, 2272, 2273, 2256, 2274, 2257, 2258, 2259, 2260, 0, - 2261, 2221, 2276, 2277, 2223, 0, 2262, 2263, 2284, 2264, - 2265, 2266, 2267, 2268, 2268, 2268, 2287, 2288, 2269, 2270, - 2271, 2268, 2272, 2273, 2290, 2274, 2278, 2278, 2278, 2291, - 2242, 2294, 2295, 2244, 2277, 2280, 2280, 2280, 2296, 2284, - 2297, 2298, 2300, 2280, 2301, 2302, 2278, 2287, 2288, 2303, - 2305, 2305, 2305, 2306, 2307, 2290, 2308, 2309, 2312, 2314, - 2291, 2315, 2294, 2295, 2276, 2310, 2310, 2310, 2317, 2296, - - 2319, 2297, 2298, 2300, 2320, 2301, 2302, 2313, 2313, 2313, - 2303, 2318, 2318, 2318, 2306, 2307, 0, 2308, 2309, 2312, - 2314, 2321, 2315, 2322, 2323, 2268, 2324, 2268, 0, 2317, - 0, 2319, 2325, 2325, 2325, 2320, 0, 0, 2278, 0, - 0, 0, 0, 0, 0, 0, 0, 2280, 0, 2280, - 0, 0, 2321, 0, 2322, 2323, 0, 2324, 0, 0, - 0, 0, 2305, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2310, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2313, - 0, 0, 0, 2318, 0, 0, 0, 0, 0, 0, + 1253, 1256, 1128, 1254, 1114, 1254, 1159, 1162, 1162, 1162, + 1253, 1256, 1116, 1270, 1255, 1126, 1165, 1165, 1165, 1255, + 0, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, 1114, 1128, 1166, 1166, 1166, 0, 1116, 1126, + 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, + 1163, 1163, 1163, 0, 1162, 1272, 1274, 1164, 1128, 1128, + 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1142, + 0, 1142, 0, 1163, 1259, 1168, 1168, 1168, 0, 1259, + 1166, 1142, 1167, 1167, 1167, 1162, 1272, 1274, 1162, 1170, + 1170, 1170, 0, 0, 1169, 1169, 1169, 1165, 1171, 1171, + + 1171, 1172, 1172, 1172, 1163, 1259, 0, 1175, 1175, 1175, + 1259, 1166, 1142, 0, 0, 1166, 1168, 1167, 1169, 1173, + 1173, 1173, 1174, 1174, 1174, 0, 1275, 1172, 1276, 1170, + 0, 1163, 0, 1175, 0, 1142, 1142, 1142, 1142, 1142, + 1142, 1142, 1142, 1142, 1142, 1142, 1143, 1168, 1167, 1169, + 1176, 1176, 1176, 1260, 1143, 1173, 1168, 1275, 1172, 1276, + 1170, 1174, 1277, 1167, 1175, 1177, 1177, 1177, 0, 0, + 1170, 1178, 1178, 1178, 1260, 1169, 1176, 1292, 1293, 1171, + 0, 0, 1172, 0, 1260, 1143, 1173, 0, 1175, 1179, + 1179, 1179, 1174, 1277, 0, 1177, 0, 1180, 1180, 1180, + + 1173, 0, 0, 1174, 1183, 1183, 1183, 1176, 1292, 1293, + 0, 1178, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, + 1143, 1143, 1143, 1160, 0, 1160, 1177, 1180, 1303, 1341, + 1179, 1176, 1181, 1181, 1181, 1160, 1182, 1182, 1182, 1186, + 1186, 1186, 1178, 1188, 1188, 1188, 1177, 1185, 1185, 1185, + 0, 0, 1178, 1342, 0, 1181, 0, 0, 1180, 1303, + 1341, 1179, 1187, 1187, 1187, 0, 1160, 1184, 1184, 1184, + 1179, 0, 1193, 1193, 1193, 1185, 1186, 1353, 1180, 0, + 1189, 1189, 1189, 0, 1342, 1183, 1181, 1182, 1187, 1160, + 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, + + 1161, 1161, 1161, 0, 0, 0, 1185, 1186, 1353, 1311, + 1190, 1190, 1190, 1181, 1161, 0, 0, 1182, 1184, 1187, + 1186, 1189, 0, 1311, 1188, 0, 0, 0, 1185, 0, + 1191, 1191, 1192, 1192, 1192, 1195, 1195, 1195, 1190, 1191, + 1311, 1191, 0, 1187, 0, 1369, 1191, 1190, 1184, 0, + 1195, 0, 1189, 1193, 1311, 1194, 1194, 1194, 1198, 1198, + 1198, 1189, 1192, 0, 0, 1196, 1196, 1196, 0, 1190, + 1199, 1199, 1199, 1191, 1191, 1191, 1369, 1191, 1190, 1370, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1190, 1371, 1192, 1194, 1196, 1197, 1197, 1197, 1198, + + 1200, 1200, 1200, 0, 1191, 0, 1191, 1201, 1201, 1201, + 1370, 1202, 1202, 1192, 1372, 0, 1195, 1204, 1204, 1204, + 1202, 1374, 1202, 1371, 0, 1194, 1196, 1202, 0, 0, + 1198, 1257, 1197, 1205, 1205, 1205, 1194, 0, 0, 1198, + 1376, 1200, 1257, 1378, 1201, 1372, 1196, 1203, 1203, 1203, + 0, 1199, 1374, 0, 1202, 1202, 1202, 0, 1202, 1206, + 1206, 1206, 1257, 1197, 1207, 1207, 1207, 1208, 1208, 1208, + 0, 1376, 1200, 1257, 1378, 1201, 0, 1197, 1209, 1209, + 1209, 1200, 1210, 1210, 1210, 1202, 1203, 1202, 1201, 1211, + 1211, 1211, 0, 1208, 1212, 1212, 1212, 0, 1204, 1213, + + 1213, 1213, 1209, 0, 1207, 1214, 1214, 1214, 1368, 1215, + 1215, 1215, 1368, 1368, 1205, 1211, 1212, 1203, 1227, 1227, + 1227, 1229, 1229, 1229, 1208, 1231, 1231, 1231, 1203, 1226, + 1226, 1226, 0, 1209, 1213, 1207, 1258, 1379, 0, 1368, + 1206, 1214, 1258, 1368, 1368, 1207, 1211, 1212, 1208, 0, + 1215, 1381, 0, 1225, 1225, 1228, 1228, 1228, 1226, 1209, + 0, 0, 1225, 1210, 1225, 1213, 0, 1258, 1379, 1225, + 1211, 0, 1214, 1258, 0, 1212, 1234, 1234, 1234, 0, + 1213, 1215, 1381, 1230, 1230, 1230, 1214, 0, 0, 1226, + 1215, 1224, 1224, 1224, 0, 1228, 1225, 1225, 1225, 1227, + + 1225, 0, 1229, 1238, 1238, 1238, 1231, 1382, 1230, 0, + 1226, 1239, 1239, 1239, 1224, 1224, 1224, 1224, 1224, 1224, + 0, 1224, 1383, 1224, 1384, 1224, 1228, 1225, 1224, 1225, + 1385, 1224, 1224, 0, 0, 1224, 1228, 0, 1382, 1230, + 1237, 1237, 1237, 0, 0, 1224, 1224, 1224, 1224, 1224, + 1224, 1239, 1224, 1383, 1224, 1384, 1224, 1234, 1308, 1224, + 1308, 1385, 1224, 1224, 1230, 1237, 1224, 1232, 1232, 1232, + 1308, 0, 1224, 1233, 1233, 1233, 1235, 1235, 1235, 1236, + 1236, 1236, 1239, 1310, 1238, 1240, 1240, 1240, 1314, 1232, + 1314, 0, 1239, 0, 1310, 1233, 1237, 1241, 1241, 1241, + + 1314, 1308, 1235, 1244, 1377, 1236, 1386, 1377, 1240, 1242, + 1242, 1242, 0, 0, 1310, 1380, 1387, 0, 0, 1388, + 1232, 1237, 1281, 1281, 1281, 1310, 1233, 1380, 1409, 1281, + 1387, 1314, 1241, 1235, 1245, 1377, 1236, 1386, 1377, 1240, + 0, 0, 1285, 1285, 1285, 0, 1380, 1387, 1232, 1285, + 1388, 0, 0, 0, 1233, 0, 0, 1235, 1380, 1409, + 1236, 1387, 0, 1241, 0, 1245, 1240, 1244, 1244, 1244, + 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1241, 1245, + 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, + 1242, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, + + 1246, 1246, 1247, 1281, 0, 0, 0, 0, 0, 0, + 0, 1248, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, + 1262, 1262, 1262, 1285, 1411, 1413, 1249, 1320, 1320, 1320, + 0, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + 1247, 1247, 1248, 1289, 1289, 1289, 1413, 1289, 0, 1322, + 1322, 1322, 1325, 1325, 1325, 1411, 1413, 1249, 1331, 1331, + 1331, 1294, 0, 1319, 1319, 1319, 0, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1251, + 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, + + 1294, 0, 1309, 1407, 1309, 1319, 1415, 1407, 1320, 0, + 1309, 1329, 1329, 1329, 1309, 1412, 1251, 0, 1410, 1261, + 1412, 0, 1410, 1416, 1289, 0, 1329, 1295, 1295, 1295, + 1322, 0, 1295, 1325, 1407, 0, 1319, 1415, 1407, 1331, + 1295, 1309, 0, 0, 1319, 1309, 1412, 1251, 1299, 1410, + 1261, 1412, 1295, 1410, 1416, 1251, 1251, 1251, 1251, 1251, + 1251, 1251, 1251, 1251, 1251, 1251, 1252, 1261, 1261, 1261, + 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1418, 1299, + 1419, 1420, 1252, 1295, 0, 1304, 0, 0, 0, 0, + 0, 0, 1329, 0, 1424, 1299, 1299, 1299, 1299, 1299, + + 1299, 1299, 1299, 1299, 1299, 1299, 0, 0, 1295, 1418, + 0, 1419, 1420, 1252, 1304, 1304, 1304, 1304, 1304, 1304, + 1304, 1304, 1304, 1304, 1304, 1424, 0, 0, 0, 0, + 0, 0, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, + 1252, 1252, 1252, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1298, 1298, 1300, 1426, 1337, + 1337, 1337, 1321, 1321, 1321, 1428, 1298, 1316, 1316, 1316, + 0, 1298, 0, 0, 1301, 0, 0, 0, 0, 0, + 0, 1339, 1339, 1339, 1351, 1351, 1351, 0, 1300, 1426, + 0, 1340, 1340, 1340, 0, 0, 1428, 0, 1298, 1298, + 1298, 1305, 1298, 1321, 1316, 1301, 1340, 1300, 1300, 1300, + 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1301, 1301, + + 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1298, + 0, 1298, 1305, 1306, 1321, 1316, 0, 1318, 1318, 1318, + 1337, 0, 1429, 1321, 0, 0, 0, 0, 1316, 0, + 0, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, + 1305, 1305, 1339, 1318, 1306, 1351, 1323, 1323, 1323, 1324, + 1324, 1324, 1340, 1429, 1315, 1315, 1315, 1306, 1306, 1306, + 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1315, 0, + 1315, 0, 1317, 1317, 1318, 0, 1326, 1326, 1326, 0, + 1315, 1317, 1430, 1317, 1327, 1327, 1327, 1323, 1317, 0, + 1324, 1330, 1330, 1330, 1431, 1328, 1328, 1328, 1318, 0, + + 1326, 0, 1332, 1332, 1332, 1333, 1333, 1333, 1433, 0, + 1327, 1315, 1434, 1430, 1330, 1317, 1317, 1317, 1323, 1317, + 1328, 1324, 1334, 1334, 1334, 1431, 0, 1323, 1332, 0, + 1324, 1326, 1336, 1336, 1336, 1315, 1345, 1345, 1345, 1433, + 1333, 1327, 1435, 1434, 1334, 1330, 1317, 0, 1317, 0, + 0, 1328, 1335, 1335, 1335, 0, 0, 1326, 0, 1332, + 1338, 1338, 1338, 0, 0, 1327, 1345, 1336, 1350, 1350, + 1350, 1333, 1330, 1435, 0, 1334, 1328, 1344, 1344, 1344, + 1346, 1346, 1346, 1332, 0, 0, 1333, 1349, 1349, 1349, + 1408, 1335, 0, 1348, 1348, 1346, 1408, 1345, 1336, 1338, + + 1414, 1350, 1348, 1334, 1348, 1352, 1352, 1352, 1414, 1348, + 0, 1438, 1344, 1336, 1359, 1359, 1359, 1345, 1355, 1355, + 1355, 1408, 1335, 1356, 1356, 1356, 1445, 1408, 1349, 1422, + 1338, 1414, 1350, 1335, 1422, 1352, 1348, 1348, 1348, 1414, + 1348, 1338, 1438, 1344, 1355, 1463, 1356, 0, 0, 1350, + 1358, 1358, 1358, 1468, 1360, 1360, 1360, 1445, 1344, 1349, + 1422, 1346, 1357, 1357, 0, 1422, 1352, 1348, 1349, 1348, + 0, 1357, 1464, 1357, 0, 1355, 1463, 1356, 1357, 1358, + 1360, 1361, 1361, 1361, 1468, 1464, 1352, 1363, 1363, 1363, + 1364, 1364, 1364, 0, 0, 1359, 1365, 1365, 1365, 1355, + + 1366, 1366, 1366, 1464, 1356, 1357, 1357, 1357, 0, 1357, + 1358, 1360, 1362, 1362, 1364, 1361, 1464, 1367, 1367, 1367, + 0, 1362, 1365, 1362, 1390, 1390, 1390, 1491, 1362, 0, + 1492, 1358, 1367, 0, 0, 1360, 1357, 0, 1357, 1391, + 1391, 1391, 1366, 0, 0, 1364, 1361, 1392, 1392, 1392, + 1395, 1395, 1395, 1365, 1500, 1362, 1362, 1362, 1491, 1362, + 1390, 1492, 1361, 1393, 1393, 1393, 1502, 0, 1363, 0, + 0, 1364, 1506, 1366, 1394, 1394, 1394, 1365, 1396, 1396, + 1396, 1366, 1397, 1397, 1397, 1500, 1362, 1393, 1362, 0, + 1514, 1390, 1515, 1396, 1398, 1398, 1398, 1502, 1367, 0, + + 1399, 1399, 1399, 1506, 1461, 1390, 1461, 1516, 1397, 1400, + 1400, 1400, 1517, 0, 1518, 1394, 1461, 1462, 1393, 1462, + 1391, 1514, 1519, 1515, 0, 1462, 1520, 1402, 1392, 1462, + 1466, 1395, 1466, 1399, 1452, 1452, 1452, 1400, 1516, 1397, + 1521, 1522, 1466, 1517, 1393, 1518, 1394, 1461, 1523, 1524, + 0, 0, 1525, 1519, 0, 1394, 1462, 1520, 1526, 1396, + 1462, 0, 0, 1397, 1399, 0, 0, 0, 1400, 0, + 0, 1521, 1522, 1466, 0, 1398, 1470, 1470, 1470, 1523, + 1524, 1399, 1404, 1525, 0, 1472, 1472, 1472, 1405, 1526, + 1400, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, + + 1402, 1402, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, + 1403, 1403, 1403, 1404, 0, 1452, 0, 0, 0, 1405, + 0, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, + 1404, 1404, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, + 1405, 1405, 1405, 1406, 1406, 1406, 1406, 1406, 1406, 1406, + 1406, 1406, 1406, 1406, 1417, 1436, 1527, 1470, 1476, 1476, + 1476, 1528, 1529, 1437, 1437, 1437, 1472, 0, 1437, 1440, + 1440, 1440, 0, 0, 1440, 0, 1437, 1473, 1473, 1473, + 0, 0, 1440, 0, 0, 1417, 1436, 1527, 1437, 1477, + 1477, 1477, 1528, 1529, 1440, 0, 1436, 1436, 1436, 1436, + + 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1473, 1417, 1417, + 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1437, + 1530, 1441, 1441, 1441, 0, 1440, 1441, 1444, 1444, 1444, + 0, 1531, 1444, 1532, 1441, 1471, 1471, 1471, 1473, 1476, + 1444, 1474, 1474, 1474, 1437, 0, 1441, 1467, 1467, 1467, + 1440, 1530, 1444, 0, 0, 1451, 1451, 1451, 1473, 0, + 1451, 1467, 1531, 1467, 1532, 1533, 1534, 1474, 1451, 0, + 1477, 1451, 1535, 1467, 1536, 1537, 1471, 1441, 0, 0, + 1451, 1538, 1539, 1444, 1453, 1453, 1453, 1453, 1453, 1453, + 1453, 1453, 1453, 1453, 1453, 1454, 1533, 1534, 1474, 1478, + + 1478, 1478, 1441, 1535, 1467, 1536, 1537, 1471, 1444, 1446, + 1446, 1451, 1538, 1539, 1478, 0, 1471, 0, 0, 0, + 1446, 0, 1474, 0, 1455, 1446, 1454, 0, 1467, 1563, + 1554, 0, 0, 0, 0, 0, 1451, 1482, 1482, 1482, + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1554, 1446, 1446, 1446, 1455, 1446, 1483, 1483, 1483, + 1563, 1554, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, + 1455, 1455, 1455, 1497, 1497, 1497, 0, 0, 0, 0, + 1478, 0, 0, 1446, 1446, 1446, 1446, 1446, 1446, 1446, + 1446, 1446, 1446, 1446, 1446, 1449, 1449, 1449, 1449, 1449, + + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1457, 1482, 1565, + 1566, 1449, 1475, 1475, 1475, 1498, 1498, 1498, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1483, 0, + 1458, 0, 0, 0, 1475, 1567, 0, 0, 1457, 0, + 1565, 1566, 1449, 0, 1497, 1488, 1488, 1488, 1457, 1457, + 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1459, + 1488, 1458, 1487, 1487, 1487, 1475, 1567, 1449, 1481, 1481, + 1481, 1449, 1449, 0, 1449, 1458, 1458, 1458, 1458, 1458, + 1458, 1458, 1458, 1458, 1458, 1458, 1484, 1484, 1484, 0, + + 1459, 0, 1487, 1475, 1481, 0, 1498, 1459, 1459, 1459, + 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1480, 1480, + 1484, 1485, 1485, 1485, 1493, 1493, 1493, 1480, 0, 1480, + 1486, 1486, 1486, 1487, 1480, 1481, 1488, 1494, 1494, 1494, + 1499, 1499, 1499, 1501, 1501, 1501, 1504, 1504, 1504, 0, + 0, 1484, 1486, 1487, 1508, 1508, 1508, 1485, 0, 1481, + 0, 1480, 1480, 1480, 1493, 1480, 1505, 1505, 1505, 1490, + 1490, 0, 1568, 1494, 0, 1553, 1499, 1484, 1490, 0, + 1490, 1505, 0, 1486, 1553, 1490, 1508, 0, 1485, 1509, + 1509, 1509, 1480, 0, 1480, 1493, 1510, 1510, 1510, 0, + + 0, 1569, 1485, 1568, 1494, 1493, 1553, 1499, 1540, 1540, + 1540, 1486, 1490, 1490, 1490, 1553, 1490, 1508, 1494, 0, + 0, 1499, 0, 0, 1501, 1556, 0, 1504, 1541, 1541, + 1541, 1510, 1569, 0, 0, 1508, 1511, 1511, 1511, 1513, + 1513, 1556, 0, 1490, 1570, 1490, 0, 1505, 1513, 1540, + 1513, 1511, 1543, 1543, 1543, 1513, 1556, 1511, 1546, 1546, + 1546, 1511, 1510, 0, 1542, 1542, 1542, 1543, 1571, 1541, + 1509, 1572, 1556, 1511, 1555, 1570, 0, 1510, 0, 1555, + 1540, 0, 1513, 1513, 1513, 0, 1513, 1545, 1545, 1540, + 1542, 0, 1511, 1547, 1547, 1547, 1545, 0, 1545, 1571, + + 1541, 0, 1572, 1545, 1511, 1555, 1548, 1548, 1548, 1541, + 1555, 1557, 1558, 1513, 0, 1513, 1557, 1511, 0, 1547, + 1558, 1542, 1559, 1560, 1550, 1573, 1574, 1559, 1560, 1575, + 1545, 1545, 1545, 1543, 1545, 1561, 1576, 1577, 1578, 1546, + 1561, 1583, 1557, 1558, 1585, 1542, 1548, 1557, 0, 1551, + 1547, 1558, 1590, 1559, 1560, 1602, 1573, 1574, 1559, 1560, + 1575, 1545, 0, 1545, 0, 0, 1561, 1576, 1577, 1578, + 0, 1561, 1583, 0, 1547, 1585, 0, 1548, 0, 1552, + 1551, 0, 1606, 1590, 1620, 0, 1602, 1548, 1550, 1550, + 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1551, + + 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, + 1552, 1562, 1579, 1606, 0, 1620, 1613, 1613, 1613, 0, + 0, 0, 0, 0, 1552, 1552, 1552, 1552, 1552, 1552, + 1552, 1552, 1552, 1552, 1552, 0, 1634, 1634, 1634, 1621, + 1628, 0, 1562, 1579, 0, 1562, 1562, 1562, 1562, 1562, + 1562, 1562, 1562, 1562, 1562, 1562, 1579, 1579, 1579, 1579, + 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1580, 1580, 1580, + 1621, 1628, 1580, 1581, 1581, 1581, 0, 0, 1581, 0, + 1580, 0, 1582, 1582, 1582, 0, 1581, 1582, 1584, 1584, + 1584, 0, 1580, 1584, 1600, 1582, 1600, 1613, 1581, 0, + + 1604, 1584, 1604, 1588, 1588, 1588, 1600, 1582, 1588, 1592, + 1592, 1592, 1604, 1584, 1592, 1581, 1588, 1634, 1601, 0, + 1601, 0, 1592, 1580, 1629, 0, 1601, 1633, 1588, 1581, + 1601, 0, 0, 1636, 1592, 0, 0, 1600, 1582, 0, + 0, 0, 1637, 1604, 1584, 1638, 1581, 1642, 1580, 0, + 1610, 1610, 1610, 0, 1581, 1629, 1594, 1601, 1633, 1588, + 0, 1601, 1595, 1582, 1636, 1592, 1605, 1605, 1605, 1584, + 1586, 1586, 1586, 1637, 0, 1586, 1638, 0, 1642, 0, + 1605, 0, 1605, 1586, 1588, 0, 0, 1594, 1596, 1644, + 1592, 1610, 1605, 1595, 1646, 1586, 1594, 1594, 1594, 1594, + + 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1595, 1595, 1595, + 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1647, 1596, + 1644, 0, 1610, 1605, 0, 1646, 1586, 0, 0, 0, + 1597, 1610, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, + 1596, 1596, 1596, 1607, 1607, 1607, 0, 1605, 0, 1647, + 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, + 1586, 1597, 1598, 1608, 1608, 1608, 1609, 1609, 1609, 1607, + 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, + 1597, 1615, 1615, 1615, 0, 0, 1614, 1614, 1614, 1616, + 1616, 1616, 0, 1598, 1622, 1622, 1622, 0, 1648, 1608, + + 1607, 1609, 1617, 1617, 1617, 0, 0, 1598, 1598, 1598, + 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1614, 1645, + 1622, 1649, 1650, 1616, 1607, 1615, 1623, 1623, 1623, 1648, + 1608, 0, 1609, 1652, 1626, 1626, 1626, 1645, 1617, 1627, + 1627, 1627, 1653, 0, 1608, 0, 0, 1609, 0, 1614, + 1645, 1622, 1649, 1650, 1616, 1651, 1615, 1630, 1630, 1630, + 1654, 1655, 1615, 1626, 1652, 1623, 1651, 1614, 1645, 1617, + 1616, 1656, 1630, 1653, 1627, 1622, 1635, 1635, 1635, 1632, + 1632, 1657, 1658, 1617, 0, 1659, 1651, 1660, 1632, 0, + 1632, 1654, 1655, 0, 1626, 1632, 1623, 1651, 1661, 1663, + + 1662, 1664, 1656, 1665, 1666, 1627, 1675, 1623, 1667, 1667, + 1667, 0, 1657, 1658, 0, 1626, 1659, 1635, 1660, 0, + 1627, 1662, 1632, 1632, 1632, 0, 1632, 1679, 1680, 1661, + 1663, 1662, 1664, 1678, 1665, 1666, 1681, 1682, 1630, 1668, + 1668, 1668, 1669, 1669, 1669, 1672, 1672, 1672, 1635, 1673, + 1673, 1673, 1662, 1632, 1678, 1632, 1676, 1635, 1679, 1680, + 0, 1683, 1685, 1686, 1678, 1683, 1689, 1681, 1682, 1668, + 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, + 1675, 0, 1692, 1684, 1693, 1672, 1697, 1676, 1700, 1667, + 1684, 1677, 1683, 1685, 1686, 0, 1683, 1689, 1701, 0, + + 1668, 0, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, + 1676, 1676, 1676, 1692, 1684, 1693, 1672, 1697, 0, 1700, + 1668, 1684, 1677, 1669, 1702, 1703, 1672, 1704, 1706, 1701, + 1673, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, + 1677, 1677, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1710, 0, 1702, 1703, 1731, 1704, 1706, + 0, 1746, 0, 1704, 1704, 1704, 1704, 1704, 1704, 1704, + 1704, 1704, 1704, 1704, 1705, 1705, 1705, 0, 1747, 1705, + 1707, 1707, 1707, 0, 1710, 1707, 0, 1705, 1731, 1708, + 1708, 1708, 1746, 1707, 1708, 1752, 1705, 1755, 0, 1705, + + 0, 1726, 1708, 1726, 0, 1707, 1709, 1709, 1709, 1747, + 0, 1709, 1756, 1726, 1708, 0, 1711, 1711, 1711, 1709, + 0, 1711, 1732, 1732, 1732, 0, 1752, 1705, 1755, 1711, + 1705, 1709, 1711, 1712, 1712, 1712, 1707, 0, 1712, 0, + 0, 1711, 0, 1756, 1726, 1708, 1712, 0, 0, 1712, + 0, 1714, 1714, 1714, 0, 1705, 1714, 1759, 1712, 1761, + 0, 1707, 1709, 0, 1714, 0, 1715, 1715, 1715, 0, + 1708, 1715, 1711, 1716, 1716, 1716, 1714, 0, 1716, 1715, + 1717, 1717, 1717, 0, 0, 1717, 1716, 1709, 1759, 1712, + 1761, 1715, 0, 1717, 1735, 1735, 1735, 1711, 1716, 1718, + + 1718, 1718, 0, 1732, 1718, 1717, 0, 1714, 1719, 1719, + 1719, 0, 1718, 1719, 1712, 1729, 0, 1729, 1762, 1763, + 1735, 1719, 1715, 1727, 1718, 1727, 1767, 1729, 1768, 1716, + 0, 1727, 1714, 1719, 1769, 1727, 1717, 1720, 1770, 1771, + 0, 1718, 1733, 1733, 1733, 1772, 0, 1715, 1773, 1762, + 1763, 1735, 1775, 1776, 1716, 1718, 1777, 1767, 1729, 1768, + 0, 1717, 1727, 0, 1719, 1769, 1727, 0, 1720, 1770, + 1771, 1721, 1718, 0, 0, 1735, 1772, 1733, 1778, 1773, + 1718, 0, 0, 1775, 1776, 0, 0, 1777, 0, 1719, + 1722, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, + + 1720, 1720, 1721, 1734, 1734, 1734, 1723, 1724, 1733, 1778, + 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, + 1721, 1722, 0, 1733, 0, 0, 1722, 1722, 1722, 1722, + 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1723, 1724, 1739, + 1739, 1739, 0, 1779, 1734, 0, 1724, 1724, 1724, 1724, + 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1730, 1730, 1730, + 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, + 1723, 1730, 0, 1730, 1779, 1734, 1738, 1738, 1738, 1740, + 1740, 1740, 1780, 1730, 1734, 1741, 1741, 1741, 1742, 1742, + 1742, 0, 1745, 1745, 1745, 1748, 1748, 1748, 1749, 1749, + + 1749, 1750, 1750, 1750, 1781, 1738, 0, 0, 1751, 1751, + 1751, 1741, 1782, 1780, 1730, 0, 1750, 1783, 1784, 1740, + 1739, 1745, 1754, 1754, 1754, 1786, 0, 1742, 1749, 1760, + 1760, 1760, 1787, 1789, 1748, 1781, 1738, 1751, 1730, 1774, + 1774, 1774, 1741, 1782, 1790, 1766, 1766, 1766, 1783, 1784, + 1740, 0, 1745, 1785, 1785, 1785, 1786, 1738, 1742, 1749, + 1740, 1791, 1792, 1787, 1789, 1748, 1741, 1793, 1751, 1742, + 1794, 1795, 0, 1745, 1766, 1790, 1748, 0, 0, 1749, + 1805, 0, 1750, 1796, 1796, 1796, 1799, 1799, 1799, 1751, + 1805, 1809, 1791, 1792, 1800, 1800, 1800, 1803, 1793, 1806, + + 1810, 1794, 1795, 1754, 1806, 1766, 0, 1811, 1808, 1807, + 1760, 1805, 1802, 1807, 1813, 1799, 1814, 1815, 1816, 1796, + 1774, 1805, 1809, 0, 0, 0, 1766, 0, 1803, 1808, + 1806, 1810, 1848, 0, 1785, 1806, 0, 1804, 1811, 1808, + 1807, 0, 0, 1854, 1807, 1813, 1799, 1814, 1815, 1816, + 1796, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, + 1803, 1803, 0, 1848, 1796, 0, 0, 1799, 1804, 0, + 1849, 1849, 1849, 1819, 1854, 1800, 1802, 1802, 1802, 1802, + 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1804, 1804, 1804, + 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1817, 1817, + + 1817, 1850, 1850, 1850, 1819, 1861, 1851, 1851, 1851, 0, + 0, 1863, 1817, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1820, 1820, 1820, 0, 1864, 1820, + 1822, 1822, 1822, 0, 0, 1822, 1861, 1820, 0, 1823, + 1823, 1823, 1863, 1822, 1823, 1824, 1824, 1824, 0, 1820, + 1824, 1849, 1823, 1869, 1843, 1822, 1843, 1820, 1824, 1864, + 1825, 1825, 1825, 0, 1823, 1825, 1843, 1871, 1875, 1846, + 1824, 1846, 1876, 1825, 0, 1853, 1853, 1853, 0, 1817, + 1820, 1846, 1850, 0, 1869, 1825, 1822, 1851, 1820, 1826, + 1826, 1826, 0, 0, 1826, 1823, 1877, 1843, 1871, 1875, + + 0, 1824, 1826, 1876, 1853, 1820, 1878, 0, 1827, 1827, + 1827, 1822, 1846, 1827, 1826, 1881, 1825, 1828, 1828, 1828, + 1823, 1827, 1828, 1830, 1830, 1830, 1824, 1877, 1830, 1883, + 1828, 1826, 0, 1827, 0, 1853, 1830, 1878, 1831, 1831, + 1831, 1825, 1828, 1831, 0, 1826, 1881, 1844, 1830, 1844, + 1884, 1831, 1832, 1832, 1832, 1844, 1853, 1832, 0, 1844, + 1883, 0, 1826, 1831, 1827, 1832, 1885, 1833, 1833, 1833, + 1826, 0, 1833, 1828, 1856, 1856, 1856, 1832, 1886, 1830, + 1833, 1884, 1834, 1834, 1834, 0, 1844, 1834, 0, 1827, + 1844, 0, 1833, 1887, 1831, 1834, 1888, 1885, 1828, 0, + + 1835, 1835, 1835, 0, 1830, 1835, 1889, 1834, 1832, 1886, + 0, 1892, 1893, 1835, 1894, 1836, 1836, 1836, 1895, 1831, + 1836, 1896, 1835, 1833, 1887, 1835, 1897, 1888, 1836, 1852, + 1852, 1852, 0, 1832, 1857, 1857, 1857, 1889, 1834, 1898, + 1836, 1837, 1892, 1893, 1852, 1894, 0, 1899, 1833, 1895, + 0, 0, 1896, 1835, 0, 1856, 1835, 1897, 1859, 1859, + 1859, 0, 1900, 1834, 1867, 1867, 1867, 0, 0, 0, + 1898, 1836, 1837, 1859, 0, 0, 0, 1839, 1899, 1867, + 0, 1835, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + 1837, 1837, 1837, 1900, 0, 0, 1836, 1838, 1838, 1838, + + 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1839, 1840, + 1852, 1858, 1858, 1858, 0, 1857, 0, 1839, 1839, 1839, + 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1841, 1841, + 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1859, + 1840, 1858, 1860, 1860, 1860, 1867, 1901, 1847, 1847, 1847, + 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, + 1840, 1847, 0, 1847, 1865, 1865, 1865, 1866, 1866, 1866, + 1904, 1860, 1858, 1847, 1874, 1874, 1874, 1901, 1879, 1879, + 1879, 1880, 1880, 1880, 1890, 1890, 1890, 1905, 1902, 1902, + 1902, 1906, 1858, 1879, 1907, 1909, 1910, 0, 0, 1911, + + 1912, 1904, 1860, 1874, 1847, 1865, 1916, 1923, 1866, 1924, + 1880, 1926, 1902, 0, 0, 1902, 0, 0, 1905, 0, + 0, 0, 1906, 1860, 0, 1907, 1909, 1910, 1847, 1902, + 1911, 1912, 1929, 1922, 1874, 1930, 1865, 1916, 1923, 1866, + 1924, 1880, 1926, 1902, 1922, 1865, 1902, 1925, 1866, 1913, + 1913, 1913, 1914, 1914, 1914, 1874, 0, 1925, 0, 1879, + 1902, 1931, 1880, 1929, 1922, 1890, 1930, 1914, 1932, 1902, + 1908, 1915, 1915, 1915, 1919, 1922, 1908, 0, 1925, 1937, + 1908, 1908, 1957, 1960, 1913, 1908, 1908, 1908, 1925, 1908, + 1964, 1952, 1931, 1952, 1934, 1934, 1934, 1957, 1965, 1932, + + 1915, 1908, 0, 1952, 0, 0, 0, 1908, 1934, 0, + 1937, 1908, 1908, 1957, 1960, 1913, 1908, 1908, 1908, 1920, + 1908, 1964, 1966, 1969, 1970, 1973, 1975, 1976, 1957, 1965, + 1913, 1915, 0, 1914, 1952, 1935, 1935, 1935, 1919, 1919, + 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1921, + 1920, 1977, 1915, 1966, 1969, 1970, 1973, 1975, 1976, 1958, + 1958, 1958, 0, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1958, 1934, 1935, 1972, 1972, 1972, + 1921, 0, 1977, 0, 0, 1962, 1962, 1962, 0, 1921, + 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, + + 1962, 1978, 0, 1953, 0, 1953, 1972, 1935, 0, 0, + 0, 1953, 1967, 1967, 1967, 1953, 1935, 1938, 1938, 1938, + 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1939, 1939, + 1939, 0, 1978, 1939, 1940, 1940, 1940, 1972, 1981, 1940, + 1958, 1939, 1953, 1941, 1941, 1941, 1953, 1940, 1941, 1942, + 1942, 1942, 0, 1939, 1942, 1955, 1941, 1955, 1972, 1940, + 1982, 1983, 1942, 1967, 0, 1941, 1962, 1955, 1941, 1981, + 1943, 1943, 1943, 0, 1942, 1943, 1944, 1944, 1944, 1984, + 0, 1944, 0, 1943, 1939, 1971, 1971, 1971, 0, 1944, + 1940, 1982, 1983, 1967, 0, 1943, 1941, 0, 1955, 1941, + + 1971, 1944, 1956, 1956, 1956, 1942, 1945, 1945, 1945, 1939, + 1984, 1945, 1946, 1946, 1946, 1940, 1956, 1946, 1956, 1945, + 0, 1985, 1986, 1990, 1941, 1946, 1943, 0, 1956, 1994, + 1942, 1945, 1944, 1947, 1947, 1947, 1996, 1946, 1947, 1997, + 1999, 2000, 2001, 2002, 2003, 1946, 1947, 0, 1979, 1979, + 1979, 1943, 1985, 1986, 1990, 1948, 0, 1944, 1947, 1956, + 1994, 0, 1945, 1979, 0, 0, 1971, 1996, 1946, 0, + 1997, 1999, 2000, 2001, 2002, 2003, 1946, 1987, 1987, 1987, + 1968, 1968, 1968, 1956, 0, 0, 1948, 1945, 0, 1947, + 1961, 1961, 1961, 1946, 1948, 1948, 1948, 1948, 1948, 1948, + + 1948, 1948, 1948, 1948, 1948, 1950, 1988, 1988, 1988, 1992, + 1992, 1992, 2005, 0, 1947, 1949, 1949, 1949, 1949, 1949, + 1949, 1949, 1949, 1949, 1949, 1949, 1968, 0, 2007, 1979, + 0, 1961, 1993, 1993, 1993, 2008, 1950, 1995, 1995, 1995, + 2004, 2004, 2004, 2005, 1950, 1950, 1950, 1950, 1950, 1950, + 1950, 1950, 1950, 1950, 1950, 2009, 0, 1968, 1987, 2007, + 2006, 1968, 1961, 2006, 2010, 2011, 2008, 2012, 2013, 2014, + 2016, 1961, 2017, 2011, 2010, 2018, 2018, 2018, 2021, 2023, + 2011, 2026, 2019, 2019, 2019, 2024, 2009, 1988, 2028, 2026, + 1992, 2006, 0, 0, 2006, 2010, 2011, 2019, 2012, 2013, + + 2014, 2016, 0, 2017, 2011, 2010, 2027, 2029, 2031, 2021, + 2027, 2011, 2026, 1993, 0, 0, 2024, 0, 1995, 2028, + 2026, 2004, 0, 2024, 2024, 2024, 2024, 2024, 2024, 2024, + 2024, 2024, 2024, 2024, 2025, 2032, 2034, 2027, 2029, 2031, + 2036, 2027, 0, 2023, 2023, 2023, 2023, 2023, 2023, 2023, + 2023, 2023, 2023, 2023, 0, 0, 2018, 2033, 2033, 2033, + 0, 0, 2047, 2019, 0, 2025, 2032, 2034, 0, 2048, + 0, 2036, 0, 2025, 2025, 2025, 2025, 2025, 2025, 2025, + 2025, 2025, 2025, 2025, 2037, 2037, 2037, 2049, 2051, 2037, + 2038, 2038, 2038, 2047, 2042, 2038, 2042, 2037, 2033, 2045, + + 2048, 2045, 2043, 2038, 2043, 2052, 2042, 0, 2053, 2037, + 2043, 2045, 0, 2060, 2043, 2038, 2062, 2037, 2049, 2051, + 2039, 2050, 2050, 2050, 2055, 2055, 2055, 0, 0, 2033, + 2054, 2054, 2054, 2056, 2056, 2056, 2052, 2042, 2033, 2053, + 2037, 2043, 2045, 2040, 2060, 2043, 2038, 2062, 2037, 2039, + 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, + 2054, 2057, 2057, 2057, 2063, 2037, 0, 2050, 0, 2065, + 0, 2038, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, + 2040, 2040, 2040, 2046, 2046, 2046, 2058, 2058, 2058, 2066, + 2067, 2054, 2068, 2070, 2075, 2063, 0, 2046, 2050, 2046, + + 2065, 2058, 2050, 2077, 0, 2055, 2071, 2071, 2071, 2046, + 2085, 2054, 0, 0, 2056, 2073, 2073, 2073, 2087, 2088, + 2066, 2067, 2092, 2068, 2070, 2075, 2076, 2076, 2076, 2078, + 2078, 2078, 2093, 0, 2077, 2080, 2080, 2080, 2094, 2095, + 2046, 2085, 2057, 2083, 2083, 2083, 2090, 2090, 2090, 2087, + 2088, 2096, 2097, 2092, 2098, 0, 0, 2099, 2100, 2102, + 2103, 2080, 2078, 2093, 2046, 2110, 2104, 2058, 2105, 2094, + 2095, 2106, 2108, 2115, 2116, 2080, 0, 2118, 2132, 2132, + 2132, 2120, 2096, 2097, 2083, 2098, 2090, 2071, 2099, 2100, + 2102, 2103, 2080, 2078, 2130, 2131, 2073, 2104, 0, 2105, + + 0, 0, 2106, 2108, 2115, 2116, 2080, 2076, 2118, 2111, + 2078, 2112, 2120, 0, 0, 2083, 2080, 2090, 2133, 2133, + 2133, 0, 0, 0, 2083, 2130, 2131, 2090, 0, 2110, + 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, + 2111, 0, 2112, 2134, 2134, 2134, 0, 0, 2111, 2111, + 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2132, + 0, 0, 2135, 0, 2136, 2112, 2112, 2112, 2112, 2112, + 2112, 2112, 2112, 2112, 2112, 2112, 2113, 2114, 2121, 2121, + 2121, 2142, 2125, 2121, 2125, 2122, 2114, 2113, 0, 2143, + 2126, 2121, 2126, 2135, 2125, 2136, 2123, 2144, 2126, 2133, + + 0, 2145, 2126, 2121, 2138, 2138, 2138, 2113, 2114, 2146, + 2146, 2146, 2142, 2151, 2151, 2151, 2122, 2114, 2113, 2128, + 2143, 2128, 0, 0, 2134, 2125, 2150, 2123, 2144, 2126, + 2152, 2128, 2145, 2126, 2121, 2122, 2122, 2122, 2122, 2122, + 2122, 2122, 2122, 2122, 2122, 2122, 2123, 2123, 2123, 2123, + 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2150, 0, 2121, + 0, 2152, 2128, 2129, 2129, 2129, 2137, 2137, 2137, 2140, + 2140, 2140, 2148, 2148, 2148, 2155, 2156, 2129, 2157, 2129, + 2153, 2153, 2153, 2158, 2159, 2138, 2148, 2160, 2161, 2129, + 2146, 2137, 2162, 2163, 2151, 2164, 2165, 2166, 2160, 2167, + + 2167, 2168, 2140, 2169, 2171, 2172, 2155, 2156, 2173, 2157, + 2174, 2175, 2181, 0, 2158, 2159, 0, 2184, 2160, 2161, + 2129, 2186, 2137, 2162, 2163, 0, 2164, 2165, 2166, 2184, + 2167, 2167, 2168, 2140, 2169, 2171, 2172, 0, 0, 2173, + 0, 2174, 2175, 2183, 2129, 0, 0, 2137, 2184, 0, + 2140, 0, 2186, 2148, 2179, 2179, 2179, 0, 0, 0, + 2184, 2153, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, + 2182, 2182, 2182, 2187, 2183, 2188, 2181, 2181, 2181, 2181, + 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2185, 2183, 2183, + 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2189, + + 2185, 2190, 2191, 2194, 2187, 2194, 2188, 2197, 2195, 2197, + 2195, 2199, 2200, 2192, 2205, 2194, 2195, 0, 2185, 2197, + 2195, 2206, 2198, 2198, 2198, 2201, 2201, 2201, 0, 0, + 2189, 2185, 2190, 2191, 0, 2179, 2198, 0, 2198, 2203, + 2203, 2203, 2199, 2200, 2192, 2205, 2194, 2195, 2198, 2208, + 2197, 2195, 2206, 2207, 2207, 2207, 2210, 2191, 2191, 2191, + 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2192, 2192, + 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2198, + 2208, 2209, 2209, 2209, 2211, 2212, 2215, 2210, 2213, 2213, + 2213, 2216, 2216, 2216, 2217, 2217, 2217, 2219, 2220, 2221, + + 2221, 2221, 2223, 2198, 0, 2216, 2201, 2224, 0, 2225, + 2226, 2227, 2228, 2230, 2231, 2211, 2212, 2215, 2232, 2233, + 2203, 2234, 2235, 2236, 2237, 2238, 2240, 2241, 2219, 2220, + 2217, 2249, 2242, 2223, 2207, 2217, 2243, 2245, 2224, 2221, + 2225, 2226, 2227, 2228, 2230, 2231, 2246, 2246, 2246, 2232, + 2233, 2250, 2234, 2235, 2236, 2237, 2238, 2240, 2241, 2253, + 2254, 2217, 2209, 2242, 0, 0, 2217, 2243, 2245, 2213, + 2221, 0, 2216, 0, 0, 2217, 0, 2271, 2271, 2271, + 2221, 2261, 2250, 2261, 0, 0, 0, 0, 2252, 2256, + 2253, 2254, 2252, 2261, 2266, 2249, 2249, 2249, 2249, 2249, + + 2249, 2249, 2249, 2249, 2249, 2249, 0, 2250, 2250, 2250, + 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2251, 2252, + 2256, 0, 0, 2252, 2261, 2266, 2267, 2246, 2251, 2258, + 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, + 2262, 2264, 2262, 2264, 2268, 2269, 2270, 2275, 2262, 2251, + 2276, 2278, 2262, 2264, 2277, 2277, 2277, 2267, 2271, 2251, + 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, + 2259, 2265, 2265, 2265, 2279, 2268, 2269, 2270, 2275, 2262, + 2281, 2276, 2278, 2262, 2264, 2265, 2282, 2265, 2283, 2284, + 2277, 2285, 2286, 2287, 2288, 2277, 2289, 2265, 2290, 2292, + + 2293, 2294, 2295, 2296, 2305, 2279, 2297, 2298, 2299, 2300, + 2302, 2281, 2307, 2310, 2311, 2318, 2319, 2282, 2320, 2283, + 2284, 2277, 2285, 2286, 2287, 2288, 2277, 2289, 2265, 2290, + 2292, 2293, 2294, 2295, 2296, 2277, 0, 2297, 2298, 2299, + 2300, 2302, 0, 2307, 2310, 2311, 2318, 2319, 2306, 2320, + 2321, 2313, 2265, 2313, 0, 2316, 0, 2316, 0, 0, + 0, 0, 0, 2313, 0, 2322, 0, 2316, 2305, 2305, + 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2306, + 2323, 2321, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, + 2306, 2306, 2306, 2308, 2313, 2314, 2322, 2314, 2316, 2317, + + 2317, 2317, 2308, 2314, 2326, 2327, 2330, 2314, 2331, 2332, + 2333, 2323, 2336, 2317, 2337, 2317, 2334, 2334, 2334, 2338, + 2339, 2341, 2342, 2344, 2308, 2317, 2346, 2348, 2349, 0, + 0, 0, 0, 2308, 2314, 2326, 2327, 2330, 2314, 2331, + 2332, 2333, 2351, 2336, 2353, 2337, 2355, 2363, 0, 0, + 2338, 2339, 2341, 2342, 2344, 0, 2317, 2346, 2348, 2349, + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, + 2352, 2364, 2367, 2370, 2357, 2353, 2357, 2355, 2363, 2358, + 2317, 2358, 2360, 0, 2360, 0, 2357, 2358, 2376, 2376, + 2376, 2358, 2371, 2372, 2360, 2373, 2374, 2334, 2375, 2377, + + 2380, 2381, 2364, 2367, 2370, 0, 2351, 2351, 2351, 2351, + 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2357, 2358, 2361, + 2361, 2361, 2358, 2371, 2372, 2360, 2373, 2374, 2383, 2375, + 2377, 2380, 2381, 2361, 2384, 2361, 2378, 2378, 2378, 2385, + 2387, 2388, 2406, 2406, 2406, 2361, 2391, 2391, 2391, 2391, + 2391, 2391, 2391, 2391, 2391, 2391, 2391, 2399, 2401, 2383, + 2402, 2394, 2403, 2394, 2404, 2384, 2395, 2405, 2395, 2376, + 2385, 2387, 2388, 2394, 2395, 2397, 2361, 2397, 2395, 2410, + 2398, 2398, 2398, 2408, 2408, 2408, 0, 2397, 2399, 2401, + 2413, 2402, 0, 2403, 2398, 2404, 2398, 2416, 2405, 2419, + + 2361, 2412, 2412, 2412, 2394, 2395, 2398, 2427, 0, 2395, + 2410, 2428, 2421, 2424, 2421, 2424, 0, 2378, 2397, 2429, + 2430, 2413, 2431, 2406, 2421, 2424, 0, 2422, 2416, 2422, + 2419, 2425, 2425, 2425, 2432, 2422, 2433, 2398, 2427, 2422, + 2436, 2437, 2428, 2438, 0, 2425, 0, 2425, 0, 0, + 2429, 2430, 2444, 2431, 0, 2421, 2424, 2425, 2434, 2434, + 2434, 2398, 0, 0, 2408, 2432, 2422, 2433, 2446, 0, + 2422, 2436, 2437, 2447, 2438, 2440, 2448, 2440, 2441, 2443, + 2441, 2443, 2412, 2444, 2449, 2434, 2441, 2440, 2425, 2450, + 2441, 2443, 2445, 2445, 2445, 2451, 2452, 2454, 2462, 2446, + + 2445, 2456, 2465, 2456, 2447, 2466, 2467, 2448, 0, 2469, + 2470, 2473, 2425, 2456, 2474, 2449, 2434, 2441, 2440, 2475, + 2450, 2441, 2443, 2458, 2458, 2458, 2451, 2452, 2454, 2462, + 2476, 2458, 2477, 2465, 2480, 2481, 2466, 2467, 2482, 2434, + 2469, 2470, 2473, 2483, 2456, 2474, 2478, 2478, 2478, 2488, + 2475, 2485, 2485, 2485, 2486, 2486, 2486, 2489, 2490, 2491, + 2494, 2476, 2495, 2477, 0, 2480, 2481, 2497, 2498, 2482, + 2492, 2492, 2492, 2445, 2483, 2445, 2496, 2496, 2496, 2499, + 2488, 2501, 2502, 2502, 2502, 2503, 2504, 2505, 2489, 2490, + 2491, 2494, 2506, 2495, 2507, 2486, 0, 2508, 2497, 2498, + + 2510, 0, 2511, 2512, 2458, 0, 2458, 2513, 2513, 2513, + 2499, 0, 2501, 0, 0, 0, 2503, 2504, 2505, 0, + 0, 0, 0, 2506, 0, 2507, 2486, 2478, 2508, 0, + 0, 2510, 2485, 2511, 2512, 2486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2325, 2327, 2327, 2327, 2327, 2327, - 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, - 2327, 2327, 2327, 2327, 2328, 2328, 2328, 2328, 2328, 2328, - 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, - 2328, 2328, 2328, 2329, 2329, 2329, 2329, 2329, 2329, 2329, - 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, - 2329, 2329, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, - 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, - 2330, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, - - 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, - 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, - 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2333, - 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2333, - 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2334, 2334, - 2334, 2334, 2334, 2334, 2334, 2334, 2334, 2334, 2334, 2334, - 2334, 2334, 2334, 2334, 2334, 2334, 2334, 2335, 2335, 2335, - 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, - 2335, 2335, 2335, 2335, 2335, 2335, 2336, 2336, 2336, 2336, - 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, - - 2336, 2336, 2336, 2336, 2336, 2337, 2337, 2337, 2337, 2337, - 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, - 2337, 2337, 2337, 2337, 2338, 2338, 2338, 2338, 2338, 2338, - 2338, 2338, 2338, 2338, 2338, 2338, 2338, 2338, 2338, 2338, - 2338, 2338, 2338, 2339, 2339, 2339, 2339, 2339, 2339, 2339, - 2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339, - 2339, 2339, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, - 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, - 2340, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, - 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, - - 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, - 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2343, - 2343, 2343, 0, 0, 0, 0, 2343, 0, 0, 0, - 0, 2343, 2343, 2343, 2343, 2344, 2344, 0, 2344, 2344, - 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, - 2344, 2344, 2344, 2344, 2345, 2345, 0, 0, 0, 0, - 2345, 0, 0, 0, 0, 2345, 2345, 2345, 2345, 2346, - 2346, 2346, 0, 0, 0, 2346, 0, 0, 0, 0, - 2346, 2346, 2346, 2346, 2347, 2347, 0, 0, 0, 0, - 2347, 0, 0, 0, 2347, 2347, 2347, 2347, 2347, 2348, - - 0, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2349, 2349, - 0, 0, 0, 0, 2349, 0, 0, 0, 0, 2349, - 2349, 2349, 2349, 2350, 0, 2350, 2350, 2350, 2350, 2350, - 2350, 2351, 2351, 0, 2351, 2351, 0, 2351, 2351, 2351, - 2351, 0, 0, 0, 0, 2351, 2351, 2351, 2351, 2352, - 0, 2352, 2352, 2352, 2352, 2353, 2353, 2353, 0, 0, - 0, 0, 2353, 0, 0, 0, 0, 2353, 2353, 2353, - 2353, 2354, 2354, 0, 0, 0, 0, 2354, 0, 0, - 0, 0, 2354, 2354, 2354, 2354, 2355, 2355, 2355, 0, - 0, 0, 2355, 0, 0, 0, 0, 2355, 2355, 2355, - - 2355, 2356, 2356, 0, 0, 0, 0, 2356, 0, 0, - 0, 2356, 2356, 2356, 2356, 2356, 2357, 0, 2357, 2357, - 2357, 2357, 2358, 0, 0, 2358, 0, 2358, 2359, 0, - 0, 2359, 0, 2359, 2360, 2360, 2360, 2360, 2360, 2360, - 0, 2360, 2360, 2360, 2360, 2360, 2360, 0, 2360, 2360, - 2360, 2360, 2360, 2361, 2361, 2361, 2361, 2361, 2361, 2361, - 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, - 2361, 2361, 2362, 2362, 2362, 2362, 2362, 2362, 0, 2362, - 2362, 2362, 2362, 2362, 2362, 0, 2362, 2362, 2362, 2362, - 2362, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, - - 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, - 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, - 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2365, - 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, - 2365, 2365, 2365, 0, 2365, 2365, 2365, 2365, 2366, 2366, - 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, - 2366, 2366, 0, 2366, 2366, 2366, 2366, 2367, 2367, 0, - 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, - 2367, 2367, 2367, 2367, 2367, 2367, 2368, 2368, 0, 0, - 0, 0, 2368, 0, 0, 0, 0, 2368, 2368, 2368, - - 2368, 2369, 0, 2369, 2369, 2369, 2369, 2369, 2370, 2370, - 0, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, - 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2371, 2371, 0, - 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, - 2371, 2371, 2371, 2371, 2371, 2371, 2372, 2372, 0, 0, - 0, 0, 2372, 0, 0, 0, 0, 2372, 2372, 2372, - 2372, 2373, 0, 2373, 2373, 2373, 2373, 2373, 2373, 2374, - 2374, 0, 0, 0, 0, 2374, 0, 0, 0, 0, - 2374, 2374, 2374, 2374, 2375, 0, 2375, 2375, 2375, 2375, - 2376, 2376, 0, 2376, 2376, 2376, 2376, 2376, 2376, 2376, - - 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2377, - 2377, 0, 0, 0, 0, 2377, 0, 0, 0, 0, - 2377, 2377, 2377, 2377, 2378, 0, 2378, 2378, 2378, 2378, - 0, 0, 2378, 2379, 2379, 0, 2379, 2379, 2379, 2379, - 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, - 2379, 2379, 2380, 2380, 0, 2380, 2380, 2380, 2380, 2380, - 2380, 2380, 2380, 2380, 2380, 2380, 2380, 2380, 2380, 2380, - 2380, 2381, 2381, 2381, 0, 0, 0, 0, 2381, 0, - 0, 0, 0, 2381, 2381, 2381, 2381, 2382, 0, 2382, - 2382, 2382, 2382, 2383, 2383, 0, 2383, 2383, 2383, 2383, - - 2383, 2383, 2383, 2383, 2383, 2383, 2383, 2383, 2383, 2383, - 2383, 2383, 2384, 2384, 0, 2384, 2384, 2384, 2384, 2384, - 2384, 2384, 2384, 2384, 2384, 2384, 2384, 2384, 2384, 2384, - 2384, 2385, 2385, 0, 2385, 2385, 2385, 2385, 2385, 2385, - 2385, 2385, 2385, 2385, 2385, 2385, 2385, 2385, 2385, 2385, - 2386, 2386, 0, 0, 0, 0, 2386, 0, 0, 0, - 0, 2386, 2386, 2386, 2386, 2387, 0, 2387, 2387, 2387, - 2387, 2388, 2388, 2388, 0, 0, 0, 2388, 0, 0, - 0, 0, 2388, 2388, 2388, 2388, 2389, 0, 2389, 2389, - 2389, 2389, 2390, 2390, 0, 0, 0, 0, 2390, 0, - - 0, 0, 2390, 2390, 2390, 2390, 2390, 2391, 0, 2391, - 2391, 2391, 2391, 2392, 2392, 0, 0, 0, 0, 2392, - 0, 0, 0, 0, 2392, 2392, 2392, 2392, 2393, 0, - 2393, 2393, 2393, 2393, 2394, 2394, 0, 2394, 2394, 0, - 2394, 2394, 2394, 2394, 0, 0, 0, 0, 2394, 2394, - 2394, 2394, 2395, 0, 2395, 2395, 2395, 2395, 2396, 2396, - 2396, 0, 0, 0, 0, 2396, 0, 0, 0, 0, - 2396, 2396, 2396, 2396, 2397, 0, 2397, 2397, 2397, 2397, - 2398, 2398, 0, 0, 0, 0, 2398, 0, 0, 0, - 0, 2398, 2398, 2398, 2398, 2399, 0, 2399, 2399, 2399, - - 2399, 2400, 2400, 2400, 0, 0, 0, 2400, 0, 0, - 0, 0, 2400, 2400, 2400, 2400, 2401, 0, 2401, 2401, - 2401, 2401, 2402, 2402, 0, 0, 0, 0, 2402, 0, - 0, 0, 2402, 2402, 2402, 2402, 2402, 2403, 0, 2403, - 2403, 2403, 2403, 2404, 0, 0, 2404, 0, 2404, 2405, - 0, 0, 2405, 0, 2405, 2406, 2406, 2406, 2406, 2406, - 2406, 0, 2406, 2406, 2406, 2406, 2406, 2406, 0, 2406, - 2406, 2406, 2406, 2406, 2407, 2407, 0, 2407, 2407, 2407, - 2407, 2407, 2407, 2407, 2407, 2407, 2407, 2407, 2407, 2407, - 2407, 2407, 2407, 2408, 2408, 2408, 2408, 2408, 2408, 0, - - 2408, 2408, 2408, 2408, 2408, 2408, 0, 2408, 2408, 2408, - 2408, 2408, 2409, 2409, 0, 2409, 2409, 2409, 2409, 2409, - 2409, 2409, 2409, 2409, 2409, 2409, 2409, 2409, 2409, 2409, - 2409, 2410, 2410, 0, 2410, 2410, 2410, 2410, 2410, 2410, - 2410, 2410, 2410, 2410, 2410, 2410, 2410, 2410, 2410, 2410, - 2411, 2411, 2411, 2411, 2411, 2411, 2411, 2411, 2411, 2411, - 2411, 2411, 2411, 2411, 0, 2411, 2411, 2411, 2411, 2412, - 2412, 2412, 2412, 2412, 2412, 2412, 2412, 2412, 2412, 2412, - 2412, 2412, 2412, 0, 2412, 2412, 2412, 2412, 2413, 2413, - 0, 2413, 2413, 2413, 2413, 2413, 2413, 2413, 2413, 2413, - - 2413, 2413, 2413, 2413, 2413, 2413, 2413, 2414, 2414, 0, - 2414, 2414, 2414, 2414, 2414, 2414, 2414, 2414, 2414, 2414, - 2414, 2414, 2414, 2414, 2414, 2414, 2415, 2415, 0, 2415, - 2415, 2415, 2415, 2415, 2415, 2415, 2415, 2415, 2415, 2415, - 2415, 2415, 2415, 2415, 2415, 2416, 2416, 0, 0, 0, - 0, 2416, 0, 0, 0, 0, 2416, 2416, 2416, 2416, - 2417, 0, 2417, 2417, 2417, 2417, 2418, 2418, 0, 2418, - 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, - 2418, 2418, 2418, 2418, 2418, 2419, 2419, 0, 2419, 2419, - 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, - - 2419, 2419, 2419, 2419, 2420, 2420, 0, 2420, 2420, 2420, - 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, - 2420, 2420, 2420, 2421, 2421, 0, 2421, 2421, 2421, 2421, - 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, - 2421, 2421, 2422, 2422, 0, 0, 0, 0, 2422, 0, - 0, 0, 0, 2422, 2422, 2422, 2422, 2423, 0, 2423, - 2423, 2423, 2423, 2424, 2424, 0, 0, 0, 0, 2424, - 0, 0, 0, 0, 2424, 2424, 2424, 2424, 2425, 0, - 2425, 2425, 2425, 2425, 2426, 2426, 0, 2426, 2426, 2426, - 2426, 2426, 2426, 2426, 2426, 2426, 2426, 2426, 2426, 2426, - - 2426, 2426, 2426, 2427, 2427, 0, 2427, 2427, 2427, 2427, - 2427, 2427, 2427, 2427, 2427, 2427, 2427, 2427, 2427, 2427, - 2427, 2427, 2428, 2428, 0, 2428, 2428, 2428, 2428, 2428, - 2428, 2428, 2428, 2428, 2428, 2428, 2428, 2428, 2428, 2428, - 2428, 2429, 2429, 0, 0, 0, 0, 2429, 0, 0, - 0, 0, 2429, 2429, 2429, 2429, 2430, 0, 2430, 2430, - 2430, 2430, 2431, 2431, 0, 2431, 2431, 2431, 2431, 2431, - 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, - 2431, 2432, 2432, 0, 2432, 2432, 2432, 2432, 2432, 2432, - 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, - - 2433, 2433, 2433, 0, 0, 0, 0, 2433, 0, 0, - 0, 0, 2433, 2433, 2433, 2433, 2434, 2434, 0, 2434, - 2434, 2434, 2434, 2434, 2434, 2434, 2434, 2434, 2434, 2434, - 2434, 2434, 2434, 2434, 2434, 2435, 2435, 0, 2435, 2435, - 2435, 2435, 2435, 2435, 2435, 2435, 2435, 2435, 2435, 2435, - 2435, 2435, 2435, 2435, 2436, 2436, 2436, 0, 0, 0, - 2436, 0, 0, 0, 0, 2436, 2436, 2436, 2436, 2437, - 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2437, - 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2438, 2438, - 0, 0, 0, 0, 2438, 0, 0, 0, 0, 2438, - - 2438, 2438, 2438, 2439, 2439, 0, 0, 0, 0, 2439, - 0, 0, 0, 2439, 2439, 2439, 2439, 2439, 2440, 2440, - 0, 0, 0, 0, 2440, 0, 0, 0, 0, 2440, - 2440, 2440, 2440, 2441, 2441, 0, 0, 0, 2441, 2441, - 0, 0, 0, 0, 2441, 2441, 2441, 2441, 2442, 2442, - 2442, 0, 0, 0, 0, 2442, 0, 0, 0, 0, - 2442, 2442, 2442, 2442, 2443, 2443, 2443, 0, 0, 0, - 2443, 0, 0, 0, 0, 2443, 2443, 2443, 2443, 2444, - 2444, 0, 0, 0, 0, 2444, 0, 0, 0, 0, - 2444, 2444, 2444, 2444, 2445, 2445, 0, 0, 0, 0, - - 2445, 0, 0, 0, 2445, 2445, 2445, 2445, 2445, 2446, - 0, 0, 2446, 0, 2446, 2447, 0, 0, 2447, 0, - 2447, 2448, 2448, 0, 2448, 2448, 2448, 2448, 2448, 2448, - 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, - 2449, 2449, 0, 2449, 2449, 2449, 2449, 2449, 2449, 2449, - 2449, 2449, 2449, 2449, 2449, 2449, 2449, 2449, 2449, 2450, - 2450, 0, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450, - 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2451, 2451, - 0, 2451, 2451, 2451, 2451, 2451, 2451, 2451, 2451, 2451, - 2451, 2451, 2451, 2451, 2451, 2451, 2451, 2452, 2452, 0, - - 2452, 2452, 2452, 2452, 2452, 2452, 2452, 2452, 2452, 2452, - 2452, 2452, 2452, 2452, 2452, 2452, 2453, 2453, 2453, 2453, - 2453, 2453, 2453, 2453, 2453, 2453, 2453, 2453, 2453, 2453, - 2453, 2453, 2453, 2453, 2453, 2454, 2454, 0, 0, 0, - 0, 2454, 0, 0, 0, 0, 2454, 2454, 2454, 2454, - 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, - 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2456, - 2456, 0, 2456, 2456, 2456, 2456, 2456, 2456, 2456, 2456, - 2456, 2456, 2456, 2456, 2456, 2456, 2456, 2456, 2457, 2457, - 0, 2457, 2457, 2457, 2457, 2457, 2457, 2457, 2457, 2457, - - 2457, 2457, 2457, 2457, 2457, 2457, 2457, 2458, 2458, 2458, - 2458, 2458, 2458, 2458, 2458, 2458, 2458, 2458, 2458, 2458, - 2458, 2458, 2458, 2458, 2458, 2458, 2459, 2459, 0, 0, - 0, 0, 2459, 0, 0, 0, 0, 2459, 2459, 2459, - 2459, 2460, 2460, 0, 0, 0, 0, 2460, 0, 0, - 0, 0, 2460, 2460, 2460, 2460, 2461, 2461, 0, 2461, - 2461, 2461, 2461, 2461, 2461, 2461, 2461, 2461, 2461, 2461, - 2461, 2461, 2461, 2461, 2461, 2462, 2462, 0, 2462, 2462, - 2462, 2462, 2462, 2462, 2462, 2462, 2462, 2462, 2462, 2462, - 2462, 2462, 2462, 2462, 2463, 2463, 2463, 2463, 2463, 2463, - - 2463, 2463, 2463, 2463, 2463, 2463, 2463, 2463, 2463, 2463, - 2463, 2463, 2463, 2464, 2464, 0, 0, 0, 0, 2464, - 0, 0, 0, 0, 2464, 2464, 2464, 2464, 2465, 2465, - 2465, 2465, 2465, 2465, 2465, 2465, 2465, 2465, 2465, 2465, - 2465, 2465, 2465, 2465, 2465, 2465, 2465, 2466, 2466, 2466, - 2466, 2466, 2466, 2466, 2466, 2466, 2466, 2466, 2466, 2466, - 2466, 2466, 2466, 2466, 2466, 2466, 2467, 2467, 0, 2467, - 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, - 2467, 2467, 2467, 2467, 2467, 2468, 2468, 0, 2468, 2468, - 2468, 2468, 2468, 2468, 2468, 2468, 2468, 2468, 2468, 2468, - - 2468, 2468, 2468, 2468, 2469, 2469, 0, 0, 0, 0, - 2469, 0, 0, 0, 0, 2469, 2469, 2469, 2469, 2470, - 2470, 0, 0, 0, 0, 2470, 0, 0, 0, 0, - 2470, 2470, 2470, 2470, 2471, 2471, 0, 0, 0, 2471, - 2471, 2471, 0, 0, 0, 2471, 2471, 2471, 2471, 2472, - 2472, 0, 0, 0, 0, 2472, 0, 0, 0, 0, - 2472, 2472, 2472, 2472, 2473, 0, 0, 2473, 0, 2473, - 2474, 0, 0, 2474, 0, 2474, 2475, 2475, 2475, 2475, - 2475, 2475, 2475, 2475, 2475, 2475, 2475, 2475, 2475, 2475, - 2475, 2475, 2475, 2475, 2475, 2476, 2476, 2476, 2476, 2476, - - 2476, 2476, 2476, 2476, 2476, 2476, 2476, 2476, 2476, 2476, - 2476, 2476, 2476, 2476, 2477, 2477, 2477, 2477, 2477, 2477, - 2477, 2477, 2477, 2477, 2477, 2477, 2477, 2477, 2477, 2477, - 2477, 2477, 2477, 2478, 2478, 0, 2478, 2478, 2478, 2478, - 2478, 2478, 2478, 2478, 2478, 2478, 2478, 2478, 2478, 2478, - 2478, 2478, 2479, 2479, 0, 2479, 2479, 2479, 2479, 2479, - 2479, 2479, 2479, 2479, 2479, 2479, 2479, 2479, 2479, 2479, - 2479, 2480, 2480, 0, 0, 0, 0, 2480, 0, 0, - 0, 0, 2480, 2480, 2480, 2480, 2481, 2481, 0, 2481, - 2481, 2481, 2481, 2481, 2481, 2481, 2481, 2481, 2481, 2481, - - 2481, 2481, 2481, 2481, 2481, 2482, 2482, 0, 2482, 2482, - 2482, 2482, 2482, 2482, 2482, 2482, 2482, 2482, 2482, 2482, - 2482, 2482, 2482, 2482, 2483, 2483, 0, 2483, 2483, 2483, - 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, - 2483, 2483, 2483, 2484, 2484, 0, 0, 0, 0, 2484, - 0, 0, 0, 0, 2484, 2484, 2484, 2484, 2485, 2485, - 0, 0, 0, 0, 2485, 0, 0, 0, 0, 2485, - 2485, 2485, 2485, 2486, 2486, 0, 2486, 2486, 2486, 2486, - 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, - 2486, 2486, 2487, 2487, 0, 2487, 2487, 2487, 2487, 2487, - - 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, - 2487, 2488, 2488, 0, 0, 0, 0, 2488, 0, 0, - 0, 0, 2488, 2488, 2488, 2488, 2489, 2489, 0, 2489, - 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, - 2489, 2489, 2489, 2489, 2489, 2490, 2490, 0, 2490, 2490, - 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, - 2490, 2490, 2490, 2490, 2491, 2491, 0, 2491, 2491, 0, - 0, 0, 0, 2491, 0, 0, 0, 0, 2491, 2491, - 2491, 2491, 2492, 2492, 0, 0, 0, 0, 2492, 0, - 0, 0, 0, 2492, 2492, 2492, 2492, 2493, 2493, 0, - - 0, 0, 2493, 2493, 0, 0, 0, 0, 2493, 2493, - 2493, 2493, 2494, 2494, 0, 0, 0, 0, 2494, 0, - 0, 0, 0, 2494, 2494, 2494, 2494, 2495, 0, 0, - 2495, 0, 2495, 2496, 0, 0, 2496, 0, 2496, 2497, - 2497, 0, 2497, 2497, 2497, 2497, 2497, 2497, 2497, 2497, - 2497, 2497, 2497, 2497, 2497, 2497, 2497, 2497, 2498, 2498, - 0, 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2498, - 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2499, 2499, 0, - 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, - 2499, 2499, 2499, 2499, 2499, 2499, 2500, 2500, 0, 0, - - 0, 0, 2500, 0, 0, 0, 0, 2500, 2500, 2500, - 2500, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, - 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, - 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, - 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2503, - 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2503, - 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2504, 2504, - 2504, 2504, 2504, 2504, 2504, 2504, 2504, 2504, 2504, 2504, - 2504, 2504, 2504, 2504, 2504, 2504, 2504, 2505, 2505, 2505, - 2505, 2505, 2505, 2505, 2505, 2505, 2505, 2505, 2505, 2505, - - 2505, 2505, 2505, 2505, 2505, 2505, 2506, 2506, 2506, 2506, - 2506, 2506, 2506, 2506, 2506, 2506, 2506, 2506, 2506, 2506, - 2506, 2506, 2506, 2506, 2506, 2507, 2507, 2507, 2507, 2507, - 2507, 2507, 2507, 2507, 2507, 2507, 2507, 2507, 2507, 2507, - 2507, 2507, 2507, 2507, 2508, 2508, 2508, 2508, 2508, 2508, - 2508, 2508, 2508, 2508, 2508, 2508, 2508, 2508, 2508, 2508, - 2508, 2508, 2508, 2509, 2509, 2509, 2509, 2509, 2509, 2509, - 2509, 2509, 2509, 2509, 2509, 2509, 2509, 2509, 2509, 2509, - 2509, 2509, 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, - 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, - - 2510, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326 - + 0, 2492, 0, 0, 0, 0, 0, 2496, 0, 0, + 0, 0, 0, 2502, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2513, 2515, + 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515, + + 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2516, 2516, 2516, + 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516, + 2516, 2516, 2516, 2516, 2516, 2517, 2517, 2517, 2517, 2517, + 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, + 2517, 2517, 2517, 2518, 2518, 2518, 2518, 2518, 2518, 2518, + 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, + 2518, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, + 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2520, + 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, + 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2521, 2521, 2521, + + 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521, + 2521, 2521, 2521, 2521, 2521, 2522, 2522, 2522, 2522, 2522, + 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522, + 2522, 2522, 2522, 2523, 2523, 2523, 2523, 2523, 2523, 2523, + 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523, + 2523, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, + 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2525, + 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525, + 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2526, 2526, 2526, + 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526, + + 2526, 2526, 2526, 2526, 2526, 2527, 2527, 2527, 2527, 2527, + 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527, + 2527, 2527, 2527, 2528, 2528, 2528, 2528, 2528, 2528, 2528, + 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528, + 2528, 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2529, + 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2530, + 2530, 2530, 2530, 2530, 2530, 2530, 2530, 2530, 2530, 2530, + 2530, 2530, 2530, 2530, 2530, 2530, 2530, 2531, 2531, 2531, + 0, 0, 0, 2531, 0, 0, 0, 0, 2531, 2531, + 2531, 2531, 2532, 2532, 0, 2532, 2532, 2532, 2532, 2532, + + 2532, 2532, 2532, 2532, 2532, 2532, 2532, 2532, 2532, 2532, + 2533, 2533, 0, 0, 0, 2533, 0, 0, 0, 0, + 2533, 2533, 2533, 2533, 2534, 2534, 2534, 0, 0, 2534, + 0, 0, 0, 0, 2534, 2534, 2534, 2534, 2535, 2535, + 0, 0, 0, 2535, 0, 0, 0, 2535, 2535, 2535, + 2535, 2535, 2536, 0, 2536, 2536, 2536, 2536, 2536, 2536, + 2536, 2537, 2537, 0, 0, 0, 2537, 0, 0, 0, + 0, 2537, 2537, 2537, 2537, 2538, 0, 2538, 2538, 2538, + 2538, 2538, 2538, 2539, 2539, 0, 2539, 2539, 0, 2539, + 2539, 2539, 0, 0, 0, 0, 2539, 2539, 2539, 2539, + + 2540, 0, 2540, 2540, 2540, 2540, 2541, 2541, 2541, 0, + 0, 0, 2541, 0, 0, 0, 0, 2541, 2541, 2541, + 2541, 2542, 2542, 0, 0, 0, 2542, 0, 0, 0, + 0, 2542, 2542, 2542, 2542, 2543, 2543, 2543, 0, 0, + 2543, 0, 0, 0, 0, 2543, 2543, 2543, 2543, 2544, + 2544, 0, 0, 0, 2544, 0, 0, 0, 2544, 2544, + 2544, 2544, 2544, 2545, 0, 2545, 2545, 2545, 2545, 2546, + 0, 2546, 0, 2546, 2547, 0, 2547, 0, 2547, 2548, + 2548, 2548, 2548, 2548, 2548, 0, 2548, 2548, 2548, 2548, + 2548, 0, 2548, 2548, 2548, 2548, 2548, 2549, 2549, 2549, + + 2549, 2549, 2549, 2549, 2549, 2549, 2549, 2549, 2549, 2549, + 2549, 2549, 2549, 2549, 2549, 2550, 2550, 2550, 2550, 2550, + 2550, 0, 2550, 2550, 2550, 2550, 2550, 0, 2550, 2550, + 2550, 2550, 2550, 2551, 2551, 2551, 2551, 2551, 2551, 2551, + 2551, 2551, 2551, 2551, 2551, 2551, 2551, 2551, 2551, 2551, + 2551, 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2552, + 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2553, + 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, + 2553, 2553, 0, 2553, 2553, 2553, 2553, 2554, 2554, 2554, + 2554, 2554, 2554, 2554, 2554, 2554, 2554, 2554, 2554, 2554, + + 0, 2554, 2554, 2554, 2554, 2555, 2555, 0, 2555, 2555, + 2555, 2555, 2555, 2555, 2555, 2555, 2555, 2555, 2555, 2555, + 2555, 2555, 2555, 2556, 2556, 0, 0, 0, 2556, 0, + 0, 0, 0, 2556, 2556, 2556, 2556, 2557, 0, 2557, + 2557, 2557, 2557, 2557, 2558, 2558, 0, 2558, 2558, 2558, + 2558, 2558, 2558, 2558, 2558, 2558, 2558, 2558, 2558, 2558, + 2558, 2558, 2559, 2559, 0, 2559, 2559, 2559, 2559, 2559, + 2559, 2559, 2559, 2559, 2559, 2559, 2559, 2559, 2559, 2559, + 2560, 2560, 0, 0, 0, 2560, 0, 0, 0, 0, + 2560, 2560, 2560, 2560, 2561, 0, 2561, 2561, 2561, 2561, + + 2561, 2561, 2562, 2562, 0, 0, 0, 2562, 0, 0, + 0, 0, 2562, 2562, 2562, 2562, 2563, 0, 2563, 2563, + 2563, 2563, 2564, 2564, 0, 2564, 2564, 2564, 2564, 2564, + 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, + 2565, 2565, 0, 0, 0, 2565, 0, 0, 0, 0, + 2565, 2565, 2565, 2565, 2566, 0, 2566, 2566, 2566, 2566, + 0, 0, 2566, 2567, 2567, 0, 2567, 2567, 2567, 2567, + 2567, 2567, 2567, 2567, 2567, 2567, 2567, 2567, 2567, 2567, + 2567, 2568, 2568, 0, 2568, 2568, 2568, 2568, 2568, 2568, + 2568, 2568, 2568, 2568, 2568, 2568, 2568, 2568, 2568, 2569, + + 2569, 2569, 0, 0, 0, 2569, 0, 0, 0, 0, + 2569, 2569, 2569, 2569, 2570, 0, 2570, 2570, 2570, 2570, + 2571, 2571, 0, 2571, 2571, 2571, 2571, 2571, 2571, 2571, + 2571, 2571, 2571, 2571, 2571, 2571, 2571, 2571, 2572, 2572, + 0, 2572, 2572, 2572, 2572, 2572, 2572, 2572, 2572, 2572, + 2572, 2572, 2572, 2572, 2572, 2572, 2573, 2573, 0, 2573, + 2573, 2573, 2573, 2573, 2573, 2573, 2573, 2573, 2573, 2573, + 2573, 2573, 2573, 2573, 2574, 2574, 0, 0, 0, 2574, + 0, 0, 0, 0, 2574, 2574, 2574, 2574, 2575, 0, + 2575, 2575, 2575, 2575, 2576, 2576, 2576, 0, 0, 2576, + + 0, 0, 0, 0, 2576, 2576, 2576, 2576, 2577, 0, + 2577, 2577, 2577, 2577, 2578, 2578, 0, 0, 0, 2578, + 0, 0, 0, 2578, 2578, 2578, 2578, 2578, 2579, 0, + 2579, 2579, 2579, 2579, 2580, 2580, 0, 0, 0, 2580, + 0, 0, 0, 0, 2580, 2580, 2580, 2580, 2581, 0, + 2581, 2581, 2581, 2581, 2582, 2582, 0, 2582, 2582, 0, + 2582, 2582, 2582, 0, 0, 0, 0, 2582, 2582, 2582, + 2582, 2583, 0, 2583, 2583, 2583, 2583, 2584, 2584, 2584, + 0, 0, 0, 2584, 0, 0, 0, 0, 2584, 2584, + 2584, 2584, 2585, 0, 2585, 2585, 2585, 2585, 2586, 2586, + + 0, 0, 0, 2586, 0, 0, 0, 0, 2586, 2586, + 2586, 2586, 2587, 0, 2587, 2587, 2587, 2587, 2588, 2588, + 2588, 0, 0, 2588, 0, 0, 0, 0, 2588, 2588, + 2588, 2588, 2589, 0, 2589, 2589, 2589, 2589, 2590, 2590, + 0, 0, 0, 2590, 0, 0, 0, 2590, 2590, 2590, + 2590, 2590, 2591, 0, 2591, 2591, 2591, 2591, 2592, 0, + 2592, 0, 2592, 2593, 0, 2593, 0, 2593, 2594, 2594, + 2594, 2594, 2594, 2594, 0, 2594, 2594, 2594, 2594, 2594, + 0, 2594, 2594, 2594, 2594, 2594, 2595, 2595, 0, 2595, + 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595, + + 2595, 2595, 2595, 2595, 2596, 2596, 2596, 2596, 2596, 2596, + 0, 2596, 2596, 2596, 2596, 2596, 0, 2596, 2596, 2596, + 2596, 2596, 2597, 2597, 0, 2597, 2597, 2597, 2597, 2597, + 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, + 2598, 2598, 0, 2598, 2598, 2598, 2598, 2598, 2598, 2598, + 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2599, 2599, + 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, + 2599, 0, 2599, 2599, 2599, 2599, 2600, 2600, 2600, 2600, + 2600, 2600, 2600, 2600, 2600, 2600, 2600, 2600, 2600, 0, + 2600, 2600, 2600, 2600, 2601, 2601, 0, 2601, 2601, 2601, + + 2601, 2601, 2601, 2601, 2601, 2601, 2601, 2601, 2601, 2601, + 2601, 2601, 2602, 2602, 0, 2602, 2602, 2602, 2602, 2602, + 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, + 2603, 2603, 0, 2603, 2603, 2603, 2603, 2603, 2603, 2603, + 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2604, 2604, + 0, 0, 0, 2604, 0, 0, 0, 0, 2604, 2604, + 2604, 2604, 2605, 0, 2605, 2605, 2605, 2605, 2606, 2606, + 0, 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, + 2606, 2606, 2606, 2606, 2606, 2606, 2607, 2607, 0, 2607, + 2607, 2607, 2607, 2607, 2607, 2607, 2607, 2607, 2607, 2607, + + 2607, 2607, 2607, 2607, 2608, 2608, 0, 2608, 2608, 2608, + 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2608, + 2608, 2608, 2609, 2609, 0, 2609, 2609, 2609, 2609, 2609, + 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, + 2610, 2610, 0, 0, 0, 2610, 0, 0, 0, 0, + 2610, 2610, 2610, 2610, 2611, 0, 2611, 2611, 2611, 2611, + 2612, 2612, 0, 0, 0, 2612, 0, 0, 0, 0, + 2612, 2612, 2612, 2612, 2613, 0, 2613, 2613, 2613, 2613, + 2614, 2614, 0, 2614, 2614, 2614, 2614, 2614, 2614, 2614, + 2614, 2614, 2614, 2614, 2614, 2614, 2614, 2614, 2615, 2615, + + 0, 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, + 2615, 2615, 2615, 2615, 2615, 2615, 2616, 2616, 0, 2616, + 2616, 2616, 2616, 2616, 2616, 2616, 2616, 2616, 2616, 2616, + 2616, 2616, 2616, 2616, 2617, 2617, 0, 0, 0, 2617, + 0, 0, 0, 0, 2617, 2617, 2617, 2617, 2618, 0, + 2618, 2618, 2618, 2618, 2619, 2619, 0, 2619, 2619, 2619, + 2619, 2619, 2619, 2619, 2619, 2619, 2619, 2619, 2619, 2619, + 2619, 2619, 2620, 2620, 0, 2620, 2620, 2620, 2620, 2620, + 2620, 2620, 2620, 2620, 2620, 2620, 2620, 2620, 2620, 2620, + 2621, 2621, 2621, 0, 0, 0, 2621, 0, 0, 0, + + 0, 2621, 2621, 2621, 2621, 2622, 2622, 0, 2622, 2622, + 2622, 2622, 2622, 2622, 2622, 2622, 2622, 2622, 2622, 2622, + 2622, 2622, 2622, 2623, 2623, 0, 2623, 2623, 2623, 2623, + 2623, 2623, 2623, 2623, 2623, 2623, 2623, 2623, 2623, 2623, + 2623, 2624, 2624, 2624, 0, 0, 2624, 0, 0, 0, + 0, 2624, 2624, 2624, 2624, 2625, 2625, 2625, 2625, 2625, + 2625, 2625, 2625, 2625, 2625, 2625, 2625, 2625, 2625, 2625, + 2625, 2625, 2625, 2626, 2626, 0, 0, 2626, 2626, 0, + 0, 0, 0, 2626, 2626, 2626, 2626, 2627, 2627, 0, + 0, 0, 2627, 0, 0, 0, 2627, 2627, 2627, 2627, + + 2627, 2628, 2628, 0, 0, 0, 2628, 0, 0, 0, + 0, 2628, 2628, 2628, 2628, 2629, 2629, 0, 0, 2629, + 2629, 0, 0, 0, 0, 2629, 2629, 2629, 2629, 2630, + 2630, 2630, 0, 0, 0, 2630, 0, 0, 0, 0, + 2630, 2630, 2630, 2630, 2631, 2631, 2631, 0, 0, 2631, + 0, 0, 0, 0, 2631, 2631, 2631, 2631, 2632, 2632, + 0, 0, 0, 2632, 0, 0, 0, 0, 2632, 2632, + 2632, 2632, 2633, 2633, 0, 0, 0, 2633, 0, 0, + 0, 2633, 2633, 2633, 2633, 2633, 2634, 0, 2634, 0, + 2634, 2635, 0, 2635, 0, 2635, 2636, 2636, 0, 2636, + + 2636, 2636, 2636, 2636, 2636, 2636, 2636, 2636, 2636, 2636, + 2636, 2636, 2636, 2636, 2637, 2637, 0, 2637, 2637, 2637, + 2637, 2637, 2637, 2637, 2637, 2637, 2637, 2637, 2637, 2637, + 2637, 2637, 2638, 2638, 0, 2638, 2638, 2638, 2638, 2638, + 2638, 2638, 2638, 2638, 2638, 2638, 2638, 2638, 2638, 2638, + 2639, 2639, 0, 2639, 2639, 2639, 2639, 2639, 2639, 2639, + 2639, 2639, 2639, 2639, 2639, 2639, 2639, 2639, 2640, 2640, + 0, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, + 2640, 2640, 2640, 2640, 2640, 2640, 2641, 2641, 2641, 2641, + 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2641, + + 2641, 2641, 2641, 2641, 2642, 2642, 0, 0, 0, 2642, + 0, 0, 0, 0, 2642, 2642, 2642, 2642, 2643, 2643, + 2643, 2643, 2643, 2643, 2643, 2643, 2643, 2643, 2643, 2643, + 2643, 2643, 2643, 2643, 2643, 2643, 2644, 2644, 0, 2644, + 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, + 2644, 2644, 2644, 2644, 2645, 2645, 0, 2645, 2645, 2645, + 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, + 2645, 2645, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, + 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, + 2647, 2647, 0, 0, 0, 2647, 0, 0, 0, 0, + + 2647, 2647, 2647, 2647, 2648, 2648, 0, 0, 0, 2648, + 0, 0, 0, 0, 2648, 2648, 2648, 2648, 2649, 2649, + 0, 2649, 2649, 2649, 2649, 2649, 2649, 2649, 2649, 2649, + 2649, 2649, 2649, 2649, 2649, 2649, 2650, 2650, 0, 2650, + 2650, 2650, 2650, 2650, 2650, 2650, 2650, 2650, 2650, 2650, + 2650, 2650, 2650, 2650, 2651, 2651, 2651, 2651, 2651, 2651, + 2651, 2651, 2651, 2651, 2651, 2651, 2651, 2651, 2651, 2651, + 2651, 2651, 2652, 2652, 0, 0, 2652, 2652, 0, 0, + 0, 0, 2652, 2652, 2652, 2652, 2653, 2653, 2653, 2653, + 2653, 2653, 2653, 2653, 2653, 2653, 2653, 2653, 2653, 2653, + + 2653, 2653, 2653, 2653, 2654, 2654, 2654, 2654, 2654, 2654, + 2654, 2654, 2654, 2654, 2654, 2654, 2654, 2654, 2654, 2654, + 2654, 2654, 2655, 2655, 0, 2655, 2655, 2655, 2655, 2655, + 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2655, + 2656, 2656, 0, 2656, 2656, 2656, 2656, 2656, 2656, 2656, + 2656, 2656, 2656, 2656, 2656, 2656, 2656, 2656, 2657, 2657, + 0, 0, 2657, 2657, 0, 0, 0, 0, 2657, 2657, + 2657, 2657, 2658, 2658, 0, 0, 0, 2658, 0, 0, + 0, 0, 2658, 2658, 2658, 2658, 2659, 2659, 0, 0, + 2659, 2659, 2659, 0, 0, 0, 2659, 2659, 2659, 2659, + + 2660, 2660, 0, 0, 0, 2660, 0, 0, 0, 0, + 2660, 2660, 2660, 2660, 2661, 0, 2661, 0, 2661, 2662, + 0, 2662, 0, 2662, 2663, 2663, 2663, 2663, 2663, 2663, + 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, + 2663, 2663, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, + 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, + 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2665, + 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2666, 2666, + 0, 2666, 2666, 2666, 2666, 2666, 2666, 2666, 2666, 2666, + 2666, 2666, 2666, 2666, 2666, 2666, 2667, 2667, 0, 2667, + + 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, + 2667, 2667, 2667, 2667, 2668, 2668, 0, 0, 0, 2668, + 0, 0, 0, 0, 2668, 2668, 2668, 2668, 2669, 2669, + 0, 2669, 2669, 2669, 2669, 2669, 2669, 2669, 2669, 2669, + 2669, 2669, 2669, 2669, 2669, 2669, 2670, 2670, 0, 2670, + 2670, 2670, 2670, 2670, 2670, 2670, 2670, 2670, 2670, 2670, + 2670, 2670, 2670, 2670, 2671, 2671, 0, 2671, 2671, 2671, + 2671, 2671, 2671, 2671, 2671, 2671, 2671, 2671, 2671, 2671, + 2671, 2671, 2672, 2672, 0, 0, 0, 2672, 0, 0, + 0, 0, 2672, 2672, 2672, 2672, 2673, 2673, 0, 0, + + 0, 2673, 0, 0, 0, 0, 2673, 2673, 2673, 2673, + 2674, 2674, 0, 2674, 2674, 2674, 2674, 2674, 2674, 2674, + 2674, 2674, 2674, 2674, 2674, 2674, 2674, 2674, 2675, 2675, + 0, 2675, 2675, 2675, 2675, 2675, 2675, 2675, 2675, 2675, + 2675, 2675, 2675, 2675, 2675, 2675, 2676, 2676, 0, 0, + 2676, 2676, 0, 0, 0, 0, 2676, 2676, 2676, 2676, + 2677, 2677, 0, 2677, 2677, 2677, 2677, 2677, 2677, 2677, + 2677, 2677, 2677, 2677, 2677, 2677, 2677, 2677, 2678, 2678, + 0, 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, + 2678, 2678, 2678, 2678, 2678, 2678, 2679, 2679, 0, 0, + + 2679, 2679, 0, 0, 0, 0, 2679, 2679, 2679, 2679, + 2680, 2680, 0, 0, 0, 2680, 0, 0, 0, 0, + 2680, 2680, 2680, 2680, 2681, 2681, 0, 0, 2681, 2681, + 0, 0, 0, 0, 2681, 2681, 2681, 2681, 2682, 2682, + 0, 0, 0, 2682, 0, 0, 0, 0, 2682, 2682, + 2682, 2682, 2683, 0, 2683, 0, 2683, 2684, 0, 2684, + 0, 2684, 2685, 2685, 0, 2685, 2685, 2685, 2685, 2685, + 2685, 2685, 2685, 2685, 2685, 2685, 2685, 2685, 2685, 2685, + 2686, 2686, 0, 2686, 2686, 2686, 2686, 2686, 2686, 2686, + 2686, 2686, 2686, 2686, 2686, 2686, 2686, 2686, 2687, 2687, + + 0, 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2687, + 2687, 2687, 2687, 2687, 2687, 2687, 2688, 2688, 0, 0, + 0, 2688, 0, 0, 0, 0, 2688, 2688, 2688, 2688, + 2689, 2689, 0, 0, 0, 2689, 0, 0, 0, 0, + 2689, 2689, 2689, 2689, 2690, 2690, 2690, 2690, 2690, 2690, + 2690, 2690, 2690, 2690, 2690, 2690, 2690, 2690, 2690, 2690, + 2690, 2690, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, + 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, + 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2692, + 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2693, 2693, + + 2693, 2693, 2693, 2693, 2693, 2693, 2693, 2693, 2693, 2693, + 2693, 2693, 2693, 2693, 2693, 2693, 2694, 2694, 2694, 2694, + 2694, 2694, 2694, 2694, 2694, 2694, 2694, 2694, 2694, 2694, + 2694, 2694, 2694, 2694, 2695, 2695, 2695, 2695, 2695, 2695, + 2695, 2695, 2695, 2695, 2695, 2695, 2695, 2695, 2695, 2695, + 2695, 2695, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, + 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, + 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2697, + 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2698, 2698, + 2698, 2698, 2698, 2698, 2698, 2698, 2698, 2698, 2698, 2698, + + 2698, 2698, 2698, 2698, 2698, 2698, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514 } ; /* The intent behind this definition is that it'll catch @@ -4959,10 +5026,13 @@ do {\ + -#line 4967 "ob_proxy_parser_gbk_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +/* binlog relate SQL */ +#line 5037 "ob_proxy_parser_gbk_lex.c" #define INITIAL 0 #define hint 1 @@ -4989,9 +5059,10 @@ do {\ #define prepare 22 #define insert_all_expr 23 #define set_expr 24 -#define show_topology 25 -#define show_tables 26 -#define proxy_icmd_state 27 +#define show_elastic_id 25 +#define show_topology 26 +#define show_tables 27 +#define proxy_icmd_state 28 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -5233,11 +5304,11 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 386 "ob_proxy_parser_gbk.l" +#line 398 "ob_proxy_parser_gbk.l" /* basic dml stmt: */ -#line 5243 "ob_proxy_parser_gbk_lex.c" +#line 5314 "ob_proxy_parser_gbk_lex.c" yylval = yylval_param; @@ -5294,13 +5365,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2327 ) + if ( yy_current_state >= 2515 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 15602 ); + while ( yy_base[yy_current_state] != 15625 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -5326,86 +5397,86 @@ YY_DECL case 1: YY_RULE_SETUP -#line 389 "ob_proxy_parser_gbk.l" +#line 401 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_SELECT); PUSH_STATE(in_expr); return SELECT; } YY_BREAK case 2: YY_RULE_SETUP -#line 390 "ob_proxy_parser_gbk.l" +#line 402 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_DELETE); PUSH_STATE_IF_NOT_ICMD(in_expr); return DELETE; } YY_BREAK case 3: YY_RULE_SETUP -#line 391 "ob_proxy_parser_gbk.l" +#line 403 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_INSERT); return INSERT; } YY_BREAK case 4: YY_RULE_SETUP -#line 392 "ob_proxy_parser_gbk.l" +#line 404 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_UPDATE); return UPDATE; } YY_BREAK case 5: YY_RULE_SETUP -#line 393 "ob_proxy_parser_gbk.l" +#line 405 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_REPLACE); return REPLACE; } YY_BREAK case 6: YY_RULE_SETUP -#line 394 "ob_proxy_parser_gbk.l" +#line 406 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_MERGE); return MERGE; } YY_BREAK case 7: YY_RULE_SETUP -#line 395 "ob_proxy_parser_gbk.l" +#line 407 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW; } YY_BREAK case 8: YY_RULE_SETUP -#line 396 "ob_proxy_parser_gbk.l" +#line 408 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(XA); } YY_BREAK /* if begin is for starting transaction, will set has_anonymous_block = false in yacc */ case 9: YY_RULE_SETUP -#line 398 "ob_proxy_parser_gbk.l" +#line 410 "ob_proxy_parser_gbk.l" { SET_HAS_ANONYMOUS_BLOCK(); RETURN_NON_RESERVED_KEYWORD(BEGI); } YY_BREAK case 10: YY_RULE_SETUP -#line 399 "ob_proxy_parser_gbk.l" +#line 411 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(START); } YY_BREAK case 11: YY_RULE_SETUP -#line 400 "ob_proxy_parser_gbk.l" +#line 412 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_COMMIT); RETURN_IGNORED_WORD(); } YY_BREAK case 12: YY_RULE_SETUP -#line 401 "ob_proxy_parser_gbk.l" +#line 413 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_ROLLBACK); RETURN_IGNORED_WORD(); } YY_BREAK case 13: YY_RULE_SETUP -#line 402 "ob_proxy_parser_gbk.l" +#line 414 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET); PUSH_STATE_IF_NOT_ICMD(set_expr); return SET; } YY_BREAK case 14: YY_RULE_SETUP -#line 403 "ob_proxy_parser_gbk.l" +#line 415 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_CALL); return CALL; } YY_BREAK case 15: YY_RULE_SETUP -#line 404 "ob_proxy_parser_gbk.l" +#line 416 "ob_proxy_parser_gbk.l" { SET_HAS_ANONYMOUS_BLOCK(); PUSH_STATE(in_anonymous_block); } YY_BREAK case 16: YY_RULE_SETUP -#line 405 "ob_proxy_parser_gbk.l" +#line 417 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = ob_proxy_parser_gbk_yyget_extra(yyscanner); if (OB_NOTNULL(p)) { - if (OBPROXY_T_INSERT == p->cur_stmt_type_) + if (OBPROXY_T_INSERT == p->cur_stmt_type_) PUSH_STATE(insert_all_expr); } return WHEN; } @@ -5413,338 +5484,338 @@ YY_RULE_SETUP /* basic ddl stmt */ case 17: YY_RULE_SETUP -#line 413 "ob_proxy_parser_gbk.l" +#line 425 "ob_proxy_parser_gbk.l" { return CREATE; } YY_BREAK case 18: YY_RULE_SETUP -#line 414 "ob_proxy_parser_gbk.l" +#line 426 "ob_proxy_parser_gbk.l" { return DROP; } YY_BREAK case 19: YY_RULE_SETUP -#line 415 "ob_proxy_parser_gbk.l" +#line 427 "ob_proxy_parser_gbk.l" { return ALTER; } YY_BREAK case 20: YY_RULE_SETUP -#line 416 "ob_proxy_parser_gbk.l" +#line 428 "ob_proxy_parser_gbk.l" { return TRUNCATE; } YY_BREAK case 21: YY_RULE_SETUP -#line 417 "ob_proxy_parser_gbk.l" +#line 429 "ob_proxy_parser_gbk.l" { return RENAME; } YY_BREAK case 22: YY_RULE_SETUP -#line 418 "ob_proxy_parser_gbk.l" +#line 430 "ob_proxy_parser_gbk.l" { return INDEX; } YY_BREAK case 23: YY_RULE_SETUP -#line 419 "ob_proxy_parser_gbk.l" +#line 431 "ob_proxy_parser_gbk.l" { return TABLE; } YY_BREAK case 24: YY_RULE_SETUP -#line 420 "ob_proxy_parser_gbk.l" +#line 432 "ob_proxy_parser_gbk.l" { return STATUS; } YY_BREAK case 25: YY_RULE_SETUP -#line 421 "ob_proxy_parser_gbk.l" +#line 433 "ob_proxy_parser_gbk.l" { return FROM; } YY_BREAK case 26: YY_RULE_SETUP -#line 422 "ob_proxy_parser_gbk.l" +#line 434 "ob_proxy_parser_gbk.l" { return UNIQUE; } YY_BREAK /* ps stmt */ case 27: YY_RULE_SETUP -#line 425 "ob_proxy_parser_gbk.l" +#line 437 "ob_proxy_parser_gbk.l" { return USING; } YY_BREAK case 28: YY_RULE_SETUP -#line 426 "ob_proxy_parser_gbk.l" +#line 438 "ob_proxy_parser_gbk.l" { PUSH_STATE(prepare); return PREPARE; } YY_BREAK case 29: YY_RULE_SETUP -#line 427 "ob_proxy_parser_gbk.l" +#line 439 "ob_proxy_parser_gbk.l" { return EXECUTE; } YY_BREAK case 30: YY_RULE_SETUP -#line 428 "ob_proxy_parser_gbk.l" -{ return DEALLOCATE; } +#line 440 "ob_proxy_parser_gbk.l" +{ return DEALLOCATE; } YY_BREAK /* oracle ddl stmt */ case 31: YY_RULE_SETUP -#line 432 "ob_proxy_parser_gbk.l" +#line 444 "ob_proxy_parser_gbk.l" { return GRANT; } YY_BREAK case 32: YY_RULE_SETUP -#line 433 "ob_proxy_parser_gbk.l" +#line 445 "ob_proxy_parser_gbk.l" { return REVOKE; } YY_BREAK case 33: YY_RULE_SETUP -#line 434 "ob_proxy_parser_gbk.l" +#line 446 "ob_proxy_parser_gbk.l" { return ANALYZE; } YY_BREAK case 34: YY_RULE_SETUP -#line 435 "ob_proxy_parser_gbk.l" +#line 447 "ob_proxy_parser_gbk.l" { return PURGE; } YY_BREAK case 35: YY_RULE_SETUP -#line 436 "ob_proxy_parser_gbk.l" +#line 448 "ob_proxy_parser_gbk.l" { return COMMENT; } YY_BREAK case 36: YY_RULE_SETUP -#line 437 "ob_proxy_parser_gbk.l" +#line 449 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(FLASHBACK); } YY_BREAK case 37: YY_RULE_SETUP -#line 438 "ob_proxy_parser_gbk.l" +#line 450 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(AUDIT); } YY_BREAK case 38: YY_RULE_SETUP -#line 439 "ob_proxy_parser_gbk.l" +#line 451 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NOAUDIT); } YY_BREAK case 39: YY_RULE_SETUP -#line 441 "ob_proxy_parser_gbk.l" +#line 453 "ob_proxy_parser_gbk.l" { return GROUP;} YY_BREAK case 40: YY_RULE_SETUP -#line 442 "ob_proxy_parser_gbk.l" +#line 454 "ob_proxy_parser_gbk.l" { return HAVING;} YY_BREAK case 41: YY_RULE_SETUP -#line 443 "ob_proxy_parser_gbk.l" +#line 455 "ob_proxy_parser_gbk.l" { return ORDER;} YY_BREAK case 42: YY_RULE_SETUP -#line 444 "ob_proxy_parser_gbk.l" +#line 456 "ob_proxy_parser_gbk.l" { return FOR;} YY_BREAK case 43: YY_RULE_SETUP -#line 445 "ob_proxy_parser_gbk.l" +#line 457 "ob_proxy_parser_gbk.l" { return UNION;} YY_BREAK case 44: YY_RULE_SETUP -#line 446 "ob_proxy_parser_gbk.l" +#line 458 "ob_proxy_parser_gbk.l" { return AS; } YY_BREAK case 45: YY_RULE_SETUP -#line 447 "ob_proxy_parser_gbk.l" +#line 459 "ob_proxy_parser_gbk.l" { return WHERE; } YY_BREAK case 46: YY_RULE_SETUP -#line 448 "ob_proxy_parser_gbk.l" +#line 460 "ob_proxy_parser_gbk.l" { return VALUES; } YY_BREAK case 47: YY_RULE_SETUP -#line 449 "ob_proxy_parser_gbk.l" +#line 461 "ob_proxy_parser_gbk.l" { return VALUES; } YY_BREAK case 48: YY_RULE_SETUP -#line 450 "ob_proxy_parser_gbk.l" +#line 462 "ob_proxy_parser_gbk.l" { SET_HAS_EXPLAIN(); return EXPLAIN; } YY_BREAK case 49: YY_RULE_SETUP -#line 451 "ob_proxy_parser_gbk.l" +#line 463 "ob_proxy_parser_gbk.l" { SET_HAS_EXPLAIN(); return DESC; } YY_BREAK case 50: YY_RULE_SETUP -#line 452 "ob_proxy_parser_gbk.l" +#line 464 "ob_proxy_parser_gbk.l" { SET_HAS_EXPLAIN(); return DESCRIBE; } YY_BREAK /*change from non_reserved to reserved according https://dev.mysql.com/doc/refman/5.6/en/keywords.html*/ case 51: YY_RULE_SETUP -#line 454 "ob_proxy_parser_gbk.l" +#line 466 "ob_proxy_parser_gbk.l" { return READ; } YY_BREAK case 52: YY_RULE_SETUP -#line 455 "ob_proxy_parser_gbk.l" +#line 467 "ob_proxy_parser_gbk.l" { return WITH; } YY_BREAK case 53: YY_RULE_SETUP -#line 456 "ob_proxy_parser_gbk.l" +#line 468 "ob_proxy_parser_gbk.l" { return USE; } YY_BREAK case 54: YY_RULE_SETUP -#line 457 "ob_proxy_parser_gbk.l" +#line 469 "ob_proxy_parser_gbk.l" { return LIMIT; } YY_BREAK case 55: YY_RULE_SETUP -#line 458 "ob_proxy_parser_gbk.l" +#line 470 "ob_proxy_parser_gbk.l" { return ALL; } YY_BREAK case 56: YY_RULE_SETUP -#line 459 "ob_proxy_parser_gbk.l" +#line 471 "ob_proxy_parser_gbk.l" { return LIKE; } YY_BREAK case 57: YY_RULE_SETUP -#line 460 "ob_proxy_parser_gbk.l" +#line 472 "ob_proxy_parser_gbk.l" { return PARTITION; } YY_BREAK case 58: YY_RULE_SETUP -#line 461 "ob_proxy_parser_gbk.l" +#line 473 "ob_proxy_parser_gbk.l" { return BINARY; } YY_BREAK case 59: YY_RULE_SETUP -#line 462 "ob_proxy_parser_gbk.l" -{ return GROUP_NAME; } +#line 474 "ob_proxy_parser_gbk.l" +{ RETURN_NON_RESERVED_KEYWORD(GROUP_NAME); } YY_BREAK /* to make bison easy, do not return these reserved keyword in non strict mode */ case 60: YY_RULE_SETUP -#line 465 "ob_proxy_parser_gbk.l" +#line 477 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 61: YY_RULE_SETUP -#line 466 "ob_proxy_parser_gbk.l" +#line 478 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 62: YY_RULE_SETUP -#line 467 "ob_proxy_parser_gbk.l" +#line 479 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 63: YY_RULE_SETUP -#line 468 "ob_proxy_parser_gbk.l" +#line 480 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 64: YY_RULE_SETUP -#line 469 "ob_proxy_parser_gbk.l" +#line 481 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK /* no reserved keyword , don't forget to add these keyword in .y */ /*refer: https://dev.mysql.com/doc/refman/5.6/en/keywords.html*/ case 65: YY_RULE_SETUP -#line 473 "ob_proxy_parser_gbk.l" +#line 485 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(QUICK); } YY_BREAK case 66: YY_RULE_SETUP -#line 474 "ob_proxy_parser_gbk.l" +#line 486 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(COUNT); } YY_BREAK case 67: YY_RULE_SETUP -#line 475 "ob_proxy_parser_gbk.l" +#line 487 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(WARNINGS); } YY_BREAK case 68: YY_RULE_SETUP -#line 476 "ob_proxy_parser_gbk.l" +#line 488 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(ERRORS); } YY_BREAK case 69: YY_RULE_SETUP -#line 477 "ob_proxy_parser_gbk.l" +#line 489 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(TRACE); } YY_BREAK case 70: YY_RULE_SETUP -#line 478 "ob_proxy_parser_gbk.l" +#line 490 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(TRANSACTION); } YY_BREAK case 71: YY_RULE_SETUP -#line 480 "ob_proxy_parser_gbk.l" +#line 492 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(ONLY); } YY_BREAK case 72: YY_RULE_SETUP -#line 482 "ob_proxy_parser_gbk.l" +#line 494 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(CONSISTENT); } YY_BREAK case 73: YY_RULE_SETUP -#line 483 "ob_proxy_parser_gbk.l" +#line 495 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(SNAPSHOT); } YY_BREAK case 74: YY_RULE_SETUP -#line 485 "ob_proxy_parser_gbk.l" +#line 497 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(HELP); } YY_BREAK /*set names*/ case 75: /* rule 75 can match eol */ YY_RULE_SETUP -#line 489 "ob_proxy_parser_gbk.l" +#line 501 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_NAMES); return SET_NAMES; } YY_BREAK /*set charset*/ case 76: /* rule 76 can match eol */ YY_RULE_SETUP -#line 491 "ob_proxy_parser_gbk.l" +#line 503 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_CHARSET); return SET_CHARSET; } YY_BREAK /*set passwd*/ case 77: /* rule 77 can match eol */ YY_RULE_SETUP -#line 493 "ob_proxy_parser_gbk.l" +#line 505 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_PASSWORD); return SET_PASSWORD; } YY_BREAK /*set default*/ case 78: /* rule 78 can match eol */ YY_RULE_SETUP -#line 495 "ob_proxy_parser_gbk.l" +#line 507 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_DEFAULT); return SET_DEFAULT; } YY_BREAK case 79: /* rule 79 can match eol */ YY_RULE_SETUP -#line 497 "ob_proxy_parser_gbk.l" +#line 509 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_OB_READ_CONSISTENCY); return SET_OB_READ_CONSISTENCY; } YY_BREAK case 80: /* rule 80 can match eol */ YY_RULE_SETUP -#line 498 "ob_proxy_parser_gbk.l" +#line 510 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_TX_READ_ONLY); return SET_TX_READ_ONLY; } YY_BREAK /*internal cmd*/ @@ -5752,453 +5823,459 @@ YY_RULE_SETUP case 81: /* rule 81 can match eol */ YY_RULE_SETUP -#line 502 "ob_proxy_parser_gbk.l" +#line 514 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_NET); return SHOW_PROXYNET; } YY_BREAK case 82: YY_RULE_SETUP -#line 503 "ob_proxy_parser_gbk.l" +#line 515 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(THREAD); } YY_BREAK case 83: YY_RULE_SETUP -#line 504 "ob_proxy_parser_gbk.l" +#line 516 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(CONNECTION); } YY_BREAK case 84: YY_RULE_SETUP -#line 506 "ob_proxy_parser_gbk.l" +#line 518 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(OFFSET); } YY_BREAK /*show session*/ case 85: /* rule 85 can match eol */ YY_RULE_SETUP -#line 509 "ob_proxy_parser_gbk.l" +#line 521 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_GLOBAL_SESSION); return SHOW_GLOBALSESSION; } YY_BREAK case 86: /* rule 86 can match eol */ YY_RULE_SETUP -#line 510 "ob_proxy_parser_gbk.l" +#line 522 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SESSION); return SHOW_PROXYSESSION; } YY_BREAK case 87: /* rule 87 can match eol */ YY_RULE_SETUP -#line 511 "ob_proxy_parser_gbk.l" +#line 523 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_PROCESSLIST); return SHOW_PROCESSLIST; } YY_BREAK case 88: YY_RULE_SETUP -#line 512 "ob_proxy_parser_gbk.l" +#line 524 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(ATTRIBUTE); } YY_BREAK case 89: YY_RULE_SETUP -#line 513 "ob_proxy_parser_gbk.l" +#line 525 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(VARIABLES); } YY_BREAK case 90: YY_RULE_SETUP -#line 515 "ob_proxy_parser_gbk.l" +#line 527 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(STAT); } YY_BREAK /*show config*/ case 91: /* rule 91 can match eol */ YY_RULE_SETUP -#line 518 "ob_proxy_parser_gbk.l" +#line 530 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CONFIG); PUSH_STATE(proxy_icmd_state); return SHOW_PROXYCONFIG; } YY_BREAK case 92: YY_RULE_SETUP -#line 520 "ob_proxy_parser_gbk.l" +#line 532 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(DIFF); } YY_BREAK case 93: YY_RULE_SETUP -#line 521 "ob_proxy_parser_gbk.l" +#line 533 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(USER); } YY_BREAK case 94: YY_RULE_SETUP -#line 522 "ob_proxy_parser_gbk.l" +#line 534 "ob_proxy_parser_gbk.l" { POP_STATE(); return LIKE; } YY_BREAK /*show sm*/ case 95: /* rule 95 can match eol */ YY_RULE_SETUP -#line 525 "ob_proxy_parser_gbk.l" +#line 537 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SM); return SHOW_PROXYSM; } YY_BREAK /*show cluster*/ case 96: /* rule 96 can match eol */ YY_RULE_SETUP -#line 528 "ob_proxy_parser_gbk.l" +#line 540 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CLUSTER); return SHOW_PROXYCLUSTER; } YY_BREAK /*show resource*/ case 97: /* rule 97 can match eol */ YY_RULE_SETUP -#line 531 "ob_proxy_parser_gbk.l" +#line 543 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_RESOURCE); return SHOW_PROXYRESOURCE; } YY_BREAK /*show congestion*/ case 98: /* rule 98 can match eol */ YY_RULE_SETUP -#line 534 "ob_proxy_parser_gbk.l" +#line 546 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CONGESTION); return SHOW_PROXYCONGESTION; } YY_BREAK /*show route*/ case 99: /* rule 99 can match eol */ YY_RULE_SETUP -#line 537 "ob_proxy_parser_gbk.l" +#line 549 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_ROUTE); return SHOW_PROXYROUTE; } YY_BREAK case 100: YY_RULE_SETUP -#line 539 "ob_proxy_parser_gbk.l" +#line 551 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(ROUTINE); } YY_BREAK /*show vip*/ case 101: /* rule 101 can match eol */ YY_RULE_SETUP -#line 542 "ob_proxy_parser_gbk.l" +#line 554 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_VIP); return SHOW_PROXYVIP; } YY_BREAK /*show memory*/ case 102: /* rule 102 can match eol */ YY_RULE_SETUP -#line 545 "ob_proxy_parser_gbk.l" +#line 557 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_MEMORY); return SHOW_PROXYMEMORY; } YY_BREAK case 103: YY_RULE_SETUP -#line 546 "ob_proxy_parser_gbk.l" +#line 558 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(OBJPOOL); } YY_BREAK /*show sqlaudit*/ case 104: /* rule 104 can match eol */ YY_RULE_SETUP -#line 549 "ob_proxy_parser_gbk.l" +#line 561 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SQLAUDIT); return SHOW_SQLAUDIT; } YY_BREAK /*show warnlog*/ case 105: /* rule 105 can match eol */ YY_RULE_SETUP -#line 552 "ob_proxy_parser_gbk.l" +#line 564 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_WARNLOG); return SHOW_WARNLOG; } YY_BREAK /*show stat*/ case 106: /* rule 106 can match eol */ YY_RULE_SETUP -#line 555 "ob_proxy_parser_gbk.l" +#line 567 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_STAT); return SHOW_PROXYSTAT; } YY_BREAK case 107: YY_RULE_SETUP -#line 556 "ob_proxy_parser_gbk.l" +#line 568 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(REFRESH); } YY_BREAK /*show trace*/ case 108: /* rule 108 can match eol */ YY_RULE_SETUP -#line 559 "ob_proxy_parser_gbk.l" +#line 571 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_TRACE); return SHOW_PROXYTRACE; } YY_BREAK /*show info*/ case 109: /* rule 109 can match eol */ YY_RULE_SETUP -#line 562 "ob_proxy_parser_gbk.l" +#line 574 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_INFO); return SHOW_PROXYINFO; } YY_BREAK case 110: YY_RULE_SETUP -#line 563 "ob_proxy_parser_gbk.l" +#line 575 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(UPGRADE); } YY_BREAK case 111: YY_RULE_SETUP -#line 564 "ob_proxy_parser_gbk.l" +#line 576 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(IDC); } YY_BREAK case 112: /* rule 112 can match eol */ YY_RULE_SETUP -#line 566 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_topology); return SHOW_TOPOLOGY; } +#line 578 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_elastic_id ); return SHOW_ELASTIC_ID; } YY_BREAK case 113: YY_RULE_SETUP -#line 567 "ob_proxy_parser_gbk.l" +#line 579 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } YY_BREAK case 114: YY_RULE_SETUP -#line 568 "ob_proxy_parser_gbk.l" +#line 580 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return WHERE; } YY_BREAK -case YY_STATE_EOF(show_topology): -#line 569 "ob_proxy_parser_gbk.l" +case YY_STATE_EOF(show_elastic_id): +#line 581 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK case 115: /* rule 115 can match eol */ YY_RULE_SETUP -#line 570 "ob_proxy_parser_gbk.l" +#line 582 "ob_proxy_parser_gbk.l" { } YY_BREAK case 116: YY_RULE_SETUP -#line 571 "ob_proxy_parser_gbk.l" +#line 583 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK case 117: YY_RULE_SETUP -#line 572 "ob_proxy_parser_gbk.l" +#line 584 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK case 118: /* rule 118 can match eol */ YY_RULE_SETUP -#line 574 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } +#line 586 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_TOPOLOGY; } YY_BREAK case 119: /* rule 119 can match eol */ YY_RULE_SETUP -#line 575 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } +#line 588 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } YY_BREAK case 120: /* rule 120 can match eol */ YY_RULE_SETUP -#line 577 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_TABLES; } +#line 589 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } YY_BREAK case 121: /* rule 121 can match eol */ YY_RULE_SETUP -#line 578 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_FULL_TABLES; } +#line 591 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_TABLES; } YY_BREAK case 122: +/* rule 122 can match eol */ YY_RULE_SETUP -#line 580 "ob_proxy_parser_gbk.l" -{ POP_STATE(); PUSH_STATE(INITIAL); return FROM; } +#line 592 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_FULL_TABLES; } YY_BREAK case 123: YY_RULE_SETUP -#line 581 "ob_proxy_parser_gbk.l" +#line 594 "ob_proxy_parser_gbk.l" +{ POP_STATE(); PUSH_STATE(INITIAL); return FROM; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 595 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return LIKE; } YY_BREAK case YY_STATE_EOF(show_tables): -#line 582 "ob_proxy_parser_gbk.l" +#line 596 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 124: -/* rule 124 can match eol */ -YY_RULE_SETUP -#line 583 "ob_proxy_parser_gbk.l" -{ } - YY_BREAK case 125: +/* rule 125 can match eol */ YY_RULE_SETUP -#line 584 "ob_proxy_parser_gbk.l" -{ POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } +#line 597 "ob_proxy_parser_gbk.l" +{ } YY_BREAK case 126: YY_RULE_SETUP -#line 585 "ob_proxy_parser_gbk.l" -{ return ERROR; } +#line 598 "ob_proxy_parser_gbk.l" +{ POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK case 127: -/* rule 127 can match eol */ YY_RULE_SETUP -#line 586 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_COLUMNS; } +#line 599 "ob_proxy_parser_gbk.l" +{ return ERROR; } YY_BREAK case 128: /* rule 128 can match eol */ YY_RULE_SETUP -#line 587 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_INDEX; } +#line 600 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_COLUMNS; } YY_BREAK case 129: /* rule 129 can match eol */ YY_RULE_SETUP -#line 589 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_CREATE_TABLE; } +#line 601 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_INDEX; } YY_BREAK case 130: /* rule 130 can match eol */ YY_RULE_SETUP -#line 590 "ob_proxy_parser_gbk.l" -{ SET_DML_STMT(OBPROXY_T_SELECT); return SELECT_DATABASE; } +#line 603 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_CREATE_TABLE; } YY_BREAK case 131: /* rule 131 can match eol */ YY_RULE_SETUP -#line 591 "ob_proxy_parser_gbk.l" -{ SET_DML_STMT(OBPROXY_T_SELECT_PROXY_VERSION); return SELECT_PROXY_VERSION; } +#line 604 "ob_proxy_parser_gbk.l" +{ SET_DML_STMT(OBPROXY_T_SELECT); return SELECT_DATABASE; } YY_BREAK -/*alter config*/ case 132: /* rule 132 can match eol */ YY_RULE_SETUP -#line 594 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_CONFIG); return ALTER_PROXYCONFIG; } +#line 605 "ob_proxy_parser_gbk.l" +{ SET_DML_STMT(OBPROXY_T_SELECT_PROXY_VERSION); return SELECT_PROXY_VERSION; } YY_BREAK -/*alter resource*/ +/*alter config*/ case 133: /* rule 133 can match eol */ YY_RULE_SETUP -#line 597 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_RESOURCE); return ALTER_PROXYRESOURCE; } +#line 608 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_CONFIG); return ALTER_PROXYCONFIG; } YY_BREAK -/*ping proxy*/ +/*alter resource*/ case 134: /* rule 134 can match eol */ YY_RULE_SETUP -#line 600 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_PING_PROXY); return PING_PROXY; } +#line 611 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_RESOURCE); return ALTER_PROXYRESOURCE; } YY_BREAK -/*kill*/ +/*ping proxy*/ case 135: /* rule 135 can match eol */ YY_RULE_SETUP -#line 603 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_SESSION); return KILL_PROXYSESSION; } +#line 614 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_PING_PROXY); return PING_PROXY; } YY_BREAK +/*kill*/ case 136: /* rule 136 can match eol */ YY_RULE_SETUP -#line 604 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_GLOBAL_SESSION); return KILL_GLOBALSESSION; } +#line 617 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_SESSION); return KILL_PROXYSESSION; } YY_BREAK case 137: +/* rule 137 can match eol */ YY_RULE_SETUP -#line 605 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_MYSQL); return KILL; } +#line 618 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_GLOBAL_SESSION); return KILL_GLOBALSESSION; } YY_BREAK case 138: YY_RULE_SETUP -#line 606 "ob_proxy_parser_gbk.l" -{ RETURN_NON_RESERVED_KEYWORD(QUERY); } +#line 619 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_MYSQL); return KILL; } YY_BREAK -/* obproxy_route_addr */ case 139: -/* rule 139 can match eol */ YY_RULE_SETUP -#line 609 "ob_proxy_parser_gbk.l" -{ return SELECT_OBPROXY_ROUTE_ADDR; } +#line 620 "ob_proxy_parser_gbk.l" +{ RETURN_NON_RESERVED_KEYWORD(QUERY); } YY_BREAK +/* obproxy_route_addr */ case 140: /* rule 140 can match eol */ YY_RULE_SETUP -#line 610 "ob_proxy_parser_gbk.l" +#line 623 "ob_proxy_parser_gbk.l" +{ return SELECT_OBPROXY_ROUTE_ADDR; } + YY_BREAK +case 141: +/* rule 141 can match eol */ +YY_RULE_SETUP +#line 624 "ob_proxy_parser_gbk.l" { return SET_OBPROXY_ROUTE_ADDR; } YY_BREAK /* identifer */ -case 141: +case 142: YY_RULE_SETUP -#line 613 "ob_proxy_parser_gbk.l" +#line 627 "ob_proxy_parser_gbk.l" { SET_FOUND_ROWS(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 142: +case 143: YY_RULE_SETUP -#line 614 "ob_proxy_parser_gbk.l" +#line 628 "ob_proxy_parser_gbk.l" { SET_ROW_COUNT(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 143: +case 144: YY_RULE_SETUP -#line 615 "ob_proxy_parser_gbk.l" +#line 629 "ob_proxy_parser_gbk.l" { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 144: +case 145: YY_RULE_SETUP -#line 616 "ob_proxy_parser_gbk.l" +#line 630 "ob_proxy_parser_gbk.l" { return ','; } YY_BREAK -case 145: +case 146: YY_RULE_SETUP -#line 617 "ob_proxy_parser_gbk.l" +#line 631 "ob_proxy_parser_gbk.l" { RETURN_INT_NUM(); } YY_BREAK -case 146: +case 147: YY_RULE_SETUP -#line 618 "ob_proxy_parser_gbk.l" +#line 632 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 147: +case 148: YY_RULE_SETUP -#line 619 "ob_proxy_parser_gbk.l" +#line 633 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_SINGLE); } YY_BREAK -case 148: +case 149: YY_RULE_SETUP -#line 620 "ob_proxy_parser_gbk.l" +#line 634 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_DOUBLE); } YY_BREAK -case 149: +case 150: YY_RULE_SETUP -#line 621 "ob_proxy_parser_gbk.l" +#line 635 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_BACK); } YY_BREAK -case 150: +case 151: YY_RULE_SETUP -#line 622 "ob_proxy_parser_gbk.l" +#line 636 "ob_proxy_parser_gbk.l" { RETURN_NUMBER_VAL(); } YY_BREAK -case 151: +case 152: YY_RULE_SETUP -#line 623 "ob_proxy_parser_gbk.l" +#line 637 "ob_proxy_parser_gbk.l" { return PLACE_HOLDER; } YY_BREAK -case 152: +case 153: YY_RULE_SETUP -#line 624 "ob_proxy_parser_gbk.l" +#line 638 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 153: +case 154: YY_RULE_SETUP -#line 625 "ob_proxy_parser_gbk.l" +#line 639 "ob_proxy_parser_gbk.l" { RETURN_WITH_CALL_CHECK(yytext[0]); } YY_BREAK -case 154: +case 155: YY_RULE_SETUP -#line 626 "ob_proxy_parser_gbk.l" +#line 640 "ob_proxy_parser_gbk.l" { RETURN_WITH_CALL_CHECK('('); } YY_BREAK -case 155: +case 156: YY_RULE_SETUP -#line 627 "ob_proxy_parser_gbk.l" +#line 641 "ob_proxy_parser_gbk.l" { RETURN_WITH_CALL_CHECK(')'); } YY_BREAK -case 156: -/* rule 156 can match eol */ +case 157: +/* rule 157 can match eol */ YY_RULE_SETUP -#line 628 "ob_proxy_parser_gbk.l" +#line 642 "ob_proxy_parser_gbk.l" { } YY_BREAK /* hint option */ -case 157: -/* rule 157 can match eol */ +case 158: +/* rule 158 can match eol */ YY_RULE_SETUP -#line 631 "ob_proxy_parser_gbk.l" +#line 645 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_expr); PUSH_STATE(hint); @@ -6206,20 +6283,20 @@ YY_RULE_SETUP return SELECT_HINT_BEGIN; } YY_BREAK -case 158: -/* rule 158 can match eol */ +case 159: +/* rule 159 can match eol */ YY_RULE_SETUP -#line 637 "ob_proxy_parser_gbk.l" +#line 651 "ob_proxy_parser_gbk.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_UPDATE); return UPDATE_HINT_BEGIN; } YY_BREAK -case 159: -/* rule 159 can match eol */ +case 160: +/* rule 160 can match eol */ YY_RULE_SETUP -#line 642 "ob_proxy_parser_gbk.l" +#line 656 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_expr); PUSH_STATE(hint); @@ -6227,95 +6304,125 @@ YY_RULE_SETUP return DELETE_HINT_BEGIN; } YY_BREAK -case 160: -/* rule 160 can match eol */ +case 161: +/* rule 161 can match eol */ YY_RULE_SETUP -#line 648 "ob_proxy_parser_gbk.l" +#line 662 "ob_proxy_parser_gbk.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_INSERT); return INSERT_HINT_BEGIN; } YY_BREAK -case 161: -/* rule 161 can match eol */ +case 162: +/* rule 162 can match eol */ YY_RULE_SETUP -#line 653 "ob_proxy_parser_gbk.l" +#line 667 "ob_proxy_parser_gbk.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_REPLACE); return REPLACE_HINT_BEGIN; } YY_BREAK -case 162: -/* rule 162 can match eol */ +case 163: +/* rule 163 can match eol */ YY_RULE_SETUP -#line 658 "ob_proxy_parser_gbk.l" +#line 672 "ob_proxy_parser_gbk.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_MERGE); return MERGE_HINT_BEGIN; } YY_BREAK -case 163: -/* rule 163 can match eol */ +case 164: +/* rule 164 can match eol */ YY_RULE_SETUP -#line 664 "ob_proxy_parser_gbk.l" -{ return AUTOCOMMIT_0; } +#line 678 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_MASTER_STATUS); return SHOW_MASTER_STATUS; } YY_BREAK -case 164: +case 165: +/* rule 165 can match eol */ +YY_RULE_SETUP +#line 679 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINARY_LOGS); return SHOW_BINARY_LOGS; } + YY_BREAK +case 166: +/* rule 166 can match eol */ +YY_RULE_SETUP +#line 680 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_EVENTS); return SHOW_BINLOG_EVENTS; } + YY_BREAK +case 167: +/* rule 167 can match eol */ YY_RULE_SETUP -#line 665 "ob_proxy_parser_gbk.l" +#line 681 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_PURGE_BINARY_LOGS); return PURGE_BINARY_LOGS; } + YY_BREAK +case 168: +/* rule 168 can match eol */ +YY_RULE_SETUP +#line 682 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_RESET_MASTER); return RESET_MASTER; } + YY_BREAK +case 169: +/* rule 169 can match eol */ +YY_RULE_SETUP +#line 683 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT); return SHOW_BINLOG_SERVER_FOR_TENANT; } + YY_BREAK +case 170: +YY_RULE_SETUP +#line 685 "ob_proxy_parser_gbk.l" { return GLOBAL; } YY_BREAK -case 165: +case 171: YY_RULE_SETUP -#line 666 "ob_proxy_parser_gbk.l" +#line 686 "ob_proxy_parser_gbk.l" { return SESSION; } YY_BREAK -case 166: +case 172: YY_RULE_SETUP -#line 667 "ob_proxy_parser_gbk.l" +#line 687 "ob_proxy_parser_gbk.l" { RETURN_INT_NUM(); } YY_BREAK -case 167: +case 173: YY_RULE_SETUP -#line 668 "ob_proxy_parser_gbk.l" +#line 688 "ob_proxy_parser_gbk.l" { return ','; } YY_BREAK -case 168: +case 174: YY_RULE_SETUP -#line 669 "ob_proxy_parser_gbk.l" +#line 689 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 169: +case 175: YY_RULE_SETUP -#line 670 "ob_proxy_parser_gbk.l" +#line 690 "ob_proxy_parser_gbk.l" { RETURN_NUMBER_VAL(); } YY_BREAK -case 170: -/* rule 170 can match eol */ +case 176: +/* rule 176 can match eol */ YY_RULE_SETUP -#line 671 "ob_proxy_parser_gbk.l" +#line 691 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 171: +case 177: YY_RULE_SETUP -#line 672 "ob_proxy_parser_gbk.l" +#line 692 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK case YY_STATE_EOF(set_expr): -#line 673 "ob_proxy_parser_gbk.l" +#line 693 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 172: +case 178: YY_RULE_SETUP -#line 674 "ob_proxy_parser_gbk.l" +#line 694 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK -case 173: +case 179: YY_RULE_SETUP -#line 676 "ob_proxy_parser_gbk.l" +#line 696 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6326,9 +6433,9 @@ YY_RULE_SETUP } } YY_BREAK -case 174: +case 180: YY_RULE_SETUP -#line 686 "ob_proxy_parser_gbk.l" +#line 706 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6339,9 +6446,9 @@ YY_RULE_SETUP } } YY_BREAK -case 175: +case 181: YY_RULE_SETUP -#line 696 "ob_proxy_parser_gbk.l" +#line 716 "ob_proxy_parser_gbk.l" { PUSH_STATE(bt); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6352,90 +6459,90 @@ YY_RULE_SETUP } } YY_BREAK -case 176: +case 182: YY_RULE_SETUP -#line 705 "ob_proxy_parser_gbk.l" +#line 725 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK -case 177: +case 183: YY_RULE_SETUP -#line 707 "ob_proxy_parser_gbk.l" +#line 727 "ob_proxy_parser_gbk.l" { POP_STATE(); RETURN_IGNORED_WORD(); } YY_BREAK -case 178: +case 184: YY_RULE_SETUP -#line 708 "ob_proxy_parser_gbk.l" +#line 728 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 179: +case 185: YY_RULE_SETUP -#line 710 "ob_proxy_parser_gbk.l" +#line 730 "ob_proxy_parser_gbk.l" { return '('; } YY_BREAK -case 180: +case 186: YY_RULE_SETUP -#line 711 "ob_proxy_parser_gbk.l" +#line 731 "ob_proxy_parser_gbk.l" { return ')'; } YY_BREAK -case 181: +case 187: YY_RULE_SETUP -#line 712 "ob_proxy_parser_gbk.l" +#line 732 "ob_proxy_parser_gbk.l" { return QUERY_TIMEOUT; } YY_BREAK -case 182: +case 188: YY_RULE_SETUP -#line 713 "ob_proxy_parser_gbk.l" +#line 733 "ob_proxy_parser_gbk.l" { RETURN_INT_NUM(); } YY_BREAK -case 183: +case 189: YY_RULE_SETUP -#line 714 "ob_proxy_parser_gbk.l" +#line 734 "ob_proxy_parser_gbk.l" { return READ_CONSISTENCY; } YY_BREAK -case 184: +case 190: YY_RULE_SETUP -#line 715 "ob_proxy_parser_gbk.l" +#line 735 "ob_proxy_parser_gbk.l" { return WEAK; } YY_BREAK -case 185: +case 191: YY_RULE_SETUP -#line 716 "ob_proxy_parser_gbk.l" +#line 736 "ob_proxy_parser_gbk.l" { return STRONG; } YY_BREAK -case 186: +case 192: YY_RULE_SETUP -#line 717 "ob_proxy_parser_gbk.l" +#line 737 "ob_proxy_parser_gbk.l" { return FROZEN; } YY_BREAK -case 187: +case 193: YY_RULE_SETUP -#line 718 "ob_proxy_parser_gbk.l" +#line 738 "ob_proxy_parser_gbk.l" { return INDEX; } YY_BREAK -case 188: +case 194: YY_RULE_SETUP -#line 719 "ob_proxy_parser_gbk.l" +#line 739 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 189: +case 195: YY_RULE_SETUP -#line 720 "ob_proxy_parser_gbk.l" +#line 740 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 190: +case 196: YY_RULE_SETUP -#line 721 "ob_proxy_parser_gbk.l" +#line 741 "ob_proxy_parser_gbk.l" { POP_STATE(); return HINT_END; } YY_BREAK -case 191: +case 197: YY_RULE_SETUP -#line 722 "ob_proxy_parser_gbk.l" +#line 742 "ob_proxy_parser_gbk.l" {} YY_BREAK /* comment */ -case 192: +case 198: YY_RULE_SETUP -#line 725 "ob_proxy_parser_gbk.l" +#line 745 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_c_comment); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6450,25 +6557,25 @@ YY_RULE_SETUP } } YY_BREAK -case 193: +case 199: YY_RULE_SETUP -#line 739 "ob_proxy_parser_gbk.l" +#line 759 "ob_proxy_parser_gbk.l" { POP_STATE(); } YY_BREAK -case 194: -/* rule 194 can match eol */ +case 200: +/* rule 200 can match eol */ YY_RULE_SETUP -#line 740 "ob_proxy_parser_gbk.l" +#line 760 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 195: +case 201: YY_RULE_SETUP -#line 741 "ob_proxy_parser_gbk.l" +#line 761 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 196: +case 202: YY_RULE_SETUP -#line 743 "ob_proxy_parser_gbk.l" +#line 763 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6479,15 +6586,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 197: +case 203: YY_RULE_SETUP -#line 753 "ob_proxy_parser_gbk.l" +#line 773 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_old_comment_expr); } YY_BREAK -case 198: -/* rule 198 can match eol */ +case 204: +/* rule 204 can match eol */ YY_RULE_SETUP -#line 754 "ob_proxy_parser_gbk.l" +#line 774 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_old_comment_expr); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6497,10 +6604,10 @@ YY_RULE_SETUP } } YY_BREAK -case 199: -/* rule 199 can match eol */ +case 205: +/* rule 205 can match eol */ YY_RULE_SETUP -#line 763 "ob_proxy_parser_gbk.l" +#line 783 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_old_comment_expr); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6512,9 +6619,9 @@ YY_RULE_SETUP } } YY_BREAK -case 200: +case 206: YY_RULE_SETUP -#line 774 "ob_proxy_parser_gbk.l" +#line 794 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6523,9 +6630,9 @@ YY_RULE_SETUP } } YY_BREAK -case 201: +case 207: YY_RULE_SETUP -#line 782 "ob_proxy_parser_gbk.l" +#line 802 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6536,29 +6643,29 @@ YY_RULE_SETUP } } YY_BREAK -case 202: +case 208: YY_RULE_SETUP -#line 792 "ob_proxy_parser_gbk.l" +#line 812 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 203: +case 209: YY_RULE_SETUP -#line 793 "ob_proxy_parser_gbk.l" +#line 813 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_SINGLE); } YY_BREAK -case 204: +case 210: YY_RULE_SETUP -#line 794 "ob_proxy_parser_gbk.l" +#line 814 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_DOUBLE); } YY_BREAK -case 205: +case 211: YY_RULE_SETUP -#line 795 "ob_proxy_parser_gbk.l" +#line 815 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_BACK); } YY_BREAK -case 206: +case 212: YY_RULE_SETUP -#line 796 "ob_proxy_parser_gbk.l" +#line 816 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6570,160 +6677,171 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 207: +case 213: YY_RULE_SETUP -#line 806 "ob_proxy_parser_gbk.l" +#line 826 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 208: +case 214: YY_RULE_SETUP -#line 808 "ob_proxy_parser_gbk.l" +#line 828 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(ODP_COMMENT); } YY_BREAK -case 209: -/* rule 209 can match eol */ +case 215: +/* rule 215 can match eol */ YY_RULE_SETUP -#line 809 "ob_proxy_parser_gbk.l" +#line 829 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(GROUP_ID); } YY_BREAK -case 210: -/* rule 210 can match eol */ +case 216: +/* rule 216 can match eol */ YY_RULE_SETUP -#line 810 "ob_proxy_parser_gbk.l" +#line 830 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TABLE_ID); } YY_BREAK -case 211: -/* rule 211 can match eol */ +case 217: +/* rule 217 can match eol */ YY_RULE_SETUP -#line 811 "ob_proxy_parser_gbk.l" +#line 831 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TABLE_NAME); } YY_BREAK -case 212: -/* rule 212 can match eol */ +case 218: +/* rule 218 can match eol */ YY_RULE_SETUP -#line 812 "ob_proxy_parser_gbk.l" +#line 832 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(ELASTIC_ID); } YY_BREAK -case 213: -/* rule 213 can match eol */ +case 219: +/* rule 219 can match eol */ YY_RULE_SETUP -#line 813 "ob_proxy_parser_gbk.l" +#line 833 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TESTLOAD); } YY_BREAK -case 214: -/* rule 214 can match eol */ +case 220: +/* rule 220 can match eol */ YY_RULE_SETUP -#line 814 "ob_proxy_parser_gbk.l" +#line 834 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(DISASTER_STATUS); } YY_BREAK -case 215: -/* rule 215 can match eol */ +case 221: +/* rule 221 can match eol */ YY_RULE_SETUP -#line 815 "ob_proxy_parser_gbk.l" +#line 835 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TNT_ID); } YY_BREAK -case 216: -/* rule 216 can match eol */ +case 222: +/* rule 222 can match eol */ YY_RULE_SETUP -#line 816 "ob_proxy_parser_gbk.l" +#line 836 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TRACE_ID); } YY_BREAK -case 217: -/* rule 217 can match eol */ +case 223: +/* rule 223 can match eol */ YY_RULE_SETUP -#line 817 "ob_proxy_parser_gbk.l" +#line 837 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT_NAME_OB_DOT(NAME_OB_DOT); } YY_BREAK -case 218: -/* rule 218 can match eol */ +case 224: +/* rule 224 can match eol */ YY_RULE_SETUP -#line 818 "ob_proxy_parser_gbk.l" +#line 838 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(RPC_ID); } YY_BREAK -case 219: +case 225: +/* rule 225 can match eol */ YY_RULE_SETUP -#line 820 "ob_proxy_parser_gbk.l" +#line 839 "ob_proxy_parser_gbk.l" +{ PUSH_STATE(in_odp_comment_expr); return TARGET_DB_SERVER; } + YY_BREAK +case 226: +YY_RULE_SETUP +#line 841 "ob_proxy_parser_gbk.l" { return GROUP_ID; } YY_BREAK -case 220: +case 227: YY_RULE_SETUP -#line 821 "ob_proxy_parser_gbk.l" +#line 842 "ob_proxy_parser_gbk.l" { return TABLE_ID; } YY_BREAK -case 221: +case 228: YY_RULE_SETUP -#line 822 "ob_proxy_parser_gbk.l" +#line 843 "ob_proxy_parser_gbk.l" { return TABLE_NAME; } YY_BREAK -case 222: +case 229: YY_RULE_SETUP -#line 823 "ob_proxy_parser_gbk.l" +#line 844 "ob_proxy_parser_gbk.l" { return ELASTIC_ID; } YY_BREAK -case 223: +case 230: YY_RULE_SETUP -#line 824 "ob_proxy_parser_gbk.l" +#line 845 "ob_proxy_parser_gbk.l" { return TESTLOAD; } YY_BREAK -case 224: +case 231: YY_RULE_SETUP -#line 825 "ob_proxy_parser_gbk.l" +#line 846 "ob_proxy_parser_gbk.l" { return DISASTER_STATUS; } YY_BREAK -case 225: +case 232: YY_RULE_SETUP -#line 826 "ob_proxy_parser_gbk.l" +#line 847 "ob_proxy_parser_gbk.l" { return TNT_ID; } YY_BREAK -case 226: +case 233: YY_RULE_SETUP -#line 827 "ob_proxy_parser_gbk.l" +#line 848 "ob_proxy_parser_gbk.l" { return TRACE_ID; } YY_BREAK -case 227: +case 234: YY_RULE_SETUP -#line 828 "ob_proxy_parser_gbk.l" +#line 849 "ob_proxy_parser_gbk.l" { return RPC_ID; } YY_BREAK -case 228: +case 235: YY_RULE_SETUP -#line 829 "ob_proxy_parser_gbk.l" +#line 850 "ob_proxy_parser_gbk.l" +{ return TARGET_DB_SERVER; } + YY_BREAK +case 236: +YY_RULE_SETUP +#line 851 "ob_proxy_parser_gbk.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 229: +case 237: YY_RULE_SETUP -#line 830 "ob_proxy_parser_gbk.l" +#line 852 "ob_proxy_parser_gbk.l" { return ','; } YY_BREAK -case 230: +case 238: YY_RULE_SETUP -#line 831 "ob_proxy_parser_gbk.l" +#line 853 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 231: +case 239: YY_RULE_SETUP -#line 832 "ob_proxy_parser_gbk.l" +#line 854 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_value_expr); return yytext[0]; } YY_BREAK -case 232: +case 240: YY_RULE_SETUP -#line 833 "ob_proxy_parser_gbk.l" +#line 855 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 233: -/* rule 233 can match eol */ +case 241: +/* rule 241 can match eol */ YY_RULE_SETUP -#line 834 "ob_proxy_parser_gbk.l" +#line 856 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 234: +case 242: YY_RULE_SETUP -#line 835 "ob_proxy_parser_gbk.l" +#line 857 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK -case 235: +case 243: YY_RULE_SETUP -#line 836 "ob_proxy_parser_gbk.l" +#line 858 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6735,22 +6853,22 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 236: +case 244: YY_RULE_SETUP -#line 847 "ob_proxy_parser_gbk.l" +#line 869 "ob_proxy_parser_gbk.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 237: +case 245: YY_RULE_SETUP -#line 848 "ob_proxy_parser_gbk.l" +#line 870 "ob_proxy_parser_gbk.l" { POP_STATE(); return ','; } YY_BREAK -case 238: +case 246: YY_RULE_SETUP -#line 852 "ob_proxy_parser_gbk.l" +#line 874 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6763,15 +6881,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 239: -/* rule 239 can match eol */ +case 247: +/* rule 247 can match eol */ YY_RULE_SETUP -#line 863 "ob_proxy_parser_gbk.l" +#line 885 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 240: +case 248: YY_RULE_SETUP -#line 864 "ob_proxy_parser_gbk.l" +#line 886 "ob_proxy_parser_gbk.l" { do { PUSH_STATE(in_odp_comment_value_expr_calc) @@ -6784,10 +6902,10 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 241: -/* rule 241 can match eol */ +case 249: +/* rule 249 can match eol */ YY_RULE_SETUP -#line 876 "ob_proxy_parser_gbk.l" +#line 898 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6800,9 +6918,9 @@ YY_RULE_SETUP } } YY_BREAK -case 242: +case 250: YY_RULE_SETUP -#line 888 "ob_proxy_parser_gbk.l" +#line 910 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6810,90 +6928,95 @@ YY_RULE_SETUP } } YY_BREAK -case 243: +case 251: YY_RULE_SETUP -#line 895 "ob_proxy_parser_gbk.l" +#line 917 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_dbp_comment_expr); RETURN_SHARD_COMMENT(DBP_COMMENT); } YY_BREAK -case 244: +case 252: YY_RULE_SETUP -#line 896 "ob_proxy_parser_gbk.l" +#line 918 "ob_proxy_parser_gbk.l" { return ROUTE_TAG; } YY_BREAK -case 245: +case 253: YY_RULE_SETUP -#line 897 "ob_proxy_parser_gbk.l" +#line 919 "ob_proxy_parser_gbk.l" { return SYS_TAG; } YY_BREAK -case 246: +case 254: YY_RULE_SETUP -#line 898 "ob_proxy_parser_gbk.l" +#line 920 "ob_proxy_parser_gbk.l" { return SCAN_ALL; } YY_BREAK -case 247: +case 255: +YY_RULE_SETUP +#line 921 "ob_proxy_parser_gbk.l" +{ return STICKY_SESSION; } + YY_BREAK +case 256: YY_RULE_SETUP -#line 899 "ob_proxy_parser_gbk.l" +#line 922 "ob_proxy_parser_gbk.l" { return SHARD_KEY; } YY_BREAK -case 248: +case 257: YY_RULE_SETUP -#line 900 "ob_proxy_parser_gbk.l" +#line 923 "ob_proxy_parser_gbk.l" { return TABLE_NAME;} YY_BREAK -case 249: +case 258: YY_RULE_SETUP -#line 901 "ob_proxy_parser_gbk.l" +#line 924 "ob_proxy_parser_gbk.l" { return PARALL; } YY_BREAK -case 250: +case 259: YY_RULE_SETUP -#line 902 "ob_proxy_parser_gbk.l" +#line 925 "ob_proxy_parser_gbk.l" { return GROUP_ID; } YY_BREAK -case 251: +case 260: YY_RULE_SETUP -#line 903 "ob_proxy_parser_gbk.l" +#line 926 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_dbp_comment_trace_expr); return TRACE; } YY_BREAK -case 252: +case 261: YY_RULE_SETUP -#line 904 "ob_proxy_parser_gbk.l" +#line 927 "ob_proxy_parser_gbk.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 253: +case 262: YY_RULE_SETUP -#line 905 "ob_proxy_parser_gbk.l" +#line 928 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 254: +case 263: YY_RULE_SETUP -#line 906 "ob_proxy_parser_gbk.l" +#line 929 "ob_proxy_parser_gbk.l" { return '('; } YY_BREAK -case 255: +case 264: YY_RULE_SETUP -#line 907 "ob_proxy_parser_gbk.l" +#line 930 "ob_proxy_parser_gbk.l" { return ')'; } YY_BREAK -case 256: +case 265: YY_RULE_SETUP -#line 908 "ob_proxy_parser_gbk.l" +#line 931 "ob_proxy_parser_gbk.l" { return ','; } YY_BREAK -case 257: -/* rule 257 can match eol */ +case 266: +/* rule 266 can match eol */ YY_RULE_SETUP -#line 909 "ob_proxy_parser_gbk.l" +#line 932 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 258: +case 267: YY_RULE_SETUP -#line 910 "ob_proxy_parser_gbk.l" +#line 933 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 259: +case 268: YY_RULE_SETUP -#line 912 "ob_proxy_parser_gbk.l" +#line 935 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6905,39 +7028,39 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 260: +case 269: YY_RULE_SETUP -#line 922 "ob_proxy_parser_gbk.l" +#line 945 "ob_proxy_parser_gbk.l" {return yytext[0];} YY_BREAK -case 261: +case 270: YY_RULE_SETUP -#line 923 "ob_proxy_parser_gbk.l" +#line 946 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_dbp_comment_trace_value_expr); return '('; } YY_BREAK -case 262: -/* rule 262 can match eol */ +case 271: +/* rule 271 can match eol */ YY_RULE_SETUP -#line 924 "ob_proxy_parser_gbk.l" +#line 947 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 263: +case 272: YY_RULE_SETUP -#line 926 "ob_proxy_parser_gbk.l" +#line 949 "ob_proxy_parser_gbk.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 264: +case 273: YY_RULE_SETUP -#line 927 "ob_proxy_parser_gbk.l" +#line 950 "ob_proxy_parser_gbk.l" { POP_STATE(); POP_STATE(); return ')'; } YY_BREAK -case 265: +case 274: YY_RULE_SETUP -#line 932 "ob_proxy_parser_gbk.l" +#line 955 "ob_proxy_parser_gbk.l" { do { PUSH_STATE(in_dbp_comment_trace_value_expr_calc) @@ -6951,9 +7074,9 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 266: +case 275: YY_RULE_SETUP -#line 944 "ob_proxy_parser_gbk.l" +#line 967 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6967,15 +7090,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 267: -/* rule 267 can match eol */ +case 276: +/* rule 276 can match eol */ YY_RULE_SETUP -#line 956 "ob_proxy_parser_gbk.l" +#line 979 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 268: +case 277: YY_RULE_SETUP -#line 957 "ob_proxy_parser_gbk.l" +#line 980 "ob_proxy_parser_gbk.l" { do { PUSH_STATE(in_dbp_comment_trace_value_expr_calc) @@ -6988,10 +7111,10 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 269: -/* rule 269 can match eol */ +case 278: +/* rule 278 can match eol */ YY_RULE_SETUP -#line 969 "ob_proxy_parser_gbk.l" +#line 992 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7004,9 +7127,9 @@ YY_RULE_SETUP } } YY_BREAK -case 270: +case 279: YY_RULE_SETUP -#line 981 "ob_proxy_parser_gbk.l" +#line 1004 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7015,9 +7138,9 @@ YY_RULE_SETUP } YY_BREAK /* quote */ -case 271: +case 280: YY_RULE_SETUP -#line 989 "ob_proxy_parser_gbk.l" +#line 1012 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7028,10 +7151,10 @@ YY_RULE_SETUP } } YY_BREAK -case 272: -/* rule 272 can match eol */ +case 281: +/* rule 281 can match eol */ YY_RULE_SETUP -#line 999 "ob_proxy_parser_gbk.l" +#line 1022 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7039,9 +7162,9 @@ YY_RULE_SETUP } } YY_BREAK -case 273: +case 282: YY_RULE_SETUP -#line 1006 "ob_proxy_parser_gbk.l" +#line 1029 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7059,32 +7182,32 @@ YY_RULE_SETUP } } YY_BREAK -case 274: +case 283: YY_RULE_SETUP -#line 1023 "ob_proxy_parser_gbk.l" +#line 1046 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 275: -/* rule 275 can match eol */ +case 284: +/* rule 284 can match eol */ YY_RULE_SETUP -#line 1024 "ob_proxy_parser_gbk.l" +#line 1047 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 276: -/* rule 276 can match eol */ +case 285: +/* rule 285 can match eol */ YY_RULE_SETUP -#line 1025 "ob_proxy_parser_gbk.l" +#line 1048 "ob_proxy_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 1026 "ob_proxy_parser_gbk.l" +#line 1049 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK /* comment sq return name_str */ -case 277: -/* rule 277 can match eol */ +case 286: +/* rule 286 can match eol */ YY_RULE_SETUP -#line 1029 "ob_proxy_parser_gbk.l" +#line 1052 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7092,9 +7215,9 @@ YY_RULE_SETUP } } YY_BREAK -case 278: +case 287: YY_RULE_SETUP -#line 1036 "ob_proxy_parser_gbk.l" +#line 1059 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7106,31 +7229,31 @@ YY_RULE_SETUP } } YY_BREAK -case 279: +case 288: YY_RULE_SETUP -#line 1047 "ob_proxy_parser_gbk.l" +#line 1070 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 280: -/* rule 280 can match eol */ +case 289: +/* rule 289 can match eol */ YY_RULE_SETUP -#line 1048 "ob_proxy_parser_gbk.l" +#line 1071 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 281: -/* rule 281 can match eol */ +case 290: +/* rule 290 can match eol */ YY_RULE_SETUP -#line 1049 "ob_proxy_parser_gbk.l" +#line 1072 "ob_proxy_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(comment_sq): -#line 1050 "ob_proxy_parser_gbk.l" +#line 1073 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK /* dquote */ -case 282: +case 291: YY_RULE_SETUP -#line 1053 "ob_proxy_parser_gbk.l" +#line 1076 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7141,10 +7264,10 @@ YY_RULE_SETUP } } YY_BREAK -case 283: -/* rule 283 can match eol */ +case 292: +/* rule 292 can match eol */ YY_RULE_SETUP -#line 1063 "ob_proxy_parser_gbk.l" +#line 1086 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7152,9 +7275,9 @@ YY_RULE_SETUP } } YY_BREAK -case 284: +case 293: YY_RULE_SETUP -#line 1070 "ob_proxy_parser_gbk.l" +#line 1093 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7172,31 +7295,31 @@ YY_RULE_SETUP } } YY_BREAK -case 285: +case 294: YY_RULE_SETUP -#line 1087 "ob_proxy_parser_gbk.l" +#line 1110 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 286: -/* rule 286 can match eol */ +case 295: +/* rule 295 can match eol */ YY_RULE_SETUP -#line 1088 "ob_proxy_parser_gbk.l" +#line 1111 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 287: -/* rule 287 can match eol */ +case 296: +/* rule 296 can match eol */ YY_RULE_SETUP -#line 1089 "ob_proxy_parser_gbk.l" +#line 1112 "ob_proxy_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 1090 "ob_proxy_parser_gbk.l" +#line 1113 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK /* backtick */ -case 288: +case 297: YY_RULE_SETUP -#line 1094 "ob_proxy_parser_gbk.l" +#line 1117 "ob_proxy_parser_gbk.l" { PUSH_STATE(bt); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7207,9 +7330,9 @@ YY_RULE_SETUP } } YY_BREAK -case 289: +case 298: YY_RULE_SETUP -#line 1104 "ob_proxy_parser_gbk.l" +#line 1127 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -7217,10 +7340,10 @@ YY_RULE_SETUP } } YY_BREAK -case 290: -/* rule 290 can match eol */ +case 299: +/* rule 299 can match eol */ YY_RULE_SETUP -#line 1111 "ob_proxy_parser_gbk.l" +#line 1134 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -7229,9 +7352,9 @@ YY_RULE_SETUP } } YY_BREAK -case 291: +case 300: YY_RULE_SETUP -#line 1119 "ob_proxy_parser_gbk.l" +#line 1142 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7245,248 +7368,242 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 1131 "ob_proxy_parser_gbk.l" +#line 1154 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK -case 292: +case 301: YY_RULE_SETUP -#line 1135 "ob_proxy_parser_gbk.l" +#line 1158 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 293: -/* rule 293 can match eol */ +case 302: +/* rule 302 can match eol */ YY_RULE_SETUP -#line 1136 "ob_proxy_parser_gbk.l" +#line 1159 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 294: +case 303: YY_RULE_SETUP -#line 1137 "ob_proxy_parser_gbk.l" +#line 1160 "ob_proxy_parser_gbk.l" { POP_STATE(); RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(bt_in_expr): -#line 1138 "ob_proxy_parser_gbk.l" +#line 1161 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK /* some useful keyword */ -case 295: -/* rule 295 can match eol */ +case 304: +/* rule 304 can match eol */ YY_RULE_SETUP -#line 1141 "ob_proxy_parser_gbk.l" +#line 1164 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD_FOR_DUAL(); } YY_BREAK -case 296: +case 305: YY_RULE_SETUP -#line 1142 "ob_proxy_parser_gbk.l" +#line 1165 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } YY_BREAK -case 297: +case 306: YY_RULE_SETUP -#line 1143 "ob_proxy_parser_gbk.l" +#line 1166 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 298: +case 307: YY_RULE_SETUP -#line 1144 "ob_proxy_parser_gbk.l" +#line 1167 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); } YY_BREAK -case 299: +case 308: YY_RULE_SETUP -#line 1145 "ob_proxy_parser_gbk.l" +#line 1168 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); } YY_BREAK -case 300: +case 309: YY_RULE_SETUP -#line 1146 "ob_proxy_parser_gbk.l" +#line 1169 "ob_proxy_parser_gbk.l" { PUSH_STATE(bt_in_expr); } YY_BREAK -case 301: +case 310: YY_RULE_SETUP -#line 1147 "ob_proxy_parser_gbk.l" +#line 1170 "ob_proxy_parser_gbk.l" { SET_FOUND_ROWS(); RETURN_IGNORED_WORD(); } YY_BREAK -case 302: +case 311: YY_RULE_SETUP -#line 1148 "ob_proxy_parser_gbk.l" +#line 1171 "ob_proxy_parser_gbk.l" { SET_ROW_COUNT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 303: +case 312: YY_RULE_SETUP -#line 1149 "ob_proxy_parser_gbk.l" +#line 1172 "ob_proxy_parser_gbk.l" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } YY_BREAK -case 304: +case 313: YY_RULE_SETUP -#line 1150 "ob_proxy_parser_gbk.l" +#line 1173 "ob_proxy_parser_gbk.l" { SET_GLOBAL_SET_STMT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 305: -/* rule 305 can match eol */ +case 314: +/* rule 314 can match eol */ YY_RULE_SETUP -#line 1151 "ob_proxy_parser_gbk.l" +#line 1174 "ob_proxy_parser_gbk.l" { RETURN_COL_NAME(TX_READ_ONLY); } YY_BREAK -case 306: -/* rule 306 can match eol */ -YY_RULE_SETUP -#line 1152 "ob_proxy_parser_gbk.l" -{ return AUTOCOMMIT_0; } - YY_BREAK -case 307: +case 315: YY_RULE_SETUP -#line 1153 "ob_proxy_parser_gbk.l" +#line 1175 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(in_expr): -#line 1154 "ob_proxy_parser_gbk.l" +#line 1176 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 308: -/* rule 308 can match eol */ +case 316: +/* rule 316 can match eol */ YY_RULE_SETUP -#line 1155 "ob_proxy_parser_gbk.l" +#line 1177 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 309: +case 317: YY_RULE_SETUP -#line 1156 "ob_proxy_parser_gbk.l" +#line 1178 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK -case 310: +case 318: YY_RULE_SETUP -#line 1157 "ob_proxy_parser_gbk.l" +#line 1179 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 311: +case 319: YY_RULE_SETUP -#line 1159 "ob_proxy_parser_gbk.l" +#line 1181 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_expr); return SELECT; } YY_BREAK -case 312: +case 320: YY_RULE_SETUP -#line 1160 "ob_proxy_parser_gbk.l" +#line 1182 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 313: +case 321: YY_RULE_SETUP -#line 1161 "ob_proxy_parser_gbk.l" +#line 1183 "ob_proxy_parser_gbk.l" { POP_STATE(); return ')'; } YY_BREAK -case 314: +case 322: YY_RULE_SETUP -#line 1162 "ob_proxy_parser_gbk.l" +#line 1184 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); } YY_BREAK -case 315: +case 323: YY_RULE_SETUP -#line 1163 "ob_proxy_parser_gbk.l" +#line 1185 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); } YY_BREAK case YY_STATE_EOF(in_subquery): -#line 1164 "ob_proxy_parser_gbk.l" +#line 1186 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 316: -/* rule 316 can match eol */ +case 324: +/* rule 324 can match eol */ YY_RULE_SETUP -#line 1165 "ob_proxy_parser_gbk.l" +#line 1187 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 317: +case 325: YY_RULE_SETUP -#line 1166 "ob_proxy_parser_gbk.l" +#line 1188 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_no_select_query); RETURN_IGNORED_WORD(); } YY_BREAK -case 318: +case 326: YY_RULE_SETUP -#line 1168 "ob_proxy_parser_gbk.l" +#line 1190 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 319: +case 327: YY_RULE_SETUP -#line 1169 "ob_proxy_parser_gbk.l" +#line 1191 "ob_proxy_parser_gbk.l" { POP_STATE(); POP_STATE(); return ')'; } YY_BREAK -case 320: +case 328: YY_RULE_SETUP -#line 1170 "ob_proxy_parser_gbk.l" +#line 1192 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); } YY_BREAK -case 321: +case 329: YY_RULE_SETUP -#line 1171 "ob_proxy_parser_gbk.l" +#line 1193 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); } YY_BREAK -case 322: +case 330: YY_RULE_SETUP -#line 1172 "ob_proxy_parser_gbk.l" +#line 1194 "ob_proxy_parser_gbk.l" { SET_FOUND_ROWS(); RETURN_IGNORED_WORD(); } YY_BREAK -case 323: +case 331: YY_RULE_SETUP -#line 1173 "ob_proxy_parser_gbk.l" +#line 1195 "ob_proxy_parser_gbk.l" { SET_ROW_COUNT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 324: +case 332: YY_RULE_SETUP -#line 1174 "ob_proxy_parser_gbk.l" +#line 1196 "ob_proxy_parser_gbk.l" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } YY_BREAK -case 325: +case 333: YY_RULE_SETUP -#line 1175 "ob_proxy_parser_gbk.l" +#line 1197 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(in_no_select_query): -#line 1176 "ob_proxy_parser_gbk.l" +#line 1198 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 326: -/* rule 326 can match eol */ +case 334: +/* rule 334 can match eol */ YY_RULE_SETUP -#line 1177 "ob_proxy_parser_gbk.l" +#line 1199 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 327: +case 335: YY_RULE_SETUP -#line 1178 "ob_proxy_parser_gbk.l" +#line 1200 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 328: +case 336: YY_RULE_SETUP -#line 1180 "ob_proxy_parser_gbk.l" +#line 1202 "ob_proxy_parser_gbk.l" { return FROM; } YY_BREAK -case 329: +case 337: YY_RULE_SETUP -#line 1181 "ob_proxy_parser_gbk.l" +#line 1203 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 330: +case 338: YY_RULE_SETUP -#line 1182 "ob_proxy_parser_gbk.l" +#line 1204 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 331: +case 339: YY_RULE_SETUP -#line 1183 "ob_proxy_parser_gbk.l" +#line 1205 "ob_proxy_parser_gbk.l" { POP_STATE(); } YY_BREAK -case 332: +case 340: YY_RULE_SETUP -#line 1184 "ob_proxy_parser_gbk.l" +#line 1206 "ob_proxy_parser_gbk.l" { POP_STATE(); } YY_BREAK -case 333: +case 341: YY_RULE_SETUP -#line 1186 "ob_proxy_parser_gbk.l" -{ POP_STATE(); return BEGI;} +#line 1208 "ob_proxy_parser_gbk.l" +{ POP_STATE(); RETURN_NON_RESERVED_KEYWORD(BEGI);} YY_BREAK -case 334: +case 342: YY_RULE_SETUP -#line 1187 "ob_proxy_parser_gbk.l" +#line 1209 "ob_proxy_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(INITIAL): @@ -7505,21 +7622,22 @@ case YY_STATE_EOF(in_dbp_comment_trace_value_expr_calc): case YY_STATE_EOF(in_anonymous_block): case YY_STATE_EOF(prepare): case YY_STATE_EOF(insert_all_expr): +case YY_STATE_EOF(show_topology): case YY_STATE_EOF(proxy_icmd_state): -#line 1189 "ob_proxy_parser_gbk.l" +#line 1211 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 335: +case 343: YY_RULE_SETUP -#line 1190 "ob_proxy_parser_gbk.l" +#line 1212 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 336: +case 344: YY_RULE_SETUP -#line 1191 "ob_proxy_parser_gbk.l" +#line 1213 "ob_proxy_parser_gbk.l" ECHO; YY_BREAK -#line 7525 "ob_proxy_parser_gbk_lex.c" +#line 7643 "ob_proxy_parser_gbk_lex.c" case YY_END_OF_BUFFER: { @@ -7811,7 +7929,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2327 ) + if ( yy_current_state >= 2515 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -7840,11 +7958,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2327 ) + if ( yy_current_state >= 2515 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 2326); + yy_is_jam = (yy_current_state == 2514); return yy_is_jam ? 0 : yy_current_state; } @@ -8669,7 +8787,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 1191 "ob_proxy_parser_gbk.l" +#line 1213 "ob_proxy_parser_gbk.l" inline void *ob_proxy_parser_gbk_yyalloc(size_t bytes,void *yyscanner) @@ -8879,96 +8997,104 @@ extern int ob_proxy_parser_gbk_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.h b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.h index 13dc516c..2f58de10 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.h @@ -244,9 +244,10 @@ void ob_proxy_parser_gbk_yyfree (void * ,yyscan_t yyscanner ); #define prepare 22 #define insert_all_expr 23 #define set_expr 24 -#define show_topology 25 -#define show_tables 26 -#define proxy_icmd_state 27 +#define show_elastic_id 25 +#define show_topology 26 +#define show_tables 27 +#define proxy_icmd_state 28 #endif @@ -364,9 +365,9 @@ extern int ob_proxy_parser_gbk_yylex \ #undef YY_DECL #endif -#line 1191 "ob_proxy_parser_gbk.l" +#line 1213 "ob_proxy_parser_gbk.l" -#line 371 "ob_proxy_parser_gbk_lex.h" +#line 372 "ob_proxy_parser_gbk_lex.h" #undef ob_proxy_parser_gbk_yyIN_HEADER #endif /* ob_proxy_parser_gbk_yyHEADER_H */ diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.c b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.c index ad65b907..4dec0fda 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.c +++ b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.c @@ -112,9 +112,6 @@ static inline void handle_stmt_end(ObProxyParseResult* result) case OBPROXY_T_SELECT_TX_RO: result->stmt_type_ = OBPROXY_T_SELECT; break; - case OBPROXY_T_SET_AC_0: - result->stmt_type_ = OBPROXY_T_OTHERS; - break; case OBPROXY_T_BEGIN: result->stmt_type_ = OBPROXY_T_OTHERS; break; @@ -133,7 +130,7 @@ static inline void handle_stmt_end(ObProxyParseResult* result) } } else { result->stmt_type_ = result->cur_stmt_type_; - } + } if (OBPROXY_T_TEXT_PS_PREPARE == result->text_ps_inner_stmt_type_) { ObProxyBasicStmtType tmp_type = result->cur_stmt_type_; @@ -459,96 +456,104 @@ extern int ob_proxy_parser_gbk_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif @@ -811,22 +816,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 322 +#define YYFINAL 314 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1614 +#define YYLAST 1384 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 182 +#define YYNTOKENS 190 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 137 +#define YYNNTS 138 /* YYNRULES -- Number of rules. */ -#define YYNRULES 442 +#define YYNRULES 435 /* YYNRULES -- Number of states. */ -#define YYNSTATES 713 +#define YYNSTATES 715 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 425 +#define YYMAXUTOK 433 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -837,16 +842,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 180, 2, 2, 2, 2, - 175, 176, 181, 2, 173, 2, 177, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 171, - 2, 174, 2, 2, 172, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 188, 2, 2, 2, 2, + 183, 184, 189, 2, 181, 2, 185, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 179, + 2, 182, 2, 2, 180, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 178, 2, 179, 2, 2, 2, 2, + 2, 2, 2, 186, 2, 187, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -876,7 +881,8 @@ static const yytype_uint8 yytranslate[] = 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170 + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178 }; #if YYDEBUG @@ -887,234 +893,231 @@ static const yytype_uint16 yyprhs[] = 0, 0, 3, 5, 7, 9, 12, 15, 18, 22, 24, 27, 31, 33, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, - 68, 70, 72, 74, 76, 78, 80, 82, 84, 88, - 91, 94, 97, 100, 103, 106, 108, 110, 113, 115, - 117, 119, 121, 122, 124, 126, 129, 131, 133, 135, - 137, 139, 141, 143, 145, 148, 153, 156, 158, 160, - 164, 167, 171, 174, 177, 181, 185, 187, 189, 191, - 193, 195, 197, 199, 201, 203, 206, 208, 210, 212, - 213, 216, 217, 219, 222, 228, 232, 234, 238, 241, - 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, - 265, 267, 269, 271, 273, 276, 279, 283, 289, 293, - 299, 300, 303, 304, 307, 311, 315, 321, 323, 325, - 329, 335, 343, 345, 349, 351, 353, 355, 357, 359, - 361, 367, 369, 373, 379, 380, 382, 386, 388, 390, - 392, 395, 399, 401, 403, 406, 408, 411, 415, 419, - 421, 423, 425, 426, 430, 432, 436, 440, 446, 449, - 452, 457, 460, 463, 467, 469, 474, 481, 486, 492, - 499, 504, 508, 510, 512, 514, 516, 519, 523, 529, - 536, 543, 550, 557, 564, 572, 579, 586, 593, 600, - 609, 618, 619, 622, 625, 628, 630, 634, 636, 641, - 646, 650, 657, 662, 667, 674, 678, 680, 684, 685, - 689, 693, 697, 701, 705, 709, 713, 717, 721, 725, - 731, 735, 736, 738, 739, 741, 743, 745, 747, 750, - 752, 755, 757, 760, 763, 767, 768, 770, 773, 775, - 778, 780, 783, 786, 787, 790, 795, 797, 802, 808, - 810, 815, 820, 826, 827, 829, 831, 833, 834, 836, - 840, 844, 847, 849, 851, 853, 855, 857, 859, 861, - 863, 865, 867, 869, 871, 873, 875, 877, 879, 881, - 883, 885, 887, 889, 891, 893, 894, 897, 902, 907, - 908, 911, 912, 915, 918, 920, 922, 926, 929, 933, - 938, 940, 943, 944, 947, 951, 954, 957, 960, 961, - 964, 968, 971, 975, 978, 982, 986, 991, 993, 996, - 999, 1003, 1006, 1009, 1010, 1012, 1014, 1017, 1020, 1024, - 1027, 1029, 1032, 1034, 1037, 1040, 1043, 1046, 1047, 1049, - 1053, 1059, 1062, 1066, 1069, 1070, 1072, 1075, 1078, 1081, - 1084, 1089, 1095, 1101, 1105, 1107, 1110, 1114, 1118, 1121, - 1124, 1128, 1132, 1133, 1136, 1138, 1142, 1146, 1150, 1151, - 1153, 1155, 1159, 1162, 1166, 1169, 1172, 1174, 1175, 1178, - 1183, 1186, 1188, 1192, 1195, 1200, 1204, 1210, 1212, 1214, - 1216, 1218, 1220, 1222, 1224, 1226, 1228, 1230, 1232, 1234, - 1236, 1238, 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, - 1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274, - 1276, 1278, 1280, 1282, 1284, 1286, 1288, 1290, 1292, 1294, - 1296, 1298, 1300 + 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, + 90, 93, 96, 99, 102, 105, 108, 110, 112, 115, + 117, 119, 121, 123, 124, 126, 128, 131, 133, 135, + 137, 139, 141, 143, 145, 147, 150, 155, 158, 160, + 162, 166, 169, 173, 176, 179, 183, 187, 189, 191, + 193, 195, 197, 199, 201, 203, 205, 208, 210, 212, + 214, 215, 218, 219, 221, 224, 230, 234, 236, 240, + 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, + 262, 264, 266, 268, 271, 274, 278, 284, 288, 294, + 295, 298, 299, 302, 306, 310, 316, 318, 320, 324, + 330, 338, 340, 344, 346, 350, 352, 354, 356, 358, + 360, 362, 368, 370, 374, 380, 381, 383, 387, 389, + 391, 393, 396, 400, 402, 404, 407, 409, 412, 416, + 420, 422, 424, 426, 427, 431, 433, 437, 441, 447, + 450, 453, 458, 461, 464, 468, 470, 475, 482, 487, + 493, 500, 505, 509, 511, 513, 515, 517, 520, 524, + 530, 537, 544, 551, 558, 565, 573, 580, 587, 594, + 601, 610, 619, 626, 627, 630, 633, 636, 638, 642, + 644, 649, 654, 658, 665, 669, 674, 679, 686, 690, + 692, 696, 697, 701, 705, 709, 713, 717, 721, 725, + 729, 733, 737, 741, 747, 751, 752, 754, 755, 757, + 759, 761, 763, 766, 768, 771, 773, 776, 779, 783, + 784, 786, 789, 791, 794, 796, 799, 802, 803, 806, + 811, 813, 818, 824, 826, 831, 836, 842, 843, 845, + 847, 849, 850, 852, 856, 860, 863, 865, 867, 869, + 871, 873, 875, 877, 879, 881, 883, 885, 887, 889, + 891, 893, 895, 897, 899, 901, 903, 905, 907, 909, + 911, 913, 915, 917, 919, 921, 922, 925, 930, 935, + 936, 939, 940, 943, 946, 948, 950, 954, 957, 961, + 966, 968, 971, 972, 975, 979, 982, 985, 988, 989, + 992, 996, 999, 1003, 1006, 1010, 1014, 1019, 1021, 1024, + 1027, 1031, 1034, 1037, 1038, 1040, 1042, 1045, 1048, 1052, + 1055, 1057, 1060, 1062, 1065, 1068, 1071, 1074, 1075, 1077, + 1081, 1087, 1090, 1094, 1097, 1098, 1100, 1103, 1106, 1109, + 1112, 1117, 1123, 1129, 1133, 1135, 1138, 1142, 1146, 1149, + 1152, 1156, 1160, 1161, 1164, 1166, 1170, 1174, 1178, 1179, + 1181, 1183, 1187, 1190, 1194, 1197, 1200, 1202, 1203, 1206, + 1211, 1214, 1216, 1220, 1223, 1228, 1232, 1238, 1240, 1242, + 1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258, 1260, 1262, + 1264, 1266, 1268, 1270, 1272, 1274, 1276, 1278, 1280, 1282, + 1284, 1286, 1288, 1290, 1292, 1294 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 183, 0, -1, 184, -1, 1, -1, 185, -1, 184, - 185, -1, 186, 50, -1, 186, 171, -1, 186, 171, - 50, -1, 171, -1, 171, 50, -1, 56, 186, 171, - -1, 187, -1, 246, 187, -1, 188, -1, 237, -1, - 242, -1, 238, -1, 239, -1, 240, -1, 189, -1, - 307, -1, 272, -1, 208, -1, 273, -1, 311, -1, - 312, -1, 220, -1, 221, -1, 222, -1, 223, -1, - 224, -1, 225, -1, 226, -1, 190, -1, 199, -1, - 241, -1, 313, -1, 260, 204, 203, -1, 201, 188, - -1, 201, 237, -1, 201, 239, -1, 201, 240, -1, - 201, 238, -1, 201, 241, -1, 191, -1, 200, -1, - 14, 192, -1, 15, -1, 16, -1, 17, -1, 18, - -1, -1, 19, -1, 64, -1, 21, 64, -1, 188, - -1, 237, -1, 238, -1, 240, -1, 239, -1, 313, - -1, 226, -1, 241, -1, 172, 85, -1, 194, 173, - 172, 85, -1, 172, 85, -1, 195, -1, 193, -1, - 29, 318, 27, -1, 30, 318, -1, 30, 318, 31, - -1, 197, 196, -1, 198, 194, -1, 15, 29, 318, - -1, 32, 29, 318, -1, 22, -1, 23, -1, 24, - -1, 25, -1, 53, -1, 26, -1, 54, -1, 55, - -1, 202, -1, 202, 85, -1, 86, -1, 87, -1, - 88, -1, -1, 27, 233, -1, -1, 230, -1, 5, - 80, -1, 5, 80, 204, 27, 233, -1, 5, 80, - 230, -1, 161, -1, 161, 71, 318, -1, 12, 81, - -1, 12, 81, 230, -1, 205, -1, 206, -1, 207, - -1, 218, -1, 219, -1, 209, -1, 217, -1, 216, - -1, 159, -1, 156, -1, 214, -1, 215, -1, 210, - -1, 211, -1, 160, 227, -1, 202, 227, -1, 162, - 27, 85, -1, 162, 27, 85, 27, 85, -1, 163, - 27, 85, -1, 163, 27, 85, 27, 85, -1, -1, - 133, 85, -1, -1, 27, 85, -1, 157, 213, 212, - -1, 158, 213, 212, -1, 11, 19, 20, 213, 212, - -1, 155, -1, 153, -1, 153, 27, 85, -1, 153, - 72, 154, 174, 85, -1, 153, 27, 85, 72, 154, - 174, 85, -1, 82, -1, 83, 174, 117, -1, 92, - -1, 93, -1, 94, -1, 95, -1, 96, -1, 97, - -1, 13, 227, 175, 228, 176, -1, 318, -1, 318, - 177, 318, -1, 318, 177, 318, 177, 318, -1, -1, - 229, -1, 228, 173, 229, -1, 85, -1, 117, -1, - 100, -1, 172, 85, -1, 172, 172, 85, -1, 49, - -1, 231, -1, 230, 231, -1, 232, -1, 175, 176, - -1, 175, 188, 176, -1, 175, 230, 176, -1, 315, - -1, 234, -1, 188, -1, -1, 175, 236, 176, -1, - 85, -1, 236, 173, 85, -1, 263, 316, 314, -1, - 263, 316, 314, 235, 234, -1, 265, 233, -1, 261, - 233, -1, 262, 271, 27, 233, -1, 266, 316, -1, - 12, 243, -1, 244, 173, 243, -1, 244, -1, 172, - 85, 174, 245, -1, 172, 172, 98, 85, 174, 245, - -1, 98, 85, 174, 245, -1, 172, 172, 85, 174, - 245, -1, 172, 172, 99, 85, 174, 245, -1, 99, - 85, 174, 245, -1, 85, 174, 245, -1, 85, -1, - 117, -1, 100, -1, 247, -1, 247, 246, -1, 40, - 248, 41, -1, 40, 105, 256, 255, 41, -1, 40, - 102, 174, 259, 255, 41, -1, 40, 113, 174, 259, - 255, 41, -1, 40, 101, 174, 259, 255, 41, -1, - 40, 103, 174, 259, 255, 41, -1, 40, 104, 174, - 259, 255, 41, -1, 40, 84, 85, 174, 258, 255, - 41, -1, 40, 108, 174, 257, 255, 41, -1, 40, - 109, 174, 257, 255, 41, -1, 40, 106, 174, 259, - 255, 41, -1, 40, 107, 174, 259, 255, 41, -1, - 40, 110, 111, 174, 178, 250, 179, 41, -1, 40, - 110, 112, 174, 178, 252, 179, 41, -1, -1, 248, - 249, -1, 42, 85, -1, 43, 85, -1, 85, -1, - 251, 173, 250, -1, 251, -1, 101, 175, 259, 176, - -1, 113, 175, 259, 176, -1, 114, 175, 176, -1, - 114, 175, 115, 174, 259, 176, -1, 116, 175, 253, - 176, -1, 68, 175, 257, 176, -1, 68, 175, 257, - 180, 257, 176, -1, 254, 173, 253, -1, 254, -1, - 85, 174, 259, -1, -1, 255, 173, 256, -1, 101, - 174, 259, -1, 102, 174, 259, -1, 113, 174, 259, - -1, 103, 174, 259, -1, 104, 174, 259, -1, 108, - 174, 257, -1, 109, 174, 257, -1, 106, 174, 259, - -1, 107, 174, 259, -1, 85, 177, 85, 174, 258, - -1, 85, 174, 258, -1, -1, 259, -1, -1, 259, - -1, 85, -1, 89, -1, 5, -1, 33, 267, -1, - 8, -1, 34, 267, -1, 6, -1, 35, 267, -1, - 7, 264, -1, 36, 267, 264, -1, -1, 128, -1, - 128, 52, -1, 9, -1, 37, 267, -1, 10, -1, - 38, 267, -1, 268, 39, -1, -1, 269, 268, -1, - 44, 175, 117, 176, -1, 117, -1, 45, 175, 270, - 176, -1, 64, 175, 85, 85, 176, -1, 85, -1, - 85, 175, 117, 176, -1, 85, 175, 85, 176, -1, - 85, 175, 85, 85, 176, -1, -1, 46, -1, 47, - -1, 48, -1, -1, 69, -1, 11, 306, 66, -1, - 11, 306, 67, -1, 11, 68, -1, 277, -1, 279, - -1, 280, -1, 283, -1, 281, -1, 285, -1, 286, - -1, 287, -1, 288, -1, 290, -1, 291, -1, 292, - -1, 293, -1, 294, -1, 296, -1, 297, -1, 299, - -1, 300, -1, 301, -1, 302, -1, 303, -1, 304, - -1, 305, -1, -1, 121, 117, -1, 121, 117, 173, - 117, -1, 121, 117, 122, 117, -1, -1, 133, 85, - -1, -1, 133, 85, -1, 118, 278, -1, 119, -1, - 120, -1, 120, 117, 274, -1, 130, 275, -1, 130, - 131, 275, -1, 130, 131, 132, 275, -1, 123, -1, - 125, 282, -1, -1, 126, 85, -1, 126, 133, 85, - -1, 126, 128, -1, 133, 85, -1, 124, 284, -1, - -1, 126, 275, -1, 126, 117, 275, -1, 129, 275, - -1, 129, 117, 275, -1, 127, 275, -1, 127, 117, - 275, -1, 127, 128, 275, -1, 127, 128, 117, 275, - -1, 134, -1, 134, 117, -1, 135, 275, -1, 135, - 152, 275, -1, 136, 275, -1, 137, 289, -1, -1, - 85, -1, 128, -1, 128, 85, -1, 138, 276, -1, - 138, 140, 276, -1, 138, 139, -1, 141, -1, 141, - 85, -1, 142, -1, 142, 143, -1, 144, 274, -1, - 144, 117, -1, 145, 295, -1, -1, 117, -1, 117, - 173, 117, -1, 117, 173, 117, 173, 85, -1, 146, - 275, -1, 146, 147, 275, -1, 148, 298, -1, -1, - 117, -1, 117, 117, -1, 149, 150, -1, 149, 151, - -1, 149, 152, -1, 164, 12, 85, 174, -1, 164, - 12, 85, 174, 85, -1, 164, 12, 85, 174, 117, - -1, 165, 6, 85, -1, 166, -1, 167, 117, -1, - 167, 117, 117, -1, 168, 85, 117, -1, 168, 85, - -1, 169, 117, -1, 169, 120, 117, -1, 169, 170, - 117, -1, -1, 70, 181, -1, 56, -1, 57, 58, - 308, -1, 65, 56, 85, -1, 65, 57, 85, -1, - -1, 309, -1, 310, -1, 309, 173, 310, -1, 59, - 60, -1, 61, 62, 63, -1, 90, 85, -1, 91, - 85, -1, 85, -1, -1, 139, 85, -1, 139, 175, - 85, 176, -1, 316, 314, -1, 318, -1, 318, 177, - 318, -1, 318, 318, -1, 318, 177, 318, 318, -1, - 318, 71, 318, -1, 318, 177, 318, 71, 318, -1, - 57, -1, 65, -1, 56, -1, 58, -1, 62, -1, - 67, -1, 66, -1, 70, -1, 69, -1, 68, -1, - 119, -1, 120, -1, 122, -1, 126, -1, 127, -1, - 129, -1, 131, -1, 132, -1, 143, -1, 147, -1, - 151, -1, 152, -1, 170, -1, 101, -1, 102, -1, - 103, -1, 104, -1, 154, -1, 105, -1, 106, -1, - 107, -1, 108, -1, 109, -1, 110, -1, 111, -1, - 112, -1, 113, -1, 115, -1, 114, -1, 116, -1, - 64, -1, 53, -1, 54, -1, 55, -1, 85, -1, - 317, -1 + 191, 0, -1, 192, -1, 1, -1, 193, -1, 192, + 193, -1, 194, 50, -1, 194, 179, -1, 194, 179, + 50, -1, 179, -1, 179, 50, -1, 56, 194, 179, + -1, 195, -1, 254, 195, -1, 196, -1, 245, -1, + 250, -1, 246, -1, 247, -1, 248, -1, 197, -1, + 316, -1, 280, -1, 215, -1, 281, -1, 320, -1, + 321, -1, 228, -1, 229, -1, 230, -1, 231, -1, + 232, -1, 233, -1, 234, -1, 198, -1, 207, -1, + 249, -1, 282, -1, 322, -1, 268, 212, 211, -1, + 209, 196, -1, 209, 245, -1, 209, 247, -1, 209, + 248, -1, 209, 246, -1, 209, 249, -1, 199, -1, + 208, -1, 14, 200, -1, 15, -1, 16, -1, 17, + -1, 18, -1, -1, 19, -1, 64, -1, 21, 64, + -1, 196, -1, 245, -1, 246, -1, 248, -1, 247, + -1, 322, -1, 234, -1, 249, -1, 180, 84, -1, + 202, 181, 180, 84, -1, 180, 84, -1, 203, -1, + 201, -1, 29, 327, 27, -1, 30, 327, -1, 30, + 327, 31, -1, 205, 204, -1, 206, 202, -1, 15, + 29, 327, -1, 32, 29, 327, -1, 22, -1, 23, + -1, 24, -1, 25, -1, 53, -1, 26, -1, 54, + -1, 55, -1, 210, -1, 210, 84, -1, 85, -1, + 86, -1, 87, -1, -1, 27, 241, -1, -1, 238, + -1, 5, 80, -1, 5, 80, 212, 27, 241, -1, + 5, 80, 238, -1, 163, -1, 163, 71, 327, -1, + 213, -1, 214, -1, 226, -1, 227, -1, 216, -1, + 224, -1, 225, -1, 223, -1, 161, -1, 158, -1, + 221, -1, 222, -1, 217, -1, 218, -1, 162, 235, + -1, 210, 327, -1, 164, 27, 84, -1, 164, 27, + 84, 27, 84, -1, 165, 27, 84, -1, 165, 27, + 84, 27, 84, -1, -1, 134, 84, -1, -1, 27, + 84, -1, 159, 220, 219, -1, 160, 220, 219, -1, + 11, 19, 20, 220, 219, -1, 157, -1, 154, -1, + 154, 27, 84, -1, 154, 72, 156, 182, 84, -1, + 154, 27, 84, 72, 156, 182, 84, -1, 155, -1, + 155, 27, 84, -1, 81, -1, 82, 182, 118, -1, + 91, -1, 92, -1, 93, -1, 94, -1, 95, -1, + 96, -1, 13, 235, 183, 236, 184, -1, 327, -1, + 327, 185, 327, -1, 327, 185, 327, 185, 327, -1, + -1, 237, -1, 236, 181, 237, -1, 84, -1, 118, + -1, 99, -1, 180, 84, -1, 180, 180, 84, -1, + 49, -1, 239, -1, 238, 239, -1, 240, -1, 183, + 184, -1, 183, 196, 184, -1, 183, 238, 184, -1, + 324, -1, 242, -1, 196, -1, -1, 183, 244, 184, + -1, 84, -1, 244, 181, 84, -1, 271, 325, 323, + -1, 271, 325, 323, 243, 242, -1, 273, 241, -1, + 269, 241, -1, 270, 279, 27, 241, -1, 274, 325, + -1, 12, 251, -1, 252, 181, 251, -1, 252, -1, + 180, 84, 182, 253, -1, 180, 180, 97, 84, 182, + 253, -1, 97, 84, 182, 253, -1, 180, 180, 84, + 182, 253, -1, 180, 180, 98, 84, 182, 253, -1, + 98, 84, 182, 253, -1, 84, 182, 253, -1, 84, + -1, 118, -1, 99, -1, 255, -1, 255, 254, -1, + 40, 256, 41, -1, 40, 104, 264, 263, 41, -1, + 40, 101, 182, 267, 263, 41, -1, 40, 113, 182, + 267, 263, 41, -1, 40, 100, 182, 267, 263, 41, + -1, 40, 102, 182, 267, 263, 41, -1, 40, 103, + 182, 267, 263, 41, -1, 40, 83, 84, 182, 266, + 263, 41, -1, 40, 107, 182, 265, 263, 41, -1, + 40, 108, 182, 265, 263, 41, -1, 40, 105, 182, + 267, 263, 41, -1, 40, 106, 182, 267, 263, 41, + -1, 40, 110, 111, 182, 186, 258, 187, 41, -1, + 40, 110, 112, 182, 186, 260, 187, 41, -1, 40, + 109, 182, 267, 263, 41, -1, -1, 256, 257, -1, + 42, 84, -1, 43, 84, -1, 84, -1, 259, 181, + 258, -1, 259, -1, 100, 183, 267, 184, -1, 113, + 183, 267, 184, -1, 114, 183, 184, -1, 114, 183, + 116, 182, 267, 184, -1, 115, 183, 184, -1, 117, + 183, 261, 184, -1, 68, 183, 265, 184, -1, 68, + 183, 265, 188, 265, 184, -1, 262, 181, 261, -1, + 262, -1, 84, 182, 267, -1, -1, 263, 181, 264, + -1, 100, 182, 267, -1, 101, 182, 267, -1, 113, + 182, 267, -1, 102, 182, 267, -1, 103, 182, 267, + -1, 107, 182, 265, -1, 108, 182, 265, -1, 105, + 182, 267, -1, 106, 182, 267, -1, 109, 182, 267, + -1, 84, 185, 84, 182, 266, -1, 84, 182, 266, + -1, -1, 267, -1, -1, 267, -1, 84, -1, 88, + -1, 5, -1, 33, 275, -1, 8, -1, 34, 275, + -1, 6, -1, 35, 275, -1, 7, 272, -1, 36, + 275, 272, -1, -1, 129, -1, 129, 52, -1, 9, + -1, 37, 275, -1, 10, -1, 38, 275, -1, 276, + 39, -1, -1, 277, 276, -1, 44, 183, 118, 184, + -1, 118, -1, 45, 183, 278, 184, -1, 64, 183, + 84, 84, 184, -1, 84, -1, 84, 183, 118, 184, + -1, 84, 183, 84, 184, -1, 84, 183, 84, 84, + 184, -1, -1, 46, -1, 47, -1, 48, -1, -1, + 69, -1, 11, 315, 66, -1, 11, 315, 67, -1, + 11, 68, -1, 286, -1, 288, -1, 289, -1, 292, + -1, 290, -1, 294, -1, 295, -1, 296, -1, 297, + -1, 299, -1, 300, -1, 301, -1, 302, -1, 303, + -1, 305, -1, 306, -1, 308, -1, 309, -1, 310, + -1, 311, -1, 312, -1, 313, -1, 314, -1, 173, + -1, 174, -1, 175, -1, 176, -1, 177, -1, 178, + -1, -1, 122, 118, -1, 122, 118, 181, 118, -1, + 122, 118, 123, 118, -1, -1, 134, 84, -1, -1, + 134, 84, -1, 119, 287, -1, 120, -1, 121, -1, + 121, 118, 283, -1, 131, 284, -1, 131, 132, 284, + -1, 131, 132, 133, 284, -1, 124, -1, 126, 291, + -1, -1, 127, 84, -1, 127, 134, 84, -1, 127, + 129, -1, 134, 84, -1, 125, 293, -1, -1, 127, + 284, -1, 127, 118, 284, -1, 130, 284, -1, 130, + 118, 284, -1, 128, 284, -1, 128, 118, 284, -1, + 128, 129, 284, -1, 128, 129, 118, 284, -1, 135, + -1, 135, 118, -1, 136, 284, -1, 136, 153, 284, + -1, 137, 284, -1, 138, 298, -1, -1, 84, -1, + 129, -1, 129, 84, -1, 139, 285, -1, 139, 141, + 285, -1, 139, 140, -1, 142, -1, 142, 84, -1, + 143, -1, 143, 144, -1, 145, 283, -1, 145, 118, + -1, 146, 304, -1, -1, 118, -1, 118, 181, 118, + -1, 118, 181, 118, 181, 84, -1, 147, 284, -1, + 147, 148, 284, -1, 149, 307, -1, -1, 118, -1, + 118, 118, -1, 150, 151, -1, 150, 152, -1, 150, + 153, -1, 166, 12, 84, 182, -1, 166, 12, 84, + 182, 84, -1, 166, 12, 84, 182, 118, -1, 167, + 6, 84, -1, 168, -1, 169, 118, -1, 169, 118, + 118, -1, 170, 84, 118, -1, 170, 84, -1, 171, + 118, -1, 171, 121, 118, -1, 171, 172, 118, -1, + -1, 70, 189, -1, 56, -1, 57, 58, 317, -1, + 65, 56, 84, -1, 65, 57, 84, -1, -1, 318, + -1, 319, -1, 318, 181, 319, -1, 59, 60, -1, + 61, 62, 63, -1, 89, 84, -1, 90, 84, -1, + 84, -1, -1, 140, 84, -1, 140, 183, 84, 184, + -1, 325, 323, -1, 327, -1, 327, 185, 327, -1, + 327, 327, -1, 327, 185, 327, 327, -1, 327, 71, + 327, -1, 327, 185, 327, 71, 327, -1, 57, -1, + 65, -1, 56, -1, 58, -1, 62, -1, 67, -1, + 66, -1, 70, -1, 69, -1, 68, -1, 120, -1, + 121, -1, 123, -1, 127, -1, 128, -1, 130, -1, + 132, -1, 133, -1, 144, -1, 148, -1, 152, -1, + 153, -1, 172, -1, 156, -1, 53, -1, 54, -1, + 55, -1, 84, -1, 326, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 336, 336, 337, 339, 340, 342, 343, 344, 345, - 346, 347, 349, 350, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 377, 379, - 380, 381, 382, 383, 384, 386, 387, 389, 390, 391, - 392, 393, 395, 396, 397, 398, 400, 401, 402, 403, - 404, 405, 406, 407, 409, 416, 424, 432, 433, 436, - 442, 447, 453, 456, 459, 464, 470, 471, 472, 473, - 474, 475, 476, 477, 479, 480, 482, 483, 484, 486, - 487, 489, 490, 492, 493, 494, 496, 497, 499, 500, - 502, 503, 504, 505, 506, 507, 509, 510, 511, 512, - 513, 514, 515, 516, 517, 518, 524, 529, 536, 541, - 548, 549, 551, 552, 554, 558, 563, 568, 570, 571, - 576, 581, 588, 591, 597, 598, 599, 600, 601, 602, - 605, 607, 611, 616, 624, 627, 632, 637, 642, 647, - 652, 657, 662, 670, 671, 673, 675, 676, 677, 679, - 680, 682, 684, 685, 687, 688, 690, 694, 695, 696, - 697, 698, 703, 705, 706, 708, 712, 716, 720, 724, - 728, 732, 736, 741, 746, 752, 753, 755, 756, 757, - 758, 759, 760, 761, 762, 768, 769, 770, 771, 772, - 773, 775, 776, 778, 779, 780, 782, 783, 785, 790, - 795, 796, 797, 799, 800, 802, 803, 805, 813, 814, - 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, - 831, 833, 834, 836, 837, 839, 840, 842, 843, 844, - 845, 846, 847, 848, 849, 851, 852, 853, 855, 856, - 857, 858, 859, 860, 861, 863, 864, 865, 866, 871, - 872, 873, 874, 876, 877, 878, 879, 881, 882, 885, - 886, 887, 890, 891, 892, 893, 894, 895, 896, 897, - 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, - 908, 909, 910, 911, 912, 917, 919, 923, 928, 936, - 937, 941, 942, 945, 947, 948, 949, 953, 954, 955, - 959, 961, 963, 964, 965, 966, 967, 970, 972, 973, - 974, 975, 976, 977, 978, 979, 980, 984, 985, 989, - 990, 995, 998, 1000, 1001, 1002, 1003, 1007, 1008, 1009, - 1013, 1014, 1018, 1019, 1023, 1024, 1027, 1029, 1030, 1031, - 1032, 1036, 1037, 1040, 1042, 1043, 1044, 1048, 1049, 1050, - 1054, 1055, 1056, 1060, 1064, 1068, 1069, 1073, 1074, 1078, - 1079, 1080, 1083, 1084, 1087, 1091, 1092, 1093, 1095, 1096, - 1098, 1099, 1102, 1103, 1106, 1112, 1115, 1117, 1118, 1119, - 1121, 1126, 1129, 1133, 1137, 1142, 1146, 1152, 1153, 1154, - 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, - 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, - 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, - 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, - 1195, 1197, 1198 + 0, 334, 334, 335, 337, 338, 340, 341, 342, 343, + 344, 345, 347, 348, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 376, + 378, 379, 380, 381, 382, 383, 385, 386, 388, 389, + 390, 391, 392, 394, 395, 396, 397, 399, 400, 401, + 402, 403, 404, 405, 406, 408, 415, 423, 431, 432, + 435, 441, 446, 452, 455, 458, 463, 469, 470, 471, + 472, 473, 474, 475, 476, 478, 479, 481, 482, 483, + 485, 486, 488, 489, 491, 492, 493, 495, 496, 498, + 499, 500, 501, 502, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 521, 526, 533, 538, 545, + 546, 548, 549, 551, 555, 560, 565, 567, 568, 573, + 578, 585, 586, 592, 595, 601, 602, 603, 604, 605, + 606, 609, 611, 615, 620, 628, 631, 636, 641, 646, + 651, 656, 661, 666, 674, 675, 677, 679, 680, 681, + 683, 684, 686, 688, 689, 691, 692, 694, 698, 699, + 700, 701, 702, 707, 709, 710, 712, 716, 720, 724, + 728, 732, 736, 740, 745, 750, 756, 757, 759, 760, + 761, 762, 763, 764, 765, 766, 772, 773, 774, 775, + 776, 777, 778, 779, 780, 782, 783, 784, 786, 787, + 789, 794, 799, 800, 801, 802, 804, 805, 807, 808, + 810, 818, 819, 821, 822, 823, 824, 825, 826, 827, + 828, 829, 830, 831, 837, 839, 840, 842, 843, 845, + 846, 848, 849, 850, 851, 852, 853, 854, 855, 857, + 858, 859, 861, 862, 863, 864, 865, 866, 867, 869, + 870, 871, 872, 877, 878, 879, 880, 882, 883, 884, + 885, 887, 888, 891, 892, 893, 896, 897, 898, 899, + 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, + 910, 911, 912, 913, 914, 915, 916, 917, 918, 920, + 921, 922, 923, 924, 925, 930, 932, 936, 941, 949, + 950, 954, 955, 958, 960, 961, 962, 966, 967, 968, + 972, 974, 976, 977, 978, 979, 980, 983, 985, 986, + 987, 988, 989, 990, 991, 992, 993, 997, 998, 1002, + 1003, 1008, 1011, 1013, 1014, 1015, 1016, 1020, 1021, 1022, + 1026, 1027, 1031, 1032, 1036, 1037, 1040, 1042, 1043, 1044, + 1045, 1049, 1050, 1053, 1055, 1056, 1057, 1061, 1062, 1063, + 1067, 1068, 1069, 1073, 1077, 1081, 1082, 1086, 1087, 1091, + 1092, 1093, 1096, 1097, 1100, 1104, 1105, 1106, 1108, 1109, + 1111, 1112, 1115, 1116, 1119, 1125, 1128, 1130, 1131, 1132, + 1134, 1139, 1142, 1146, 1150, 1155, 1159, 1165, 1166, 1167, + 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, + 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, + 1188, 1189, 1190, 1191, 1193, 1194 }; #endif @@ -1137,26 +1140,29 @@ static const char *const yytname[] = "ONLY", "WITH", "CONSISTENT", "SNAPSHOT", "INDEX", "XA", "WARNINGS", "ERRORS", "TRACE", "QUICK", "COUNT", "AS", "WHERE", "VALUES", "ORDER", "GROUP", "HAVING", "INTO", "UNION", "FOR", "TX_READ_ONLY", - "AUTOCOMMIT_0", "SELECT_OBPROXY_ROUTE_ADDR", "SET_OBPROXY_ROUTE_ADDR", - "NAME_OB_DOT", "NAME_OB", "EXPLAIN", "DESC", "DESCRIBE", "NAME_STR", - "USE", "HELP", "SET_NAMES", "SET_CHARSET", "SET_PASSWORD", "SET_DEFAULT", + "SELECT_OBPROXY_ROUTE_ADDR", "SET_OBPROXY_ROUTE_ADDR", "NAME_OB_DOT", + "NAME_OB", "EXPLAIN", "DESC", "DESCRIBE", "NAME_STR", "USE", "HELP", + "SET_NAMES", "SET_CHARSET", "SET_PASSWORD", "SET_DEFAULT", "SET_OB_READ_CONSISTENCY", "SET_TX_READ_ONLY", "GLOBAL", "SESSION", "NUMBER_VAL", "GROUP_ID", "TABLE_ID", "ELASTIC_ID", "TESTLOAD", "ODP_COMMENT", "TNT_ID", "DISASTER_STATUS", "TRACE_ID", "RPC_ID", - "DBP_COMMENT", "ROUTE_TAG", "SYS_TAG", "TABLE_NAME", "SCAN_ALL", - "PARALL", "SHARD_KEY", "INT_NUM", "SHOW_PROXYNET", "THREAD", - "CONNECTION", "LIMIT", "OFFSET", "SHOW_PROCESSLIST", "SHOW_PROXYSESSION", - "SHOW_GLOBALSESSION", "ATTRIBUTE", "VARIABLES", "ALL", "STAT", - "SHOW_PROXYCONFIG", "DIFF", "USER", "LIKE", "SHOW_PROXYSM", - "SHOW_PROXYCLUSTER", "SHOW_PROXYRESOURCE", "SHOW_PROXYCONGESTION", - "SHOW_PROXYROUTE", "PARTITION", "ROUTINE", "SHOW_PROXYVIP", - "SHOW_PROXYMEMORY", "OBJPOOL", "SHOW_SQLAUDIT", "SHOW_WARNLOG", - "SHOW_PROXYSTAT", "REFRESH", "SHOW_PROXYTRACE", "SHOW_PROXYINFO", - "BINARY", "UPGRADE", "IDC", "SHOW_TOPOLOGY", "GROUP_NAME", - "SHOW_DB_VERSION", "SHOW_DATABASES", "SHOW_TABLES", "SHOW_FULL_TABLES", - "SELECT_DATABASE", "SHOW_CREATE_TABLE", "SELECT_PROXY_VERSION", - "SHOW_COLUMNS", "SHOW_INDEX", "ALTER_PROXYCONFIG", "ALTER_PROXYRESOURCE", - "PING_PROXY", "KILL_PROXYSESSION", "KILL_GLOBALSESSION", "KILL", "QUERY", + "TARGET_DB_SERVER", "DBP_COMMENT", "ROUTE_TAG", "SYS_TAG", "TABLE_NAME", + "SCAN_ALL", "STICKY_SESSION", "PARALL", "SHARD_KEY", "INT_NUM", + "SHOW_PROXYNET", "THREAD", "CONNECTION", "LIMIT", "OFFSET", + "SHOW_PROCESSLIST", "SHOW_PROXYSESSION", "SHOW_GLOBALSESSION", + "ATTRIBUTE", "VARIABLES", "ALL", "STAT", "SHOW_PROXYCONFIG", "DIFF", + "USER", "LIKE", "SHOW_PROXYSM", "SHOW_PROXYCLUSTER", + "SHOW_PROXYRESOURCE", "SHOW_PROXYCONGESTION", "SHOW_PROXYROUTE", + "PARTITION", "ROUTINE", "SHOW_PROXYVIP", "SHOW_PROXYMEMORY", "OBJPOOL", + "SHOW_SQLAUDIT", "SHOW_WARNLOG", "SHOW_PROXYSTAT", "REFRESH", + "SHOW_PROXYTRACE", "SHOW_PROXYINFO", "BINARY", "UPGRADE", "IDC", + "SHOW_ELASTIC_ID", "SHOW_TOPOLOGY", "GROUP_NAME", "SHOW_DB_VERSION", + "SHOW_DATABASES", "SHOW_TABLES", "SHOW_FULL_TABLES", "SELECT_DATABASE", + "SHOW_CREATE_TABLE", "SELECT_PROXY_VERSION", "SHOW_COLUMNS", + "SHOW_INDEX", "ALTER_PROXYCONFIG", "ALTER_PROXYRESOURCE", "PING_PROXY", + "KILL_PROXYSESSION", "KILL_GLOBALSESSION", "KILL", "QUERY", + "SHOW_MASTER_STATUS", "SHOW_BINARY_LOGS", "SHOW_BINLOG_EVENTS", + "PURGE_BINARY_LOGS", "RESET_MASTER", "SHOW_BINLOG_SERVER_FOR_TENANT", "';'", "'@'", "','", "'='", "'('", "')'", "'.'", "'{'", "'}'", "'#'", "'*'", "$accept", "root", "sql_stmts", "sql_stmt", "comment_stmt", "stmt", "select_stmt", "explain_stmt", "ddl_stmt", "mysql_ddl_stmt", @@ -1165,10 +1171,10 @@ static const char *const yytname[] = "text_ps_prepare_stmt", "text_ps_execute_stmt", "text_ps_stmt", "oracle_ddl_stmt", "explain_or_desc_stmt", "explain_or_desc", "opt_from", "select_expr_list", "select_tx_read_only_stmt", - "select_proxy_version_stmt", "set_autocommit_0_stmt", "hooked_stmt", - "shard_special_stmt", "show_columns_stmt", "show_index_stmt", - "opt_show_like", "opt_show_from", "show_tables_stmt", - "show_table_status_stmt", "show_db_version_stmt", "show_es_id_stmt", + "select_proxy_version_stmt", "hooked_stmt", "shard_special_stmt", + "show_columns_stmt", "show_index_stmt", "opt_show_like", "opt_show_from", + "show_tables_stmt", "show_table_status_stmt", "show_db_version_stmt", + "show_es_id_stmt", "show_topology_stmt", "select_obproxy_route_addr_stmt", "set_obproxy_route_addr_stmt", "set_names_stmt", "set_charset_stmt", "set_password_stmt", "set_default_stmt", "set_ob_read_consistency_stmt", @@ -1185,8 +1191,8 @@ static const char *const yytname[] = "insert_with_opt_hint", "insert_all_when", "replace_with_opt_hint", "merge_with_opt_hint", "hint_list_with_end", "hint_list", "hint", "opt_read_consistency", "opt_quick", "show_stmt", "icmd_stmt", - "opt_limit", "opt_like", "opt_large_like", "show_proxynet", - "opt_show_net", "show_proxyconfig", "show_processlist", + "binlog_stmt", "opt_limit", "opt_like", "opt_large_like", + "show_proxynet", "opt_show_net", "show_proxyconfig", "show_processlist", "show_globalsession", "opt_show_global_session", "show_proxysession", "opt_show_session", "show_proxysm", "show_proxycluster", "show_proxyresource", "show_proxycongestion", "opt_show_congestion", @@ -1224,59 +1230,58 @@ static const yytype_uint16 yytoknum[] = 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 59, 64, 44, 61, 40, 41, 46, 123, 125, - 35, 42 + 425, 426, 427, 428, 429, 430, 431, 432, 433, 59, + 64, 44, 61, 40, 41, 46, 123, 125, 35, 42 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 182, 183, 183, 184, 184, 185, 185, 185, 185, - 185, 185, 186, 186, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 188, 189, - 189, 189, 189, 189, 189, 190, 190, 191, 191, 191, - 191, 191, 192, 192, 192, 192, 193, 193, 193, 193, - 193, 193, 193, 193, 194, 194, 195, 196, 196, 197, - 198, 198, 199, 199, 199, 199, 200, 200, 200, 200, - 200, 200, 200, 200, 201, 201, 202, 202, 202, 203, - 203, 204, 204, 205, 205, 205, 206, 206, 207, 207, - 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 210, 210, 211, 211, - 212, 212, 213, 213, 214, 214, 215, 216, 217, 217, - 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, - 229, 229, 229, 230, 230, 231, 232, 232, 232, 233, - 233, 234, 235, 235, 236, 236, 237, 237, 238, 239, - 240, 241, 242, 243, 243, 244, 244, 244, 244, 244, - 244, 244, 245, 245, 245, 246, 246, 247, 247, 247, - 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, - 247, 248, 248, 249, 249, 249, 250, 250, 251, 251, - 251, 251, 251, 252, 252, 253, 253, 254, 255, 255, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 257, 257, 258, 258, 259, 259, 260, 260, 261, - 261, 262, 262, 263, 263, 264, 264, 264, 265, 265, - 266, 266, 267, 268, 268, 269, 269, 269, 269, 269, - 269, 269, 269, 270, 270, 270, 270, 271, 271, 272, - 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 274, 274, 274, 274, 275, - 275, 276, 276, 277, 278, 278, 278, 279, 279, 279, - 280, 281, 282, 282, 282, 282, 282, 283, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 285, 285, 286, - 286, 287, 288, 289, 289, 289, 289, 290, 290, 290, - 291, 291, 292, 292, 293, 293, 294, 295, 295, 295, - 295, 296, 296, 297, 298, 298, 298, 299, 299, 299, - 300, 300, 300, 301, 302, 303, 303, 304, 304, 305, - 305, 305, 306, 306, 307, 307, 307, 307, 308, 308, - 309, 309, 310, 310, 311, 312, 313, 314, 314, 314, - 315, 316, 316, 316, 316, 316, 316, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 318, 318 + 0, 190, 191, 191, 192, 192, 193, 193, 193, 193, + 193, 193, 194, 194, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 196, + 197, 197, 197, 197, 197, 197, 198, 198, 199, 199, + 199, 199, 199, 200, 200, 200, 200, 201, 201, 201, + 201, 201, 201, 201, 201, 202, 202, 203, 204, 204, + 205, 206, 206, 207, 207, 207, 207, 208, 208, 208, + 208, 208, 208, 208, 208, 209, 209, 210, 210, 210, + 211, 211, 212, 212, 213, 213, 213, 214, 214, 215, + 215, 215, 215, 215, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 217, 217, 218, 218, 219, + 219, 220, 220, 221, 221, 222, 223, 224, 224, 224, + 224, 225, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 235, 235, 236, 236, 236, 237, 237, + 237, 237, 237, 237, 238, 238, 239, 240, 240, 240, + 241, 241, 242, 243, 243, 244, 244, 245, 245, 246, + 247, 248, 249, 250, 251, 251, 252, 252, 252, 252, + 252, 252, 252, 253, 253, 253, 254, 254, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 256, 256, 257, 257, 257, 258, 258, + 259, 259, 259, 259, 259, 259, 260, 260, 261, 261, + 262, 263, 263, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 265, 265, 266, 266, 267, + 267, 268, 268, 269, 269, 270, 270, 271, 271, 272, + 272, 272, 273, 273, 274, 274, 275, 276, 276, 277, + 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, + 278, 279, 279, 280, 280, 280, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, + 282, 282, 282, 282, 282, 283, 283, 283, 283, 284, + 284, 285, 285, 286, 287, 287, 287, 288, 288, 288, + 289, 290, 291, 291, 291, 291, 291, 292, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 294, 294, 295, + 295, 296, 297, 298, 298, 298, 298, 299, 299, 299, + 300, 300, 301, 301, 302, 302, 303, 304, 304, 304, + 304, 305, 305, 306, 307, 307, 307, 308, 308, 308, + 309, 309, 309, 310, 311, 312, 312, 313, 313, 314, + 314, 314, 315, 315, 316, 316, 316, 316, 317, 317, + 318, 318, 319, 319, 320, 321, 322, 323, 323, 323, + 324, 325, 325, 325, 325, 325, 325, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 327, 327 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -1285,31 +1290,32 @@ static const yytype_uint8 yyr2[] = 0, 2, 1, 1, 1, 2, 2, 2, 3, 1, 2, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, - 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, - 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 4, 2, 1, 1, 3, - 2, 3, 2, 2, 3, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, - 2, 0, 1, 2, 5, 3, 1, 3, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, + 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 4, 2, 1, 1, + 3, 2, 3, 2, 2, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 0, 2, 0, 1, 2, 5, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 3, 5, 3, 5, 0, + 2, 0, 2, 3, 3, 5, 1, 1, 3, 5, + 7, 1, 3, 1, 3, 1, 1, 1, 1, 1, + 1, 5, 1, 3, 5, 0, 1, 3, 1, 1, + 1, 2, 3, 1, 1, 2, 1, 2, 3, 3, + 1, 1, 1, 0, 3, 1, 3, 3, 5, 2, + 2, 4, 2, 2, 3, 1, 4, 6, 4, 5, + 6, 4, 3, 1, 1, 1, 1, 2, 3, 5, + 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, + 8, 8, 6, 0, 2, 2, 2, 1, 3, 1, + 4, 4, 3, 6, 3, 4, 4, 6, 3, 1, + 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 3, 0, 1, 0, 1, 1, + 1, 1, 2, 1, 2, 1, 2, 2, 3, 0, + 1, 2, 1, 2, 1, 2, 2, 0, 2, 4, + 1, 4, 5, 1, 4, 4, 5, 0, 1, 1, + 1, 0, 1, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 3, 5, 3, 5, - 0, 2, 0, 2, 3, 3, 5, 1, 1, 3, - 5, 7, 1, 3, 1, 1, 1, 1, 1, 1, - 5, 1, 3, 5, 0, 1, 3, 1, 1, 1, - 2, 3, 1, 1, 2, 1, 2, 3, 3, 1, - 1, 1, 0, 3, 1, 3, 3, 5, 2, 2, - 4, 2, 2, 3, 1, 4, 6, 4, 5, 6, - 4, 3, 1, 1, 1, 1, 2, 3, 5, 6, - 6, 6, 6, 6, 7, 6, 6, 6, 6, 8, - 8, 0, 2, 2, 2, 1, 3, 1, 4, 4, - 3, 6, 4, 4, 6, 3, 1, 3, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, - 3, 0, 1, 0, 1, 1, 1, 1, 2, 1, - 2, 1, 2, 2, 3, 0, 1, 2, 1, 2, - 1, 2, 2, 0, 2, 4, 1, 4, 5, 1, - 4, 4, 5, 0, 1, 1, 1, 0, 1, 3, - 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 4, 4, 0, 2, 0, 2, 2, 1, 1, 3, 2, 3, 4, @@ -1324,9 +1330,7 @@ static const yytype_uint8 yyr2[] = 2, 1, 3, 2, 4, 3, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 + 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -1334,532 +1338,486 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 3, 237, 241, 245, 239, 248, 250, 372, 0, - 0, 52, 48, 49, 50, 51, 76, 77, 78, 79, - 81, 0, 0, 0, 253, 253, 253, 253, 253, 253, - 201, 80, 82, 83, 374, 0, 0, 132, 0, 386, - 86, 87, 88, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 310, 318, 312, 299, 327, 299, 299, 333, - 301, 340, 342, 295, 347, 299, 354, 0, 128, 127, - 109, 122, 122, 108, 0, 96, 0, 0, 0, 0, - 364, 0, 0, 0, 9, 0, 2, 4, 0, 12, - 14, 20, 34, 45, 0, 0, 35, 46, 0, 84, - 100, 101, 102, 23, 105, 112, 113, 110, 111, 107, - 106, 103, 104, 27, 28, 29, 30, 31, 32, 33, - 15, 17, 18, 19, 36, 16, 0, 185, 91, 0, - 267, 0, 0, 0, 22, 24, 272, 273, 274, 276, - 275, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 21, - 25, 26, 37, 93, 246, 243, 0, 271, 0, 0, - 98, 0, 0, 0, 0, 172, 174, 438, 439, 440, - 399, 397, 400, 401, 437, 398, 403, 402, 406, 405, - 404, 441, 420, 421, 422, 423, 425, 426, 427, 428, - 429, 430, 431, 432, 433, 435, 434, 436, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, - 424, 419, 0, 442, 141, 53, 0, 54, 47, 0, - 0, 70, 0, 0, 0, 0, 259, 256, 238, 0, - 253, 240, 242, 245, 249, 251, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, - 0, 378, 0, 0, 0, 384, 385, 304, 305, 303, - 299, 299, 299, 317, 0, 0, 311, 299, 0, 307, - 328, 299, 329, 331, 334, 335, 332, 0, 339, 301, - 337, 341, 343, 345, 0, 344, 348, 346, 299, 351, - 355, 353, 357, 358, 359, 0, 0, 0, 120, 120, - 114, 0, 0, 0, 0, 0, 365, 368, 369, 0, - 0, 10, 1, 5, 6, 7, 237, 0, 56, 68, - 67, 72, 62, 57, 58, 60, 59, 63, 61, 0, - 73, 39, 40, 43, 41, 42, 44, 85, 115, 13, - 186, 0, 89, 92, 153, 155, 161, 169, 160, 159, - 387, 391, 268, 0, 387, 168, 171, 0, 95, 247, - 122, 373, 269, 270, 99, 0, 0, 0, 0, 0, - 0, 144, 0, 55, 74, 69, 71, 75, 0, 263, - 0, 0, 252, 254, 244, 0, 0, 0, 0, 0, + 0, 3, 241, 245, 249, 243, 252, 254, 382, 0, + 0, 53, 49, 50, 51, 52, 77, 78, 79, 80, + 82, 0, 0, 0, 257, 257, 257, 257, 257, 257, + 203, 81, 83, 84, 384, 0, 0, 133, 0, 396, + 87, 88, 89, 0, 0, 135, 136, 137, 138, 139, + 140, 0, 320, 328, 322, 309, 337, 309, 309, 343, + 311, 350, 352, 305, 357, 309, 364, 0, 127, 131, + 126, 108, 121, 121, 107, 0, 97, 0, 0, 0, + 0, 374, 0, 0, 0, 299, 300, 301, 302, 303, + 304, 9, 0, 2, 4, 0, 12, 14, 20, 34, + 46, 0, 0, 35, 47, 0, 85, 99, 100, 23, + 103, 111, 112, 109, 110, 106, 104, 105, 101, 102, + 27, 28, 29, 30, 31, 32, 33, 15, 17, 18, + 19, 36, 16, 0, 186, 92, 0, 271, 0, 0, + 0, 22, 24, 37, 276, 277, 278, 280, 279, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 21, 25, 26, + 38, 94, 250, 247, 0, 275, 0, 0, 0, 0, + 0, 0, 173, 175, 431, 432, 433, 409, 407, 410, + 411, 408, 413, 412, 416, 415, 414, 434, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 430, 429, 0, 435, 142, 54, 0, 55, 48, 0, + 0, 71, 0, 0, 0, 0, 263, 260, 242, 0, + 257, 244, 246, 249, 253, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 218, 0, 0, 231, 231, 0, 0, 0, 187, 0, - 0, 205, 202, 11, 0, 0, 375, 379, 380, 376, - 377, 133, 295, 299, 319, 299, 299, 323, 299, 321, - 313, 315, 0, 316, 299, 308, 300, 330, 336, 302, - 338, 296, 0, 352, 356, 129, 0, 123, 0, 124, - 125, 97, 116, 118, 0, 363, 366, 367, 370, 371, - 8, 66, 64, 0, 156, 0, 0, 0, 38, 154, - 0, 390, 0, 0, 393, 0, 162, 0, 120, 182, - 184, 183, 181, 0, 0, 0, 0, 0, 0, 173, - 152, 147, 149, 148, 0, 0, 145, 142, 0, 264, - 265, 266, 0, 0, 0, 0, 233, 235, 236, 218, - 218, 218, 218, 233, 0, 0, 0, 0, 0, 0, - 0, 231, 231, 0, 0, 218, 218, 218, 232, 218, - 0, 0, 218, 203, 204, 382, 0, 0, 306, 320, - 324, 299, 325, 322, 314, 309, 0, 0, 349, 0, - 0, 121, 0, 0, 360, 0, 157, 158, 90, 388, - 0, 395, 392, 170, 0, 0, 94, 126, 177, 180, - 175, 0, 0, 0, 150, 0, 0, 140, 0, 255, - 257, 0, 0, 261, 260, 218, 234, 0, 0, 0, - 0, 230, 0, 220, 221, 223, 224, 227, 228, 225, - 226, 222, 188, 0, 0, 0, 0, 0, 0, 0, - 0, 383, 381, 326, 298, 297, 0, 0, 130, 117, - 119, 361, 362, 65, 0, 0, 394, 164, 0, 167, - 178, 0, 0, 151, 146, 143, 258, 262, 0, 191, - 189, 192, 193, 233, 219, 197, 198, 195, 196, 0, - 0, 0, 0, 0, 207, 0, 0, 190, 350, 0, - 389, 396, 0, 163, 176, 179, 194, 229, 0, 0, - 0, 0, 0, 0, 231, 0, 131, 165, 0, 0, - 0, 210, 0, 0, 216, 199, 206, 0, 200, 208, - 209, 0, 0, 212, 0, 213, 231, 0, 217, 215, - 0, 211, 214 + 384, 0, 388, 0, 0, 0, 394, 395, 314, 315, + 313, 309, 309, 309, 327, 0, 0, 321, 309, 0, + 317, 338, 309, 339, 341, 344, 345, 342, 0, 349, + 311, 347, 351, 353, 355, 0, 354, 358, 356, 309, + 361, 365, 363, 367, 368, 369, 0, 0, 0, 0, + 119, 119, 113, 0, 0, 0, 0, 0, 375, 378, + 379, 0, 0, 10, 1, 5, 6, 7, 241, 0, + 57, 69, 68, 73, 63, 58, 59, 61, 60, 64, + 62, 0, 74, 40, 41, 44, 42, 43, 45, 86, + 114, 13, 187, 0, 90, 93, 154, 156, 162, 170, + 161, 160, 397, 401, 272, 0, 397, 169, 172, 0, + 96, 251, 121, 383, 273, 274, 0, 0, 0, 0, + 0, 0, 145, 0, 56, 75, 70, 72, 76, 0, + 267, 0, 0, 256, 258, 248, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 221, 0, 0, 235, 235, 0, 0, 0, + 0, 188, 0, 0, 207, 204, 11, 0, 0, 385, + 389, 390, 386, 387, 134, 305, 309, 329, 309, 309, + 333, 309, 331, 323, 325, 0, 326, 309, 318, 310, + 340, 346, 312, 348, 306, 0, 362, 366, 128, 0, + 132, 122, 0, 123, 124, 98, 115, 117, 0, 373, + 376, 377, 380, 381, 8, 67, 65, 0, 157, 0, + 0, 0, 39, 155, 0, 400, 0, 0, 403, 0, + 163, 0, 119, 183, 185, 184, 182, 0, 0, 0, + 0, 0, 0, 174, 153, 148, 150, 149, 0, 0, + 146, 143, 0, 268, 269, 270, 0, 0, 0, 0, + 237, 239, 240, 221, 221, 221, 221, 237, 0, 0, + 0, 0, 0, 0, 0, 235, 235, 0, 0, 0, + 221, 221, 221, 236, 221, 221, 0, 0, 221, 205, + 206, 392, 0, 0, 316, 330, 334, 309, 335, 332, + 324, 319, 0, 0, 359, 0, 0, 120, 0, 0, + 370, 0, 158, 159, 91, 398, 0, 405, 402, 171, + 0, 0, 95, 125, 178, 181, 176, 0, 0, 0, + 151, 0, 0, 141, 0, 259, 261, 0, 0, 265, + 264, 221, 238, 0, 0, 0, 0, 234, 0, 223, + 224, 226, 227, 230, 231, 228, 229, 232, 225, 189, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, + 391, 336, 308, 307, 0, 0, 129, 116, 118, 371, + 372, 66, 0, 0, 404, 165, 0, 168, 179, 0, + 0, 152, 147, 144, 262, 266, 0, 192, 190, 193, + 194, 237, 222, 198, 199, 196, 197, 202, 0, 0, + 0, 0, 0, 0, 209, 0, 0, 191, 360, 0, + 399, 406, 0, 164, 177, 180, 195, 233, 0, 0, + 0, 0, 0, 0, 0, 235, 0, 130, 166, 0, + 0, 0, 212, 214, 0, 0, 219, 200, 208, 0, + 201, 210, 211, 0, 0, 215, 0, 216, 235, 0, + 220, 218, 0, 213, 217 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 85, 86, 87, 88, 89, 356, 91, 92, 93, - 228, 329, 340, 330, 331, 94, 95, 96, 97, 98, - 99, 478, 352, 100, 101, 102, 103, 104, 105, 106, - 459, 308, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 222, 505, 506, 353, 354, - 355, 357, 358, 575, 638, 120, 121, 122, 123, 124, - 125, 175, 176, 492, 126, 127, 258, 422, 663, 664, - 666, 693, 694, 534, 410, 537, 595, 538, 128, 129, - 130, 131, 165, 132, 133, 238, 239, 240, 512, 363, - 134, 135, 295, 279, 290, 136, 269, 137, 138, 139, - 276, 140, 273, 141, 142, 143, 144, 286, 145, 146, - 147, 148, 149, 297, 150, 151, 301, 152, 153, 154, - 155, 156, 157, 158, 169, 159, 426, 427, 428, 160, - 161, 162, 481, 359, 360, 223, 361 + -1, 92, 93, 94, 95, 96, 348, 98, 99, 100, + 218, 321, 332, 322, 323, 101, 102, 103, 104, 105, + 106, 472, 344, 107, 108, 109, 110, 111, 112, 453, + 300, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 212, 499, 500, 345, 346, + 347, 349, 350, 571, 636, 127, 128, 129, 130, 131, + 132, 182, 183, 486, 133, 134, 249, 415, 663, 664, + 666, 695, 696, 529, 402, 532, 591, 533, 135, 136, + 137, 138, 173, 139, 140, 228, 229, 230, 506, 355, + 141, 142, 143, 286, 270, 281, 144, 260, 145, 146, + 147, 267, 148, 264, 149, 150, 151, 152, 277, 153, + 154, 155, 156, 157, 288, 158, 159, 292, 160, 161, + 162, 163, 164, 165, 166, 177, 167, 419, 420, 421, + 168, 169, 170, 475, 351, 352, 213, 353 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -485 +#define YYPACT_NINF -479 static const yytype_int16 yypact[] = { - 392, -485, 32, -485, 42, -485, -485, -485, 49, -12, - 1337, 63, 91, -485, -485, -485, -485, -485, -485, -485, - -485, 1337, 1337, 172, 31, 31, 31, 31, 31, 31, - 145, -485, -485, -485, 830, 151, 161, -485, 102, -485, - -485, -485, -485, 138, 210, -485, -485, -485, -485, -485, - -485, 124, -485, 105, -33, 169, 190, -45, 176, -5, - 57, 231, 174, 34, 203, 35, 204, 56, 50, -485, - -485, 291, 291, -485, 1337, 251, 296, 297, 313, 320, - -485, 211, 242, -65, 279, 330, 559, -485, 17, -485, - -485, -485, -485, -485, 23, 159, -485, -485, 230, 1444, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, 995, 292, 158, 680, - 265, 1337, 680, 1337, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -8, 283, -485, 316, -485, 156, 193, - 158, 164, 254, 255, -31, -485, 168, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, 167, -485, 166, -485, 280, -485, -485, 1337, - 318, 315, 1337, 175, 177, 178, 179, -485, -485, 308, - 31, -485, -485, 42, -485, -485, 272, 185, 186, 188, - 189, 171, 191, 192, 194, 195, 201, 196, 68, -485, - 202, 244, 276, 282, 232, -485, -485, -485, 247, -485, - 26, -36, 30, -485, -32, 286, -485, 150, 289, -485, - -485, 176, -485, -485, -485, 290, -485, 293, -485, 243, - -485, -485, -485, -485, 266, -485, 208, -485, 176, -485, - 267, -485, -485, -485, -485, 300, 233, 301, 256, 256, - -485, 1337, 305, 306, 307, 309, 278, 294, -485, 295, - 302, -485, -485, -485, -485, 346, -485, 328, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, 335, - 250, -485, -485, -485, -485, -485, -485, 12, -485, -485, - -485, 9, 404, 158, -485, -485, -485, -485, -485, -485, - 298, 1112, -485, 406, 298, -485, -485, 407, -4, -485, - 291, -485, -485, -485, 158, 33, 261, 262, 268, 106, - -20, 14, 1337, -485, -485, -485, -485, -485, 321, 223, - 354, -14, -485, -485, -485, 269, 39, 39, 39, 39, - -83, 270, 277, 281, 284, 285, 287, 288, 317, 319, - -485, 39, 39, 39, 39, 322, 323, 39, -485, 355, - 356, -485, -485, -485, 390, 391, -485, 303, -485, -485, - -485, -485, 331, 176, -485, 176, 60, -485, 176, -485, - -485, -485, 369, -485, 176, -485, -485, -485, -485, -485, - -485, -52, 339, -485, -485, 388, 324, -485, 378, -485, - -485, -485, 437, 438, 325, -485, -485, -485, -485, -485, - -485, -485, -485, 299, -485, 314, 139, 680, -485, -485, - -35, -485, 1337, 1337, -485, 680, -13, 680, 256, -485, - -485, -485, -485, 33, 33, 33, 326, 381, 382, -485, - -485, -485, -485, -485, -11, -27, -485, 304, 327, -485, - -485, -485, 329, 383, -50, 332, 39, -485, -485, -485, - -485, -485, -485, 39, 384, 39, 39, 39, 39, 39, - 39, 39, 39, 39, -17, -485, -485, -485, -485, -485, - 333, 334, -485, -485, -485, -485, 429, 244, -485, -485, - -485, 176, -485, -485, -485, -485, 353, 377, 336, 347, - 417, -485, 419, 421, -2, 422, -485, -485, -485, -485, - 428, -485, 1230, -485, 433, 80, -485, -485, -485, -485, - -485, 33, 340, 345, -485, 435, 14, -485, 1337, -485, - -485, 348, 349, -485, -485, -485, -485, -16, -7, -1, - 0, -485, 357, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, 171, 2, 3, 5, 6, 86, 453, - 7, -485, -485, -485, -485, -485, 447, 361, -485, -485, - -485, -485, -485, -485, 363, 1337, -485, -485, 123, -485, - -485, 33, 33, -485, -485, -485, -485, -485, 8, -485, - -485, -485, -485, 39, -485, -485, -485, -485, -485, 367, - 368, 371, 405, 344, 413, 412, 365, -485, -485, 494, - -485, -485, 505, -485, -485, -485, -485, -485, 39, 39, - -70, 513, 560, 86, 39, 561, -485, -485, 424, 427, - 430, -485, 431, 432, 434, -485, -485, 18, -485, -485, - -485, 39, 39, -485, 513, -485, 39, 441, -485, -485, - 442, -485, -485 + 418, -479, 36, -479, -62, -479, -479, -479, 47, -14, + 1104, 50, 68, -479, -479, -479, -479, -479, -479, -479, + -479, 1104, 1104, 116, 8, 8, 8, 8, 8, 8, + 300, -479, -479, -479, 770, 109, 51, -479, 29, -479, + -479, -479, -479, 137, 157, -479, -479, -479, -479, -479, + -479, 129, -479, 221, 54, 71, 210, -54, 124, -2, + -36, 182, 172, 92, 217, -15, 224, 148, 49, 297, + -479, -479, 319, 319, -479, 1104, 285, 328, 330, 348, + 355, -479, 254, 291, -40, -479, -479, -479, -479, -479, + -479, 327, 379, 595, -479, -8, -479, -479, -479, -479, + -479, 11, 200, -479, -479, 360, 1212, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, 944, 341, 201, 95, 316, 1104, 95, + 1104, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, 0, 334, -479, 367, -479, 199, 218, 208, 305, + 308, -11, -479, 230, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, 216, -479, 227, -479, 350, -479, -479, 1104, + 388, 385, 1104, 234, 235, 237, 238, -479, -479, 383, + 8, -479, -479, -62, -479, -479, 353, 256, 257, 263, + 264, 212, 267, 275, 277, 278, 279, 198, 280, 46, + -479, 286, 76, 380, 384, 345, -479, -479, -479, 351, + -479, -25, -44, 38, -479, -16, 386, -479, 207, 392, + -479, -479, 124, -479, -479, -479, 393, -479, 394, -479, + 346, -479, -479, -479, -479, 361, -479, 301, -479, 124, + -479, 363, -479, -479, -479, -479, 400, 329, 402, 403, + 354, 354, -479, 1104, 405, 406, 407, 409, 376, 377, + -479, 378, 397, -479, -479, -479, -479, 447, -479, 414, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, 417, 325, -479, -479, -479, -479, -479, -479, 13, + -479, -479, -479, 10, 489, 201, -479, -479, -479, -479, + -479, -479, 381, 206, -479, 490, 381, -479, -479, 491, + 3, -479, 319, -479, -479, -479, 120, 337, 338, 340, + 147, -14, 2, 1104, -479, -479, -479, -479, -479, 408, + 284, 439, -7, -479, -479, -479, 342, 136, 136, 136, + 136, -27, 343, 347, 349, 352, 356, 357, 358, 359, + 364, 365, -479, 136, 136, 136, 136, 136, 366, 368, + 136, -479, 443, 444, -479, -479, -479, 470, 471, -479, + 370, -479, -479, -479, -479, 410, 124, -479, 124, 41, + -479, 124, -479, -479, -479, 451, -479, 124, -479, -479, + -479, -479, -479, -479, -69, 427, -479, -479, 464, 387, + -479, -479, 468, -479, -479, -479, 532, 535, 389, -479, + -479, -479, -479, -479, -479, -479, -479, 390, -479, 382, + 169, 95, -479, -479, -29, -479, 1104, 1104, -479, 95, + -9, 95, 354, -479, -479, -479, -479, 120, 120, 120, + 416, 506, 515, -479, -479, -479, -479, -479, 7, 110, + -479, 429, 431, -479, -479, -479, 432, 538, -53, 442, + 136, -479, -479, -479, -479, -479, -479, 136, 550, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, -13, + -479, -479, -479, -479, -479, -479, 450, 452, -479, -479, + -479, -479, 574, 76, -479, -479, -479, 124, -479, -479, + -479, -479, 521, 522, 460, 486, 559, -479, 560, 561, + 26, 562, -479, -479, -479, -479, 563, -479, 1070, -479, + 569, 70, -479, -479, -479, -479, -479, 120, 472, 473, + -479, 572, 2, -479, 1104, -479, -479, 474, 475, -479, + -479, -479, -479, -5, -4, -3, -1, -479, 479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + 212, 9, 15, 17, 18, 19, 140, 589, 20, -479, + -479, -479, -479, -479, 578, 481, -479, -479, -479, -479, + -479, -479, 480, 1104, -479, -479, 111, -479, -479, 120, + 120, -479, -479, -479, -479, -479, 21, -479, -479, -479, + -479, 136, -479, -479, -479, -479, -479, -479, 482, 483, + 484, 485, 487, 488, 492, 495, 496, -479, -479, 585, + -479, -479, 587, -479, -479, -479, -479, -479, 136, 136, + -59, 508, 588, 633, 140, 136, 652, -479, -479, 510, + 511, 514, -479, -479, 516, 513, 518, -479, -479, 42, + -479, -479, -479, 136, 136, -479, 588, -479, 136, 517, + -479, -479, 519, -479, -479 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -485, -485, -485, 520, 575, 484, 4, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, 448, -485, -485, -485, -485, -485, -485, -485, - -296, -62, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, 525, 55, -485, 36, -148, -302, - -485, -129, 45, -485, -485, 126, 147, 163, 187, 200, - -485, 241, -485, -477, 496, -485, -485, -485, -57, -485, - -485, -77, -485, -309, 15, -387, -484, -391, -485, -485, - -485, -485, 386, -485, -485, 264, 393, -485, -485, -485, - -485, -485, 198, -56, 342, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, 85, -485, - -485, 540, 271, -485, 173, -485, -10 + -479, -479, -479, 607, 668, 571, 1, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, 534, -479, -479, -479, -479, -479, -479, -287, + -60, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, 605, 632, -479, 126, -146, -281, + -479, -134, 138, -479, -479, 128, 131, 141, 151, 164, + -479, 339, -479, -455, 577, -479, -479, -479, 28, -479, + -479, 12, -479, -227, 103, -402, -478, -381, -479, -479, + -479, -479, 494, -479, -479, 253, 493, -479, -479, -479, + -479, -479, -479, 290, -55, 436, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, 174, + -479, -479, 621, 369, -479, 97, -479, -10 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -442 +#define YYTABLE_NINF -435 static const yytype_int16 yytable[] = { - 224, 282, 283, 365, 90, 519, 520, 521, 522, 299, - 309, 230, 231, 460, 326, 368, 578, 579, 580, -91, - 535, 536, 374, -92, 612, 649, 542, 539, 326, 3, - 4, 5, 6, 7, 650, 592, 10, -166, 90, 601, - 651, 652, 24, 655, 656, 690, 657, 658, 667, 676, - 569, 479, 318, 440, 378, 319, 24, 25, 26, 27, - 28, 29, -441, 500, 224, 171, 479, 324, 166, 170, - 556, 514, 479, 171, 584, 233, 234, 305, 172, 173, - 284, 435, 225, 631, 226, 326, 172, 173, 278, 224, - 90, 523, 436, 274, 524, 235, 441, 278, 328, 501, - 275, 442, 341, 515, 640, 320, 691, 281, 39, 418, - 419, 420, 163, 24, 502, 632, 236, 167, 489, 168, - 229, 557, 306, 285, 517, 596, 593, 227, 518, 310, - 90, 503, 596, 490, 603, 604, 605, 606, 607, 608, - 570, 379, 611, 433, 609, 610, 586, 438, 237, 587, - 491, 293, 174, 421, 348, 294, 613, 613, -166, 278, - 174, 585, 574, 278, 674, 675, 613, 351, 278, 677, - 164, 351, 613, 613, 479, 613, 613, 551, 613, 613, - 613, 613, 298, -441, 351, 474, 504, 659, 325, -441, - 287, 496, 577, 278, 705, 327, 288, 289, 706, 660, - 661, 232, 662, 476, 497, 498, 302, 303, 304, 261, - 597, 598, 599, 600, 434, 437, 439, 262, 263, 384, - 333, 445, 387, 265, 342, 447, 614, 615, 616, 246, - 617, 270, 271, 620, 272, 326, 3, 4, 5, 6, - 7, 334, 453, 267, 268, 343, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 400, 335, 257, 372, - 373, 344, 596, 24, 25, 26, 27, 28, 29, 509, - 510, 511, 401, 402, 403, 404, 264, 405, 406, 407, - 408, 336, 444, 278, 409, 345, 648, 688, 689, 241, - 242, 243, 244, 245, 337, 266, 672, 697, 346, 673, - 277, 461, 278, 424, 364, 425, 366, 280, 488, 278, - 707, 708, 415, 416, 351, 567, 291, 292, 307, 710, - 296, 300, 311, 312, 313, 314, 315, 317, 316, 321, - 322, 339, 30, 351, 362, 369, 370, 371, 375, 376, - 377, 380, 381, 382, 383, 385, 386, 392, 568, 431, - 388, 484, 389, 390, 391, 475, 573, 395, 576, 396, - 397, 429, 398, 399, 432, 411, 412, 430, 413, 414, - 417, 443, 507, 423, 446, 448, 287, 549, 449, 550, - 552, 452, 553, 451, 454, 455, 457, 456, 555, 458, - 462, 463, 464, 1, 465, 466, 470, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 467, 468, 471, 16, 17, 18, 19, 20, 469, - 472, 21, 22, 473, 23, 24, 25, 26, 27, 28, - 29, 477, 30, 485, 487, 493, 494, 480, 508, 513, - 543, 544, 495, 516, 525, 31, 32, 33, 34, 35, - 545, 526, 294, 546, 554, 527, 558, 36, 528, 529, - 559, 530, 531, 561, 562, 563, 582, 583, 591, 602, - 624, 565, 571, 572, 37, 38, 547, 39, 40, 41, - 42, 588, 43, 44, 45, 46, 47, 48, 49, 50, - 566, 532, 621, 533, 625, 623, 540, 541, 560, 564, - 581, 627, 628, 589, 629, 590, 630, 633, 594, 626, - 51, 618, 619, 634, 641, 52, 53, 54, 637, 642, - 643, 665, 55, 682, 646, 647, 56, 57, 58, 59, - 60, 653, 668, 61, 62, 669, 63, 64, 65, 670, - 66, 67, 678, 679, 685, 68, 680, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 636, 84, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 645, 686, - 681, 16, 17, 18, 19, 20, 683, 684, 21, 22, - 687, 23, 24, 25, 26, 27, 28, 29, 692, 30, - 699, 695, 698, 700, 701, 702, 323, 704, 703, 260, - 349, 367, 31, 32, 33, 34, 35, 711, 712, 332, - 639, 499, 644, 350, 36, 671, 696, 709, 654, 394, - 548, 450, 622, 393, 338, 486, 0, 0, 0, 0, - 0, 37, 38, 0, 39, 40, 41, 42, 0, 43, - 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, - 0, 0, 52, 53, 54, 326, 0, 0, 0, 55, - 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, - 61, 62, 0, 63, 64, 65, 0, 66, 67, 0, - 0, 0, 68, 24, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 0, - 84, 0, 0, 177, 178, 179, 180, 181, 182, 0, - 0, 0, 183, 0, 184, 185, 186, 187, 188, 189, - 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 0, 0, 208, - 209, 0, 210, 0, 0, 0, 211, 212, 0, 213, - 0, 214, 215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 216, 0, 0, 0, 217, 0, 0, - 0, 218, 219, 0, 220, 2, 3, 4, 5, 6, + 214, 97, 273, 274, 534, 357, 513, 514, 515, 516, + 290, 220, 221, 301, 454, 318, 318, 3, 4, 5, + 6, 7, 530, 531, 10, 360, 535, -92, 609, 538, + -93, 588, 574, 575, 576, 97, 647, 648, 649, 597, + 650, -167, 316, 24, 24, 25, 26, 27, 28, 29, + 653, 494, 223, 224, 552, 565, 654, 691, 655, 656, + 657, 667, 676, -434, 473, 214, 174, 172, 433, 215, + 178, 216, 225, 369, 428, 318, 296, 508, 310, 473, + 269, 311, 275, 179, 180, 429, 495, 411, 412, 413, + 269, 580, 226, 426, 97, 39, 340, 219, 278, 272, + 318, 496, 320, 24, 279, 280, 333, 253, 254, 269, + 629, 509, 553, 434, 217, 175, 171, 176, 435, 269, + 497, 297, 638, 605, 606, 692, 227, 276, 24, 592, + 414, 589, 312, 289, 97, 417, 592, 418, 599, 600, + 601, 602, 603, 604, 630, 222, 607, 608, 184, 185, + 186, 187, 188, 189, 566, 517, 431, 190, 518, 547, + 191, 192, 193, 194, 195, 196, 181, 252, 610, 370, + -167, 317, 269, 677, 570, 269, 610, 610, 610, 197, + 610, 265, 498, 343, 674, 675, 343, 581, 266, 473, + 610, 319, -434, 343, 468, 573, 610, 470, 610, 610, + 610, 610, 610, 268, 483, 269, 427, 430, 432, 375, + 284, 255, 378, 438, 285, 198, 199, 440, 200, 484, + 511, 256, 201, 202, 512, 203, 707, 204, 205, 325, + 708, 490, 326, 334, 446, 356, 335, 358, 485, 206, + 658, 257, 327, 207, 491, 492, 336, 208, 209, 258, + 259, 210, 328, 659, 660, 661, 337, 662, 269, 184, + 185, 186, 187, 188, 189, 329, 282, 211, 190, 338, + 592, 191, 192, 193, 194, 195, 196, 476, 231, 232, + 233, 234, 235, 699, 364, 365, 593, 594, 595, 596, + 197, 582, 672, 455, 583, 673, 391, 689, 690, 293, + 294, 295, 482, 611, 612, 613, 712, 614, 615, 408, + 409, 618, 392, 393, 394, 395, 283, 396, 397, 398, + 399, 400, 709, 710, 298, 401, 198, 199, 271, 200, + 503, 504, 505, 201, 202, 287, 203, 564, 204, 205, + 437, 269, 291, 478, 469, 569, 299, 572, 261, 262, + 206, 263, 343, 563, 207, 304, 303, 305, 208, 209, + 306, 307, 210, 501, 646, 318, 3, 4, 5, 6, + 7, 545, 308, 546, 548, 309, 549, 313, 211, 314, + 331, 30, 551, 236, 343, 354, 361, 362, 363, 367, + 366, 477, 368, 24, 25, 26, 27, 28, 29, 372, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 371, 373, 248, 374, 376, 377, 379, 380, 1, + 381, 382, 383, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 386, 387, 388, + 16, 17, 18, 19, 20, 389, 390, 21, 22, 403, + 23, 24, 25, 26, 27, 28, 29, 404, 30, 405, + 406, 407, 410, 424, 422, 416, 567, 568, 423, 425, + 436, 31, 32, 33, 34, 35, 439, 441, 442, 444, + 278, 447, 445, 36, 448, 449, 450, 451, 452, 456, + 457, 458, 621, 459, 460, 461, 462, 464, 465, 37, + 38, 466, 39, 40, 41, 42, 467, 43, 44, 45, + 46, 47, 48, 49, 50, 463, 471, 479, 481, 487, + 488, 474, 489, 507, 510, 519, 502, 539, 540, 520, + 541, 521, 285, 542, 522, 550, 555, 51, 523, 524, + 525, 526, 52, 53, 54, 554, 527, 528, 536, 55, + 537, 543, 557, 56, 57, 58, 59, 60, 634, 558, + 61, 62, 559, 63, 64, 65, 562, 66, 67, 556, + 561, 560, 68, 69, 643, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 578, 85, 86, 87, 88, 89, 90, 91, 577, 579, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 584, 585, 586, 16, 17, 18, + 19, 20, 587, 671, 21, 22, 590, 23, 24, 25, + 26, 27, 28, 29, 598, 30, 616, 619, 617, 622, + 623, 624, 625, 626, 627, 628, 631, 632, 31, 32, + 33, 34, 35, 635, 639, 640, 641, 665, 644, 645, + 36, 651, 668, 669, 670, 678, 679, 680, 681, 687, + 682, 688, 694, 684, 697, 683, 37, 38, 685, 39, + 40, 41, 42, 686, 43, 44, 45, 46, 47, 48, + 49, 50, 693, 700, 701, 702, 703, 705, 704, 706, + 315, 713, 251, 714, 341, 359, 324, 302, 642, 637, + 493, 342, 698, 652, 51, 544, 443, 620, 711, 52, + 53, 54, 330, 384, 0, 480, 55, 385, 0, 0, + 56, 57, 58, 59, 60, 0, 0, 61, 62, 0, + 63, 64, 65, 0, 66, 67, 0, 0, 0, 68, + 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 0, 85, 86, + 87, 88, 89, 90, 91, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, - 221, 0, 16, 17, 18, 19, 20, 0, 0, 21, + 0, 0, 16, 17, 18, 19, 20, 0, 0, 21, 22, 0, 23, 24, 25, 26, 27, 28, 29, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 31, 32, 33, 259, 35, 0, 0, + 0, 0, 0, 31, 32, 33, 250, 35, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 37, 38, 0, 39, 40, 41, 42, 0, - 43, 44, 45, 46, 47, 48, 49, 50, 0, 0, + 0, 37, 38, 0, 39, 40, 41, 42, 0, 43, + 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, - 0, 0, 0, 52, 53, 54, 0, 0, 0, 0, - 55, 0, 0, 0, 56, 57, 58, 59, 60, 0, - 0, 61, 62, 0, 63, 64, 65, 0, 66, 67, - 0, 0, 0, 68, 0, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 16, 17, 18, - 19, 20, 0, 0, 21, 22, 0, 23, 24, 25, - 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, - 33, 259, 35, 0, 0, 0, 0, 0, 0, 0, - 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 37, 38, 0, - 39, 40, 41, 42, 0, 43, 44, 45, 46, 47, - 48, 49, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 0, 0, 0, 0, 52, 53, 54, 0, 0, 0, + 0, 55, 0, 0, 0, 56, 57, 58, 59, 60, + 0, 0, 61, 62, 0, 63, 64, 65, 0, 66, + 67, 0, 0, 0, 68, 69, 0, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 0, 85, 86, 87, 88, 89, 90, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 16, 17, 18, 19, + 20, 0, 0, 21, 22, 0, 23, 24, 25, 26, + 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, + 250, 35, 0, 0, 0, 0, 0, 0, 0, 36, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 37, 38, 0, 39, 40, + 41, 42, 0, 43, 44, 45, 46, 47, 48, 49, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 52, 53, 54, 0, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, 61, 62, 0, 63, - 64, 65, 0, 66, 67, 0, 0, 0, 68, 0, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 177, 178, 179, 180, 181, - 182, 0, 0, 0, 183, 0, 184, 185, 186, 187, - 188, 189, 190, 482, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 191, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, - 0, 208, 209, 0, 210, 0, 0, 0, 211, 212, - 0, 213, 0, 214, 215, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 216, 0, 0, 0, 217, - 0, 0, 0, 218, 219, 0, 220, 0, 0, 0, + 64, 65, 0, 66, 67, 0, 0, 0, 68, 69, + 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 0, 85, 86, 87, + 88, 89, 90, 184, 185, 186, 187, 188, 189, 0, + 0, 0, 190, 0, 0, 191, 192, 193, 194, 195, + 196, 633, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 197, 0, 0, 184, 185, 186, + 187, 188, 189, 0, 0, 0, 190, 0, 0, 191, + 192, 193, 194, 195, 196, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, + 198, 199, 0, 200, 0, 0, 0, 201, 202, 0, + 203, 0, 204, 205, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 206, 0, 0, 0, 207, 0, + 0, 0, 208, 209, 198, 199, 210, 200, 0, 0, + 0, 201, 202, 0, 203, 0, 204, 205, 0, 0, + 0, 0, 211, 0, 0, 0, 0, 0, 206, 0, + 0, 0, 207, 0, 0, 0, 208, 209, 0, 0, + 210, 0, 0, 0, 0, 184, 185, 186, 187, 188, + 189, 0, 0, 0, 190, 0, 211, 191, 192, 193, + 194, 195, 196, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 221, 177, 178, 179, 180, 181, 182, 483, - 0, 0, 183, 0, 184, 185, 186, 187, 188, 189, - 190, 635, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 0, 0, 208, - 209, 0, 210, 0, 0, 0, 211, 212, 0, 213, - 0, 214, 215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 216, 0, 0, 0, 217, 0, 0, - 0, 218, 219, 0, 220, 0, 0, 0, 0, 0, - 177, 178, 179, 180, 181, 182, 0, 0, 0, 183, - 221, 184, 185, 186, 187, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 0, 0, 208, 209, 0, 210, - 0, 0, 0, 211, 212, 0, 213, 0, 214, 215, + 0, 0, 198, 199, 0, 200, 0, 0, 0, 201, + 202, 0, 203, 0, 204, 205, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, + 207, 0, 0, 0, 208, 209, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 216, 0, 0, 0, 217, 0, 0, 0, 218, 219, - 0, 220, 0, 0, 0, 0, 0, 177, 178, 179, - 180, 181, 182, 0, 0, 0, 183, 221, 184, 185, - 186, 187, 188, 189, 190, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 347, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 0, 0, 208, 209, 0, 210, 0, 0, 0, - 211, 212, 0, 213, 0, 214, 215, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, - 0, 217, 0, 0, 0, 218, 219, 0, 220, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 221 + 0, 0, 0, 0, 211 }; static const yytype_int16 yycheck[] = { - 10, 57, 58, 132, 0, 396, 397, 398, 399, 65, - 72, 21, 22, 309, 5, 163, 493, 494, 495, 27, - 411, 412, 170, 27, 41, 41, 417, 414, 5, 6, - 7, 8, 9, 10, 41, 85, 13, 50, 34, 523, - 41, 41, 33, 41, 41, 115, 41, 41, 41, 41, - 85, 353, 117, 85, 85, 120, 33, 34, 35, 36, - 37, 38, 50, 49, 74, 85, 368, 50, 19, 81, - 122, 85, 374, 85, 85, 44, 45, 27, 98, 99, - 85, 117, 19, 85, 21, 5, 98, 99, 133, 99, - 86, 174, 128, 126, 177, 64, 128, 133, 94, 85, - 133, 133, 98, 117, 581, 170, 176, 152, 85, 41, - 42, 43, 80, 33, 100, 117, 85, 68, 85, 70, - 29, 173, 72, 128, 85, 516, 176, 64, 89, 74, - 126, 117, 523, 100, 525, 526, 527, 528, 529, 530, - 175, 172, 533, 117, 531, 532, 173, 117, 117, 176, - 117, 117, 172, 85, 99, 121, 173, 173, 171, 133, - 172, 172, 175, 133, 641, 642, 173, 175, 133, 653, - 128, 175, 173, 173, 476, 173, 173, 117, 173, 173, - 173, 173, 147, 171, 175, 176, 172, 101, 171, 177, - 133, 85, 488, 133, 176, 172, 139, 140, 180, 113, - 114, 29, 116, 351, 98, 99, 150, 151, 152, 58, - 519, 520, 521, 522, 270, 271, 272, 56, 57, 229, - 94, 277, 232, 85, 98, 281, 535, 536, 537, 84, - 539, 126, 127, 542, 129, 5, 6, 7, 8, 9, - 10, 94, 298, 119, 120, 98, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 85, 94, 113, 66, - 67, 98, 653, 33, 34, 35, 36, 37, 38, 46, - 47, 48, 101, 102, 103, 104, 174, 106, 107, 108, - 109, 94, 132, 133, 113, 98, 595, 678, 679, 25, - 26, 27, 28, 29, 94, 85, 173, 684, 98, 176, - 131, 311, 133, 59, 131, 61, 133, 117, 370, 133, - 701, 702, 111, 112, 175, 176, 85, 143, 27, 706, - 117, 117, 71, 27, 27, 12, 6, 85, 117, 50, - 0, 172, 40, 175, 69, 52, 20, 181, 174, 85, - 85, 173, 175, 177, 64, 27, 31, 39, 477, 117, - 175, 361, 175, 175, 175, 351, 485, 85, 487, 174, - 174, 85, 174, 174, 117, 174, 174, 85, 174, 174, - 174, 85, 382, 171, 85, 85, 133, 433, 85, 435, - 436, 173, 438, 117, 117, 85, 85, 154, 444, 133, - 85, 85, 85, 1, 85, 117, 50, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 117, 117, 85, 22, 23, 24, 25, 26, 117, - 85, 29, 30, 173, 32, 33, 34, 35, 36, 37, - 38, 27, 40, 27, 27, 174, 174, 139, 117, 85, - 85, 85, 174, 174, 174, 53, 54, 55, 56, 57, - 60, 174, 121, 62, 85, 174, 117, 65, 174, 174, - 72, 174, 174, 85, 27, 27, 85, 85, 85, 85, - 117, 172, 482, 483, 82, 83, 173, 85, 86, 87, - 88, 177, 90, 91, 92, 93, 94, 95, 96, 97, - 176, 174, 63, 174, 117, 551, 174, 174, 174, 174, - 174, 154, 85, 176, 85, 176, 85, 85, 176, 173, - 118, 178, 178, 85, 174, 123, 124, 125, 85, 174, - 85, 68, 130, 179, 176, 176, 134, 135, 136, 137, - 138, 174, 85, 141, 142, 174, 144, 145, 146, 176, - 148, 149, 175, 175, 179, 153, 175, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 572, 171, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 588, 85, - 175, 22, 23, 24, 25, 26, 173, 175, 29, 30, - 85, 32, 33, 34, 35, 36, 37, 38, 85, 40, - 176, 41, 41, 176, 174, 174, 86, 173, 176, 34, - 126, 163, 53, 54, 55, 56, 57, 176, 176, 94, - 575, 380, 586, 127, 65, 635, 683, 704, 613, 243, - 432, 289, 547, 240, 94, 364, -1, -1, -1, -1, - -1, 82, 83, -1, 85, 86, 87, 88, -1, 90, - 91, 92, 93, 94, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, - -1, -1, 123, 124, 125, 5, -1, -1, -1, 130, - -1, -1, -1, 134, 135, 136, 137, 138, -1, -1, - 141, 142, -1, 144, 145, 146, -1, 148, 149, -1, - -1, -1, 153, 33, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, -1, -1, 53, 54, 55, 56, 57, 58, -1, - -1, -1, 62, -1, 64, 65, 66, 67, 68, 69, - 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, -1, 119, - 120, -1, 122, -1, -1, -1, 126, 127, -1, 129, - -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 143, -1, -1, -1, 147, -1, -1, - -1, 151, 152, -1, 154, 5, 6, 7, 8, 9, + 10, 0, 57, 58, 406, 139, 387, 388, 389, 390, + 65, 21, 22, 73, 301, 5, 5, 6, 7, 8, + 9, 10, 403, 404, 13, 171, 407, 27, 41, 410, + 27, 84, 487, 488, 489, 34, 41, 41, 41, 517, + 41, 50, 50, 33, 33, 34, 35, 36, 37, 38, + 41, 49, 44, 45, 123, 84, 41, 116, 41, 41, + 41, 41, 41, 50, 345, 75, 19, 129, 84, 19, + 84, 21, 64, 84, 118, 5, 27, 84, 118, 360, + 134, 121, 84, 97, 98, 129, 84, 41, 42, 43, + 134, 84, 84, 118, 93, 84, 106, 29, 134, 153, + 5, 99, 101, 33, 140, 141, 105, 56, 57, 134, + 84, 118, 181, 129, 64, 68, 80, 70, 134, 134, + 118, 72, 577, 525, 526, 184, 118, 129, 33, 510, + 84, 184, 172, 148, 133, 59, 517, 61, 519, 520, + 521, 522, 523, 524, 118, 29, 527, 528, 53, 54, + 55, 56, 57, 58, 183, 182, 118, 62, 185, 118, + 65, 66, 67, 68, 69, 70, 180, 58, 181, 180, + 179, 179, 134, 651, 183, 134, 181, 181, 181, 84, + 181, 127, 180, 183, 639, 640, 183, 180, 134, 470, + 181, 180, 179, 183, 184, 482, 181, 343, 181, 181, + 181, 181, 181, 132, 84, 134, 261, 262, 263, 219, + 118, 182, 222, 268, 122, 120, 121, 272, 123, 99, + 84, 84, 127, 128, 88, 130, 184, 132, 133, 101, + 188, 84, 101, 105, 289, 138, 105, 140, 118, 144, + 100, 84, 101, 148, 97, 98, 105, 152, 153, 120, + 121, 156, 101, 113, 114, 115, 105, 117, 134, 53, + 54, 55, 56, 57, 58, 101, 84, 172, 62, 105, + 651, 65, 66, 67, 68, 69, 70, 71, 25, 26, + 27, 28, 29, 685, 66, 67, 513, 514, 515, 516, + 84, 181, 181, 303, 184, 184, 84, 678, 679, 151, + 152, 153, 362, 530, 531, 532, 708, 534, 535, 111, + 112, 538, 100, 101, 102, 103, 144, 105, 106, 107, + 108, 109, 703, 704, 27, 113, 120, 121, 118, 123, + 46, 47, 48, 127, 128, 118, 130, 471, 132, 133, + 133, 134, 118, 353, 343, 479, 27, 481, 127, 128, + 144, 130, 183, 184, 148, 27, 71, 27, 152, 153, + 12, 6, 156, 373, 591, 5, 6, 7, 8, 9, + 10, 426, 118, 428, 429, 84, 431, 50, 172, 0, + 180, 40, 437, 83, 183, 69, 52, 20, 189, 84, + 182, 185, 84, 33, 34, 35, 36, 37, 38, 183, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 181, 185, 113, 64, 27, 31, 183, 183, 1, + 183, 183, 39, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 84, 182, 182, + 22, 23, 24, 25, 26, 182, 182, 29, 30, 182, + 32, 33, 34, 35, 36, 37, 38, 182, 40, 182, + 182, 182, 182, 118, 84, 179, 476, 477, 84, 118, + 84, 53, 54, 55, 56, 57, 84, 84, 84, 118, + 134, 118, 181, 65, 84, 156, 84, 84, 134, 84, + 84, 84, 547, 84, 118, 118, 118, 50, 84, 81, + 82, 84, 84, 85, 86, 87, 181, 89, 90, 91, + 92, 93, 94, 95, 96, 118, 27, 27, 27, 182, + 182, 140, 182, 84, 182, 182, 118, 84, 84, 182, + 60, 182, 122, 62, 182, 84, 72, 119, 182, 182, + 182, 182, 124, 125, 126, 118, 182, 182, 182, 131, + 182, 181, 84, 135, 136, 137, 138, 139, 568, 27, + 142, 143, 27, 145, 146, 147, 184, 149, 150, 182, + 180, 182, 154, 155, 584, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 84, 173, 174, 175, 176, 177, 178, 179, 182, 84, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 185, 184, 184, 22, 23, 24, + 25, 26, 84, 633, 29, 30, 184, 32, 33, 34, + 35, 36, 37, 38, 84, 40, 186, 63, 186, 118, + 118, 181, 156, 84, 84, 84, 84, 84, 53, 54, + 55, 56, 57, 84, 182, 182, 84, 68, 184, 184, + 65, 182, 84, 182, 184, 183, 183, 183, 183, 84, + 183, 84, 84, 181, 41, 187, 81, 82, 183, 84, + 85, 86, 87, 187, 89, 90, 91, 92, 93, 94, + 95, 96, 184, 41, 184, 184, 182, 184, 182, 181, + 93, 184, 34, 184, 133, 171, 101, 75, 582, 571, + 371, 134, 684, 610, 119, 425, 280, 543, 706, 124, + 125, 126, 101, 230, -1, 356, 131, 233, -1, -1, + 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, + 145, 146, 147, -1, 149, 150, -1, -1, -1, 154, + 155, -1, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, -1, 173, 174, + 175, 176, 177, 178, 179, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, - 170, -1, 22, 23, 24, 25, 26, -1, -1, 29, + -1, -1, 22, 23, 24, 25, 26, -1, -1, 29, 30, -1, 32, 33, 34, 35, 36, 37, 38, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 82, 83, -1, 85, 86, 87, 88, -1, - 90, 91, 92, 93, 94, 95, 96, 97, -1, -1, + -1, 81, 82, -1, 84, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, 95, 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 118, -1, - -1, -1, -1, 123, 124, 125, -1, -1, -1, -1, - 130, -1, -1, -1, 134, 135, 136, 137, 138, -1, - -1, 141, 142, -1, 144, 145, 146, -1, 148, 149, - -1, -1, -1, 153, -1, 155, 156, 157, 158, 159, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 119, + -1, -1, -1, -1, 124, 125, 126, -1, -1, -1, + -1, 131, -1, -1, -1, 135, 136, 137, 138, 139, + -1, -1, 142, 143, -1, 145, 146, 147, -1, 149, + 150, -1, -1, -1, 154, 155, -1, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, -1, -1, -1, 22, 23, 24, - 25, 26, -1, -1, 29, 30, -1, 32, 33, 34, - 35, 36, 37, 38, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 53, 54, - 55, 56, 57, -1, -1, -1, -1, -1, -1, -1, - 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 82, 83, -1, - 85, 86, 87, 88, -1, 90, 91, 92, 93, 94, - 95, 96, 97, -1, -1, -1, -1, -1, -1, -1, + 170, 171, -1, 173, 174, 175, 176, 177, 178, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, -1, -1, -1, 22, 23, 24, 25, + 26, -1, -1, 29, 30, -1, 32, 33, 34, 35, + 36, 37, 38, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 53, 54, 55, + 56, 57, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 118, -1, -1, -1, -1, 123, 124, - 125, -1, -1, -1, -1, 130, -1, -1, -1, 134, - 135, 136, 137, 138, -1, -1, 141, 142, -1, 144, - 145, 146, -1, 148, 149, -1, -1, -1, 153, -1, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 53, 54, 55, 56, 57, - 58, -1, -1, -1, 62, -1, 64, 65, 66, 67, - 68, 69, 70, 71, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 85, -1, -1, + -1, -1, -1, -1, -1, 81, 82, -1, 84, 85, + 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, + 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - -1, 119, 120, -1, 122, -1, -1, -1, 126, 127, - -1, 129, -1, 131, 132, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 143, -1, -1, -1, 147, - -1, -1, -1, 151, 152, -1, 154, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 170, 53, 54, 55, 56, 57, 58, 177, - -1, -1, 62, -1, 64, 65, 66, 67, 68, 69, + -1, -1, -1, 119, -1, -1, -1, -1, 124, 125, + 126, -1, -1, -1, -1, 131, -1, -1, -1, 135, + 136, 137, 138, 139, -1, -1, 142, 143, -1, 145, + 146, 147, -1, 149, 150, -1, -1, -1, 154, 155, + -1, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, -1, 173, 174, 175, + 176, 177, 178, 53, 54, 55, 56, 57, 58, -1, + -1, -1, 62, -1, -1, 65, 66, 67, 68, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, -1, 119, - 120, -1, 122, -1, -1, -1, 126, 127, -1, 129, - -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 143, -1, -1, -1, 147, -1, -1, - -1, 151, 152, -1, 154, -1, -1, -1, -1, -1, - 53, 54, 55, 56, 57, 58, -1, -1, -1, 62, - 170, 64, 65, 66, 67, 68, 69, 70, -1, -1, + -1, -1, -1, -1, 84, -1, -1, 53, 54, 55, + 56, 57, 58, -1, -1, -1, 62, -1, -1, 65, + 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 84, -1, + 120, 121, -1, 123, -1, -1, -1, 127, 128, -1, + 130, -1, 132, 133, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 144, -1, -1, -1, 148, -1, + -1, -1, 152, 153, 120, 121, 156, 123, -1, -1, + -1, 127, 128, -1, 130, -1, 132, 133, -1, -1, + -1, -1, 172, -1, -1, -1, -1, -1, 144, -1, + -1, -1, 148, -1, -1, -1, 152, 153, -1, -1, + 156, -1, -1, -1, -1, 53, 54, 55, 56, 57, + 58, -1, -1, -1, 62, -1, 172, 65, 66, 67, + 68, 69, 70, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, -1, 119, 120, -1, 122, - -1, -1, -1, 126, 127, -1, 129, -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 143, -1, -1, -1, 147, -1, -1, -1, 151, 152, - -1, 154, -1, -1, -1, -1, -1, 53, 54, 55, - 56, 57, 58, -1, -1, -1, 62, 170, 64, 65, - 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, -1, 119, 120, -1, 122, -1, -1, -1, - 126, 127, -1, 129, -1, 131, 132, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 143, -1, -1, - -1, 147, -1, -1, -1, 151, 152, -1, 154, -1, + -1, -1, 120, 121, -1, 123, -1, -1, -1, 127, + 128, -1, 130, -1, 132, 133, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 144, -1, -1, -1, + 148, -1, -1, -1, 152, 153, -1, -1, 156, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 170 + -1, -1, -1, -1, 172 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1869,75 +1827,75 @@ static const yytype_uint16 yystos[] = 0, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 26, 29, 30, 32, 33, 34, 35, 36, 37, 38, - 40, 53, 54, 55, 56, 57, 65, 82, 83, 85, - 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, - 97, 118, 123, 124, 125, 130, 134, 135, 136, 137, - 138, 141, 142, 144, 145, 146, 148, 149, 153, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 171, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 197, 198, 199, 200, 201, 202, - 205, 206, 207, 208, 209, 210, 211, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 237, 238, 239, 240, 241, 242, 246, 247, 260, 261, - 262, 263, 265, 266, 272, 273, 277, 279, 280, 281, - 283, 285, 286, 287, 288, 290, 291, 292, 293, 294, - 296, 297, 299, 300, 301, 302, 303, 304, 305, 307, - 311, 312, 313, 80, 128, 264, 19, 68, 70, 306, - 81, 85, 98, 99, 172, 243, 244, 53, 54, 55, - 56, 57, 58, 62, 64, 65, 66, 67, 68, 69, - 70, 85, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 119, 120, - 122, 126, 127, 129, 131, 132, 143, 147, 151, 152, - 154, 170, 227, 317, 318, 19, 21, 64, 192, 29, - 318, 318, 29, 44, 45, 64, 85, 117, 267, 268, - 269, 267, 267, 267, 267, 267, 84, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 113, 248, 56, - 186, 58, 56, 57, 174, 85, 85, 119, 120, 278, - 126, 127, 129, 284, 126, 133, 282, 131, 133, 275, - 117, 152, 275, 275, 85, 128, 289, 133, 139, 140, - 276, 85, 143, 117, 121, 274, 117, 295, 147, 275, - 117, 298, 150, 151, 152, 27, 72, 27, 213, 213, - 227, 71, 27, 27, 12, 6, 117, 85, 117, 120, - 170, 50, 0, 185, 50, 171, 5, 172, 188, 193, - 195, 196, 226, 237, 238, 239, 240, 241, 313, 172, - 194, 188, 237, 238, 239, 240, 241, 85, 227, 187, - 246, 175, 204, 230, 231, 232, 188, 233, 234, 315, - 316, 318, 69, 271, 316, 233, 316, 204, 230, 52, - 20, 181, 66, 67, 230, 174, 85, 85, 85, 172, - 173, 175, 177, 64, 318, 27, 31, 318, 175, 175, - 175, 175, 39, 268, 264, 85, 174, 174, 174, 174, - 85, 101, 102, 103, 104, 106, 107, 108, 109, 113, - 256, 174, 174, 174, 174, 111, 112, 174, 41, 42, - 43, 85, 249, 171, 59, 61, 308, 309, 310, 85, - 85, 117, 117, 117, 275, 117, 128, 275, 117, 275, - 85, 128, 133, 85, 132, 275, 85, 275, 85, 85, - 276, 117, 173, 275, 117, 85, 154, 85, 133, 212, - 212, 318, 85, 85, 85, 85, 117, 117, 117, 117, - 50, 85, 85, 173, 176, 188, 230, 27, 203, 231, - 139, 314, 71, 177, 318, 27, 314, 27, 213, 85, - 100, 117, 245, 174, 174, 174, 85, 98, 99, 243, - 49, 85, 100, 117, 172, 228, 229, 318, 117, 46, - 47, 48, 270, 85, 85, 117, 174, 85, 89, 259, - 259, 259, 259, 174, 177, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 255, 259, 259, 257, 259, 257, - 174, 174, 259, 85, 85, 60, 62, 173, 274, 275, - 275, 117, 275, 275, 85, 275, 122, 173, 117, 72, - 174, 85, 27, 27, 174, 172, 176, 176, 233, 85, - 175, 318, 318, 233, 175, 235, 233, 212, 245, 245, - 245, 174, 85, 85, 85, 172, 173, 176, 177, 176, - 176, 85, 85, 176, 176, 258, 259, 255, 255, 255, - 255, 258, 85, 259, 259, 259, 259, 259, 259, 257, - 257, 259, 41, 173, 255, 255, 255, 255, 178, 178, - 255, 63, 310, 275, 117, 117, 173, 154, 85, 85, - 85, 85, 117, 85, 85, 71, 318, 85, 236, 234, - 245, 174, 174, 85, 229, 318, 176, 176, 255, 41, - 41, 41, 41, 174, 256, 41, 41, 41, 41, 101, - 113, 114, 116, 250, 251, 68, 252, 41, 85, 174, - 176, 318, 173, 176, 245, 245, 41, 258, 175, 175, - 175, 175, 179, 173, 175, 179, 85, 85, 259, 259, - 115, 176, 85, 253, 254, 41, 250, 257, 41, 176, - 176, 174, 174, 176, 173, 176, 180, 259, 259, 253, - 257, 176, 176 + 40, 53, 54, 55, 56, 57, 65, 81, 82, 84, + 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, + 96, 119, 124, 125, 126, 131, 135, 136, 137, 138, + 139, 142, 143, 145, 146, 147, 149, 150, 154, 155, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, + 178, 179, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 205, 206, 207, 208, 209, 210, 213, 214, 215, + 216, 217, 218, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 245, 246, 247, + 248, 249, 250, 254, 255, 268, 269, 270, 271, 273, + 274, 280, 281, 282, 286, 288, 289, 290, 292, 294, + 295, 296, 297, 299, 300, 301, 302, 303, 305, 306, + 308, 309, 310, 311, 312, 313, 314, 316, 320, 321, + 322, 80, 129, 272, 19, 68, 70, 315, 84, 97, + 98, 180, 251, 252, 53, 54, 55, 56, 57, 58, + 62, 65, 66, 67, 68, 69, 70, 84, 120, 121, + 123, 127, 128, 130, 132, 133, 144, 148, 152, 153, + 156, 172, 235, 326, 327, 19, 21, 64, 200, 29, + 327, 327, 29, 44, 45, 64, 84, 118, 275, 276, + 277, 275, 275, 275, 275, 275, 83, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 113, 256, + 56, 194, 58, 56, 57, 182, 84, 84, 120, 121, + 287, 127, 128, 130, 293, 127, 134, 291, 132, 134, + 284, 118, 153, 284, 284, 84, 129, 298, 134, 140, + 141, 285, 84, 144, 118, 122, 283, 118, 304, 148, + 284, 118, 307, 151, 152, 153, 27, 72, 27, 27, + 220, 220, 235, 71, 27, 27, 12, 6, 118, 84, + 118, 121, 172, 50, 0, 193, 50, 179, 5, 180, + 196, 201, 203, 204, 234, 245, 246, 247, 248, 249, + 322, 180, 202, 196, 245, 246, 247, 248, 249, 84, + 327, 195, 254, 183, 212, 238, 239, 240, 196, 241, + 242, 324, 325, 327, 69, 279, 325, 241, 325, 212, + 238, 52, 20, 189, 66, 67, 182, 84, 84, 84, + 180, 181, 183, 185, 64, 327, 27, 31, 327, 183, + 183, 183, 183, 39, 276, 272, 84, 182, 182, 182, + 182, 84, 100, 101, 102, 103, 105, 106, 107, 108, + 109, 113, 264, 182, 182, 182, 182, 182, 111, 112, + 182, 41, 42, 43, 84, 257, 179, 59, 61, 317, + 318, 319, 84, 84, 118, 118, 118, 284, 118, 129, + 284, 118, 284, 84, 129, 134, 84, 133, 284, 84, + 284, 84, 84, 285, 118, 181, 284, 118, 84, 156, + 84, 84, 134, 219, 219, 327, 84, 84, 84, 84, + 118, 118, 118, 118, 50, 84, 84, 181, 184, 196, + 238, 27, 211, 239, 140, 323, 71, 185, 327, 27, + 323, 27, 220, 84, 99, 118, 253, 182, 182, 182, + 84, 97, 98, 251, 49, 84, 99, 118, 180, 236, + 237, 327, 118, 46, 47, 48, 278, 84, 84, 118, + 182, 84, 88, 267, 267, 267, 267, 182, 185, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 263, + 267, 267, 265, 267, 265, 267, 182, 182, 267, 84, + 84, 60, 62, 181, 283, 284, 284, 118, 284, 284, + 84, 284, 123, 181, 118, 72, 182, 84, 27, 27, + 182, 180, 184, 184, 241, 84, 183, 327, 327, 241, + 183, 243, 241, 219, 253, 253, 253, 182, 84, 84, + 84, 180, 181, 184, 185, 184, 184, 84, 84, 184, + 184, 266, 267, 263, 263, 263, 263, 266, 84, 267, + 267, 267, 267, 267, 267, 265, 265, 267, 267, 41, + 181, 263, 263, 263, 263, 263, 186, 186, 263, 63, + 319, 284, 118, 118, 181, 156, 84, 84, 84, 84, + 118, 84, 84, 71, 327, 84, 244, 242, 253, 182, + 182, 84, 237, 327, 184, 184, 263, 41, 41, 41, + 41, 182, 264, 41, 41, 41, 41, 41, 100, 113, + 114, 115, 117, 258, 259, 68, 260, 41, 84, 182, + 184, 327, 181, 184, 253, 253, 41, 266, 183, 183, + 183, 183, 183, 187, 181, 183, 187, 84, 84, 267, + 267, 116, 184, 184, 84, 261, 262, 41, 258, 265, + 41, 184, 184, 182, 182, 184, 181, 184, 188, 267, + 267, 261, 265, 184, 184 }; #define yyerrok (yyerrstatus = 0) @@ -2945,42 +2903,42 @@ YYLTYPE yylloc; case 37: - { result->cur_stmt_type_ = OBPROXY_T_OTHERS; ;} + {;} break; - case 47: + case 38: - { result->cur_stmt_type_ = OBPROXY_T_CREATE; ;} + { result->cur_stmt_type_ = OBPROXY_T_OTHERS; ;} break; case 48: - { result->cur_stmt_type_ = OBPROXY_T_DROP; ;} + { result->cur_stmt_type_ = OBPROXY_T_CREATE; ;} break; case 49: - { result->cur_stmt_type_ = OBPROXY_T_ALTER; ;} + { result->cur_stmt_type_ = OBPROXY_T_DROP; ;} break; case 50: - { result->cur_stmt_type_ = OBPROXY_T_TRUNCATE; ;} + { result->cur_stmt_type_ = OBPROXY_T_ALTER; ;} break; case 51: - { result->cur_stmt_type_ = OBPROXY_T_RENAME; ;} + { result->cur_stmt_type_ = OBPROXY_T_TRUNCATE; ;} break; - case 53: + case 52: - { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_TABLE; ;} + { result->cur_stmt_type_ = OBPROXY_T_RENAME; ;} break; case 54: - { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_INDEX; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_TABLE; ;} break; case 55: @@ -2990,7 +2948,7 @@ YYLTYPE yylloc; case 56: - {;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_INDEX; ;} break; case 57: @@ -3030,6 +2988,11 @@ YYLTYPE yylloc; case 64: + {;} + break; + + case 65: + { ObProxyTextPsParseNode *node = NULL; malloc_parse_node(node); @@ -3038,7 +3001,7 @@ YYLTYPE yylloc; ;} break; - case 65: + case 66: { ObProxyTextPsParseNode *node = NULL; @@ -3048,7 +3011,7 @@ YYLTYPE yylloc; ;} break; - case 66: + case 67: { ObProxyTextPsParseNode *node = NULL; @@ -3058,7 +3021,7 @@ YYLTYPE yylloc; ;} break; - case 69: + case 70: { result->text_ps_inner_stmt_type_ = OBPROXY_T_TEXT_PS_PREPARE; @@ -3066,7 +3029,7 @@ YYLTYPE yylloc; ;} break; - case 70: + case 71: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_EXECUTE; @@ -3074,7 +3037,7 @@ YYLTYPE yylloc; ;} break; - case 71: + case 72: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_EXECUTE; @@ -3082,19 +3045,19 @@ YYLTYPE yylloc; ;} break; - case 72: + case 73: { ;} break; - case 73: + case 74: { ;} break; - case 74: + case 75: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_DROP; @@ -3102,7 +3065,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 76: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_DROP; @@ -3110,74 +3073,74 @@ YYLTYPE yylloc; ;} break; - case 76: + case 77: { result->cur_stmt_type_ = OBPROXY_T_GRANT; ;} break; - case 77: + case 78: { result->cur_stmt_type_ = OBPROXY_T_REVOKE; ;} break; - case 78: + case 79: { result->cur_stmt_type_ = OBPROXY_T_ANALYZE; ;} break; - case 79: + case 80: { result->cur_stmt_type_ = OBPROXY_T_PURGE; ;} break; - case 80: + case 81: { result->cur_stmt_type_ = OBPROXY_T_FLASHBACK; ;} break; - case 81: + case 82: { result->cur_stmt_type_ = OBPROXY_T_COMMENT; ;} break; - case 82: + case 83: { result->cur_stmt_type_ = OBPROXY_T_AUDIT; ;} break; - case 83: + case 84: { result->cur_stmt_type_ = OBPROXY_T_NOAUDIT; ;} break; - case 86: + case 87: {;} break; - case 87: + case 88: {;} break; - case 88: + case 89: {;} break; - case 93: + case 94: { result->cur_stmt_type_ = OBPROXY_T_SELECT_TX_RO; ;} break; - case 97: + case 98: { result->col_name_ = (yyvsp[(3) - (3)].str); ;} break; - case 98: + case 99: - { result->cur_stmt_type_ = OBPROXY_T_SET_AC_0; ;} + {;} break; case 100: @@ -3217,17 +3180,17 @@ YYLTYPE yylloc; case 107: - {;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; ;} break; case 108: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; ;} break; case 109: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; ;} + {;} break; case 110: @@ -3247,23 +3210,19 @@ YYLTYPE yylloc; case 113: - {;} - break; - - case 114: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_CREATE_TABLE; ;} break; - case 115: + case 114: { + result->table_info_.table_name_ = (yyvsp[(2) - (2)].str); result->cur_stmt_type_ = OBPROXY_T_DESC; result->sub_stmt_type_ = OBPROXY_T_SUB_DESC_TABLE; ;} break; - case 116: + case 115: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_COLUMNS; @@ -3271,7 +3230,7 @@ YYLTYPE yylloc; ;} break; - case 117: + case 116: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_COLUMNS; @@ -3280,7 +3239,7 @@ YYLTYPE yylloc; ;} break; - case 118: + case 117: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_INDEX; @@ -3288,7 +3247,7 @@ YYLTYPE yylloc; ;} break; - case 119: + case 118: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_INDEX; @@ -3297,98 +3256,106 @@ YYLTYPE yylloc; ;} break; - case 120: + case 119: {;} break; - case 121: + case 120: { result->table_info_.table_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 122: + case 121: {;} break; - case 123: + case 122: { result->table_info_.database_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 124: + case 123: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TABLES; ;} break; - case 125: + case 124: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_FULL_TABLES; ;} break; - case 126: + case 125: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TABLE_STATUS; ;} break; - case 127: + case 126: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DB_VERSION; ;} break; - case 128: + case 127: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 129: + case 128: { SET_ICMD_ONE_STRING((yyvsp[(3) - (3)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 130: + case 129: { SET_ICMD_SECOND_STRING((yyvsp[(5) - (5)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 131: + case 130: { SET_ICMD_ONE_STRING((yyvsp[(3) - (7)].str)); SET_ICMD_SECOND_STRING((yyvsp[(7) - (7)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; + case 131: + + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; ;} + break; + case 132: - { result->cur_stmt_type_ = OBPROXY_T_SELECT_ROUTE_ADDR; ;} + { + result->table_info_.table_name_ = (yyvsp[(3) - (3)].str); + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + ;} break; case 133: - { - result->cur_stmt_type_ = OBPROXY_T_SET_ROUTE_ADDR; - result->cmd_info_.integer_[0] = (yyvsp[(3) - (3)].num); - ;} + { result->cur_stmt_type_ = OBPROXY_T_SELECT_ROUTE_ADDR; ;} break; case 134: - {;} + { + result->cur_stmt_type_ = OBPROXY_T_SET_ROUTE_ADDR; + result->cmd_info_.integer_[0] = (yyvsp[(3) - (3)].num); + ;} break; case 135: @@ -3416,14 +3383,19 @@ YYLTYPE yylloc; {;} break; - case 141: + case 140: + + {;} + break; + + case 142: { result->table_info_.table_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 142: + case 143: { result->table_info_.package_name_ = (yyvsp[(1) - (3)].str); @@ -3431,7 +3403,7 @@ YYLTYPE yylloc; ;} break; - case 143: + case 144: { result->table_info_.database_name_ = (yyvsp[(1) - (5)].str); @@ -3440,14 +3412,14 @@ YYLTYPE yylloc; ;} break; - case 144: + case 145: { result->call_parse_info_.node_count_ = 0; ;} break; - case 145: + case 146: { result->call_parse_info_.node_count_ = 0; @@ -3455,14 +3427,14 @@ YYLTYPE yylloc; ;} break; - case 146: + case 147: { add_call_node(result->call_parse_info_, (yyvsp[(3) - (3)].node)); ;} break; - case 147: + case 148: { malloc_call_node((yyval.node), CALL_TOKEN_STR_VAL); @@ -3470,7 +3442,7 @@ YYLTYPE yylloc; ;} break; - case 148: + case 149: { malloc_call_node((yyval.node), CALL_TOKEN_INT_VAL); @@ -3478,7 +3450,7 @@ YYLTYPE yylloc; ;} break; - case 149: + case 150: { malloc_call_node((yyval.node), CALL_TOKEN_NUMBER_VAL); @@ -3486,7 +3458,7 @@ YYLTYPE yylloc; ;} break; - case 150: + case 151: { malloc_call_node((yyval.node), CALL_TOKEN_USER_VAR); @@ -3494,7 +3466,7 @@ YYLTYPE yylloc; ;} break; - case 151: + case 152: { malloc_call_node((yyval.node), CALL_TOKEN_SYS_VAR); @@ -3502,7 +3474,7 @@ YYLTYPE yylloc; ;} break; - case 152: + case 153: { result->placeholder_list_idx_++; @@ -3511,7 +3483,7 @@ YYLTYPE yylloc; ;} break; - case 166: + case 167: { handle_stmt_end(result); @@ -3519,7 +3491,7 @@ YYLTYPE yylloc; ;} break; - case 171: + case 172: { handle_stmt_end(result); @@ -3527,56 +3499,56 @@ YYLTYPE yylloc; ;} break; - case 175: + case 176: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_USER); ;} break; - case 176: + case 177: { add_set_var_node(result->set_parse_info_, (yyvsp[(6) - (6)].var_node), (yyvsp[(4) - (6)].str), SET_VAR_SYS); ;} break; - case 177: + case 178: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_SYS); ;} break; - case 178: + case 179: { add_set_var_node(result->set_parse_info_, (yyvsp[(5) - (5)].var_node), (yyvsp[(3) - (5)].str), SET_VAR_SYS); ;} break; - case 179: + case 180: { add_set_var_node(result->set_parse_info_, (yyvsp[(6) - (6)].var_node), (yyvsp[(4) - (6)].str), SET_VAR_SYS); ;} break; - case 180: + case 181: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_SYS); ;} break; - case 181: + case 182: { add_set_var_node(result->set_parse_info_, (yyvsp[(3) - (3)].var_node), (yyvsp[(1) - (3)].str), SET_VAR_SYS); ;} break; - case 182: + case 183: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_STR); @@ -3584,7 +3556,7 @@ YYLTYPE yylloc; ;} break; - case 183: + case 184: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_INT); @@ -3592,7 +3564,7 @@ YYLTYPE yylloc; ;} break; - case 184: + case 185: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_NUMBER); @@ -3600,42 +3572,42 @@ YYLTYPE yylloc; ;} break; - case 187: + case 188: {;} break; - case 188: + case 189: {;} break; - case 189: + case 190: { result->dbmesh_route_info_.tb_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 190: + case 191: { result->dbmesh_route_info_.table_name_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 191: + case 192: { result->dbmesh_route_info_.group_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 192: + case 193: { result->dbmesh_route_info_.es_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 193: + case 194: { result->dbmesh_route_info_.testload_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 194: + case 195: { malloc_shard_column_node((yyval.shard_node), (yyvsp[(2) - (7)].str), (yyvsp[(3) - (7)].str), DBMESH_TOKEN_STR_VAL); @@ -3644,52 +3616,57 @@ YYLTYPE yylloc; ;} break; - case 195: + case 196: { result->trace_id_ = (yyvsp[(4) - (6)].str); ;} break; - case 196: + case 197: { result->rpc_id_ = (yyvsp[(4) - (6)].str); ;} break; - case 197: + case 198: { result->dbmesh_route_info_.tnt_id_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 198: + case 199: { result->dbmesh_route_info_.disaster_status_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 199: + case 200: {;} break; - case 200: + case 201: {;} break; - case 201: + case 202: - {;} + { result->target_db_server_ = (yyvsp[(4) - (6)].str); ;} break; case 203: + {;} + break; + + case 205: + { result->has_simple_route_info_ = true; result->simple_route_info_.table_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 204: + case 206: { result->simple_route_info_.part_key_ = (yyvsp[(2) - (2)].str); ;} break; - case 208: + case 210: { result->dbp_route_info_.has_group_info_ = true; @@ -3697,7 +3674,7 @@ YYLTYPE yylloc; ;} break; - case 209: + case 211: { result->dbp_route_info_.has_group_info_ = true; @@ -3705,37 +3682,42 @@ YYLTYPE yylloc; ;} break; - case 210: + case 212: { result->dbp_route_info_.scan_all_ = true; ;} break; - case 211: + case 213: { result->dbp_route_info_.scan_all_ = true; ;} break; - case 212: + case 214: + + { result->dbp_route_info_.sticky_session_ = true; ;} + break; + + case 215: {result->dbp_route_info_.has_shard_key_ = true;;} break; - case 213: + case 216: { result->trace_id_ = (yyvsp[(3) - (4)].str); ;} break; - case 214: + case 217: { result->trace_id_ = (yyvsp[(3) - (6)].str); result->rpc_id_ = (yyvsp[(5) - (6)].str); ;} break; - case 215: + case 218: {;} break; - case 217: + case 220: { if (result->dbp_route_info_.shard_key_count_ < OBPROXY_MAX_DBP_SHARD_KEY_NUM) { @@ -3746,52 +3728,57 @@ YYLTYPE yylloc; ;} break; - case 220: + case 223: { result->dbmesh_route_info_.group_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 221: + case 224: { result->dbmesh_route_info_.tb_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 222: + case 225: { result->dbmesh_route_info_.table_name_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 223: + case 226: { result->dbmesh_route_info_.es_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 224: + case 227: { result->dbmesh_route_info_.testload_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 225: + case 228: { result->trace_id_ = (yyvsp[(3) - (3)].str); ;} break; - case 226: + case 229: { result->rpc_id_ = (yyvsp[(3) - (3)].str); ;} break; - case 227: + case 230: { result->dbmesh_route_info_.tnt_id_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 228: + case 231: { result->dbmesh_route_info_.disaster_status_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 229: + case 232: + + { result->target_db_server_ = (yyvsp[(3) - (3)].str); ;} + break; + + case 233: { malloc_shard_column_node((yyval.shard_node), (yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), DBMESH_TOKEN_STR_VAL); @@ -3800,32 +3787,32 @@ YYLTYPE yylloc; ;} break; - case 230: + case 234: {;} break; - case 231: + case 235: { (yyval.str).str_ = NULL; (yyval.str).str_len_ = 0; ;} break; - case 233: + case 237: { (yyval.str).str_ = NULL; (yyval.str).str_len_ = 0; ;} break; - case 255: + case 259: { result->query_timeout_ = (yyvsp[(3) - (4)].num); ;} break; - case 256: + case 260: {;} break; - case 258: + case 262: { add_hint_index(result->dbmesh_route_info_, (yyvsp[(3) - (5)].str)); @@ -3833,75 +3820,105 @@ YYLTYPE yylloc; ;} break; - case 259: + case 263: {;} break; - case 260: + case 264: {;} break; - case 261: + case 265: {;} break; - case 262: + case 266: {;} break; - case 263: + case 267: {;} break; - case 264: + case 268: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_WEAK); ;} break; - case 265: + case 269: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_STRONG); ;} break; - case 266: + case 270: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_FROZEN); ;} break; - case 269: + case 273: { result->cur_stmt_type_ = OBPROXY_T_SHOW_WARNINGS; ;} break; - case 270: + case 274: { result->cur_stmt_type_ = OBPROXY_T_SHOW_ERRORS; ;} break; - case 271: + case 275: { result->cur_stmt_type_ = OBPROXY_T_SHOW_TRACE; ;} break; - case 295: + case 299: + + {;} + break; + + case 300: + + {;} + break; + + case 301: + + {;} + break; + + case 302: + + {;} + break; + + case 303: + + {;} + break; + + case 304: + + {;} + break; + + case 305: { ;} break; - case 296: + case 306: { result->cmd_info_.integer_[2] = (yyvsp[(2) - (2)].num);/*row*/ ;} break; - case 297: + case 307: { result->cmd_info_.integer_[1] = (yyvsp[(2) - (4)].num);/*offset*/ @@ -3909,7 +3926,7 @@ YYLTYPE yylloc; ;} break; - case 298: + case 308: { result->cmd_info_.integer_[1] = (yyvsp[(4) - (4)].num);/*offset*/ @@ -3917,342 +3934,342 @@ YYLTYPE yylloc; ;} break; - case 299: + case 309: {;} break; - case 300: + case 310: { result->cmd_info_.string_[0] = (yyvsp[(2) - (2)].str);;} break; - case 301: + case 311: {;} break; - case 302: + case 312: { result->cmd_info_.string_[1] = (yyvsp[(2) - (2)].str);;} break; - case 304: + case 314: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_NET_THREAD); ;} break; - case 305: + case 315: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_NET_CONNECTION); ;} break; - case 306: + case 316: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_NET_CONNECTION, (yyvsp[(2) - (3)].num)); ;} break; - case 307: + case 317: {;} break; - case 308: + case 318: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONFIG_DIFF); ;} break; - case 309: + case 319: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONFIG_DIFF_USER); ;} break; - case 310: + case 320: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_LIST); ;} break; - case 312: + case 322: {SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_GLOBAL_SESSION_LIST);;} break; - case 313: + case 323: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_INFO, (yyvsp[(2) - (2)].str));;} break; - case 314: + case 324: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_LIKE, (yyvsp[(3) - (3)].str));;} break; - case 315: + case 325: {SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_INFO_ALL);;} break; - case 316: + case 326: {result->cmd_info_.string_[0] = (yyvsp[(2) - (2)].str);;} break; - case 318: + case 328: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_LIST_INTERNAL); ;} break; - case 319: + case 329: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_ATTRIBUTE); ;} break; - case 320: + case 330: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_ATTRIBUTE, (yyvsp[(2) - (3)].num)); ;} break; - case 321: + case 331: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_STAT); ;} break; - case 322: + case 332: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_STAT, (yyvsp[(2) - (3)].num)); ;} break; - case 323: + case 333: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_VARIABLES_LOCAL); ;} break; - case 324: + case 334: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_VARIABLES_LOCAL, (yyvsp[(2) - (3)].num)); ;} break; - case 325: + case 335: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_VARIABLES_ALL); ;} break; - case 326: + case 336: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_VARIABLES_ALL, (yyvsp[(3) - (4)].num)); ;} break; - case 327: + case 337: {;} break; - case 328: + case 338: { SET_ICMD_ONE_ID((yyvsp[(2) - (2)].num)); ;} break; - case 329: + case 339: {;} break; - case 330: + case 340: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_IDC); ;} break; - case 331: + case 341: {;} break; - case 333: + case 343: {;} break; - case 334: + case 344: { SET_ICMD_ONE_STRING((yyvsp[(1) - (1)].str)); ;} break; - case 335: + case 345: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONGEST_ALL);;} break; - case 336: + case 346: { SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_CONGEST_ALL, (yyvsp[(2) - (2)].str));;} break; - case 337: + case 347: {;} break; - case 338: + case 348: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_ROUTE_ROUTINE); ;} break; - case 339: + case 349: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_ROUTE_PARTITION); ;} break; - case 340: + case 350: {;} break; - case 341: + case 351: { SET_ICMD_ONE_STRING((yyvsp[(2) - (2)].str)); ;} break; - case 342: + case 352: {;} break; - case 343: + case 353: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_MEMORY_OBJPOOL); ;} break; - case 344: + case 354: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SQLAUDIT_AUDIT_ID); ;} break; - case 345: + case 355: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SQLAUDIT_SM_ID, (yyvsp[(2) - (2)].num)); ;} break; - case 347: + case 357: {;} break; - case 348: + case 358: { SET_ICMD_SECOND_ID((yyvsp[(1) - (1)].num)); ;} break; - case 349: + case 359: { SET_ICMD_TWO_ID((yyvsp[(3) - (3)].num), (yyvsp[(1) - (3)].num)); ;} break; - case 350: + case 360: { SET_ICMD_TWO_ID((yyvsp[(3) - (5)].num), (yyvsp[(1) - (5)].num)); SET_ICMD_ONE_STRING((yyvsp[(5) - (5)].str)); ;} break; - case 351: + case 361: {;} break; - case 352: + case 362: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_STAT_REFRESH); ;} break; - case 354: + case 364: {;} break; - case 355: + case 365: { SET_ICMD_ONE_ID((yyvsp[(1) - (1)].num)); ;} break; - case 356: + case 366: { SET_ICMD_SUB_AND_TWO_ID(OBPROXY_T_SUB_TRACE_LIMIT, (yyvsp[(1) - (2)].num),(yyvsp[(2) - (2)].num)); ;} break; - case 357: + case 367: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_BINARY); ;} break; - case 358: + case 368: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_UPGRADE); ;} break; - case 359: + case 369: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_IDC); ;} break; - case 360: + case 370: { SET_ICMD_ONE_STRING((yyvsp[(3) - (4)].str)); ;} break; - case 361: + case 371: { SET_ICMD_TWO_STRING((yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].str)); ;} break; - case 362: + case 372: { SET_ICMD_CONFIG_INT_VALUE((yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].num)); ;} break; - case 363: + case 373: { SET_ICMD_ONE_STRING((yyvsp[(3) - (3)].str)); ;} break; - case 364: + case 374: {;} break; - case 365: + case 375: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CS, (yyvsp[(2) - (2)].num)); ;} break; - case 366: + case 376: { SET_ICMD_SUB_AND_TWO_ID(OBPROXY_T_SUB_KILL_SS, (yyvsp[(2) - (3)].num), (yyvsp[(3) - (3)].num)); ;} break; - case 367: + case 377: {SET_ICMD_TYPE_STRING_INT_VALUE(OBPROXY_T_SUB_KILL_GLOBAL_SS_ID, (yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].num));;} break; - case 368: + case 378: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_KILL_GLOBAL_SS_DBKEY, (yyvsp[(2) - (2)].str));;} break; - case 369: + case 379: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CONNECTION, (yyvsp[(2) - (2)].num)); ;} break; - case 370: + case 380: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CONNECTION, (yyvsp[(3) - (3)].num)); ;} break; - case 371: + case 381: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_QUERY, (yyvsp[(3) - (3)].num)); ;} break; - case 374: + case 384: { result->has_anonymous_block_ = false ; @@ -4260,22 +4277,22 @@ YYLTYPE yylloc; ;} break; - case 375: + case 385: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 376: + case 386: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 377: + case 387: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 384: + case 394: { result->cur_stmt_type_ = OBPROXY_T_USE_DB; @@ -4283,27 +4300,27 @@ YYLTYPE yylloc; ;} break; - case 385: + case 395: { result->cur_stmt_type_ = OBPROXY_T_HELP; ;} break; - case 387: + case 397: {;} break; - case 388: + case 398: { result->part_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 389: + case 399: { result->part_name_ = (yyvsp[(3) - (4)].str); ;} break; - case 390: + case 400: { handle_stmt_end(result); @@ -4311,14 +4328,14 @@ YYLTYPE yylloc; ;} break; - case 391: + case 401: { result->table_info_.table_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 392: + case 402: { result->table_info_.database_name_ = (yyvsp[(1) - (3)].str); @@ -4326,7 +4343,7 @@ YYLTYPE yylloc; ;} break; - case 393: + case 403: { UPDATE_ALIAS_NAME((yyvsp[(2) - (2)].str)); @@ -4334,7 +4351,7 @@ YYLTYPE yylloc; ;} break; - case 394: + case 404: { UPDATE_ALIAS_NAME((yyvsp[(4) - (4)].str)); @@ -4343,7 +4360,7 @@ YYLTYPE yylloc; ;} break; - case 395: + case 405: { UPDATE_ALIAS_NAME((yyvsp[(3) - (3)].str)); @@ -4351,7 +4368,7 @@ YYLTYPE yylloc; ;} break; - case 396: + case 406: { UPDATE_ALIAS_NAME((yyvsp[(5) - (5)].str)); diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.h b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.h index df8485c1..6ecd470a 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.h @@ -134,96 +134,104 @@ extern int ob_proxy_parser_gbk_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c index b7c45705..b220208d 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c +++ b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 336 -#define YY_END_OF_BUFFER 337 +#define YY_NUM_RULES 344 +#define YY_END_OF_BUFFER 345 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,294 +357,314 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[2597] = +static yyconst flex_int16_t yy_accept[2787] = { 0, - 146, 146, 189, 189, 0, 0, 0, 0, 202, 202, - 230, 230, 0, 0, 0, 0, 0, 0, 258, 258, + 147, 147, 195, 195, 0, 0, 0, 0, 208, 208, + 238, 238, 0, 0, 0, 0, 0, 0, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 307, 307, 0, 0, - 0, 0, 325, 325, 330, 330, 0, 0, 168, 168, - 0, 0, 0, 0, 0, 0, 337, 335, 156, 156, - 152, 282, 146, 146, 271, 153, 152, 144, 335, 152, - 152, 145, 151, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 288, 335, 335, 335, - - 335, 335, 335, 191, 336, 189, 188, 191, 191, 182, - 189, 189, 189, 189, 189, 189, 191, 191, 191, 191, - 191, 191, 195, 194, 195, 197, 197, 336, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 207, 207, 202, 207, - 207, 202, 202, 207, 207, 207, 207, 207, 207, 207, - 234, 233, 233, 230, 228, 234, 230, 229, 230, 232, - 231, 230, 230, 230, 230, 230, 234, 234, 240, 239, - 239, 236, 240, 237, 240, 240, 242, 241, 241, 241, - 242, 242, 242, 260, 257, 257, 258, 252, 253, 260, - - 258, 256, 258, 258, 258, 258, 258, 258, 260, 260, - 262, 261, 336, 336, 268, 267, 267, 265, 263, 264, - 268, 268, 268, 270, 269, 269, 269, 270, 270, 270, - 277, 278, 336, 272, 273, 336, 283, 284, 336, 290, - 291, 293, 294, 310, 308, 308, 298, 307, 307, 299, - 297, 310, 309, 310, 307, 307, 307, 307, 307, 300, - 310, 310, 310, 310, 310, 310, 334, 334, 317, 316, - 316, 314, 316, 315, 312, 313, 317, 317, 317, 317, - 327, 326, 326, 320, 325, 325, 321, 318, 319, 327, - 325, 325, 325, 327, 327, 327, 327, 327, 327, 331, - - 330, 332, 329, 330, 336, 336, 336, 336, 336, 336, - 178, 178, 176, 170, 170, 174, 168, 168, 173, 176, - 167, 176, 176, 166, 172, 171, 171, 168, 168, 168, - 175, 176, 176, 176, 176, 176, 176, 117, 115, 115, - 115, 117, 116, 117, 117, 117, 126, 124, 124, 124, - 126, 125, 126, 126, 126, 336, 336, 336, 156, 0, - 148, 0, 0, 0, 0, 0, 0, 0, 156, 146, - 156, 156, 156, 156, 156, 156, 146, 0, 0, 0, - 0, 0, 0, 0, 147, 0, 0, 0, 0, 0, - 0, 145, 0, 150, 192, 150, 145, 146, 146, 146, - - 44, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 8, 0, 149, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 315, 315, 0, 0, + 0, 0, 333, 333, 338, 338, 0, 0, 174, 174, + 0, 0, 0, 0, 0, 0, 0, 0, 345, 343, + 157, 157, 153, 291, 147, 147, 280, 154, 153, 145, + 343, 153, 153, 146, 152, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 297, 343, + + 343, 343, 343, 343, 343, 197, 344, 195, 194, 197, + 197, 188, 195, 195, 195, 195, 195, 195, 197, 197, + 197, 197, 197, 197, 201, 200, 201, 203, 203, 344, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 213, 213, + 208, 213, 213, 208, 208, 213, 213, 213, 213, 213, + 213, 213, 242, 241, 241, 238, 236, 242, 238, 237, + 238, 240, 239, 238, 238, 238, 238, 238, 242, 242, + 248, 247, 247, 244, 248, 245, 248, 248, 250, 249, + 249, 249, 250, 250, 250, 269, 266, 266, 267, 261, + + 262, 269, 267, 265, 267, 267, 267, 267, 267, 267, + 269, 269, 271, 270, 344, 344, 277, 276, 276, 274, + 272, 273, 277, 277, 277, 279, 278, 278, 278, 279, + 279, 279, 286, 287, 344, 281, 282, 344, 292, 293, + 344, 299, 300, 302, 303, 318, 316, 316, 307, 315, + 315, 308, 306, 318, 317, 318, 315, 315, 315, 315, + 309, 318, 318, 318, 318, 318, 318, 342, 342, 325, + 324, 324, 322, 324, 323, 320, 321, 325, 325, 325, + 325, 335, 334, 334, 328, 333, 333, 329, 326, 327, + 335, 333, 333, 333, 335, 335, 335, 335, 335, 335, + + 339, 338, 340, 337, 338, 344, 344, 344, 344, 344, + 344, 184, 184, 182, 176, 176, 180, 174, 174, 179, + 182, 173, 182, 182, 172, 178, 177, 174, 174, 181, + 182, 182, 182, 182, 182, 182, 117, 115, 115, 115, + 117, 116, 117, 117, 117, 127, 125, 125, 125, 127, + 126, 127, 127, 127, 344, 344, 344, 157, 0, 149, + 0, 0, 0, 0, 0, 0, 0, 157, 147, 157, + 157, 157, 157, 157, 157, 147, 0, 0, 0, 0, + 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, + 146, 0, 0, 146, 151, 198, 151, 146, 147, 147, + + 147, 44, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 8, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 0, 0, 0, 0, 0, 0, 0, 190, 182, - 182, 189, 189, 189, 189, 189, 189, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, + 0, 195, 0, 0, 0, 0, 0, 0, 0, 196, + 188, 188, 195, 195, 195, 195, 195, 195, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, - 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 196, 0, 0, 0, 0, + 0, 223, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, - 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, - 0, 203, 0, 0, 0, 0, 0, 0, 0, 206, - 202, 202, 0, 205, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, - 235, 230, 230, 230, 230, 230, 230, 230, 230, 0, - 0, 0, 238, 0, 0, 0, 241, 0, 0, 258, - - 258, 258, 0, 259, 258, 258, 258, 258, 258, 258, - 0, 0, 0, 0, 0, 266, 0, 0, 0, 269, - 0, 0, 277, 0, 0, 279, 0, 0, 280, 272, - 0, 0, 274, 0, 0, 275, 0, 285, 0, 0, - 0, 286, 290, 289, 293, 292, 308, 0, 308, 307, - 308, 308, 308, 308, 308, 308, 307, 0, 0, 0, - 0, 0, 0, 0, 0, 307, 307, 307, 307, 307, - 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 316, 0, 316, 0, 0, 0, 0, 326, 0, 326, - 325, 326, 326, 326, 326, 326, 326, 325, 0, 0, - - 0, 0, 0, 0, 0, 325, 325, 325, 0, 0, - 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, - 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 170, 0, 170, 168, 170, 170, 170, - 170, 170, 170, 168, 0, 0, 0, 0, 0, 0, - 166, 0, 169, 169, 166, 168, 0, 168, 168, 168, - 0, 0, 0, 0, 0, 0, 0, 0, 115, 0, - 115, 0, 0, 0, 0, 124, 0, 124, 0, 0, + 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, + 0, 0, 0, 0, 208, 0, 0, 0, 0, 0, + 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, + 212, 208, 208, 0, 211, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, + 0, 243, 238, 238, 238, 238, 238, 238, 238, 238, + 0, 0, 0, 246, 0, 0, 0, 249, 0, 0, + + 267, 267, 267, 0, 268, 267, 267, 267, 267, 267, + 267, 267, 0, 0, 0, 0, 0, 275, 0, 0, + 0, 278, 0, 0, 286, 0, 0, 288, 0, 0, + 289, 281, 0, 0, 283, 0, 0, 284, 0, 294, + 0, 0, 0, 295, 299, 298, 302, 301, 316, 0, + 316, 315, 316, 316, 316, 316, 316, 316, 315, 0, + 0, 0, 0, 0, 0, 0, 0, 315, 315, 315, + 315, 315, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 324, 0, 324, 0, 0, 0, 0, 334, 0, + 334, 333, 334, 334, 334, 334, 334, 334, 333, 0, + + 0, 0, 0, 0, 0, 0, 333, 333, 333, 0, + 0, 0, 0, 0, 0, 0, 0, 338, 0, 0, + 0, 0, 0, 0, 338, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 176, 0, 176, 174, 176, 176, + 176, 176, 176, 176, 174, 0, 0, 0, 0, 0, + 0, 172, 0, 0, 172, 175, 175, 172, 174, 174, + 174, 0, 0, 0, 0, 0, 0, 0, 0, 115, + 0, 115, 0, 0, 0, 0, 125, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 156, 156, 156, 156, 156, 156, - - 156, 156, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 156, 0, 0, 150, 0, 0, 146, 55, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 42, 146, 146, 146, 146, 146, 146, 146, 111, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 13, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 53, 146, 146, 146, 146, 146, 146, 0, 0, 0, - - 0, 0, 0, 0, 0, 146, 146, 154, 155, 144, - 0, 0, 189, 189, 189, 189, 189, 189, 189, 189, - 179, 180, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 157, 157, 157, 157, 157, + + 157, 157, 157, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 146, 157, 0, 146, 0, 0, 151, + 0, 146, 0, 147, 55, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 42, 147, 147, 147, 147, + 147, 147, 147, 111, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 13, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 53, 147, 147, 147, + + 147, 147, 147, 0, 0, 0, 0, 0, 0, 0, + 0, 147, 147, 155, 156, 145, 0, 0, 188, 188, + 195, 195, 195, 195, 195, 195, 195, 195, 185, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 202, 202, 0, 0, 0, 0, - 0, 0, 0, 0, 202, 202, 0, 230, 230, 230, - 230, 230, 230, 230, 230, 233, 229, 239, 237, 241, - 258, 258, 258, 258, 258, 258, 258, 258, 257, 254, - 255, 256, 262, 261, 267, 264, 269, 281, 0, 281, - - 0, 0, 276, 0, 276, 0, 0, 287, 0, 287, - 0, 0, 0, 308, 308, 308, 308, 308, 308, 308, - 308, 0, 0, 308, 0, 0, 0, 0, 307, 307, - 307, 307, 307, 307, 307, 307, 297, 0, 0, 316, - 0, 0, 312, 313, 0, 326, 326, 326, 326, 326, - 326, 326, 326, 0, 0, 326, 0, 325, 325, 325, - 325, 325, 318, 319, 0, 330, 330, 330, 0, 0, - 0, 170, 170, 170, 170, 170, 170, 170, 170, 0, - 0, 170, 0, 0, 169, 0, 0, 168, 0, 0, - 168, 168, 168, 168, 168, 167, 0, 115, 0, 0, - - 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 146, 146, 156, 0, 0, 0, 156, 156, 156, - 0, 0, 150, 0, 150, 150, 146, 146, 146, 146, - 146, 146, 14, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 49, 18, 146, 146, 146, 146, 146, 25, - 146, 146, 146, 74, 146, 146, 146, 146, 61, 137, - 146, 56, 146, 146, 146, 146, 146, 146, 71, 146, - 146, 146, 146, 146, 146, 146, 51, 146, 146, 146, - 146, 146, 146, 146, 146, 0, 0, 7, 146, 146, - 90, 146, 146, 146, 146, 146, 146, 146, 146, 146, - - 146, 146, 146, 146, 16, 146, 52, 0, 0, 0, - 189, 189, 189, 189, 189, 184, 0, 0, 0, 0, - 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 202, 202, 0, 0, 0, 230, 230, - 230, 230, 230, 230, 230, 230, 258, 245, 258, 258, - 258, 258, 258, 258, 0, 0, 0, 0, 0, 0, - 307, 307, 308, 308, 308, 308, 0, 0, 0, 0, - 307, 307, 296, 307, 307, 307, 0, 316, 316, 316, - 0, 0, 325, 325, 326, 326, 326, 326, 0, 325, - 325, 325, 328, 177, 168, 168, 170, 170, 170, 170, - - 0, 0, 169, 0, 169, 169, 0, 0, 168, 168, - 168, 115, 115, 115, 0, 113, 0, 124, 124, 124, - 0, 122, 123, 92, 94, 93, 156, 19, 146, 146, - 37, 9, 146, 146, 146, 146, 146, 66, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 31, - 39, 146, 146, 146, 22, 146, 0, 0, 146, 54, - 146, 6, 146, 146, 146, 41, 146, 0, 0, 146, - 34, 138, 65, 146, 146, 146, 146, 146, 146, 146, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 146, 10, 146, 23, 146, 69, 146, 146, - - 43, 146, 146, 146, 27, 47, 146, 146, 45, 189, - 187, 189, 189, 189, 243, 0, 0, 0, 0, 0, - 198, 0, 0, 0, 202, 200, 230, 230, 230, 230, - 230, 230, 230, 230, 258, 258, 258, 258, 258, 258, - 251, 0, 0, 281, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 287, 0, 0, 308, 0, 0, 0, - 307, 307, 0, 307, 0, 0, 307, 307, 307, 333, - 316, 0, 326, 325, 325, 325, 170, 0, 0, 168, - 168, 168, 115, 114, 124, 0, 0, 146, 146, 58, - 146, 11, 146, 146, 17, 146, 146, 146, 2, 146, - - 68, 146, 146, 146, 146, 146, 40, 146, 60, 3, - 0, 0, 0, 0, 146, 146, 0, 0, 0, 146, - 146, 84, 146, 0, 0, 0, 146, 146, 21, 146, - 32, 146, 146, 146, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 146, 24, 82, - 146, 146, 26, 4, 146, 46, 146, 146, 186, 189, - 189, 185, 0, 0, 0, 0, 218, 0, 0, 215, - 0, 202, 230, 230, 230, 227, 230, 230, 225, 230, - 244, 258, 258, 258, 258, 258, 0, 0, 0, 0, - - 0, 0, 307, 307, 0, 0, 0, 0, 0, 307, - 307, 0, 307, 0, 0, 0, 0, 0, 0, 0, - 0, 304, 307, 307, 311, 325, 325, 325, 0, 0, - 168, 164, 168, 0, 0, 0, 33, 146, 35, 146, - 146, 146, 15, 63, 0, 0, 0, 146, 29, 48, - 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 146, 146, 0, 0, 0, 38, 103, 146, 0, 0, - 28, 107, 5, 146, 100, 146, 0, 0, 0, 0, + 0, 0, 0, 208, 208, 0, 0, 0, 0, 0, + 0, 0, 0, 208, 208, 0, 238, 238, 238, 238, + 238, 238, 238, 238, 238, 241, 237, 247, 245, 249, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 266, + + 263, 264, 265, 271, 270, 276, 273, 278, 290, 0, + 290, 0, 0, 285, 0, 285, 0, 0, 296, 0, + 296, 0, 0, 0, 316, 316, 316, 316, 316, 316, + 316, 316, 0, 0, 316, 0, 0, 0, 315, 315, + 315, 315, 315, 315, 315, 306, 0, 0, 324, 0, + 0, 320, 321, 0, 334, 334, 334, 334, 334, 334, + 334, 334, 0, 0, 334, 0, 333, 333, 333, 333, + 333, 326, 327, 0, 338, 338, 338, 0, 0, 0, + 176, 176, 176, 176, 176, 176, 176, 176, 0, 0, + 172, 176, 0, 172, 0, 0, 175, 0, 172, 0, + + 174, 174, 174, 174, 174, 173, 0, 115, 0, 0, + 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 147, 147, 157, 0, 0, 0, 146, 157, 157, + 157, 0, 146, 151, 0, 151, 0, 151, 146, 147, + 147, 147, 147, 147, 147, 14, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 49, 18, 147, 147, 147, + 147, 147, 25, 147, 147, 147, 74, 147, 147, 147, + 147, 61, 138, 147, 56, 147, 147, 147, 147, 147, + 147, 71, 147, 147, 147, 147, 147, 147, 147, 51, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 0, + + 0, 7, 147, 147, 90, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 16, 147, + 52, 0, 0, 0, 188, 188, 195, 195, 195, 195, + 195, 190, 0, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 208, 208, 0, 0, 0, 238, 238, 238, 238, 238, + 238, 238, 238, 238, 267, 253, 267, 267, 267, 267, + 267, 267, 267, 0, 0, 0, 0, 0, 0, 315, + 315, 316, 316, 316, 316, 0, 0, 0, 315, 305, + 315, 315, 315, 0, 324, 324, 324, 0, 0, 333, + + 333, 334, 334, 334, 334, 0, 333, 333, 333, 336, + 183, 174, 174, 176, 172, 176, 176, 176, 0, 172, + 175, 0, 175, 0, 175, 172, 174, 174, 115, 115, + 115, 0, 113, 0, 125, 125, 125, 0, 123, 124, + 92, 94, 93, 146, 157, 146, 146, 19, 147, 147, + 37, 9, 147, 147, 147, 147, 147, 66, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 31, + 39, 147, 147, 147, 22, 147, 0, 0, 147, 54, + 147, 6, 147, 147, 147, 41, 147, 0, 0, 147, + 34, 139, 65, 147, 147, 147, 147, 147, 147, 147, + + 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 147, 10, 147, 23, 147, 69, 147, + 147, 43, 147, 147, 147, 27, 47, 147, 147, 45, + 188, 188, 195, 193, 195, 195, 195, 251, 0, 0, + 0, 0, 0, 204, 0, 0, 0, 0, 208, 206, + 238, 238, 238, 238, 238, 238, 238, 238, 238, 267, + 267, 267, 267, 267, 267, 267, 260, 0, 0, 290, + 0, 0, 0, 0, 285, 0, 0, 0, 0, 296, + 0, 0, 316, 0, 0, 315, 0, 315, 0, 0, + 315, 315, 315, 341, 324, 0, 334, 333, 333, 333, + + 172, 176, 172, 172, 174, 174, 115, 114, 125, 146, + 146, 146, 0, 0, 147, 147, 58, 147, 11, 147, + 147, 17, 147, 147, 147, 2, 147, 68, 147, 147, + 147, 147, 147, 40, 147, 60, 3, 0, 0, 0, + 0, 147, 147, 0, 0, 0, 147, 147, 84, 147, + 0, 0, 0, 147, 0, 0, 147, 21, 147, 0, + 0, 32, 147, 147, 147, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 146, 146, 146, 0, 0, 0, 110, - 146, 146, 189, 189, 0, 0, 0, 0, 0, 0, - 0, 0, 202, 230, 230, 230, 230, 230, 230, 230, - 258, 258, 258, 258, 258, 0, 0, 0, 307, 307, - 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 307, 307, 325, - 325, 325, 0, 0, 168, 165, 0, 0, 146, 146, - 146, 146, 0, 0, 0, 50, 146, 146, 146, 146, - 0, 0, 0, 0, 0, 146, 146, 0, 0, 0, - 162, 146, 0, 0, 0, 0, 12, 146, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 147, 24, 82, 147, 147, 26, 4, 147, 46, 147, + + 147, 188, 188, 192, 195, 195, 191, 0, 0, 0, + 0, 224, 0, 0, 0, 221, 0, 208, 238, 238, + 238, 234, 238, 238, 238, 232, 238, 252, 267, 267, + 267, 267, 267, 267, 0, 0, 0, 0, 0, 315, + 0, 0, 0, 0, 0, 315, 315, 0, 315, 0, + 0, 0, 0, 0, 0, 0, 0, 313, 315, 315, + 319, 333, 333, 333, 172, 172, 172, 170, 174, 146, + 146, 146, 0, 0, 0, 33, 147, 35, 147, 147, + 147, 15, 63, 0, 0, 0, 147, 29, 48, 147, + 147, 147, 147, 0, 0, 0, 0, 0, 0, 147, + + 147, 0, 0, 0, 38, 103, 147, 0, 0, 28, + 0, 0, 0, 107, 5, 0, 0, 0, 147, 100, + 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 73, 146, 20, - 0, 0, 0, 146, 67, 189, 189, 0, 0, 209, - 199, 210, 0, 213, 216, 201, 230, 230, 219, 220, - 230, 223, 226, 250, 258, 246, 258, 258, 0, 0, - 0, 307, 307, 0, 0, 0, 0, 0, 0, 307, - 307, 307, 0, 0, 0, 0, 0, 0, 0, 0, - 307, 307, 325, 325, 325, 0, 0, 168, 0, 88, - 146, 146, 146, 0, 0, 0, 159, 36, 146, 146, - - 146, 0, 0, 0, 160, 0, 0, 146, 146, 0, - 0, 0, 0, 57, 0, 0, 0, 0, 142, 0, - 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, - 0, 146, 0, 0, 0, 158, 89, 189, 189, 0, - 0, 0, 230, 230, 230, 258, 258, 258, 0, 0, - 0, 307, 307, 0, 295, 0, 0, 0, 0, 0, - 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, - 307, 302, 325, 325, 323, 0, 0, 168, 0, 83, - - 72, 30, 0, 0, 0, 0, 141, 59, 146, 0, - 0, 0, 0, 0, 0, 146, 146, 0, 0, 0, - 0, 134, 0, 0, 0, 161, 0, 0, 0, 0, + 0, 147, 147, 147, 0, 0, 0, 110, 147, 147, + 188, 188, 195, 195, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 208, 238, 238, 238, 238, 238, 238, + 238, 238, 267, 267, 267, 267, 267, 267, 0, 0, + 315, 0, 0, 0, 0, 0, 0, 315, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 315, 315, + 333, 333, 333, 172, 172, 172, 171, 146, 146, 146, + 0, 0, 147, 147, 147, 147, 0, 0, 0, 50, + 147, 147, 147, 147, 0, 0, 0, 0, 0, 147, + 147, 0, 0, 0, 163, 147, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 128, 0, 0, 0, 0, 0, 146, - 0, 0, 0, 0, 189, 189, 0, 212, 211, 230, - 222, 221, 258, 258, 248, 0, 0, 0, 0, 0, - 307, 301, 295, 0, 0, 0, 0, 0, 0, 307, - 322, 325, 0, 0, 0, 0, 168, 0, 0, 0, - - 0, 0, 146, 0, 0, 0, 0, 0, 0, 146, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 0, 73, 147, + 20, 0, 0, 0, 147, 67, 188, 188, 195, 195, + + 0, 0, 215, 205, 216, 0, 0, 219, 222, 207, + 238, 238, 226, 227, 238, 238, 230, 233, 259, 267, + 254, 267, 267, 267, 0, 0, 315, 0, 0, 0, + 0, 0, 0, 315, 315, 315, 0, 0, 0, 0, + 0, 0, 0, 0, 315, 315, 333, 333, 333, 172, + 172, 172, 146, 146, 146, 0, 88, 147, 147, 147, + 0, 0, 0, 160, 36, 147, 147, 147, 0, 0, + 0, 161, 0, 0, 147, 147, 0, 0, 0, 0, + 57, 0, 0, 0, 0, 0, 0, 143, 0, 0, + 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 120, 0, 70, 0, - 0, 0, 0, 189, 189, 0, 230, 249, 258, 0, + 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, + 0, 0, 0, 0, 147, 0, 0, 0, 159, 89, + 188, 188, 195, 195, 0, 0, 0, 0, 238, 238, + 238, 238, 267, 267, 267, 267, 0, 0, 315, 0, + 304, 0, 0, 0, 0, 0, 0, 0, 304, 0, + 0, 0, 0, 0, 0, 0, 315, 311, 333, 333, + 331, 172, 172, 172, 146, 146, 146, 0, 83, 72, + 30, 0, 0, 0, 0, 142, 59, 147, 0, 0, + 0, 0, 0, 0, 147, 147, 0, 0, 0, 0, + + 135, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 295, 307, 325, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, - - 146, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 76, 0, 78, - 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, - 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 95, 0, 0, 0, 0, 105, 0, 0, 189, - 189, 0, 230, 247, 0, 0, 0, 0, 0, 0, - 0, 306, 0, 0, 295, 307, 325, 0, 0, 0, - 0, 0, 163, 0, 0, 0, 0, 0, 64, 0, - 0, 0, 146, 162, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, + 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, + 0, 0, 0, 0, 147, 0, 0, 0, 0, 188, + 188, 195, 195, 0, 218, 217, 0, 238, 229, 228, + 238, 267, 267, 267, 257, 0, 0, 0, 0, 310, + 304, 0, 0, 0, 0, 0, 0, 315, 330, 333, + 172, 172, 172, 146, 146, 146, 0, 0, 0, 0, + 0, 147, 0, 0, 0, 0, 0, 0, 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 81, 0, 0, 0, 0, 0, 101, - 104, 0, 181, 189, 0, 230, 0, 0, 0, 0, - 0, 307, 325, 0, 0, 0, 0, 0, 159, 0, - 160, 0, 0, 0, 143, 0, 0, 0, 0, 0, - 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 119, 0, 0, 0, 0, 0, - 0, 0, 0, 109, 0, 0, 0, 0, 106, 0, - 158, 0, 189, 0, 230, 0, 0, 305, 303, 324, - 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 121, 0, 0, 70, 0, 0, 0, 0, 188, 188, + 195, 195, 0, 0, 238, 238, 258, 267, 267, 0, + 0, 0, 0, 0, 0, 304, 315, 333, 172, 172, + 172, 146, 146, 146, 0, 0, 0, 0, 147, 0, + 0, 0, 0, 147, 62, 0, 0, 0, 0, 0, + + 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 76, 0, 78, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, + 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 0, 0, 0, 105, 0, + 0, 188, 188, 195, 195, 0, 0, 238, 238, 256, + 267, 0, 0, 0, 304, 315, 333, 172, 172, 172, + 146, 146, 146, 0, 0, 0, 64, 0, 0, 0, + 147, 163, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, - 0, 0, 0, 0, 0, 0, 99, 0, 108, 0, - 189, 214, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 80, 0, 0, 121, 0, 87, 0, - 91, 0, 102, 0, 0, 183, 0, 0, 0, 132, - 0, 0, 135, 0, 130, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80, 0, 129, 0, 0, - 96, 0, 0, 86, 0, 0, 0, 0, 136, 0, - - 0, 0, 0, 0, 0, 80, 0, 76, 0, 0, - 0, 0, 85, 0, 97, 0, 0, 0, 133, 0, + 81, 0, 0, 0, 0, 0, 101, 104, 118, 0, + 188, 188, 187, 195, 0, 0, 238, 238, 267, 0, + 0, 315, 333, 172, 172, 172, 146, 146, 146, 0, + 0, 160, 0, 161, 0, 0, 0, 144, 0, 0, + 0, 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 109, 0, 0, 0, 0, 106, 0, 159, + + 0, 188, 188, 195, 0, 0, 238, 238, 255, 0, + 314, 312, 332, 172, 172, 172, 146, 146, 146, 0, + 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, + 0, 108, 0, 188, 188, 195, 220, 0, 231, 238, + 0, 172, 172, 172, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 118, 0, 0, 131, 0, 0, - 0, 0, 0, 0, 0, 0, 305, 0, 0, 0, - 0, 0, 140, 79, 0, 0, 0, 0, 79, 0, - 0, 79, 0, 0, 0, 139, 0, 80, 0, 0, - 0, 0, 0, 0, 79, 0 + 0, 0, 0, 0, 0, 80, 165, 0, 0, 0, + 0, 122, 0, 0, 87, 0, 91, 0, 102, 0, + 0, 188, 188, 189, 225, 235, 0, 172, 172, 172, + 146, 146, 146, 133, 0, 0, 136, 167, 0, 131, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 0, 0, 0, 130, 0, 0, 0, 96, 0, + 0, 86, 188, 188, 0, 172, 172, 172, 146, 146, + 147, 0, 137, 0, 0, 0, 0, 0, 0, 80, + 0, 76, 0, 0, 0, 166, 0, 0, 85, 164, + 0, 97, 188, 0, 172, 172, 174, 151, 151, 147, + 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 175, 175, 174, 151, 151, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, + 0, 175, 175, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 119, 0, 0, 132, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, + 0, 0, 0, 141, 79, 0, 0, 0, 0, 0, + 0, 79, 0, 0, 0, 0, 79, 0, 0, 0, + 0, 140, 0, 80, 0, 0, 0, 0, 0, 0, + 169, 0, 0, 0, 79, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -653,2595 +673,2684 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 6, 7, 8, 5, 5, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 20, 21, 1, - 22, 1, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 1, 51, 1, 5, 52, 53, 54, 55, 56, 57, - - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 5, 80, 5, 1, 81, 82, 82, - 82, 82, 82, 82, 82, 83, 84, 85, 85, 86, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 88, 89, 89, - 89, 1, 1, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 91, 91, 91, 92, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 94, 95, - 95, 95, 95, 95, 1, 1, 1, 1, 1, 1, + 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, 20, 1, + 21, 1, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 1, 50, 1, 5, 51, 52, 53, 54, 55, 56, + + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 5, 79, 5, 1, 80, 81, 81, + 81, 81, 81, 81, 81, 82, 83, 84, 84, 85, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 87, 88, 88, + 88, 1, 1, 89, 89, 89, 89, 89, 89, 89, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 90, 90, 90, 91, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 93, 94, + 94, 94, 94, 94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[96] = +static yyconst flex_int32_t yy_meta[95] = { 0, 1, 2, 3, 3, 1, 4, 5, 6, 7, 1, - 1, 1, 8, 1, 9, 10, 1, 6, 6, 11, - 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 1, 1, 2, 1, 8, 9, 1, 6, 10, 1, + 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 12, 6, 13, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 11, + 6, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, - 5, 5, 5, 5, 5 + 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, + 5, 5, 5, 5 } ; -static yyconst flex_int16_t yy_base[2759] = +static yyconst flex_int16_t yy_base[2949] = { 0, - 0, 0, 95, 0, 188, 189, 201, 0, 296, 0, - 391, 0, 485, 489, 502, 506, 0, 0, 600, 0, - 694, 697, 706, 717, 728, 739, 481, 486, 487, 491, - 496, 501, 5821, 5819, 5818, 5787, 833, 0, 509, 510, - 927, 937, 1031, 0, 1126, 0, 516, 518, 1221, 0, - 1315, 1322, 1346, 1356, 489, 517, 5839,17443, 1330, 1336, - 17443, 1340, 1448, 103, 702,17443, 504,17443, 509, 511, - 5795, 687,17443, 1508, 920, 733, 903, 912, 1518, 1309, - 1383, 1527, 722, 1590, 933, 1412, 1598, 1605, 494, 1427, - 1672, 1600, 1665, 1398, 1736, 1601, 669, 1427, 1636, 1665, - - 1730, 1739, 1748,17443,17443, 465,17443, 514, 522, 1693, - 1701, 1771, 1794, 1750, 1802, 1818, 1767, 1817, 1833, 1842, - 1851, 1860,17443,17443, 531,17443, 1948, 2042, 1969, 549, - 1997, 516,17443, 922, 708, 728, 542, 931, 1316, 2089, - 1945, 2080, 2089, 2098, 2107, 2116,17443, 1476, 873, 1863, - 555, 2031, 2058, 1958, 2125, 2134, 2143, 2152, 2161, 2170, - 17443,17443,17443, 0,17443, 559, 0,17443, 0,17443, - 17443, 690, 689, 705, 734, 1949, 5724, 5716,17443,17443, - 17443,17443, 578,17443, 5683, 5675,17443,17443,17443,17443, - 580, 5643, 5635,17443,17443,17443, 915,17443,17443, 754, - - 0,17443, 0, 0, 748, 946, 1357, 1520, 5597, 5571, - 17443,17443, 5577, 5558,17443,17443,17443,17443,17443,17443, - 790, 5558, 5549,17443,17443,17443,17443, 793, 5555, 5546, - 0, 2065, 0, 0, 2258, 0,17443, 1867, 0, 0, - 5570, 0, 5514,17443, 1391, 1522,17443, 2350, 1709,17443, - 17443, 5549,17443, 5519, 2218, 2227, 2234, 2243, 2300,17443, - 2193, 2202, 2259, 2294, 2323, 2332,17443, 943,17443, 1545, - 1574,17443, 0,17443,17443,17443, 5525, 1299, 5414, 5406, - 17443, 1602, 1875,17443, 2445, 1903,17443,17443,17443, 5400, - 2384, 2399, 2456, 2399, 2418, 2427, 2471, 2480, 2489,17443, - - 2003,17443,17443, 2537, 2499, 2508, 2517, 2528, 2537, 2552, - 17443, 1297,17443, 2425, 2640,17443, 2732, 2013,17443, 715, - 17443, 958, 749, 2629,17443,17443, 5389, 2601, 2613, 2621, - 17443, 2578, 2676, 2685, 2705, 2714, 2747,17443, 2686, 2773, - 0, 5397,17443, 1299, 1322, 5300,17443, 2777, 2802, 0, - 5365,17443, 1326, 1355, 5196, 1357, 1363, 1367, 2805, 5162, - 17443, 2294, 2756, 2765, 2774, 2789, 2798, 2817, 0, 2906, - 2850, 2859, 2879, 2888, 2921, 2930, 2211, 2939, 2948, 2957, - 2966, 2975, 2984, 2859,17443, 2993, 3002, 3011, 3020, 3029, - 3038, 811, 2886, 1951,17443, 2018, 3112, 3119, 2636, 3104, - - 2428, 3089, 3128, 3140, 3097, 3150, 3191, 3179, 3223, 3199, - 3207, 3267, 3250, 3261, 3280, 3295, 3301, 3274, 3319, 3350, - 3340, 3380, 3364, 3356, 3401, 3392, 3418, 3436, 3442, 3448, - 3479, 3460, 3504, 3510, 3489, 3516, 3527, 3598, 3588, 3604, - 3430, 3612, 3618, 3629, 3643, 3700, 3667, 3687, 3710, 3747, - 3754, 3658, 3236, 2561, 3083,17443, 3061, 3745, 3769, 3778, - 3787, 3796, 3805, 3814, 3823, 3832, 3841, 3850, 3859, 3868, - 2591, 3877, 3886, 3895, 3904, 3913, 3922, 1005,17443, 1302, - 3994, 3716, 3986, 4000, 4006, 3973, 4015, 3935, 3333, 3964, - 4030, 4039, 3682, 4048, 4057, 1330,17443, 4145, 4151, 4166, - - 17443, 4191, 1523, 1606, 1602, 1669, 4159, 4181, 4190, 4206, - 4215, 4224, 4233, 4242, 1412,17443, 1680, 1598, 1653, 2077, - 3184, 3583, 3530, 3601, 3516, 1517, 2076, 4251, 4260, 4269, - 4278, 4287, 3072, 4296, 4305,17443, 2889, 4314, 4323, 4332, - 4341, 4350, 4359, 3409, 4368, 4377, 4386, 4395, 4404, 4413, - 4494,17443, 4423, 4432, 4441, 4450, 4459, 4468, 1430,17443, - 4157, 4535, 3980,17443, 4481, 4490, 4510, 4519, 4528, 4550, - 4559, 4567, 4576, 4585, 4594, 3316, 4603, 4612, 0, 1467, - 17443, 1383, 1442, 1455, 1471, 1537, 1521, 1697, 1719, 5161, - 5140, 1469,17443, 5144, 5138, 1759,17443, 5142, 5102, 0, - - 1738, 1911, 1763,17443, 1936, 1944, 2104, 2239, 2268, 2344, - 5106, 1360, 5102, 5098, 2006,17443, 5082, 5073, 2142,17443, - 5038, 1282, 0, 3163, 5109,17443, 5100, 5033,17443, 0, - 4700, 4989,17443, 4981, 4860,17443, 3724,17443, 4928, 4918, - 4848,17443, 0,17443, 0,17443, 4616, 4846, 0, 4792, - 4629, 4638, 4647, 4656, 4665, 4674, 3729, 4683, 4692, 4701, - 4736, 4745, 4765, 4703, 3587, 4766, 4817, 4802, 4830, 4845, - 4852, 4867, 4876, 4885, 4894, 4903, 4912, 4921, 4930, 2365, - 4834, 4835, 0, 4928, 2361, 4833, 1295, 5019, 4825, 0, - 5111, 4943, 4952, 4961, 4970, 4979, 4988, 3944, 4997, 5006, - - 5015, 5055, 5064, 5084, 5152, 5084, 5117, 5137, 5133, 5152, - 5164, 5173, 5182, 5191, 5200, 5209, 4773, 5218, 5227, 5236, - 5245, 5254, 5263, 5314, 5273, 5281, 5290, 5302, 5311, 5329, - 5338, 5347, 2624, 5399, 4809, 0, 5491, 5356, 5365, 5374, - 5383, 5392, 5401, 4810, 5435, 5444, 5464, 5473, 5506, 5515, - 1577, 5532, 2681, 3757, 5589, 5550, 3604, 5562, 5570, 5576, - 5544, 5604, 5613, 5622, 5631, 5640, 5649, 5658, 5670, 4808, - 0, 5673, 2630, 2644, 4774, 5746, 4763, 0, 5749, 2743, - 2829, 4754, 2837, 2921, 3110, 4719, 5685, 5528, 5694, 5703, - 5712, 5721, 5730, 5739, 5748, 5672, 5761, 5770, 5779, 5788, - - 5797, 5806, 5814, 5823, 5832, 5840, 5849, 5858, 5867, 5876, - 5885, 5894, 5982, 4718, 3549, 4133, 4214, 1708, 5941, 5015, - 5933, 5951, 5958, 5968, 5975, 5985, 6018, 6027, 6056, 6047, - 6062, 6068, 6079, 6139, 6109, 6126, 6145, 6151, 6158, 6182, - 5902, 6188, 6219, 6225, 6212, 6231, 6258, 6238, 5912, 6269, - 6307, 6313, 6299, 6319, 6342, 6327, 6333, 6282, 6356, 6384, - 6390, 6396, 6414, 6435, 6421, 6407, 6455, 6472, 6480, 6496, - 6503, 6511, 6529, 6519, 6539, 6563, 6571, 6288, 6579, 6555, - 6591, 6599, 6633, 6623, 6647, 6692, 6641, 6681, 6675, 6708, - 5927, 6714, 6743, 6728, 6757, 6772, 6764, 6452, 6103, 6787, - - 6796, 6805, 6094, 6814, 6823, 6350, 6362,17443,17443,17443, - 6832, 6180, 6872, 6894, 6882, 6736, 6888, 6904, 6663, 6838, - 17443,17443, 6859, 6918, 6921, 6992, 6975, 7003, 6934, 7015, - 7021, 7027, 7055, 7039, 7045, 7062, 7073, 7088, 7097, 7105, - 7114, 7123, 7132, 6614, 7141, 7150, 7159, 7167, 7176, 7185, - 7194, 6951, 7203, 7212, 7258, 7267, 7223, 7231, 7240, 7252, - 7282, 6969, 7291, 7300, 7252, 7300, 7315, 3115, 3182, 3182, - 4744, 3203, 3203, 4739, 3281,17443,17443,17443,17443,17443, - 3432, 3473, 3516, 3588, 3594, 3597, 3610, 3690,17443,17443, - 17443,17443,17443,17443,17443,17443,17443,17443, 4615, 4614, - - 6009, 4541,17443, 4612, 4574, 6053, 4501,17443, 4575, 4574, - 6088, 4479, 4478, 7324, 7332, 7341, 7350, 7359, 7368, 7377, - 7386, 7394, 7403, 6122, 4477, 3711, 3759, 3766, 7447, 7455, - 7461, 7468, 7484, 7474, 7409, 7415,17443, 7499, 3992, 6208, - 4199, 3997,17443,17443, 4174, 7508, 7447, 7517, 7526, 7535, - 7431, 7544, 7553, 7561, 7570, 6469, 4173, 7615, 7621, 7608, - 7576, 7582,17443,17443, 7602, 7627, 7633, 7639, 7654, 3988, - 4153, 7663, 7671, 7680, 7689, 7698, 7707, 7716, 7725, 7733, - 7742, 6842, 4150, 4900, 5480, 5167, 1710, 7772, 3983, 4001, - 7786, 7800, 7810, 7742, 7748,17443, 7763, 7569, 4142, 3995, - - 4115, 7854, 4141, 4134, 4151, 4153, 4161, 4154, 7822, 7862, - 7837, 7957, 8052, 7846, 7850, 7897, 7912, 0, 7868, 4139, - 4134, 1839, 1841, 1862, 1872, 1947, 7933, 7927, 7997, 7941, - 8017, 8028, 7793, 8067, 8073, 8091, 8082, 8105, 8114, 8126, - 8144, 8150, 8159, 7987, 8184, 8211, 8177, 8171, 8200, 8097, - 8236, 8220, 8249, 8120, 8229, 8265, 8277, 8290, 8255, 8296, - 8283, 8302, 8335, 8362, 8374, 8381, 8368, 8387, 8320, 8399, - 8450, 8415, 8459, 8466, 8356, 8482, 8406, 8473, 8489, 8508, - 8543, 8559, 8553, 8565, 8583, 8677, 8541, 8592, 8444, 8598, - 8661, 8636, 8670, 8680, 8694, 8686, 8701, 8737, 8746, 8758, - - 8766, 8775, 8781, 8792, 8428, 8805, 8708, 8752, 8811, 8826, - 8833, 8840, 8867, 8877, 8883, 8723, 8861, 8920, 8963, 8926, - 17443, 8970, 9007, 8980, 9013, 9019, 9030, 8992, 8999, 9045, - 9057, 9067, 9054, 9092, 9116, 9100, 9110, 9083, 4768, 4798, - 5090, 5128, 5481, 5501, 5508, 5591, 5577, 0, 5582, 5973, - 4159, 6043, 6044, 6069, 8716, 4129, 8985, 4127, 8009, 4117, - 9211, 9306, 9155, 0, 7894, 4097, 4094, 6059, 6062, 4113, - 9162, 9191, 9243, 9255, 9177, 9283, 6068, 0, 8167, 4082, - 4078, 6140, 9401, 9496, 9279, 0, 8396, 4075, 4069, 9351, - 9261, 9377, 9085,17443, 9591, 9686, 9374, 0, 8419, 4023, - - 4022, 2047, 2059, 2101, 2122, 2253, 6133, 6155, 9447, 9474, - 9467, 0, 8440, 4021, 4002,17443, 6229, 0, 8525, 4001, - 3981,17443,17443,17443,17443,17443, 3961, 9432, 9568, 9663, - 9529, 9541, 9710, 9652, 9718, 9637, 9746, 9731, 9761, 9781, - 9790, 9831, 9840, 9825, 9864, 9893, 9906, 9925, 9900, 9938, - 9958, 9944, 9974,10042, 9967,10003,10023,10020,10077,10070, - 10083,10109,10117,10127,10140,10149,10179, 9340,10104,10155, - 10212,10225,10234,10251,10263,10257,10279,10285,10273,10293, - 10387, 6612, 6227, 6231, 6241, 6313, 6316, 6383, 3960,10311, - 10481,10320,10408,10331,10470,10439,10487,10493,10502,10544, - - 10515,10572,10587,10600,10609,10615,10621,10650,10629,10658, - 9183, 9385,10641,10667,17443,10702,10714, 9558,10721,10753, - 10738,10782,10761,10747,10579, 9336, 6512, 6645, 3784, 6732, - 3783, 6723, 6735, 3761, 6782, 3747, 6776, 6788, 6799, 3746, - 0, 3788, 9861, 3778, 1346, 3692, 3733, 9890, 3732, 1491, - 3659, 3726, 8666, 3725, 751, 3620, 3605, 6887, 6949, 6951, - 10732,10361,10430,10877, 3659,10776,10937,10943,10949,17443, - 3590, 6976, 3589,10928,10962,10977, 3570, 6984, 6992,11007, - 11013,11019, 3569,17443, 3568, 9910,10925,11057,11079,10776, - 11086,11092,11116,11123,11129,11135,11229,11235,11242,11248, - - 11190,11273,11306,11263,11343,11312,11296,11368,11357,11378, - 7009, 7033, 3545,11116,11390,11413, 9813, 3603,11337,11451, - 11428,11438,11463, 7453, 3533,11428,11532,11545,11474,11570, - 11488,11585,11591,11598,11612, 8668, 7470, 7489, 7633, 7823, - 3541, 7864, 3539, 3495, 8295, 7883, 7873, 8053, 7874, 8018, - 8200, 8246, 8292, 8379, 8381, 3485,11569,11605,11628,11643, - 11712,11667,11706,11724,11750,11740,11773,11761, 9460,10371, - 11781, 9535,11821,11767,11861,11867,11050,11901,11853,11696, - 11887,11879, 8456, 8459, 8554, 0, 8964, 8564, 0, 8557, - 0, 8558, 8582, 8576, 8594, 8629, 2321, 2390, 1325, 8676, - - 8681, 8860,11938,11838,11982, 8845, 3484,11996,12010, 0, - 0,12019, 8848,12110,12201,12292,12383,12474,12565, 8945, - 11803,10891,11407,11656,17443,11964,11970,11999, 8937, 8966, - 12005,10899,12013, 8959, 3416,12045,12066,12079,12133,12144, - 12151,12160,12179,12185,11778, 3469,12178,12301,12218,12245, - 12314,12329,12358,12423,11808, 3468,12240, 8964, 9012, 3398, - 12414,12435, 3385, 2302,12269,12340,12442,12456, 9028, 3383, - 12494,12508,12536,12517,12571,12602,12615, 3451,12592, 9091, - 9201, 9212, 9221, 9298, 9316, 9390, 9378, 9491, 9504, 9573, - 9587, 9573, 9669, 9682, 9812, 9811, 9829, 9810, 9823, 9902, - - 9917, 9902, 3381,12656,12683,12699,12398, 3415,12627,12631, - 12729,12716,12672,12049,12744,12690,12784,12752,12797,12815, - 12836,12842,12822, 9903, 3374, 9983, 9984, 9988,10027,10042, - 10060,10053,10080,10096,10171,10212,10217,10232,12790,12828, - 12936,12942,12951,10237, 3344,12958,10239,13049,13140,13231, - 13322,13413,12973,13504,13595,13010, 3321,12645,12929,12979, - 12994,13001,10262,10270,13079,10906,10292, 3303,13095,13109, - 13116,13123, 3302, 2319,13075,12988,13177,13189,13240,13253, - 3301, 2341,13212,10391,10370,13307,13300, 3300, 2345, 2659, - 10568,13358,10371,12575, 3368,13270,13283,13382,10381,10403, - - 10388, 3243, 2436,13348, 3271,10395, 3270,10397,10730,10449, - 10464,10491,10479,10586,10575,10596,10597,10583,10591,10610, - 10712,10710,10729,11213,10749,10752,10753,13366,13460,13436, - 3240, 2451,13397,13534,13488,13352,13472,13523,13541,13159, - 13552,13568,13603,13614,13621,11679, 3260,10941, 0, 0, - 10938, 0, 0, 0,11014, 0, 3259,11011,11013,11013, - 11034,13637,13627,13731,13737,11027,13746,13764,13774,11028, - 0, 0,13865,13794,13804,13813,13832,13888,13850, 3224, - 13819,12912,13879,13844,13912,11080,11090,13896,11081,13957, - 13963,13973,13979, 3206, 2460, 2723,12118,13990,14016,14031, - - 14073, 3183, 2529, 2897,12767,11109,11086,14088,14094,12687, - 12794,11103, 3181,14009,11112, 3180, 2531,13940,14041,11140, - 11168,11196, 3179, 2705, 3321,13722,11200,11200,11207,11218, - 11233,11233,11232, 9195,11323,11310,11358,11347,11383,11536, - 11519,11547, 9381,11551,11536,17443,11590,11706,11711,11764, - 11845,14135, 3171, 2738, 3502,14110,14114,14100,14177,14127, - 14141,14184,11850,11867,11868,11855,11871,11892,11899, 9722, - 3199,14167,14194,14288,17443,14294,14303,14310,14326,14333, - 14340,14370, 0,14385,14401,14407,14437,14446,14453,14468, - 14395,13905,14441,14449,14055,11901,13106,14464,11927,14158, - - 14498,14512,13148,14212,11954, 3145,14519,14544,14561,13272, - 14362,11957, 3135,11971,11977,14571,14577,13556, 3120,12005, - 3112,17443, 3082, 2879, 4160,14367,12006,12023,12002,13651, - 14565,12053, 3074,12120,12151,12157,12142,12157,12167,12224, - 12344, 3071,12306,12357,12385,12376,12425,12430,12429,12420, - 14656, 3070,12457,12465,12498,14722,12514,12511,12526,14643, - 13823,14616,12558, 2877,14649,14630,14710,14537,14600,12551, - 0, 0,12559,12584, 0,12582,13872,14754, 2874,12577, - 14728,14492,14809,14826,14832,14841,14848,14875,14889,14821, - 14679,14858,12608,14695,13464, 2844,14904,12955,14868, 2843, - - 12705, 2832,14917,14871, 2829,12765, 2785,12761,12836,14932, - 14939, 2729,12822,14955,14974,12835, 2703,12830,12847,12893, - 14962, 2655,12914, 2644,12944,12961,13021,13027,13071,12858, - 13379, 2596, 2622,13089, 2618,13106,13420,13123,13149,17443, - 13180,13198,13212, 2576,13218,13219,13235,13477,13300,13459, - 13475,13583,14984,13472,13487,13507,17443,13510,14983,14966, - 2526,13509, 2464,14946,14970,15028,13546, 0,13523,13565, - 15081,13575,13573, 2416, 2389,13618,13688,13840,15005,15096, - 15124,14910,15050,13613,15105,13626, 2341, 2268,14151,14548, - 15081,13633,13644, 2226,13711,15111, 2215,13713,13729,13719, - - 15145,15134,13917,15093, 2074,13726, 2063,13731,13750, 2090, - 2047,13751,13802,13795,13822, 2029,13829,14036, 1998,14173, - 1994,13867,14354,13859,17443,14788, 1954,13870, 1972,13875, - 14003,17443,14136,14167,14216,14234,14245,14250,14277,14276, - 14291,17443,14321,14327,14322,14357,17443, 1941,14390,15127, - 15100,15168,14394, 0,15153,14403, 1962, 1921,14433, 1902, - 15228,17443, 1900,15166,15262,15180,15223,15276,14436, 1887, - 1881,15279,17443, 1826,15218,14457,14454,14597,15284,15289, - 14552,14553,15306,15292, 1802, 1786,14605,14626,14632,14630, - 15319, 1753,15322, 1737,14638,15325, 1701, 1693,14645,15328, - - 1659,14647,14662, 1655,14675,14713,14715,14709,14720,14724, - 14755,14738,14770,17443,14819,14824,14838,14855,14882,17443, - 17443,15333,14977,15295,15348,14899,14906,14947,14967, 1633, - 1606,15312,15337,14980, 1592, 1570,15021,15013,15341, 1568, - 15344, 1535,15061,15072,15354, 1526,15406,15068,15121,15122, - 15448, 1516,15155,15451,15455, 1416,15147,15175,15458, 1406, - 15274, 1359,15315,15327,17443,15320,15355,15363,15391,15392, - 15393,15423,15439,17443,15429,15428,15445,15442,17443,15447, - 15475, 1355,15461,15467,15437,15455,15455,17443,15441,15478, - 15459,15454,15444, 1339, 1328,15457,15452,15504, 1306, 1323, - - 2306,15450, 1291,15454,15542,15469,15448, 1246, 1242,15474, - 15492,15519, 949,15506,15514,15528,15536,17443,15531,15542, - 15532,15550,15549,15539,15534,15542,17443,15546,17443, 939, - 15538,15572, 0,15550,15565,15552,15564,15555,15559,15568, - 935,15565, 924, 920,15574,15583, 940, 938, 900,15586, - 15579,15581,15606,15597,15611,15599,17443,15603,17443,15601, - 17443,15600,17443,15618,15609,15565,15611,15621,15616,17443, - 15634,15637,17443,15640,17443, 887, 886,15647,15638,15641, - 15642,15636,15657,15689,15644,15692, 870,17443,15645,15659, - 17443,15665,15670,17443,15663, 769,15664,15673,17443,15658, - - 734,15666,15673,15678,15682,15716, 756,15719, 725,15680, - 702,15692,17443,15694,17443,15704,15699,15706,17443,15697, - 15704,15700,15719,15720,15721, 688,15718,15709,15711,15706, - 15713,15712,15728,15785,15717,15735,15736,15737,15731,15745, - 17443,15797,15755,15800, 701,15803, 3252, 646, 626,15767, - 660, 650,15769,15782,17443,15761,15789,17443, 505, 494, - 486,15777,15789,15778,15776,15772,17443,15795, 466,15797, - 15788,15790,17443,15756,15801,15781,15793,15796,15831, 452, - 15794,15838,15794,15800, 118,17443,15818,15860,15811,15811, - 15838,15831,15843,15822,15870,17443,15962,15975,15988,16001, - - 16014,16027,16040,16053,16066,16079,16092,16105,16118,16131, - 16144,16157,16167,16173,16182,16184,16187,16196,16201,16208, - 16210,16212,16215,16223,16227,16236,16249,16262,16275,16288, - 16301,16313,16325,16334,16340,16353,16362,16364,16370,16379, - 16385,16398,16408,16414,16427,16436,16438,16441,16450,16455, - 16462,16464,16466,16469,16477,16481,16490,16503,16516,16529, - 16542,16555,16567,16579,16592,16601,16607,16620,16633,16642, - 16644,16650,16663,16672,16678,16691,16704,16717,16726,16728, - 16730,16736,16737,16741,16750,16763,16776,16789,16802,16811, - 16817,16830,16843,16852,16854,16860,16873,16882,16888,16901, - - 16911,16917,16930,16939,16946,16955,16957,16966,16968,16976, - 16978,16981,16983,16991,16995,17004,17017,17030,17043,17056, - 17069,17078,17084,17097,17110,17123,17132,17134,17140,17153, - 17166,17175,17181,17194,17207,17219,17221,17223,17229,17230, - 17234,17243,17256,17269,17282,17291,17297,17310,17319,17325, - 17338,17351,17364,17377,17390,17403,17416,17429 + 0, 0, 94, 0, 186, 187, 199, 0, 293, 0, + 387, 0, 480, 484, 497, 501, 0, 0, 594, 0, + 687, 690, 699, 710, 721, 732, 476, 481, 482, 486, + 491, 496, 6207, 6185, 6184, 6183, 825, 0, 504, 505, + 918, 928, 1021, 0, 1115, 0, 511, 513, 1209, 0, + 1302, 1308, 0, 0, 1323, 1360, 493, 512, 6229,17872, + 1316, 1330,17872, 1336, 1451, 102, 695,17872, 6210,17872, + 503, 6208, 6212, 924,17872, 1511, 1312, 726, 1343, 679, + 912, 668, 1387, 1520, 490, 1527, 717, 1416, 1597, 1583, + 901, 1431, 1664, 927, 1591, 1422, 1672, 1315, 471, 1409, + + 1486, 1679, 1688, 1697, 1706,17872,17872, 872,17872, 500, + 6202, 1708, 1657, 1758, 1752, 1775, 1764, 1781, 1730, 1796, + 1805, 1814, 1823, 1832,17872,17872, 521,17872, 1919, 2012, + 1940, 523, 1967, 497,17872, 721, 919, 928, 498, 1297, + 917, 2059, 1915, 2050, 2059, 2068, 2077, 2086,17872, 1556, + 1737, 1928, 538, 1983, 2028, 1874, 2095, 2104, 2113, 2122, + 2131, 2140,17872,17872,17872, 0,17872, 574, 0,17872, + 0,17872,17872, 666, 683, 696, 707, 2205, 6133, 6107, + 17872,17872,17872,17872, 739,17872, 6113, 6102,17872,17872, + 17872,17872, 782, 6100, 6091,17872,17872,17872, 907,17872, + + 17872, 783, 0,17872, 0, 0, 735, 933, 1668, 1582, + 6096, 6088,17872,17872, 6088, 6080,17872,17872,17872,17872, + 17872,17872, 785, 6055, 6047,17872,17872,17872,17872, 924, + 6053, 6045, 0, 2228, 0, 0, 2245, 0,17872, 2261, + 0, 0, 6078, 0, 6075,17872, 1394, 1587,17872, 2352, + 1954,17872,17872, 6106,17872, 6097, 2000, 2205, 2217, 2223, + 17872, 2197, 2240, 2257, 2296, 2305, 2325,17872, 939,17872, + 1638, 1715,17872, 0,17872,17872,17872, 6074, 1279, 6008, + 5992,17872, 1857, 2327,17872, 2446, 2211,17872,17872,17872, + 6062, 2332, 2396, 2412, 2390, 2427, 2436, 2461, 2470, 2479, + + 17872, 2257,17872,17872, 2527, 2489, 2498, 2507, 2518, 2527, + 2542,17872, 1279,17872, 2392, 2629,17872, 2720, 2545,17872, + 6058,17872, 806, 6057, 2624,17872,17872, 2606, 2615,17872, + 2573, 2602, 2664, 2673, 2693, 2702,17872, 2647, 2671, 0, + 6059,17872, 1300, 1318, 5987,17872, 2674, 2764, 0, 6051, + 17872, 1316, 1329, 5955, 1333, 1347, 1349, 2789, 5951,17872, + 2757, 2735, 2744, 2753, 2776, 2785, 2801, 0, 2889, 2833, + 2842, 2862, 2871, 2904, 2913, 2573, 2922, 2931, 2940, 2949, + 2958, 2967, 2785,17872, 2976, 2985, 2994, 3003, 3012, 3021, + 6012, 2840, 6011, 1427, 1499,17872, 1501, 3094, 3100, 3076, + + 3106, 2843, 3082, 3122, 3147, 3164, 3170, 3206, 3176, 3249, + 3236, 3242, 3280, 3128, 3274, 3286, 3357, 3134, 3322, 3328, + 3336, 3365, 3396, 3371, 3402, 3409, 3429, 3435, 3417, 3450, + 3487, 3495, 3457, 3512, 3501, 3526, 3555, 3579, 3650, 3586, + 3651, 3562, 3573, 3607, 3155, 3637, 3666, 3651, 3690, 3704, + 3735, 3696, 3720, 3728, 2871, 3307,17872, 3051, 3750, 3759, + 3768, 3777, 3786, 3795, 3804, 3813, 3822, 3831, 3840, 3849, + 3858, 3052, 3867, 3876, 3885, 3894, 3903, 3912, 995,17872, + 6009, 3479, 3963, 3975, 3981, 3987, 3969, 3993, 3938, 4007, + 4016, 4025, 4034, 3206, 4043, 4052, 1296,17872, 4139, 4145, + + 4160,17872, 4184, 1377, 1661, 1605, 1593, 4153, 4175, 4184, + 4199, 4208, 4217, 4226, 4235, 1334,17872, 1680, 2053, 1607, + 1676, 1913, 1674, 3095, 4299, 3566, 1520, 3253, 4261, 4290, + 4299, 4308, 4317, 3476, 4326, 4335,17872, 3388, 4344, 4353, + 4362, 4371, 4380, 4389, 3442, 4398, 4407, 4416, 4425, 4434, + 4443, 4523,17872, 4453, 4462, 4471, 4480, 4489, 4498, 1405, + 17872, 4548, 4565, 4273,17872, 4511, 4520, 4540, 4563, 4580, + 4589, 4598, 4251, 4607, 4616, 4625, 3948, 4634, 4643, 0, + 1430,17872, 1368, 1434, 1461, 1523, 1936, 1522, 1628, 1685, + 5936, 5924, 1652,17872, 5927, 5911, 1653,17872, 5913, 5906, + + 0, 1672, 1756, 1822,17872, 1770, 1884, 1904, 1906, 1918, + 2010, 2013, 5909, 1513, 5902, 5899, 1823,17872, 5892, 5886, + 1912,17872, 5804, 487, 0, 3380, 5874,17872, 5844, 5776, + 17872, 0, 4238, 5816,17872, 5809, 5742,17872, 3678,17872, + 5815, 5804, 5738,17872, 0,17872, 0,17872, 3160, 5736, + 0, 4731, 4675, 4684, 4704, 4713, 4746, 4755, 3914, 4764, + 4773, 4782, 4791, 4800, 4809, 3620, 2007, 4854, 4861, 4867, + 4878, 4887, 4826, 4902, 4911, 4920, 4929, 3961, 4938, 4947, + 2067, 4961, 5735, 0, 4971, 2063, 5734, 613, 5034, 5733, + 0, 5125, 4959, 4973, 4983, 4992, 5001, 5010, 4265, 5019, + + 5028, 5069, 5078, 5098, 5107, 5165, 5152, 5158, 5178, 5150, + 5177, 5193, 5202, 5211, 4835, 5220, 5229, 4540, 5238, 5247, + 5256, 5265, 5274, 5283, 5334, 5293, 4692, 5302, 5311, 5322, + 4851, 5331, 5349, 2056, 5418, 5732, 0, 5509, 5358, 5367, + 5376, 5385, 5394, 5403, 4713, 5412, 5453, 5462, 5482, 5491, + 5524, 5763, 5549, 5761, 3098, 2216, 2436, 5597, 5542, 5576, + 5582, 5564, 5575, 5597, 5612, 5621, 5542, 5630, 5639, 5726, + 5698, 0, 5729, 2207, 2229, 5584, 5732, 5562, 0, 5735, + 2221, 2255, 5561, 2369, 2366, 2373, 5559, 5660, 5036, 5669, + 5678, 5687, 5696, 5705, 5714, 5723, 5420, 5747, 5756, 5765, + + 5774, 5783, 5792, 5499, 5801, 5810, 5818, 5827, 5836, 5845, + 5854, 5863, 5872, 5620, 5959, 5557, 3289, 1918, 2095, 3293, + 2238, 5948, 5540, 5921, 5954, 5962, 5968, 5979, 6002, 6048, + 6012, 6062, 6071, 6106, 6092, 6150, 6115, 6157, 6199, 6175, + 6186, 6215, 6206, 6222, 6239, 5992, 6257, 6301, 6287, 6310, + 6323, 6329, 6336, 6267, 6369, 6354, 6382, 6415, 6421, 6408, + 6436, 6462, 6452, 6501, 6474, 6480, 6508, 6533, 6559, 6541, + 6587, 6569, 6598, 6604, 6613, 6627, 6659, 6620, 6651, 6706, + 6692, 6712, 6719, 6738, 6730, 6753, 6761, 6798, 6824, 6833, + 6841, 6883, 6863, 6870, 6854, 6895, 6877, 6942, 6934, 6977, + + 6964, 7006, 6988, 6030, 6451, 6930, 7003, 7021, 5887, 7030, + 7039, 6905, 7043,17872,17872,17872, 7058, 5899, 5536, 6681, + 6971, 5908, 7087, 7102, 7093, 7125, 5527, 5932,17872,17872, + 7067, 7080, 7158, 7174, 7183, 7189, 7204, 7197, 7219, 7268, + 7226, 7283, 7255, 7276, 7244, 7289, 7304, 7313, 7321, 7330, + 7339, 7348, 6130, 7357, 7366, 7375, 7383, 7392, 7401, 7410, + 6254, 7419, 7428, 6791, 7482, 7438, 7446, 7455, 7467, 7476, + 6354, 7497, 7506, 6782, 6812, 7515, 2429, 2652, 2725, 5466, + 2903, 3094, 3085, 5465, 3103,17872,17872,17872,17872,17872, + 3158, 3161, 3208, 3256, 3279, 3281, 3297, 3321, 3335,17872, + + 17872,17872,17872,17872,17872,17872,17872,17872,17872, 5504, + 5391, 6096, 5186,17872, 5246, 5245, 6121, 5160,17872, 5233, + 5222, 6142, 5143, 5142, 7524, 7532, 7541, 7550, 7559, 6680, + 7568, 7577, 7585, 7120, 6167, 5141, 3375, 3357, 7637, 7643, + 7650, 7666, 7625, 7476, 7591,17872, 7606, 3373, 6317, 5140, + 3379,17872,17872, 5121, 7665, 7614, 7681, 7690, 7699, 7150, + 7708, 7717, 7725, 7241, 6485, 5096, 7777, 7783, 7767, 7631, + 7730,17872,17872, 7747, 7789, 7747, 7755, 7804, 3370, 5091, + 7813, 7821, 7830, 7839, 7848, 7857, 7866, 7875, 7883, 7892, + 5115, 6518, 5052, 3734, 2401, 2479, 3581, 3720, 7959, 5111, + + 7965, 7972, 7989, 7978, 7995,17872, 7937, 6734, 5048, 3404, + 3496, 6938, 4971, 3577, 3586, 3696, 3706, 3731, 8001, 8007, + 7952, 8101, 8195, 8045, 8065, 8130, 8060, 5032, 0, 7167, + 4969, 4968, 4156, 4948, 4924, 4923, 4922, 4918, 8145, 8162, + 8213, 8230, 8224, 8292, 8256, 8241, 8309, 8282, 8327, 8320, + 8335, 8344, 8353, 8374, 8380, 8389, 8364, 8434, 8416, 8424, + 8460, 8474, 8445, 8468, 8480, 8539, 8496, 8505, 8565, 8528, + 8575, 8584, 8599, 8591, 8607, 8636, 8647, 8678, 8686, 8693, + 8704, 8654, 8718, 8741, 8747, 8765, 8785, 8774, 8809, 8798, + 8853, 8844, 8829, 8868, 8878, 8899, 8916, 8923, 8939, 9032, + + 8084, 8948, 9002, 9035, 8910, 9044, 9050, 9061, 9074, 9093, + 9133, 9086, 9145, 9157, 9101, 9173, 9180, 9196, 9186, 9203, + 9213, 7952, 8557, 8939, 4908, 8956, 9224, 9021, 8263, 8992, + 8547, 7909, 9237, 9282, 9292, 9320,17872, 9303, 9326, 9332, + 9349, 9411, 9417, 9428, 9151, 9361, 9377, 9311, 9390, 9386, + 9397, 9466, 9440, 9446, 9461, 3731, 3731, 3736, 3746, 3987, + 4122, 4148, 4157, 4163, 4149, 0, 4154, 4180, 4874, 4190, + 4866, 4873, 5115, 7982, 4844, 8491, 4824, 8173, 4823, 9560, + 9654, 9504, 0, 7848, 4822, 4729, 5128, 4757, 9537, 9592, + 9544, 9512, 9606, 5136, 0, 8134, 4702, 4669, 5148, 9748, + + 9842, 9533, 0, 8543, 4659, 4658, 9631, 9621, 9700, 9599, + 17872, 9936,10030, 9692, 4717, 0, 8623, 4654, 4573, 5976, + 4634, 4618, 4617, 4593, 4592, 9788, 9796, 9879, 0, 8701, + 4529, 4508,17872, 5169, 0, 8708, 4507, 4288,17872,17872, + 17872,17872,17872, 4343, 4272, 6131, 9886, 9779, 9984,10038, + 9807, 9900,10048,10067, 9966,10079, 9995,10054,10134,10147, + 10085,10164,10172,10181,10188,10204,10228,10194,10216,10234, + 10252,10274,10313,10283,10296,10319,10390,10273,10363,10353, + 10380,10414,10403,10421,10444,10432,10459, 9915,10459,10513, + 10474,10466,10482,10545,10553,10562,10582,10573,10595,10604, + + 10611,10634, 5489, 5167, 5829, 5953, 5963, 6066, 6081, 4271, + 10627,10727,10652,10731,10501,10755,10652,10748,10742,10763, + 10777,10784,10801,10844,10869,10790,10881,10887,10902,10893, + 4332, 9873,10932, 9638, 9816,10962,10718,17872,10973,10981, + 10913,10994,11002,11017,11033,11023,11062,11053,10627,10532, + 6147, 6202, 4279, 6218, 4277, 6229, 6298, 6316, 4276, 6316, + 4275, 6415, 6430, 6423, 6409, 4197, 0, 4234, 8714, 4218, + 1422, 4146, 4216, 8817, 4215, 1517, 4128, 4199, 9999, 4198, + 1480, 4123, 4122, 6424, 6518,10853,11133,11224, 4186,11081, + 11085,11109,11091,17872, 4091, 6534, 4090,11008,11125,11281, + + 4150, 4085, 8242,11304,11312,11318, 4079,17872, 4077, 4138, + 8596,11324,10096,11124,11330,11383,11103,11409,11339,11418, + 11424,11352,11431,11437,11477,11446,11518,11455,11525,11536, + 11560,11590,11604,11466,11616,11503,11583, 6543, 6541, 4073, + 11581,11622,11639, 9784, 4139,11637,11683,11718,11669,11724, + 6542, 4066,11661,11711,10345,11706,11735,11741,11820,10335, + 11757,11762,11831,11842,11853,11859,10396, 6561, 6565, 6611, + 6605, 4094, 6600, 4093, 3971, 6623, 8225, 6632, 6637, 7180, + 6730, 6751, 6805, 6811, 6807, 6952, 8175, 7020, 3970,11807, + 11889,11790,11869,11882,11912,11899,11983,11938,11922,11961, + + 12003, 4019,11946,11273,11954,11996,11553,12041,12052,12067, + 12090,12033,12132,12098,12084,12113,12138,12144, 7017, 7020, + 7141, 0, 9137, 3982, 7179, 0, 7178, 0, 7196, 7273, + 7279, 7286, 3976, 7287, 1599, 1743, 1982, 7310, 7649,12124, + 12193, 7634, 3936,12237,12243, 0, 0,12252, 8003,12342, + 12432,12522,12612,12702,12792, 8813,12229,12182,12211,12246, + 17872,12281,12287,12274, 3996, 8746,12374,12314,12325, 3995, + 9305,12381, 8034, 3932,12368,12404,12461,12416,12467,12473, + 12558,12453,12495,10811, 3811,12510,12584,12532,12564,12646, + 12621,12655,12629,11375, 3804,12548, 8067, 8160, 3735,12686, + + 12734, 3728, 703,12679,12740,12752,12797, 8192, 3726,12765, + 8212, 3712,12812,12776,12834, 8241, 3688,12821,12847,12823, + 12895,12927, 3755,12887, 8246, 8281, 8315, 8325, 8324, 8344, + 8474, 8462, 8537, 8602, 8658, 8765, 8795, 8801, 8861, 8868, + 8892, 8928, 8955, 9028, 9037, 9133, 9197, 9229, 9216, 9268, + 3684,12919,12933,12949,11587, 3741,12916,12866,12962,12978, + 3733,12989,12293,12995,13005,13012,13018,13042,13097,13076, + 13121,13127,13136,12592, 9271, 3696, 9305, 9307, 9313, 9313, + 9322, 9323, 9381, 9460, 9461, 9467, 9457, 9654, 9641, 9656, + 13082,13178,13229,13235, 9732, 3633,13244, 9760,13334,13424, + + 13514,13604,13694,13272,13784,13874,13251, 3629,13108,13204, + 13219,13275,13240, 3684, 9789,13354,13285, 3673, 9793,13367, + 9758, 3608,13373,13433,13453,13459, 3578, 1437,13322,13465, + 13498,13487,13547,13555, 3555, 1807,13411, 9772, 9827,13614, + 13587, 3554, 1809, 2238,13192,13636, 9836, 9847, 3553,12062, + 3563,13581, 9873, 3494,13524,13667, 9943, 9960, 9944, 3485, + 1850,13631, 3510,10023, 3507,10027,10112,10035,10110,10125, + 10120,10139,10181,10142,10165,10169,10160,10171,10182,10276, + 10274,10309,10355,10454,10398,10397,10395,10452,13642,13731, + 13677, 3475, 1926,13720,13756,13724, 3534,13344,13793,13652, + + 13803,13819,13825,13843,13857,13887,13913,13904,13923,12351, + 3466,10459, 0, 0,10463,10545, 0, 0, 0,10547, + 0, 3464,10552,10564,10591,10604,13395,13984,14016,10605, + 14023,14032,14042,10687, 0, 0,14132,14049,14059,14114, + 14141,14151,14169, 3434,14001,13881,14100,14071,14109, 3448, + 10870,14193, 3435,10871,14210,10702,14163,14224,14235,14248, + 3362, 1928, 2275,13830,14242,14277,14263,14305, 3329, 1960, + 2343,14078,10736,10717,14331,14290,12663,14232,10735, 3313, + 14296,10726,10752, 3312, 1972,14322,10868,14342,10894,10877, + 10883, 3308, 1980, 2483,14409,10881,10882,10885,10952,10975, + + 10980,10974, 9118,10987,10974,10990,10974,10993,11012,11007, + 11078,11078,11103,10677,11167,11274,17872,11296,11297,11282, + 11287,11323,11322,11391,14362, 3280, 1992, 2707,14412,14401, + 3337,14270,14180,14386,14425,14432,14442,14450,11393,11412, + 11423, 3303,11412,11424,11417,11432,11688, 3298,14415,14543, + 17872,14549,14558,14564,14579,14585,14594,14615, 0,14621, + 14657,14676,14690,14707,14716,14723,14663,12479,14693,14701, + 13066, 3292,11546,14731, 3283,11850,14781,11484,14684,14742, + 14750,13027,14758,11518, 3202,14764,14788,14829,13113,14864, + 11519, 3198,11519,11563,14821,14844,13301, 3196,11621, 3155, + + 17872,11694, 3149, 2226, 2880,14894,11708,11699,11728,11707, + 13565,14897,11737, 3130,11742,11788,11793,11820,11828,11829, + 11830,11387, 3127,11847,11898,11913,11893,11935,12004,12014, + 12056,12049,12040,14901, 3102,12049,12063,12080,12096,14967, + 12112,12209,12215,12219,14924,13835,14945,12228, 3081, 3142, + 14873,14953,14889,14959,14968,14978,14984,12219, 0, 0, + 12221,12229,12238,12226, 0,13341,12730, 3067,12231,13445, + 15077,15083,15092,15098,15119,15125,15134,15128,13851,15137, + 3105,12332,15102, 3102,12464,15144,12700,13840, 3037,12241, + 2886,15160,14481, 2860,12286, 2827,12284,12299,15151,15191, + + 2816,12286,12284,14650,15244,12327, 2813,12416,12417,12436, + 12414,14798, 2774,12465, 2773,12479,12579,12636,12639,12696, + 12409,12573, 2772, 2794,12715, 2746,12640,12944,12727,13321, + 12732,12765,17872,12773,12786,12898, 2716,12892,12910,13474, + 12911,12998,12927,13009,13019,13356,15229,13007,13032,13090, + 17872,13148,13176,15169,14848, 2715,13206, 2691, 2746,15206, + 15220,15230,15250,15260,13236,13233, 0,13215,13287,15021, + 13274, 2648, 2647,13285,15330,15356,15236,15285, 2694,13736, + 15352, 2693,13737,15369,13333,13422, 2630,13410,15340, 2623, + 13411,13444,13533,15375,15382,13631,13980,15275, 2622,13584, + + 2621,17872,13586,13601, 2642, 2612,13583,13616,13633,13693, + 2640,13742,14458, 2600,14525, 2599,13771,14826,13793,15416, + 2591,15451, 2589,17872,15446, 2588,13834, 2597,13873,13871, + 17872,15435, 2567,13928,13997,14011,14025,14019,14017,14026, + 14029,14059,17872,14079,14084,14074,14077,14103,17872, 2566, + 14114, 2627,15392,15312,15442,15471,15478,14134,14163, 0, + 14172, 2593, 2516,14195,15488,15464,15484, 2481,14629,15493, + 2473,14671,15523,14209,14206,14881,15501,14904,14223,14224, + 15572,14939, 2404,15594, 2401, 2400,14225,14233,14239,14299, + 14949, 2377,15411, 2366,14304,15304, 2335, 2323,14401,15344, + + 2317,14405,14406, 2279,14400,14453, 2276,14458, 2255,14506, + 14498,14520,14532,14532, 2254,14570,14566,14686,14572,14577, + 17872,14589,14590,14604,14626,14647,17872,17872,17872,15421, + 2315,15511,15517,15552,15603,15609,14663,14694,14780,14778, + 14799,15597,15621, 2314,15621,15651, 2275,15652,15689,14830, + 14825,15628, 2211,15631, 2192,14887,14913,15634, 2186,14930, + 2156,15669,14921,14949,14999,15727, 2043,15008,15731,15734, + 2031,15016,15044,15746, 2029,15051, 2027,15071,15084,15087, + 15083,15125,17872,15110,15130,15130,15135,15158,15247,15295, + 15329,15336,17872,15341,15355,15470,15469,17872,15492,15749, + + 2008, 2047,15700,15706,15742,15757,15481,15594, 0,15595, + 17872,15673,15718, 2045,15758,15810, 2036,15811,15825,15594, + 15583, 1946, 1944,15643,15701,15745,15753, 1906, 1900, 1494, + 15746, 1847,15785,15817,15805,15795, 1725, 1640,15808,15810, + 15828, 1617,15815,15810,15819,15825,15818,15829,15837,17872, + 15824,15837,15833,15834,15850,15850,15839,15848,15856,17872, + 15873,17872, 1519, 1567,15852,15872,15863,15897, 0,15880, + 15898, 1500,15911,15919, 1482,15942,15957,15900,15907,15931, + 15934,15930, 1402,15933, 915, 1336,15936,15955, 1365, 1341, + 1302,15958,15951,15952,15964,15929,17872,15954,15974,15976, + + 15964,17872,15968,15971,17872,15975,17872,15984,17872,16002, + 15992, 1356,15999,15890,16014, 0,16005, 1354,16024,16025, + 1337,16044,16052,17872,16010,16000,17872,17872,16000,17872, + 1248, 1247,16022,16013,16028,16030,16025,16066,16072,16053, + 16075, 1234,16054,16056,17872,16057,16073,16069,17872,16088, + 16093,17872, 1002,16040, 959, 954,16119,16120, 905,16136, + 16137,16094,17872,16083, 730,16119,16126,16131,16132,16083, + 753,16165, 718,16118, 711,17872,16168,16130,17872,17872, + 16135,17872,17872,16137, 747,16164,16179, 745,16180,16187, + 17872,16163,16179,16175,16194,16195,16196, 674,16194,16236, + + 672,16185,16187,16188, 722,16239,16246, 711,16267,16204, + 16287,16191,16231,16248,16255,16247,16248, 627,16251,17872, + 16257, 687,16284, 648,16304, 1550, 513, 502,16265, 536, + 527,16272,16275,16264,17872,16268,16294,17872, 480, 472, + 466,16282,16294,16285,16284,16278,16329,17872,16302, 461, + 16316,16305,16307,17872,16357,16360, 462,16319,16302,16316, + 16321,16363, 454,16329, 447,16328,16385,16328,16328, 117, + 16340,17872,16349,16388,16359,16342,16356,16351,16353,16372, + 17872,16364,16376,16356,16405,17872,16496,16508,16520,16532, + 16544,16556,16568,16580,16592,16604,16616,16628,16640,16652, + + 16664,16676,16685,16691,16699,16701,16704,16712,16717,16723, + 16725,16727,16730,16737,16740,16748,16760,16772,16784,16796, + 16808,16819,16830,16838,16844,16856,16864,16866,16872,16880, + 16886,16898,16907,16913,16925,16933,16935,16938,16946,16951, + 16957,16959,16961,16964,16971,16974,16982,16994,17006,17018, + 17030,17042,17053,17064,17076,17084,17090,17102,17114,17122, + 17124,17130,17142,17150,17156,17168,17180,17192,17200,17205, + 17207,17212,17213,17216,17224,17236,17248,17260,17272,17280, + 17286,17298,17310,17318,17320,17326,17338,17346,17355,17367, + 17376,17382,17394,17402,17409,17417,17422,17430,17432,17439, + + 17441,17444,17446,17453,17456,17464,17476,17488,17500,17512, + 17524,17532,17538,17550,17562,17574,17582,17584,17590,17602, + 17614,17622,17631,17643,17655,17663,17668,17670,17675,17676, + 17679,17687,17699,17711,17723,17731,17737,17749,17757,17763, + 17775,17787,17799,17811,17823,17835,17847,17859 } ; -static yyconst flex_int16_t yy_def[2759] = +static yyconst flex_int16_t yy_def[2949] = { 0, - 2596, 1, 2596, 3, 2597, 2597, 2596, 7, 2596, 9, - 2596, 11, 2598, 2598, 2599, 2599, 2600, 2600, 2596, 19, - 2600, 2600, 2601, 2601, 2602, 2602, 2603, 2603, 2604, 2604, - 2605, 2605, 2606, 2606, 2607, 2607, 2596, 37, 2608, 2608, - 2609, 2609, 2596, 43, 2596, 45, 2610, 2610, 2596, 49, - 2611, 2611, 2612, 2612, 2600, 2600, 2596, 2596, 2596, 2596, - 2596, 2613, 2614, 2615, 2616, 2596, 2596, 2596, 2596, 2596, - 2596, 2615, 2596, 2615, 2615, 2615, 2615, 2615, 2615, 2615, - 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, - 2615, 88, 2615, 2615, 88, 88, 2617, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2618, 2596, 2596, 2596, 2618, - 2618, 2618, 2618, 2618, 2618, 2618, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2619, 2619, 2619, 2596, - 2619, 131, 2596, 131, 131, 131, 131, 131, 131, 131, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2620, 2621, 2622, - 2596, 2621, 2621, 2623, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2624, 2596, 2596, 2624, 2596, 2624, 2596, - 2596, 2624, 2624, 2624, 2624, 2624, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2625, 2596, 2596, 2596, - - 2625, 2596, 2625, 2625, 2625, 2625, 2625, 2625, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2626, 2596, 2627, 2628, 2596, 2629, 2596, 2596, 2630, 2631, - 2596, 2632, 2596, 2596, 2596, 2596, 2596, 2633, 2634, 2596, - 2596, 2596, 2596, 2596, 2634, 2634, 2634, 2634, 2634, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2635, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2636, 2637, 2596, 2596, 2596, 2596, - 2637, 2637, 2637, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2638, 2596, 2596, 2638, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2639, 2640, 2596, 2596, - 2596, 2596, 2596, 2640, 2596, 2596, 2596, 2640, 2640, 2640, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2641, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2642, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2643, 2596, 2596, 2596, 2596, 2596, 2596, 2644, 2645, - 2644, 2644, 2644, 2644, 2644, 2644, 2646, 2596, 2596, 2596, - 2596, 2596, 2596, 2647, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2646, 2646, 2646, 2646, - - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2648, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2649, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2649, 2649, 2649, 2649, 2649, 2649, 2649, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2650, 2650, 2650, - - 2596, 2650, 502, 502, 502, 502, 502, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2651, 2596, 2596, 2596, - 2596, 2596, 2596, 2652, 2596, 2596, 2596, 2596, 2596, 2596, - 2653, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2652, 2652, 2654, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2655, 2596, - 2596, 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2656, - - 2656, 2656, 2596, 2596, 2656, 2656, 2656, 2656, 2656, 2656, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2657, 2596, 2658, 2596, 2596, 2596, 2596, 2659, - 2596, 2660, 2596, 2596, 2596, 2596, 2596, 2596, 2661, 2596, - 2596, 2596, 2662, 2596, 2663, 2596, 2596, 2596, 2664, 2665, - 2664, 2664, 2664, 2664, 2664, 2664, 2666, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2666, 2666, 2666, 2666, 2666, - 2666, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2667, 2596, 2596, 2596, 2596, 2596, 2596, 2668, - 2669, 2668, 2668, 2668, 2668, 2668, 2668, 2670, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2670, 2670, 2670, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2671, 2596, 2596, 2596, - 2596, 2596, 2596, 2671, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2672, 2673, 2672, 2672, 2672, - 2672, 2672, 2672, 2674, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2674, 2674, 2596, 2674, 2674, 2674, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2675, 2596, 2596, 2596, 2596, 2596, 2596, 2676, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2677, 2677, 2677, 2677, 2677, 2677, - - 2677, 2677, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2678, 2596, 2596, 2596, 2596, 2596, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2679, 2679, 2596, 2596, 2596, - 2596, 2596, 2680, 2680, 2680, 2680, 2680, 2680, 2680, 2680, - 2596, 2596, 2596, 2596, 2681, 2681, 2681, 2681, 2681, 2681, - 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2682, 2682, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2682, 2682, 2596, 2683, 2683, 2683, - 2683, 2683, 2683, 2683, 2683, 2596, 2596, 2596, 2596, 2596, - 2684, 2684, 2684, 2684, 2684, 2684, 2684, 2684, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2685, 2685, - - 2596, 2596, 2596, 2686, 2686, 2596, 2596, 2596, 2687, 2687, - 2596, 2596, 2596, 2688, 2688, 2688, 2688, 2688, 2688, 2688, - 2688, 2596, 2596, 2689, 2596, 2596, 2596, 2596, 2690, 2690, - 2690, 2690, 2690, 2690, 2690, 2690, 2596, 2596, 2596, 2691, - 2596, 2596, 2596, 2596, 2596, 2692, 2692, 2692, 2692, 2692, - 2692, 2692, 2692, 2596, 2596, 2693, 2596, 2694, 2694, 2694, - 2694, 2694, 2596, 2596, 2596, 2695, 2695, 2695, 2596, 2596, - 2596, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2596, - 2596, 2697, 2596, 2596, 2596, 2596, 2596, 2698, 2596, 2596, - 2698, 2698, 2698, 2698, 2698, 2596, 2596, 2699, 2596, 2596, - - 2596, 2700, 2596, 2596, 2596, 2596, 2596, 2596, 2701, 2701, - 2596, 2702, 2702, 2703, 2704, 2704, 2596, 2705, 2705, 2705, - 2596, 2596, 2596, 2596, 2596, 2596, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2596, 2596, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2707, 2707, 2596, - 2708, 2708, 2708, 2708, 2708, 2708, 2709, 2709, 2709, 2709, - 2596, 2709, 2709, 2709, 2709, 2709, 2709, 2710, 2710, 2596, - 2711, 2711, 2596, 2712, 2712, 2713, 2713, 2596, 2714, 2714, - 2714, 2714, 2714, 2714, 2714, 2714, 2715, 2715, 2715, 2715, - 2715, 2715, 2715, 2715, 2716, 2596, 2717, 2596, 2718, 2596, - 2719, 2719, 2720, 2721, 2721, 2721, 2596, 2596, 2596, 2596, - 2722, 2722, 2722, 2722, 2722, 2722, 2596, 2723, 2723, 2723, - 2596, 2596, 2724, 2724, 2725, 2726, 2726, 2726, 2596, 2727, - 2727, 2727, 2728, 2596, 2729, 2729, 2730, 2731, 2731, 2731, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2732, 2732, - 2732, 2733, 2733, 2733, 2596, 2596, 2596, 2734, 2734, 2734, - 2596, 2596, 2596, 2596, 2596, 2596, 2735, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2596, 2596, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2596, 2596, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2737, - 2737, 2737, 2737, 2737, 2596, 2738, 2738, 2738, 2738, 2738, - 2738, 2738, 2738, 2738, 2739, 2739, 2740, 2740, 2740, 2740, - 2740, 2740, 2740, 2740, 2741, 2741, 2741, 2741, 2741, 2741, - 2741, 2742, 2742, 2742, 2742, 2596, 2743, 2743, 2743, 2743, - 2596, 2744, 2744, 2744, 2744, 2596, 2745, 2596, 2596, 2596, - 2746, 2746, 2596, 2596, 2596, 2596, 2746, 2746, 2746, 2596, - 2747, 2596, 2748, 2749, 2749, 2749, 2731, 2596, 2596, 2732, - 2732, 2732, 2733, 2596, 2734, 2596, 2596, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - 2596, 2596, 2596, 2596, 2736, 2736, 2596, 2596, 2596, 2736, - 2736, 2736, 2736, 2596, 2596, 2596, 2736, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2737, 2737, - 2737, 2737, 2738, 2738, 2738, 2738, 2738, 2738, 2738, 2738, - 2738, 2739, 2740, 2740, 2740, 2740, 2740, 2740, 2740, 2740, - 2741, 2741, 2741, 2741, 2741, 2741, 2742, 2743, 2744, 2596, - - 2596, 2596, 2746, 2746, 2750, 2596, 2596, 2750, 2750, 1464, - 1464, 2750, 1464, 2750, 2750, 2750, 2750, 2750, 2750, 2596, - 2596, 2746, 2746, 2746, 2596, 2749, 2749, 2749, 2596, 2596, - 2732, 2732, 2732, 2596, 2596, 2596, 2736, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2596, 2596, 2596, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2596, 2596, 2596, 2596, 2596, 2596, - 2736, 2736, 2596, 2751, 2596, 2736, 2736, 2736, 2596, 2596, - 2736, 2736, 2736, 2736, 2736, 2736, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2736, 2736, 2736, 2596, 2596, 2596, 2736, - 2736, 2736, 2737, 2737, 2738, 2738, 2738, 2738, 2738, 2738, - 2738, 2738, 2739, 2740, 2740, 2740, 2740, 2740, 2740, 2740, - 2741, 2741, 2741, 2741, 2741, 2596, 2596, 2596, 2746, 2746, - 2750, 2750, 2750, 2596, 2596, 2750, 1464, 2750, 2750, 2750, - 2750, 2750, 2750, 2750, 2750, 2752, 2596, 2746, 2746, 2749, - 2749, 2749, 2596, 2596, 2732, 2732, 2596, 2596, 2736, 2736, - 2736, 2736, 2596, 2753, 2596, 2736, 2736, 2736, 2736, 2736, - 2596, 2754, 2596, 2596, 2596, 2736, 2736, 2596, 2751, 2751, - 2596, 2736, 2596, 2596, 2596, 2596, 2736, 2736, 2596, 2596, - - 2596, 2596, 2755, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, 2736, 2736, - 2596, 2756, 2596, 2736, 2736, 2737, 2737, 2738, 2738, 2738, - 2738, 2738, 2738, 2738, 2738, 2739, 2740, 2740, 2740, 2740, - 2740, 2740, 2740, 2741, 2741, 2741, 2741, 2741, 2596, 2596, - 2596, 2746, 2746, 2750, 2750, 2596, 2757, 2752, 2750, 1464, - 1464, 1464, 2750, 2752, 2752, 2757, 2752, 2752, 2752, 2596, - 2746, 2746, 2749, 2749, 2749, 2596, 2596, 2732, 2596, 2736, - 2736, 2736, 2736, 2596, 2753, 2753, 2596, 2736, 2736, 2736, - - 2736, 2596, 2754, 2754, 2596, 2596, 2596, 2736, 2736, 2596, - 2596, 2596, 2596, 2736, 2596, 2596, 2758, 2596, 2736, 2596, - 2596, 2596, 2596, 2755, 2755, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2736, 2596, 2756, 2756, 2596, 2736, 2737, 2737, 2738, - 2738, 2738, 2740, 2740, 2740, 2741, 2741, 2741, 2596, 2596, - 2596, 2746, 2746, 2750, 2596, 2757, 2757, 2757, 2757, 2757, - 2757, 2750, 1464, 2752, 2752, 2757, 2757, 2752, 2752, 2752, - 2746, 2746, 2749, 2749, 2749, 2596, 2596, 2732, 2596, 2736, - - 2736, 2736, 2596, 2596, 2596, 2596, 2736, 2736, 2736, 2596, - 2596, 2596, 2596, 2596, 2596, 2736, 2736, 2596, 2596, 2596, - 2596, 2596, 2596, 2758, 2758, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, - 2596, 2596, 2596, 2596, 2737, 2737, 2738, 2738, 2738, 2740, - 2740, 2740, 2741, 2741, 2741, 2596, 2596, 2596, 2596, 2596, - 2746, 2746, 2750, 2757, 2757, 2757, 2752, 2757, 2752, 2746, - 2749, 2749, 2596, 2596, 2596, 2596, 2732, 2596, 2596, 2596, - - 2596, 2596, 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2736, - 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, 2596, - 2596, 2596, 2596, 2737, 2737, 2738, 2740, 2741, 2741, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2757, - 2752, 2746, 2749, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2736, 2596, 2596, 2596, 2596, - - 2736, 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2737, - 2737, 2738, 2740, 2741, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2757, 2746, 2749, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, 2596, - 2596, 2596, 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2737, 2737, 2738, 2740, 2596, 2596, 2596, 2596, - 2596, 2746, 2749, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2736, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2737, 2738, 2740, 2596, 2596, 2596, 2746, 2749, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2737, 2738, 2740, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2737, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 0, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596 + 2786, 1, 2786, 3, 2787, 2787, 2786, 7, 2786, 9, + 2786, 11, 2788, 2788, 2789, 2789, 2790, 2790, 2786, 19, + 2790, 2790, 2791, 2791, 2792, 2792, 2793, 2793, 2794, 2794, + 2795, 2795, 2796, 2796, 2797, 2797, 2786, 37, 2798, 2798, + 2799, 2799, 2786, 43, 2786, 45, 2800, 2800, 2786, 49, + 2801, 2801, 2790, 2790, 2802, 2802, 2790, 2790, 2786, 2786, + 2786, 2786, 2786, 2803, 2804, 2805, 2806, 2786, 2786, 2786, + 2786, 2786, 2786, 2805, 2786, 2805, 2805, 2805, 2805, 2805, + 2805, 2805, 2805, 2805, 2805, 2805, 2805, 2805, 2805, 2805, + 2805, 2805, 2805, 90, 2805, 2805, 90, 90, 2807, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2808, 2786, 2786, + 2786, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2809, 2809, + 2809, 2786, 2809, 133, 2786, 133, 133, 133, 133, 133, + 133, 133, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2810, + 2811, 2812, 2786, 2811, 2811, 2813, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2814, 2786, 2786, 2814, 2786, + 2814, 2786, 2786, 2814, 2814, 2814, 2814, 2814, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2815, 2786, + + 2786, 2786, 2815, 2786, 2815, 2815, 2815, 2815, 2815, 2815, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2816, 2786, 2817, 2818, 2786, 2819, 2786, 2786, + 2820, 2821, 2786, 2822, 2786, 2786, 2786, 2786, 2786, 2823, + 2824, 2786, 2786, 2786, 2786, 2786, 2824, 2824, 2824, 2824, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2825, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2826, 2827, 2786, 2786, 2786, + 2786, 2827, 2827, 2827, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2828, 2786, 2786, 2828, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2829, 2830, 2786, + 2786, 2786, 2786, 2786, 2830, 2786, 2786, 2830, 2830, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2831, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2832, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2833, 2786, 2786, 2786, 2786, 2786, 2786, 2834, 2835, 2834, + 2834, 2834, 2834, 2834, 2834, 2836, 2786, 2786, 2786, 2786, + 2786, 2786, 2837, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2836, 2836, 2836, + + 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, + 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, + 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, + 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 410, 410, + 410, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, + 2836, 2836, 2836, 2836, 2836, 2838, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2839, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2839, 2839, 2839, 2839, 2839, 2839, 2839, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2840, 2840, + + 2840, 2786, 2840, 503, 503, 503, 503, 503, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2841, 2786, 2786, + 2786, 2786, 2786, 2786, 2842, 2786, 2786, 2786, 2786, 2786, + 2786, 2843, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2842, 2842, 2844, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2845, + 2786, 2786, 2845, 2845, 2845, 2845, 2845, 2845, 2845, 2845, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2846, 2846, 2846, 2786, 2786, 2846, 2846, 2846, 2846, 2846, + 2846, 2846, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2847, 2786, 2848, 2786, 2786, 2786, + 2786, 2849, 2786, 2850, 2786, 2786, 2786, 2786, 2786, 2786, + 2851, 2786, 2786, 2786, 2852, 2786, 2853, 2786, 2786, 2786, + 2854, 2855, 2854, 2854, 2854, 2854, 2854, 2854, 2856, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2856, 2856, 2856, + 2856, 2856, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2857, 2786, 2786, 2786, 2786, 2786, 2786, + 2858, 2859, 2858, 2858, 2858, 2858, 2858, 2858, 2860, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2860, 2860, 2860, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2861, 2786, 2786, + 2786, 2786, 2786, 2786, 2861, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2862, 2863, 2862, 2862, + 2862, 2862, 2862, 2862, 2864, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2864, 2864, 2864, + 2864, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2865, 2786, 2786, 2786, 2786, 2786, 2786, 2866, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2867, 2867, 2867, 2867, 2867, + + 2867, 2867, 2867, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2868, 2786, 2786, 2786, 2786, 2786, + 2786, 2869, 2786, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + + 2869, 2869, 2869, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2869, 2869, 2786, 2786, 2786, 2786, 2786, 2786, 2870, + 2870, 2870, 2870, 2870, 2870, 2870, 2870, 2870, 2786, 2786, + 2786, 2786, 2871, 2871, 2871, 2871, 2871, 2871, 2871, 2871, + 2871, 2871, 2871, 2871, 2871, 2871, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2872, 2872, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2872, 2872, 2786, 2873, 2873, 2873, 2873, + 2873, 2873, 2873, 2873, 2873, 2786, 2786, 2786, 2786, 2786, + 2874, 2874, 2874, 2874, 2874, 2874, 2874, 2874, 2874, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2875, + 2875, 2786, 2786, 2786, 2876, 2876, 2786, 2786, 2786, 2877, + 2877, 2786, 2786, 2786, 2878, 2878, 2878, 2878, 2878, 2878, + 2878, 2878, 2786, 2786, 2879, 2786, 2786, 2786, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2786, 2786, 2786, 2881, 2786, + 2786, 2786, 2786, 2786, 2882, 2882, 2882, 2882, 2882, 2882, + 2882, 2882, 2786, 2786, 2883, 2786, 2884, 2884, 2884, 2884, + 2884, 2786, 2786, 2786, 2885, 2885, 2885, 2786, 2786, 2786, + 2886, 2886, 2886, 2886, 2886, 2886, 2886, 2886, 2786, 2786, + 2786, 2887, 2786, 2786, 2786, 2786, 2786, 2786, 2888, 2786, + + 2888, 2888, 2888, 2888, 2888, 2786, 2786, 2889, 2786, 2786, + 2786, 2890, 2786, 2786, 2786, 2786, 2786, 2786, 2891, 2891, + 2786, 2892, 2892, 2893, 2894, 2894, 2786, 2786, 2895, 2895, + 2895, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2786, + + 2786, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2897, 2897, 2786, 2786, 2898, 2898, 2898, 2898, 2898, + 2898, 2898, 2899, 2899, 2899, 2899, 2786, 2899, 2899, 2899, + 2899, 2899, 2899, 2899, 2900, 2900, 2786, 2901, 2901, 2786, + 2902, 2902, 2903, 2903, 2786, 2904, 2904, 2904, 2904, 2904, + 2904, 2904, 2904, 2904, 2905, 2905, 2905, 2905, 2905, 2905, + 2905, 2905, 2905, 2906, 2786, 2907, 2786, 2908, 2786, 2909, + 2909, 2910, 2911, 2911, 2911, 2786, 2786, 2786, 2912, 2912, + 2912, 2912, 2912, 2786, 2913, 2913, 2913, 2786, 2786, 2914, + + 2914, 2915, 2916, 2916, 2916, 2786, 2917, 2917, 2917, 2918, + 2786, 2919, 2919, 2920, 2786, 2921, 2921, 2921, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2922, 2922, 2922, 2923, 2923, + 2923, 2786, 2786, 2786, 2924, 2924, 2924, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2925, 2786, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2786, 2786, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2786, 2786, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + + 2926, 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2786, 2927, 2927, 2927, 2927, 2927, 2927, 2786, 2928, 2928, + 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2929, 2929, + 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2931, + 2931, 2931, 2931, 2931, 2931, 2931, 2931, 2932, 2932, 2932, + 2932, 2786, 2933, 2933, 2933, 2933, 2786, 2934, 2934, 2934, + 2934, 2786, 2935, 2786, 2786, 2936, 2786, 2786, 2786, 2786, + 2936, 2936, 2936, 2786, 2937, 2786, 2938, 2939, 2939, 2939, + + 2786, 2921, 2786, 2922, 2922, 2922, 2923, 2786, 2924, 2786, + 2786, 2926, 2786, 2786, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2786, 2786, 2786, + 2786, 2926, 2926, 2786, 2786, 2786, 2926, 2926, 2926, 2926, + 2786, 2786, 2786, 2926, 2786, 2786, 2926, 2926, 2926, 2786, + 2786, 2926, 2926, 2926, 2926, 2926, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + + 2926, 2786, 2927, 2927, 2927, 2927, 2927, 2928, 2928, 2928, + 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2929, 2930, 2930, + 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2931, 2931, 2931, + 2931, 2931, 2931, 2931, 2932, 2933, 2934, 2786, 2786, 2936, + 2940, 2786, 2786, 2940, 2940, 1488, 1488, 2940, 1488, 2940, + 2940, 2940, 2940, 2940, 2940, 2786, 2786, 2936, 2936, 2936, + 2786, 2939, 2939, 2939, 2786, 2786, 2922, 2922, 2922, 2786, + 2786, 2926, 2786, 2786, 2786, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2786, 2786, 2786, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2926, + + 2926, 2786, 2941, 2786, 2926, 2926, 2926, 2786, 2786, 2926, + 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2926, 2926, + 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2926, 2926, 2926, 2786, 2786, 2786, 2926, 2926, 2926, + 2786, 2927, 2927, 2927, 2928, 2928, 2928, 2928, 2928, 2928, + 2928, 2928, 2928, 2929, 2930, 2930, 2930, 2930, 2930, 2930, + 2930, 2930, 2931, 2931, 2931, 2931, 2931, 2931, 2786, 2786, + 2936, 2940, 2940, 2940, 2786, 2786, 2940, 1488, 2940, 2940, + + 2940, 2940, 2940, 2940, 2940, 2940, 2942, 2786, 2936, 2936, + 2939, 2939, 2939, 2786, 2786, 2922, 2922, 2786, 2786, 2926, + 2786, 2786, 2926, 2926, 2926, 2926, 2786, 2943, 2786, 2926, + 2926, 2926, 2926, 2926, 2786, 2944, 2786, 2786, 2786, 2926, + 2926, 2786, 2941, 2941, 2786, 2926, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2786, + 2945, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2926, 2926, + 2926, 2786, 2946, 2786, 2926, 2926, 2786, 2927, 2927, 2927, + + 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2929, + 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2931, 2931, + 2931, 2931, 2931, 2931, 2786, 2786, 2936, 2940, 2940, 2786, + 2947, 2942, 2940, 1488, 1488, 1488, 2940, 2942, 2942, 2947, + 2942, 2942, 2942, 2786, 2936, 2936, 2939, 2939, 2939, 2786, + 2786, 2922, 2786, 2786, 2926, 2786, 2926, 2926, 2926, 2926, + 2786, 2943, 2943, 2786, 2926, 2926, 2926, 2926, 2786, 2944, + 2944, 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2786, + 2926, 2786, 2786, 2786, 2948, 2786, 2786, 2926, 2786, 2786, + 2786, 2786, 2945, 2945, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2926, 2786, 2946, 2946, 2786, 2926, + 2786, 2927, 2927, 2927, 2928, 2928, 2928, 2928, 2930, 2930, + 2930, 2930, 2931, 2931, 2931, 2931, 2786, 2786, 2936, 2940, + 2786, 2947, 2947, 2947, 2947, 2947, 2947, 2940, 1488, 2942, + 2942, 2947, 2947, 2942, 2942, 2942, 2936, 2936, 2939, 2939, + 2939, 2786, 2786, 2922, 2786, 2786, 2926, 2786, 2926, 2926, + 2926, 2786, 2786, 2786, 2786, 2926, 2926, 2926, 2786, 2786, + 2786, 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2948, 2948, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2926, 2786, 2786, 2786, 2786, 2786, + 2927, 2927, 2927, 2928, 2928, 2928, 2928, 2930, 2930, 2930, + 2930, 2931, 2931, 2931, 2931, 2786, 2786, 2786, 2786, 2936, + 2940, 2947, 2947, 2947, 2942, 2947, 2942, 2936, 2939, 2939, + 2786, 2786, 2922, 2786, 2786, 2926, 2786, 2786, 2786, 2786, + 2786, 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2926, 2926, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2926, 2786, 2786, 2786, 2786, 2786, 2927, + 2927, 2927, 2928, 2928, 2930, 2930, 2931, 2931, 2931, 2786, + 2786, 2786, 2786, 2786, 2947, 2942, 2936, 2939, 2786, 2786, + 2922, 2786, 2786, 2926, 2786, 2786, 2786, 2786, 2926, 2786, + 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2927, 2927, 2927, 2928, 2928, 2930, 2930, 2931, + 2931, 2786, 2786, 2786, 2947, 2936, 2939, 2786, 2786, 2922, + 2786, 2786, 2926, 2786, 2786, 2786, 2926, 2786, 2786, 2786, + 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2927, 2927, 2927, 2928, 2928, 2930, 2930, 2931, 2786, + 2786, 2936, 2939, 2786, 2786, 2922, 2786, 2786, 2926, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2926, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2927, 2927, 2928, 2928, 2930, 2930, 2931, 2786, + 2786, 2936, 2939, 2786, 2786, 2922, 2786, 2786, 2926, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2927, 2927, 2928, 2928, 2930, 2930, + 2786, 2786, 2786, 2922, 2786, 2786, 2926, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2927, 2927, 2928, 2930, 2786, 2786, 2786, 2922, + 2786, 2786, 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2927, 2786, 2786, 2786, 2922, 2786, 2786, + 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2922, 2786, 2786, 2926, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2922, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 0, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786 } ; -static yyconst flex_int16_t yy_nxt[17539] = +static yyconst flex_int16_t yy_nxt[17967] = { 0, - 58, 59, 60, 59, 61, 62, 63, 64, 65, 66, - 66, 61, 67, 68, 69, 70, 71, 72, 72, 61, - 61, 61, 73, 61, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 64, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 64, 64, - 58, 64, 97, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 64, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 64, 64, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 98, - 99, 100, 101, 102, 103, 104, 104, 105, 104, 104, - - 104, 106, 106, 104, 107, 107, 108, 109, 104, 109, - 104, 104, 110, 110, 104, 104, 104, 104, 104, 106, - 106, 106, 106, 106, 111, 106, 106, 112, 106, 106, - 106, 106, 106, 106, 106, 113, 114, 115, 106, 106, - 106, 116, 106, 106, 106, 104, 106, 104, 106, 106, - 106, 106, 106, 111, 106, 106, 112, 106, 106, 106, - 106, 106, 106, 106, 113, 114, 115, 106, 106, 106, - 116, 106, 106, 106, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 117, 118, 119, 120, 121, 122, - 124, 124, 378, 379, 380, 381, 382, 383, 2579, 125, - - 125, 126, 127, 128, 127, 126, 126, 129, 129, 126, - 126, 126, 130, 131, 126, 132, 133, 126, 129, 129, - 126, 126, 126, 126, 126, 129, 129, 129, 134, 135, - 129, 136, 129, 129, 129, 129, 129, 129, 129, 137, - 138, 129, 139, 129, 140, 129, 129, 129, 129, 129, - 129, 126, 129, 126, 129, 129, 129, 134, 135, 129, - 136, 129, 129, 129, 129, 129, 129, 129, 137, 138, - 129, 139, 129, 140, 129, 129, 129, 129, 129, 129, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 141, 142, 143, 144, 145, 146, 147, 147, 105, 147, - - 147, 148, 149, 149, 150, 147, 147, 151, 147, 147, - 147, 147, 147, 149, 149, 147, 147, 147, 147, 147, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 152, 149, 149, 149, 153, - 149, 149, 149, 149, 149, 149, 147, 149, 154, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 152, 149, 149, 149, 153, 149, - 149, 149, 149, 149, 149, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 162, 161, 161, 161, 164, 165, - - 161, 161, 166, 167, 168, 169, 170, 161, 164, 164, - 161, 161, 171, 161, 161, 164, 164, 164, 172, 173, - 164, 174, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 175, 164, 176, 164, 164, 164, 164, 164, - 164, 161, 164, 161, 164, 164, 164, 172, 173, 164, - 174, 164, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 175, 164, 176, 164, 164, 164, 164, 164, 164, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 177, 161, 178, 161, 180, 181, 180, 232, - 180, 181, 180, 182, 232, 235, 183, 182, 184, 235, - - 183, 238, 184, 188, 189, 188, 238, 188, 189, 188, - 190, 105, 105, 191, 190, 190, 356, 191, 105, 190, - 105, 392, 392, 393, 357, 478, 392, 392, 394, 394, - 479, 233, 2585, 358, 268, 268, 233, 236, 437, 480, - 480, 236, 496, 499, 356, 356, 239, 497, 312, 2558, - 312, 239, 357, 357, 472, 473, 474, 475, 476, 477, - 515, 358, 358, 268, 268, 516, 559, 437, 2547, 521, - 580, 560, 499, 356, 2546, 581, 185, 312, 186, 312, - 185, 357, 186, 378, 379, 380, 381, 382, 383, 592, - 358, 596, 2569, 192, 593, 193, 597, 192, 521, 193, - - 194, 195, 196, 195, 194, 194, 194, 197, 198, 199, - 199, 200, 201, 202, 203, 194, 194, 204, 204, 194, - 194, 199, 194, 194, 204, 204, 204, 204, 204, 204, - 205, 204, 204, 204, 204, 204, 204, 204, 204, 206, - 204, 204, 207, 208, 204, 204, 204, 204, 204, 204, - 194, 204, 194, 204, 204, 204, 204, 204, 204, 205, - 204, 204, 204, 204, 204, 204, 204, 204, 206, 204, - 204, 207, 208, 204, 204, 204, 204, 204, 204, 199, - 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 209, 194, 210, 194, 211, 211, 211, 211, 211, - - 211, 2564, 396, 212, 397, 397, 212, 216, 217, 216, - 385, 2563, 218, 2561, 219, 398, 220, 221, 216, 217, - 216, 456, 582, 218, 583, 219, 2560, 220, 221, 225, - 226, 225, 751, 751, 227, 499, 227, 227, 227, 228, - 225, 226, 225, 519, 398, 227, 584, 227, 227, 227, - 228, 582, 2557, 583, 423, 499, 1454, 406, 457, 458, - 459, 460, 461, 462, 499, 603, 753, 753, 2508, 520, - 604, 407, 519, 585, 408, 584, 378, 379, 380, 381, - 382, 383, 2486, 423, 499, 213, 406, 214, 213, 605, - 214, 386, 387, 388, 389, 390, 391, 222, 520, 223, - - 407, 615, 585, 408, 619, 2526, 616, 2525, 222, 620, - 223, 378, 379, 380, 381, 382, 383, 2475, 605, 229, - 2517, 230, 378, 379, 380, 381, 382, 383, 392, 392, - 229, 1599, 230, 244, 245, 246, 245, 244, 247, 248, - 249, 250, 251, 244, 244, 244, 244, 252, 244, 244, - 249, 249, 244, 253, 244, 244, 254, 255, 249, 249, - 249, 249, 256, 257, 249, 249, 249, 249, 258, 249, - 249, 249, 249, 249, 259, 249, 249, 249, 249, 249, - 249, 249, 249, 244, 249, 260, 255, 249, 249, 249, - 249, 256, 257, 249, 249, 249, 249, 258, 249, 249, - - 249, 249, 249, 259, 249, 249, 249, 249, 249, 249, - 249, 249, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 261, 262, 263, 264, 265, 266, 270, 271, - 270, 409, 272, 273, 2475, 274, 275, 276, 270, 271, - 270, 277, 272, 273, 410, 274, 275, 276, 404, 499, - 2511, 277, 405, 411, 518, 522, 601, 602, 499, 412, - 409, 427, 545, 546, 547, 548, 549, 550, 2443, 278, - 606, 680, 752, 410, 2501, 751, 751, 404, 499, 278, - 2405, 405, 411, 518, 522, 601, 602, 499, 412, 2481, - 427, 2480, 378, 379, 380, 381, 382, 383, 278, 606, - - 680, 378, 379, 380, 381, 382, 383, 2477, 278, 378, - 379, 380, 381, 382, 383, 2398, 478, 2476, 279, 2381, - 280, 479, 378, 379, 380, 381, 382, 383, 279, 2359, - 280, 281, 282, 283, 282, 281, 284, 285, 286, 287, - 288, 289, 281, 281, 281, 290, 281, 281, 286, 286, - 281, 281, 281, 281, 281, 286, 286, 286, 286, 286, - 291, 286, 286, 286, 286, 286, 292, 286, 286, 286, - 286, 286, 293, 286, 286, 286, 286, 286, 286, 286, - 286, 281, 286, 281, 286, 286, 286, 286, 286, 291, - 286, 286, 286, 286, 286, 292, 286, 286, 286, 286, - - 286, 293, 286, 286, 286, 286, 286, 286, 286, 286, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 294, 295, 296, 297, 298, 299, 105, 105, 105, 105, - 105, 300, 301, 301, 302, 105, 105, 105, 105, 105, - 105, 105, 105, 301, 301, 105, 105, 105, 105, 303, - 301, 301, 301, 301, 301, 304, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 105, 301, 105, 301, - 301, 301, 301, 301, 304, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - - 301, 301, 301, 301, 301, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 305, 306, 307, 308, 309, - 310, 313, 314, 315, 314, 313, 316, 317, 318, 319, - 313, 313, 313, 320, 321, 322, 323, 313, 324, 324, - 313, 325, 326, 313, 327, 328, 318, 318, 318, 318, - 318, 329, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 330, 318, 318, 318, 318, 318, 318, - 318, 313, 318, 331, 328, 318, 318, 318, 318, 318, - 329, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 330, 318, 318, 318, 318, 318, 318, 318, - - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 332, 333, 334, 335, 336, 337, 339, 340, 339, 480, - 480, 341, 2354, 339, 340, 339, 2449, 685, 341, 342, - 1454, 359, 359, 359, 733, 343, 342, 359, 359, 359, - 773, 496, 343, 499, 344, 361, 497, 348, 349, 348, - 416, 344, 350, 774, 1444, 523, 685, 348, 349, 348, - 351, 345, 350, 733, 620, 620, 352, 780, 345, 773, - 351, 2351, 499, 344, 2442, 353, 352, 1043, 1044, 416, - 344, 354, 774, 607, 523, 353, 2441, 781, 608, 783, - 345, 354, 647, 647, 647, 784, 780, 345, 378, 379, - - 380, 381, 382, 383, 353, 1453, 346, 417, 2341, 785, - 354, 418, 607, 346, 353, 419, 781, 608, 783, 2339, - 354, 360, 450, 515, 784, 968, 1597, 360, 516, 363, - 364, 365, 366, 367, 368, 2430, 417, 355, 785, 2300, - 418, 559, 990, 991, 419, 992, 560, 355, 369, 369, - 428, 450, 369, 369, 968, 438, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 439, 969, 369, 369, 369, - 369, 369, 378, 379, 380, 381, 382, 383, 580, 428, - 592, 536, 648, 581, 438, 593, 2413, 378, 379, 380, - 381, 382, 383, 970, 439, 969, 2409, 971, 369, 1449, - - 369, 378, 379, 380, 381, 382, 383, 377, 377, 377, - 377, 377, 377, 377, 377, 377, 378, 379, 380, 381, - 382, 383, 970, 647, 647, 647, 971, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 371, 372, 373, - 374, 375, 376, 399, 609, 400, 681, 681, 681, 499, - 401, 402, 403, 413, 420, 499, 414, 421, 519, 415, - 934, 610, 972, 973, 422, 538, 539, 540, 541, 542, - 543, 1598, 399, 609, 400, 681, 681, 681, 499, 401, - 402, 403, 413, 420, 499, 414, 421, 519, 415, 934, - 610, 972, 973, 422, 751, 751, 2403, 378, 379, 380, - - 381, 382, 383, 688, 688, 688, 2284, 378, 379, 380, - 381, 382, 383, 648, 424, 2395, 378, 379, 380, 381, - 382, 383, 425, 429, 444, 454, 522, 430, 426, 433, - 499, 445, 377, 377, 499, 431, 682, 434, 499, 432, - 926, 446, 377, 424, 377, 377, 435, 520, 2394, 436, - 2272, 425, 429, 444, 454, 522, 430, 426, 433, 499, - 445, 377, 377, 499, 431, 682, 434, 499, 432, 926, - 446, 377, 2189, 377, 377, 435, 520, 927, 436, 378, - 379, 380, 381, 382, 383, 499, 2261, 378, 379, 380, - 381, 382, 383, 689, 378, 379, 380, 381, 382, 383, - - 440, 499, 447, 441, 448, 925, 927, 449, 523, 442, - 481, 481, 499, 2177, 499, 443, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 1126, 1126, 1306, 1306, 440, - 499, 447, 441, 448, 925, 2226, 449, 523, 442, 2362, - 974, 499, 482, 975, 443, 464, 465, 465, 465, 465, - 465, 465, 465, 465, 378, 379, 380, 381, 382, 383, - 451, 378, 379, 380, 381, 382, 383, 452, 453, 974, - 596, 482, 975, 2220, 603, 597, 981, 377, 485, 604, - 377, 2218, 472, 473, 474, 475, 476, 477, 2357, 451, - 472, 473, 474, 475, 476, 477, 452, 453, 658, 659, - - 660, 661, 662, 663, 2353, 981, 377, 485, 483, 377, - 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, - 467, 467, 467, 467, 467, 467, 468, 469, 470, 470, - 470, 470, 470, 470, 470, 470, 470, 483, 484, 472, - 473, 474, 475, 476, 477, 486, 487, 471, 471, 471, - 471, 471, 471, 471, 471, 471, 1123, 1123, 1123, 1123, - 472, 473, 474, 475, 476, 477, 2204, 484, 637, 637, - 637, 552, 638, 639, 486, 487, 688, 688, 688, 1125, - 1125, 640, 2346, 472, 473, 474, 475, 476, 477, 1125, - 1125, 472, 473, 474, 475, 476, 477, 488, 488, 488, - - 488, 488, 488, 488, 488, 488, 2336, 472, 473, 474, - 475, 476, 477, 489, 490, 490, 490, 490, 490, 490, - 490, 490, 491, 491, 491, 491, 491, 491, 491, 491, - 491, 492, 492, 492, 492, 492, 492, 492, 493, 494, - 495, 495, 495, 495, 495, 495, 495, 495, 495, 498, - 498, 498, 553, 554, 555, 556, 557, 558, 641, 982, - 500, 2335, 500, 501, 1126, 1126, 689, 2185, 394, 394, - 2596, 2596, 2596, 586, 983, 502, 503, 587, 504, 815, - 2331, 2596, 2330, 2596, 501, 984, 588, 505, 982, 506, - 589, 507, 699, 700, 701, 702, 703, 704, 2596, 2596, - - 2596, 2171, 586, 983, 502, 503, 587, 504, 815, 2596, - 564, 2596, 501, 2328, 984, 588, 505, 615, 506, 589, - 507, 2160, 616, 2306, 517, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 2304, 816, 816, 508, 509, 510, - 511, 512, 513, 498, 498, 498, 817, 565, 566, 567, - 568, 569, 570, 517, 500, 561, 500, 501, 508, 509, - 514, 511, 512, 513, 1303, 1303, 624, 624, 624, 502, - 503, 625, 504, 626, 2298, 817, 1303, 1303, 2297, 627, - 2295, 505, 562, 506, 561, 507, 508, 509, 514, 511, - 512, 513, 718, 719, 720, 721, 722, 723, 502, 503, - - 935, 504, 745, 746, 747, 748, 749, 750, 499, 499, - 505, 562, 506, 524, 507, 928, 499, 525, 1305, 1305, - 545, 546, 547, 548, 549, 550, 526, 2121, 985, 935, - 527, 508, 509, 510, 511, 512, 513, 499, 499, 1305, - 1305, 2290, 524, 2115, 928, 499, 525, 545, 546, 547, - 548, 549, 550, 619, 2286, 526, 628, 985, 620, 527, - 528, 528, 528, 528, 528, 528, 528, 528, 528, 529, - 530, 530, 530, 530, 530, 530, 530, 530, 531, 531, + 60, 61, 62, 61, 63, 64, 65, 66, 67, 68, + 68, 63, 69, 70, 71, 72, 73, 74, 63, 63, + 63, 75, 63, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 66, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 66, 66, 60, + 66, 99, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 66, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 66, 66, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 100, 101, + 102, 103, 104, 105, 106, 106, 107, 106, 106, 106, + + 108, 108, 106, 109, 109, 110, 111, 106, 111, 106, + 106, 112, 106, 106, 106, 106, 106, 108, 108, 108, + 108, 108, 113, 108, 108, 114, 108, 108, 108, 108, + 108, 108, 108, 115, 116, 117, 108, 108, 108, 118, + 108, 108, 108, 106, 108, 106, 108, 108, 108, 108, + 108, 113, 108, 108, 114, 108, 108, 108, 108, 108, + 108, 108, 115, 116, 117, 108, 108, 108, 118, 108, + 108, 108, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 119, 120, 121, 122, 123, 124, 126, 126, + 377, 378, 379, 380, 381, 382, 2762, 127, 127, 128, + + 129, 130, 129, 128, 128, 131, 131, 128, 128, 128, + 132, 133, 128, 134, 135, 128, 131, 128, 128, 128, + 128, 128, 131, 131, 131, 136, 137, 131, 138, 131, + 131, 131, 131, 131, 131, 131, 139, 140, 131, 141, + 131, 142, 131, 131, 131, 131, 131, 131, 128, 131, + 128, 131, 131, 131, 136, 137, 131, 138, 131, 131, + 131, 131, 131, 131, 131, 139, 140, 131, 141, 131, + 142, 131, 131, 131, 131, 131, 131, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 143, 144, 145, + 146, 147, 148, 149, 149, 107, 149, 149, 150, 151, + + 151, 152, 149, 149, 153, 149, 149, 149, 149, 149, + 151, 149, 149, 149, 149, 149, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 154, 151, 151, 151, 155, 151, 151, 151, 151, + 151, 151, 149, 151, 156, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 154, 151, 151, 151, 155, 151, 151, 151, 151, 151, + 151, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 164, 163, 163, 163, 166, 167, 163, 163, 168, 169, + + 170, 171, 172, 163, 166, 163, 163, 173, 163, 163, + 166, 166, 166, 174, 175, 166, 176, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 177, 166, 178, + 166, 166, 166, 166, 166, 166, 163, 166, 163, 166, + 166, 166, 174, 175, 166, 176, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 177, 166, 178, 166, + 166, 166, 166, 166, 166, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 163, 163, 179, 163, 180, + 163, 182, 183, 182, 234, 182, 183, 182, 184, 234, + 237, 185, 184, 186, 237, 185, 240, 186, 190, 191, + + 190, 240, 190, 191, 190, 192, 107, 107, 193, 192, + 192, 479, 193, 107, 192, 107, 480, 392, 393, 355, + 394, 424, 457, 500, 522, 235, 2756, 356, 269, 269, + 235, 238, 497, 2770, 516, 238, 357, 498, 355, 517, + 241, 2765, 313, 2738, 313, 241, 356, 2726, 355, 560, + 424, 2725, 500, 522, 561, 357, 356, 269, 269, 458, + 459, 460, 461, 462, 463, 357, 2750, 355, 622, 622, + 187, 313, 188, 313, 187, 356, 188, 2744, 377, 378, + 379, 380, 381, 382, 357, 581, 2743, 194, 2741, 195, + 582, 194, 2740, 195, 196, 197, 198, 197, 196, 196, + + 196, 199, 200, 201, 201, 202, 203, 204, 205, 196, + 196, 206, 196, 196, 201, 196, 196, 206, 206, 206, + 206, 206, 206, 207, 206, 206, 206, 206, 206, 206, + 206, 206, 208, 206, 206, 209, 210, 206, 206, 206, + 206, 206, 206, 196, 206, 196, 206, 206, 206, 206, + 206, 206, 207, 206, 206, 206, 206, 206, 206, 206, + 206, 208, 206, 206, 209, 210, 206, 206, 206, 206, + 206, 206, 201, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 211, 196, 212, 196, 213, 213, + 213, 213, 213, 213, 1052, 1053, 214, 583, 2737, 214, + + 218, 219, 218, 384, 2722, 220, 2700, 221, 417, 222, + 223, 218, 219, 218, 1844, 1845, 220, 584, 221, 412, + 222, 223, 227, 228, 227, 413, 583, 229, 2708, 229, + 229, 229, 230, 227, 228, 227, 585, 417, 229, 2722, + 229, 229, 229, 230, 428, 586, 584, 500, 412, 407, + 593, 2718, 519, 2672, 413, 594, 377, 378, 379, 380, + 381, 382, 2708, 408, 2705, 585, 409, 377, 378, 379, + 380, 381, 382, 428, 586, 606, 500, 215, 407, 216, + 215, 519, 216, 385, 386, 387, 388, 389, 390, 224, + 2641, 225, 408, 597, 604, 409, 617, 2698, 598, 605, + + 224, 618, 225, 2697, 606, 377, 378, 379, 380, 381, + 382, 231, 2630, 232, 377, 378, 379, 380, 381, 382, + 753, 754, 231, 755, 232, 246, 247, 248, 247, 246, + 249, 250, 251, 252, 253, 246, 246, 246, 246, 254, + 246, 246, 251, 246, 255, 246, 246, 256, 251, 251, + 251, 251, 251, 257, 258, 251, 251, 251, 251, 259, + 251, 251, 251, 251, 251, 260, 251, 251, 251, 251, + 251, 251, 251, 251, 246, 251, 261, 251, 251, 251, + 251, 251, 257, 258, 251, 251, 251, 251, 259, 251, + 251, 251, 251, 251, 260, 251, 251, 251, 251, 251, + + 251, 251, 251, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 262, 263, 264, 265, 266, 267, 271, + 272, 271, 2688, 273, 274, 2630, 275, 276, 277, 271, + 272, 271, 278, 273, 274, 621, 275, 276, 277, 397, + 622, 398, 278, 500, 438, 500, 414, 602, 603, 415, + 445, 399, 416, 520, 500, 524, 607, 446, 376, 279, + 473, 474, 475, 476, 477, 478, 681, 447, 521, 279, + 376, 2685, 500, 438, 500, 414, 602, 603, 415, 445, + 399, 416, 520, 500, 524, 607, 446, 376, 279, 377, + 378, 379, 380, 381, 382, 681, 447, 521, 279, 376, + + 377, 378, 379, 380, 381, 382, 479, 2631, 280, 2684, + 281, 480, 377, 378, 379, 380, 381, 382, 280, 2683, + 281, 282, 283, 284, 283, 282, 285, 286, 287, 288, + 289, 290, 282, 282, 282, 291, 282, 282, 287, 282, + 282, 282, 282, 282, 287, 287, 287, 287, 287, 292, + 287, 287, 287, 287, 287, 293, 287, 287, 287, 287, + 287, 294, 287, 287, 287, 287, 287, 287, 287, 287, + 282, 287, 282, 287, 287, 287, 287, 287, 292, 287, + 287, 287, 287, 287, 293, 287, 287, 287, 287, 287, + 294, 287, 287, 287, 287, 287, 287, 287, 287, 282, + + 282, 282, 282, 282, 282, 282, 282, 282, 282, 295, + 296, 297, 298, 299, 300, 107, 107, 107, 107, 107, + 301, 302, 302, 303, 107, 107, 107, 107, 107, 107, + 107, 107, 302, 107, 107, 107, 107, 304, 302, 302, + 302, 302, 302, 305, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 107, 302, 107, 302, 302, 302, + 302, 302, 305, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 107, 107, 107, 107, 107, 107, 107, + + 107, 107, 107, 306, 307, 308, 309, 310, 311, 314, + 315, 316, 315, 314, 317, 318, 319, 320, 314, 314, + 314, 321, 322, 323, 324, 314, 325, 314, 326, 327, + 314, 327, 319, 319, 319, 319, 319, 319, 328, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 329, 319, 319, 319, 319, 319, 319, 319, 314, 319, + 330, 319, 319, 319, 319, 319, 319, 328, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 329, + 319, 319, 319, 319, 319, 319, 319, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 331, 332, 333, + + 334, 335, 336, 338, 339, 338, 686, 497, 340, 338, + 339, 338, 498, 2675, 340, 734, 341, 358, 358, 358, + 523, 342, 341, 500, 347, 348, 347, 342, 2585, 349, + 343, 358, 358, 358, 2665, 686, 343, 350, 455, 405, + 774, 360, 351, 406, 734, 516, 376, 344, 775, 523, + 517, 352, 500, 344, 2659, 376, 781, 353, 376, 343, + 782, 347, 348, 347, 784, 343, 349, 455, 405, 774, + 410, 2656, 406, 2653, 350, 376, 344, 775, 785, 351, + 352, 2534, 344, 411, 376, 781, 353, 376, 352, 782, + 786, 2636, 345, 784, 353, 649, 649, 649, 345, 410, + + 377, 378, 379, 380, 381, 382, 359, 785, 500, 977, + 418, 520, 411, 354, 419, 2635, 560, 352, 420, 786, + 359, 561, 2632, 353, 362, 363, 364, 365, 366, 367, + 1470, 377, 378, 379, 380, 381, 382, 500, 977, 418, + 520, 581, 397, 419, 817, 451, 582, 420, 1963, 1964, + 354, 368, 368, 429, 818, 368, 368, 978, 439, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 440, 368, + 368, 368, 368, 368, 451, 377, 378, 379, 380, 381, + 382, 2527, 429, 818, 650, 1480, 978, 439, 376, 376, + 376, 376, 376, 376, 376, 376, 376, 440, 979, 2621, + + 368, 1635, 368, 2585, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 395, 2618, 820, 377, + 378, 379, 380, 381, 382, 1475, 819, 979, 821, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 370, + 371, 372, 373, 374, 375, 400, 421, 401, 980, 422, + 425, 500, 402, 403, 404, 819, 423, 821, 426, 1637, + 2738, 537, 943, 983, 427, 464, 464, 464, 464, 464, + 464, 464, 464, 464, 400, 421, 401, 980, 422, 425, + 500, 402, 403, 404, 2612, 423, 2586, 426, 649, 649, + 649, 943, 983, 427, 1001, 1002, 1636, 1003, 2500, 377, + + 378, 379, 380, 381, 382, 611, 434, 1470, 377, 378, + 379, 380, 381, 382, 435, 377, 378, 379, 380, 381, + 382, 430, 612, 436, 500, 431, 437, 448, 523, 449, + 935, 524, 450, 432, 611, 434, 500, 433, 500, 682, + 682, 682, 2739, 435, 539, 540, 541, 542, 543, 544, + 430, 612, 436, 500, 431, 437, 448, 523, 449, 935, + 524, 450, 432, 593, 597, 500, 433, 500, 594, 598, + 984, 377, 378, 379, 380, 381, 382, 650, 1469, 377, + 378, 379, 380, 381, 382, 377, 378, 379, 380, 381, + 382, 441, 500, 608, 442, 452, 2474, 483, 609, 984, + + 443, 521, 453, 454, 933, 500, 444, 500, 985, 991, + 610, 500, 376, 936, 938, 376, 682, 682, 682, 2469, + 441, 500, 608, 442, 452, 482, 483, 609, 683, 443, + 521, 453, 454, 933, 500, 444, 500, 985, 991, 610, + 500, 376, 936, 938, 376, 473, 474, 475, 476, 477, + 478, 1475, 377, 378, 379, 380, 381, 382, 465, 466, + 466, 466, 466, 466, 466, 466, 466, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 468, 468, 468, 468, + 468, 468, 468, 469, 470, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 484, 485, 473, 474, 475, 476, + + 477, 478, 486, 992, 2591, 683, 487, 993, 488, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 1971, 1972, + 1844, 2786, 1474, 484, 485, 546, 547, 548, 549, 550, + 551, 486, 992, 604, 617, 487, 993, 488, 605, 618, + 473, 474, 475, 476, 477, 478, 473, 474, 475, 476, + 477, 478, 473, 474, 475, 476, 477, 478, 689, 689, + 689, 1994, 1995, 473, 474, 475, 476, 477, 478, 473, + 474, 475, 476, 477, 478, 489, 489, 489, 489, 489, + 489, 489, 489, 489, 490, 491, 491, 491, 491, 491, + 491, 491, 491, 492, 492, 492, 492, 492, 492, 492, + + 492, 492, 493, 493, 493, 493, 493, 493, 493, 494, + 495, 496, 496, 496, 496, 496, 496, 496, 496, 496, + 499, 499, 499, 621, 994, 565, 2466, 995, 622, 996, + 823, 501, 823, 501, 502, 1134, 553, 2028, 2029, 1963, + 2786, 2786, 2786, 2786, 500, 503, 504, 690, 505, 997, + 2584, 937, 2786, 994, 2786, 502, 995, 506, 996, 507, + 981, 508, 566, 567, 568, 569, 570, 571, 2786, 2786, + 2786, 1971, 2786, 500, 503, 504, 982, 505, 997, 2786, + 937, 2786, 502, 2105, 2106, 2583, 506, 1480, 507, 981, + 508, 1994, 2786, 518, 500, 500, 500, 500, 500, 500, + + 500, 500, 500, 2028, 2786, 982, 562, 509, 510, 511, + 512, 513, 514, 499, 499, 499, 554, 555, 556, 557, + 558, 559, 518, 2454, 501, 2452, 501, 502, 509, 510, + 515, 512, 513, 514, 998, 562, 999, 668, 503, 504, + 669, 505, 660, 661, 662, 663, 664, 665, 1037, 1038, + 506, 563, 507, 2575, 508, 509, 510, 515, 512, 513, + 514, 1479, 2572, 998, 2564, 999, 668, 503, 504, 669, + 505, 546, 547, 548, 549, 550, 551, 1037, 1038, 506, + 563, 507, 525, 508, 500, 500, 526, 2563, 660, 661, + 662, 663, 664, 665, 934, 527, 1048, 1051, 1079, 528, + + 509, 510, 511, 512, 513, 514, 2400, 1135, 2542, 1135, + 2538, 525, 1136, 500, 500, 526, 546, 547, 548, 549, + 550, 551, 2532, 934, 527, 1048, 1051, 1079, 528, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 530, 531, 531, 531, 531, 531, 531, 531, 531, 532, 532, 532, - 532, 532, 532, 532, 533, 534, 535, 535, 535, 535, - - 535, 535, 535, 535, 535, 544, 544, 544, 544, 544, - 544, 544, 544, 544, 571, 571, 571, 571, 571, 571, - 571, 571, 571, 572, 573, 573, 573, 573, 573, 573, - 573, 573, 574, 574, 574, 574, 574, 574, 574, 574, - 574, 575, 575, 575, 575, 575, 575, 575, 576, 577, - 578, 578, 578, 578, 578, 578, 578, 578, 578, 631, - 631, 631, 666, 986, 632, 667, 633, 670, 668, 669, - 1306, 1306, 634, 657, 657, 657, 657, 657, 657, 657, - 657, 657, 672, 672, 672, 672, 672, 672, 672, 672, - 672, 666, 986, 987, 667, 2104, 670, 668, 669, 361, - - 378, 379, 380, 381, 382, 383, 2099, 658, 659, 660, - 661, 662, 663, 1790, 1791, 2443, 658, 659, 660, 661, - 662, 663, 987, 658, 659, 660, 661, 662, 663, 1444, - 1896, 1897, 658, 659, 660, 661, 662, 663, 671, 673, - 674, 674, 674, 674, 674, 674, 674, 674, 2094, 635, - 649, 649, 1904, 1905, 649, 649, 1790, 2596, 649, 649, - 649, 649, 649, 649, 649, 649, 649, 671, 988, 649, - 649, 649, 649, 649, 675, 675, 675, 675, 675, 675, - 675, 675, 675, 363, 364, 365, 366, 367, 368, 658, - 659, 660, 661, 662, 663, 1039, 1042, 988, 1449, 2444, - - 649, 1443, 649, 676, 676, 676, 676, 676, 676, 676, - 677, 678, 679, 679, 679, 679, 679, 679, 679, 679, - 679, 2270, 706, 707, 1039, 1042, 734, 734, 734, 649, - 649, 649, 649, 649, 649, 649, 649, 649, 649, 651, - 652, 653, 654, 655, 656, 690, 690, 1925, 1926, 690, - 690, 706, 707, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 1955, 1956, 690, 690, 690, 690, 690, 2077, - 1448, 1896, 2596, 699, 700, 701, 702, 703, 704, 698, - 698, 698, 698, 698, 698, 698, 698, 698, 699, 700, - 701, 702, 703, 704, 708, 690, 2258, 690, 709, 709, - - 709, 709, 709, 709, 709, 709, 709, 710, 711, 711, - 711, 711, 711, 711, 711, 711, 735, 378, 379, 380, - 381, 382, 383, 708, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 690, 692, 693, 694, 695, 696, 697, - 1904, 2596, 2025, 2026, 2062, 699, 700, 701, 702, 703, - 704, 712, 712, 712, 712, 712, 712, 712, 712, 712, - 713, 713, 713, 713, 713, 713, 713, 714, 715, 716, - 716, 716, 716, 716, 716, 716, 716, 716, 724, 717, - 717, 717, 717, 717, 717, 717, 717, 717, 725, 725, - 725, 725, 725, 725, 725, 725, 725, 726, 727, 727, - - 727, 727, 727, 727, 727, 727, 2248, 724, 728, 728, - 728, 728, 728, 728, 728, 728, 728, 729, 729, 729, - 729, 729, 729, 729, 730, 731, 718, 719, 720, 721, - 722, 723, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 734, 734, 734, 754, 758, 755, 755, 759, 760, - 378, 379, 380, 381, 382, 383, 2051, 756, 744, 744, - 744, 744, 744, 744, 744, 744, 744, 1070, 1100, 2224, - 1790, 820, 1101, 2222, 758, 1910, 2041, 759, 760, 821, - 472, 473, 474, 475, 476, 477, 756, 769, 769, 769, - 745, 746, 747, 748, 749, 750, 1070, 1100, 753, 753, - - 820, 1101, 745, 746, 747, 748, 749, 750, 821, 1084, - 745, 746, 747, 748, 749, 750, 1925, 2596, 745, 746, - 747, 748, 749, 750, 2031, 378, 379, 380, 381, 382, - 383, 735, 736, 736, 1896, 2211, 736, 736, 1084, 2003, - 736, 736, 736, 736, 736, 736, 736, 736, 736, 1955, - 2596, 736, 736, 736, 736, 736, 761, 761, 761, 761, - 761, 761, 761, 761, 761, 762, 763, 763, 763, 763, - 763, 763, 763, 763, 769, 769, 769, 770, 776, 776, - 776, 1104, 736, 2207, 736, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 765, 765, 765, 765, 765, 765, - - 765, 766, 767, 776, 776, 776, 359, 359, 359, 2018, - 1104, 736, 736, 736, 736, 736, 736, 736, 736, 736, - 736, 738, 739, 740, 741, 742, 743, 768, 768, 768, - 768, 768, 768, 768, 768, 768, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 788, 789, 789, 789, 789, 789, - 789, 789, 789, 1105, 770, 2011, 1106, 385, 777, 790, - 790, 790, 790, 790, 790, 790, 790, 790, 791, 791, - 791, 791, 791, 791, 791, 792, 793, 813, 813, 813, - 2025, 2596, 1105, 777, 536, 1106, 360, 794, 794, 794, - - 794, 794, 794, 794, 794, 794, 369, 369, 1904, 2197, - 369, 369, 2004, 2010, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 2194, 2188, 369, 369, 369, 369, 369, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 795, - 795, 795, 795, 795, 795, 795, 795, 795, 386, 387, - 388, 389, 390, 391, 2175, 1107, 369, 2163, 369, 796, - 797, 797, 797, 797, 797, 797, 797, 797, 798, 798, - 798, 798, 798, 798, 798, 798, 798, 814, 538, 539, - 540, 541, 542, 543, 1107, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 371, 372, 373, 374, 375, - - 376, 799, 799, 799, 799, 799, 799, 799, 800, 801, - 802, 802, 802, 802, 802, 802, 802, 802, 802, 377, - 377, 377, 377, 377, 377, 377, 377, 377, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 803, 465, 465, - 465, 465, 465, 465, 465, 465, 466, 466, 466, 466, - 466, 466, 466, 466, 466, 467, 467, 467, 467, 467, - 467, 467, 804, 469, 470, 470, 470, 470, 470, 470, - 470, 470, 470, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 805, 805, 805, 805, 805, 805, 805, 805, - 805, 806, 807, 807, 807, 807, 807, 807, 807, 807, - - 808, 808, 808, 808, 808, 808, 808, 808, 808, 809, - 809, 809, 809, 809, 809, 809, 810, 811, 812, 812, - 812, 812, 812, 812, 812, 812, 812, 396, 822, 397, - 397, 818, 823, 818, 826, 456, 819, 819, 1108, 1239, - 398, 455, 455, 455, 455, 455, 455, 455, 455, 455, - 2144, 2132, 937, 937, 2124, 824, 937, 822, 937, 937, - 937, 823, 1794, 826, 624, 624, 624, 1108, 1239, 398, - 825, 998, 457, 458, 459, 460, 461, 462, 378, 379, - 380, 381, 382, 383, 824, 827, 378, 379, 380, 381, - 382, 383, 1911, 378, 379, 380, 381, 382, 383, 825, - - 2112, 378, 379, 380, 381, 382, 383, 831, 378, 379, - 380, 381, 382, 383, 827, 2107, 499, 378, 379, 380, - 381, 382, 383, 929, 1240, 2102, 1241, 828, 829, 378, - 379, 380, 381, 382, 383, 830, 831, 836, 1243, 378, - 379, 380, 381, 382, 383, 499, 1244, 832, 837, 833, - 2080, 1707, 929, 1240, 628, 1241, 828, 829, 834, 1677, - 2023, 2021, 2558, 1655, 830, 835, 836, 1243, 378, 379, - 380, 381, 382, 383, 840, 1244, 832, 837, 833, 897, - 378, 379, 380, 381, 382, 383, 1645, 834, 378, 379, - 380, 381, 382, 383, 835, 838, 378, 379, 380, 381, - - 382, 383, 841, 840, 1756, 842, 839, 1246, 897, 847, - 1967, 1963, 378, 379, 380, 381, 382, 383, 843, 844, - 1953, 1929, 1927, 1923, 838, 378, 379, 380, 381, 382, - 383, 841, 1925, 845, 842, 839, 1246, 2030, 847, 378, - 379, 380, 381, 382, 383, 2559, 846, 843, 844, 848, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 845, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 846, 849, 850, 848, 1917, - 1517, 1902, 1894, 1486, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 966, 966, 855, 854, - - 966, 1880, 966, 966, 966, 849, 850, 851, 378, 379, - 380, 381, 382, 383, 919, 919, 919, 919, 919, 919, - 919, 919, 852, 853, 1463, 1848, 1832, 855, 854, 378, - 379, 380, 381, 382, 383, 856, 851, 857, 858, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 852, 853, 378, 379, 380, 381, 382, 383, 859, - 860, 1391, 1803, 1368, 856, 1788, 857, 858, 881, 378, - 379, 380, 381, 382, 383, 861, 1247, 862, 1357, 1782, - 1774, 378, 379, 380, 381, 382, 383, 864, 859, 860, - 378, 379, 380, 381, 382, 383, 1768, 881, 545, 546, - - 547, 548, 549, 550, 861, 1247, 862, 378, 379, 380, - 381, 382, 383, 1955, 863, 1248, 864, 867, 2061, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 863, 1248, 865, 867, 866, 499, 378, - 379, 380, 381, 382, 383, 869, 931, 868, 933, 870, - 1249, 1122, 499, 1122, 1745, 1703, 1123, 1123, 378, 379, - 380, 381, 382, 383, 865, 1186, 866, 499, 378, 379, - 380, 381, 382, 383, 869, 931, 868, 933, 870, 1249, - 1689, 499, 1687, 378, 379, 380, 381, 382, 383, 378, - - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 1026, 1250, 1670, 1664, 499, 378, 379, 380, 381, - 382, 383, 871, 876, 930, 1660, 932, 872, 1089, 1027, - 1028, 1251, 877, 499, 878, 873, 882, 874, 1252, 879, - 1026, 1250, 883, 875, 499, 1253, 1090, 880, 1319, 1313, - 1299, 871, 876, 930, 884, 932, 872, 1089, 1027, 1028, - 1251, 877, 499, 878, 873, 882, 874, 1252, 879, 1287, - 1279, 883, 875, 1620, 1253, 1090, 880, 378, 379, 380, - 381, 382, 383, 884, 885, 1265, 896, 378, 379, 380, - 381, 382, 383, 378, 379, 380, 381, 382, 383, 888, - - 1259, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 885, 889, 896, 1254, 890, 378, 379, - 380, 381, 382, 383, 886, 637, 637, 637, 888, 1008, - 1454, 1454, 378, 379, 380, 381, 382, 383, 891, 1257, - 1449, 1449, 892, 889, 887, 1254, 890, 378, 379, 380, - 381, 382, 383, 886, 913, 1268, 378, 379, 380, 381, - 382, 383, 920, 920, 921, 922, 920, 891, 920, 920, - 920, 892, 1255, 887, 1085, 1085, 378, 379, 380, 381, - 382, 383, 893, 913, 1268, 1086, 1444, 1269, 894, 378, - 379, 380, 381, 382, 383, 895, 1444, 1596, 1592, 378, - - 379, 380, 381, 382, 383, 472, 473, 474, 475, 476, - 477, 893, 1590, 1270, 1086, 641, 1269, 894, 658, 659, - 660, 661, 662, 663, 895, 898, 898, 898, 898, 898, - 898, 898, 898, 898, 1587, 1585, 378, 379, 380, 381, - 382, 383, 1270, 378, 379, 380, 381, 382, 383, 899, - 900, 900, 900, 900, 900, 900, 900, 900, 901, 901, - 901, 901, 901, 901, 901, 901, 901, 902, 902, 902, - 902, 902, 902, 902, 903, 904, 905, 905, 905, 905, - 905, 905, 905, 905, 905, 377, 377, 377, 377, 377, - 377, 377, 377, 377, 359, 906, 906, 906, 906, 906, - - 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, - 906, 906, 377, 377, 377, 377, 377, 377, 377, 377, - 377, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 908, 909, 907, 910, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 911, 911, - 911, 911, 911, 911, 911, 911, 911, 471, 471, 471, - 471, 471, 471, 471, 471, 471, 488, 488, 488, 488, - 488, 488, 488, 488, 488, 489, 490, 490, 490, 490, - 490, 490, 490, 490, 491, 491, 491, 491, 491, 491, + 532, 532, 532, 532, 532, 532, 533, 533, 533, 533, + 533, 533, 533, 534, 535, 536, 536, 536, 536, 536, + 536, 536, 536, 536, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 573, 574, 574, 574, 574, 574, 574, 574, + + 574, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 576, 576, 576, 576, 576, 576, 576, 577, 578, 579, + 579, 579, 579, 579, 579, 579, 579, 579, 587, 626, + 626, 626, 588, 756, 627, 2384, 628, 2105, 2786, 670, + 671, 589, 629, 1096, 1110, 590, 633, 633, 633, 1844, + 1137, 634, 1137, 635, 1977, 1138, 1111, 587, 1114, 636, + 672, 588, 639, 639, 639, 2382, 640, 641, 670, 671, + 589, 2523, 1096, 1110, 590, 642, 659, 659, 659, 659, + 659, 659, 659, 659, 659, 1111, 1963, 1114, 1115, 672, + 2522, 2082, 2517, 660, 661, 662, 663, 664, 665, 700, + + 701, 702, 703, 704, 705, 660, 661, 662, 663, 664, + 665, 660, 661, 662, 663, 664, 665, 1115, 630, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 689, 689, + 689, 2514, 2502, 2332, 2325, 637, 674, 675, 675, 675, + 675, 675, 675, 675, 675, 719, 720, 721, 722, 723, + 724, 643, 651, 651, 1971, 2322, 651, 651, 2320, 2089, + 651, 651, 651, 651, 651, 651, 651, 651, 651, 707, + 651, 651, 651, 651, 651, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 677, 677, 677, 677, 677, 677, + 677, 678, 679, 735, 735, 735, 2477, 1116, 707, 1117, + + 1118, 651, 2315, 651, 680, 680, 680, 680, 680, 680, + 680, 680, 680, 1100, 2313, 1100, 2472, 690, 1321, 708, + 700, 701, 702, 703, 704, 705, 1116, 2468, 1117, 1118, + 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, + 653, 654, 655, 656, 657, 658, 691, 691, 708, 709, + 691, 691, 1256, 1097, 691, 691, 691, 691, 691, 691, + 691, 691, 691, 1098, 691, 691, 691, 691, 691, 699, + 699, 699, 699, 699, 699, 699, 699, 699, 709, 2298, + 2461, 1256, 736, 2459, 700, 701, 702, 703, 704, 705, + 2447, 1322, 1098, 1322, 1994, 691, 1323, 691, 2444, 2111, + + 700, 701, 702, 703, 704, 705, 710, 710, 710, 710, + 710, 710, 710, 710, 710, 711, 712, 712, 712, 712, + 712, 712, 712, 712, 691, 691, 691, 691, 691, 691, + 691, 691, 691, 691, 693, 694, 695, 696, 697, 698, + 713, 713, 713, 713, 713, 713, 713, 713, 713, 714, + 714, 714, 714, 714, 714, 714, 715, 716, 717, 717, + 717, 717, 717, 717, 717, 717, 717, 725, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 726, 726, 726, + 726, 726, 726, 726, 726, 726, 727, 728, 728, 728, + 728, 728, 728, 728, 728, 2270, 725, 729, 729, 729, + + 729, 729, 729, 729, 729, 729, 730, 730, 730, 730, + 730, 730, 730, 731, 732, 719, 720, 721, 722, 723, + 724, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 735, 735, 735, 746, 747, 748, 749, 750, 751, 757, + 760, 758, 761, 2440, 2431, 2255, 2415, 2411, 770, 770, + 770, 759, 745, 745, 745, 745, 745, 745, 745, 745, + 745, 377, 378, 379, 380, 381, 382, 2409, 2407, 760, + 2404, 761, 770, 770, 770, 777, 777, 777, 2398, 2397, + 759, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 2395, 2212, 2390, 1257, 746, 747, 748, 749, 750, 751, + + 2205, 2386, 2193, 746, 747, 748, 749, 750, 751, 2188, + 2371, 2368, 746, 747, 748, 749, 750, 751, 2028, 736, + 737, 737, 1257, 2146, 737, 737, 2166, 2363, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 771, 737, 737, + 737, 737, 737, 763, 764, 764, 764, 764, 764, 764, + 764, 764, 765, 765, 765, 765, 765, 765, 765, 765, + 765, 771, 360, 2352, 778, 777, 777, 777, 1258, 737, + 2147, 737, 766, 766, 766, 766, 766, 766, 766, 767, + 768, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 358, 358, 358, 384, 2350, 2134, 2319, 1258, 737, 737, + + 737, 737, 737, 737, 737, 737, 737, 737, 739, 740, + 741, 742, 743, 744, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 789, 790, 790, 790, 790, 790, 790, 790, + 790, 815, 815, 815, 2317, 362, 363, 364, 365, 366, + 367, 2122, 2112, 2306, 778, 791, 791, 791, 791, 791, + 791, 791, 791, 791, 792, 792, 792, 792, 792, 792, + 792, 793, 794, 385, 386, 387, 388, 389, 390, 359, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 368, + 368, 2105, 2301, 368, 368, 2097, 2204, 368, 368, 368, + + 368, 368, 368, 368, 368, 368, 2090, 368, 368, 368, + 368, 368, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 796, 796, 796, 796, 796, 796, 796, 796, 796, + 816, 377, 378, 379, 380, 381, 382, 1260, 368, 2290, + 368, 797, 798, 798, 798, 798, 798, 798, 798, 798, + 799, 799, 799, 799, 799, 799, 799, 799, 799, 377, + 378, 379, 380, 381, 382, 2083, 1260, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 370, 371, 372, + 373, 374, 375, 800, 800, 800, 800, 800, 800, 800, + 801, 802, 803, 803, 803, 803, 803, 803, 803, 803, + + 803, 376, 376, 376, 376, 376, 376, 376, 376, 376, + 464, 464, 464, 464, 464, 464, 464, 464, 464, 804, + 466, 466, 466, 466, 466, 466, 466, 466, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 468, 468, 468, + 468, 468, 468, 468, 805, 470, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 806, 806, 806, 806, 806, 806, + 806, 806, 806, 807, 808, 808, 808, 808, 808, 808, + 808, 808, 809, 809, 809, 809, 809, 809, 809, 809, + 809, 810, 810, 810, 810, 810, 810, 810, 811, 812, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 397, + 825, 822, 823, 757, 823, 1094, 2287, 824, 826, 2282, + 939, 399, 2279, 1261, 828, 1095, 500, 1262, 1264, 827, + 456, 456, 456, 456, 456, 456, 456, 456, 456, 825, + 473, 474, 475, 476, 477, 478, 2273, 826, 829, 939, + 399, 845, 1261, 828, 1095, 500, 1262, 1264, 827, 2259, + 2258, 649, 649, 649, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 830, 829, 851, 890, + 845, 2237, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + + 831, 1265, 1266, 836, 832, 830, 2223, 851, 890, 2215, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1850, 831, + 1265, 1266, 836, 832, 1978, 377, 378, 379, 380, 381, + 382, 833, 834, 377, 378, 379, 380, 381, 382, 835, + 650, 1267, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 833, 834, 837, 841, 838, 2201, 944, 2196, 835, 1268, + 1267, 2191, 842, 839, 500, 928, 928, 929, 930, 928, + 840, 928, 928, 928, 377, 378, 379, 380, 381, 382, + + 2184, 837, 841, 838, 397, 944, 1133, 843, 1268, 2181, + 820, 842, 839, 500, 846, 1269, 818, 847, 844, 840, + 821, 1270, 1271, 848, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 843, 377, 378, 379, + 380, 381, 382, 846, 1269, 818, 847, 844, 2169, 821, + 1270, 1271, 848, 2161, 2150, 1272, 852, 853, 457, 1755, + 1273, 854, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 849, 626, 626, 626, 1272, 852, 853, 1722, 1009, 1273, + 854, 2103, 2100, 537, 850, 458, 459, 460, 461, 462, + + 463, 855, 1287, 1288, 1294, 859, 1299, 1311, 1694, 849, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 856, 850, 377, 378, 379, 380, 381, 382, + 855, 1287, 1288, 1294, 859, 1299, 1311, 857, 858, 1333, + 865, 1684, 861, 860, 862, 377, 378, 379, 380, 381, + 382, 856, 2075, 377, 378, 379, 380, 381, 382, 377, + 378, 379, 380, 381, 382, 2072, 857, 858, 1333, 865, + 630, 861, 860, 862, 863, 864, 539, 540, 541, 542, + 543, 544, 866, 869, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 920, 377, 378, 379, + + 380, 381, 382, 863, 864, 377, 378, 379, 380, 381, + 382, 866, 869, 1807, 2044, 867, 2039, 377, 378, 379, + 380, 381, 382, 377, 378, 379, 380, 381, 382, 868, + 546, 547, 548, 549, 550, 551, 1334, 871, 377, 378, + 379, 380, 381, 382, 867, 377, 378, 379, 380, 381, + 382, 2031, 870, 872, 2026, 946, 946, 1998, 868, 946, + 1996, 946, 946, 946, 1992, 1334, 871, 473, 474, 475, + 476, 477, 478, 1560, 1985, 377, 378, 379, 380, 381, + 382, 870, 872, 377, 378, 379, 380, 381, 382, 377, + 378, 379, 380, 381, 382, 873, 888, 500, 1097, 887, + + 377, 378, 379, 380, 381, 382, 874, 942, 1098, 376, + 875, 376, 1339, 1340, 377, 378, 379, 380, 381, 382, + 882, 1035, 1035, 1035, 873, 888, 500, 376, 887, 883, + 889, 884, 1555, 1544, 1969, 874, 942, 1098, 376, 875, + 376, 1339, 1340, 377, 378, 379, 380, 381, 382, 882, + 377, 378, 379, 380, 381, 382, 376, 1961, 883, 889, + 884, 377, 378, 379, 380, 381, 382, 377, 378, 379, + 380, 381, 382, 876, 376, 376, 376, 891, 877, 639, + 639, 639, 894, 1019, 376, 885, 878, 1513, 879, 892, + 1953, 880, 376, 886, 881, 377, 378, 379, 380, 381, + + 382, 1950, 876, 376, 376, 376, 891, 877, 1944, 893, + 1036, 894, 1487, 376, 885, 878, 895, 879, 892, 896, + 880, 376, 886, 881, 1341, 377, 378, 379, 380, 381, + 382, 897, 1324, 1342, 1324, 898, 901, 1325, 893, 377, + 378, 379, 380, 381, 382, 895, 1912, 902, 896, 757, + 1897, 1320, 1893, 1341, 377, 378, 379, 380, 381, 382, + 897, 1095, 1342, 1412, 898, 901, 1861, 1854, 643, 899, + 903, 1343, 1451, 1452, 1453, 900, 902, 1454, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 1095, 1849, 377, 378, 379, 380, 381, 382, 899, 903, + + 1343, 1451, 1452, 1453, 900, 1388, 1454, 1842, 377, 378, + 379, 380, 381, 382, 1377, 1836, 377, 378, 379, 380, + 381, 382, 1828, 377, 378, 379, 380, 381, 382, 904, + 904, 904, 904, 904, 904, 904, 904, 904, 905, 906, + 906, 906, 906, 906, 906, 906, 906, 907, 907, 907, + 907, 907, 907, 907, 907, 907, 908, 908, 908, 908, + 908, 908, 908, 909, 910, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 376, 376, 376, 376, 376, 376, + 376, 376, 376, 358, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + + 912, 376, 376, 376, 376, 376, 376, 376, 376, 376, + 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, + 913, 914, 915, 913, 916, 913, 913, 913, 913, 913, + 913, 913, 913, 913, 913, 913, 913, 917, 917, 917, + 917, 917, 917, 917, 917, 917, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 489, 489, 489, 489, 489, + 489, 489, 489, 489, 490, 491, 491, 491, 491, 491, 491, 491, 491, 492, 492, 492, 492, 492, 492, 492, + 492, 492, 493, 493, 493, 493, 493, 493, 493, 918, + 495, 496, 496, 496, 496, 496, 496, 496, 496, 496, + + 921, 922, 660, 661, 662, 663, 664, 665, 923, 925, + 924, 1822, 1818, 1814, 1455, 1796, 926, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 1787, 975, 975, 921, + 922, 975, 1780, 975, 975, 975, 1761, 923, 925, 924, + 1045, 1045, 1046, 1455, 1045, 926, 1045, 1045, 1045, 1751, + 1200, 473, 474, 475, 476, 477, 478, 473, 474, 475, + 476, 477, 478, 473, 474, 475, 476, 477, 478, 473, + 474, 475, 476, 477, 478, 473, 474, 475, 476, 477, + 478, 473, 474, 475, 476, 477, 478, 927, 927, 927, + 927, 927, 927, 927, 927, 927, 927, 927, 927, 927, + + 927, 927, 927, 927, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 928, 928, 928, 928, 928, 928, 928, + 928, 928, 928, 928, 928, 928, 928, 928, 928, 928, + 928, 931, 931, 931, 931, 931, 931, 931, 931, 931, + 499, 499, 499, 1734, 1732, 1709, 2786, 2786, 2786, 1456, + 1703, 501, 1699, 501, 502, 1670, 1336, 2786, 1330, 2786, + 502, 2786, 2786, 2786, 1317, 503, 504, 1665, 505, 1304, + 1296, 397, 2786, 1346, 2786, 502, 525, 506, 1456, 507, + 526, 508, 1457, 818, 500, 2786, 2786, 2786, 1458, 527, + 1459, 1460, 1461, 528, 503, 504, 2786, 505, 2786, 502, + + 1656, 1284, 1278, 1480, 1480, 525, 506, 1276, 507, 526, + 508, 1457, 818, 500, 1462, 519, 1464, 1458, 527, 1459, + 1460, 1461, 528, 1475, 1475, 1274, 1470, 509, 510, 511, + 512, 513, 514, 509, 510, 515, 512, 513, 514, 633, + 633, 633, 1470, 1462, 519, 1464, 1014, 1634, 509, 510, + 515, 512, 513, 514, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 529, 529, 529, 529, 529, 529, 529, + 529, 529, 509, 510, 515, 512, 513, 514, 530, 531, + 531, 531, 531, 531, 531, 531, 531, 532, 532, 532, + 532, 532, 532, 532, 532, 532, 533, 533, 533, 533, + + 533, 533, 533, 534, 535, 536, 536, 536, 536, 536, + 536, 536, 536, 536, 932, 531, 531, 531, 531, 531, + 531, 531, 531, 940, 565, 1629, 1627, 1623, 637, 1621, + 500, 974, 974, 974, 974, 974, 974, 974, 974, 941, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 1602, + 1575, 1130, 940, 700, 701, 702, 703, 704, 705, 500, + 1510, 566, 567, 568, 569, 570, 571, 1112, 941, 499, + 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, + 945, 945, 945, 945, 945, 945, 945, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 946, 946, 946, 946, + + 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 947, 947, 947, 947, 947, 947, + 947, 947, 947, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 948, 948, 948, 948, 948, 948, 948, 948, + 948, 949, 950, 950, 950, 950, 950, 950, 950, 950, + 951, 951, 951, 951, 951, 951, 951, 951, 951, 952, + 952, 952, 952, 952, 952, 952, 953, 954, 955, 955, + 955, 955, 955, 955, 955, 955, 955, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 573, 574, 574, 574, 574, - 912, 494, 495, 495, 495, 495, 495, 495, 495, 495, - 495, 481, 481, 914, 917, 471, 471, 471, 471, 471, - 471, 471, 471, 471, 1277, 1282, 1294, 1307, 915, 1308, - 916, 1316, 564, 699, 700, 701, 702, 703, 704, 918, - 1544, 1119, 914, 917, 919, 919, 919, 919, 919, 919, - 919, 919, 919, 1277, 1282, 1294, 1307, 915, 1308, 916, - 1316, 1102, 472, 473, 474, 475, 476, 477, 918, 565, - 566, 567, 568, 569, 570, 472, 473, 474, 475, 476, - 477, 1485, 1098, 472, 473, 474, 475, 476, 477, 472, - 473, 474, 475, 476, 477, 472, 473, 474, 475, 476, - - 477, 1483, 1082, 1477, 472, 473, 474, 475, 476, 477, - 471, 471, 471, 471, 471, 471, 471, 471, 471, 920, - 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, - 920, 920, 920, 920, 920, 920, 920, 923, 923, 923, - 923, 923, 923, 923, 923, 923, 498, 498, 498, 1056, - 816, 816, 2596, 2596, 2596, 1473, 1317, 500, 1040, 500, - 501, 817, 1471, 2596, 1460, 2596, 501, 2596, 2596, 2596, - 1322, 2025, 502, 503, 1024, 504, 2114, 1457, 2596, 1323, - 2596, 501, 1324, 524, 505, 1317, 506, 525, 507, 1325, - 817, 499, 2596, 2596, 2596, 1326, 526, 1456, 955, 1322, - - 527, 502, 503, 2596, 504, 2596, 501, 1451, 1323, 1446, - 1438, 1324, 524, 505, 813, 506, 525, 507, 1325, 1327, - 499, 1321, 1315, 518, 1326, 526, 1124, 955, 1124, 527, - 1301, 1125, 1125, 734, 508, 509, 510, 511, 512, 513, - 508, 509, 514, 511, 512, 513, 545, 546, 547, 548, - 549, 550, 518, 1289, 688, 508, 509, 514, 511, 512, - 513, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 528, 528, 528, 528, 528, 528, 528, 528, 528, 1281, - 508, 509, 514, 511, 512, 513, 529, 530, 530, 530, - 530, 530, 530, 530, 530, 531, 531, 531, 531, 531, - - 531, 531, 531, 531, 532, 532, 532, 532, 532, 532, - 532, 533, 534, 535, 535, 535, 535, 535, 535, 535, - 535, 535, 924, 530, 530, 530, 530, 530, 530, 530, - 530, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 498, 936, 936, 936, 936, 936, 936, 936, 936, 936, - 936, 936, 936, 936, 936, 936, 936, 936, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 937, 937, 937, - 937, 937, 937, 937, 937, 937, 937, 937, 937, 937, - 937, 937, 937, 937, 937, 938, 938, 938, 938, 938, - 938, 938, 938, 938, 537, 537, 537, 537, 537, 537, - - 537, 537, 537, 939, 939, 939, 939, 939, 939, 939, - 939, 939, 940, 941, 941, 941, 941, 941, 941, 941, - 941, 942, 942, 942, 942, 942, 942, 942, 942, 942, - 943, 943, 943, 943, 943, 943, 943, 944, 945, 946, - 946, 946, 946, 946, 946, 946, 946, 946, 544, 544, - 544, 544, 544, 544, 544, 544, 544, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 572, 573, 573, 573, - 573, 573, 573, 573, 573, 574, 574, 574, 574, 574, 574, 574, 574, 574, 575, 575, 575, 575, 575, 575, - 575, 576, 577, 578, 578, 578, 578, 578, 578, 578, - - 578, 578, 552, 551, 551, 551, 551, 551, 551, 551, - 551, 551, 947, 947, 947, 947, 947, 947, 947, 947, - 947, 948, 949, 949, 949, 949, 949, 949, 949, 949, - 950, 950, 950, 950, 950, 950, 950, 950, 950, 951, - 951, 951, 951, 951, 951, 951, 952, 953, 954, 954, - 954, 954, 954, 954, 954, 954, 954, 1267, 647, 637, - 956, 563, 563, 563, 563, 563, 563, 563, 563, 563, - 957, 957, 957, 957, 957, 957, 957, 957, 957, 1010, - 1010, 631, 1005, 553, 554, 555, 556, 557, 558, 956, - 958, 959, 959, 959, 959, 959, 959, 959, 959, 960, - - 960, 960, 960, 960, 960, 960, 960, 960, 961, 961, - 961, 961, 961, 961, 961, 962, 963, 647, 647, 647, - 1005, 624, 1000, 1000, 545, 546, 547, 548, 549, 550, - 964, 964, 964, 964, 964, 964, 964, 964, 964, 544, - 544, 544, 544, 544, 544, 544, 544, 544, 965, 965, - 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, - 965, 965, 965, 965, 965, 544, 544, 544, 544, 544, - 544, 544, 544, 544, 966, 966, 966, 966, 966, 966, - 966, 966, 966, 966, 966, 966, 966, 966, 966, 966, - 966, 966, 967, 967, 967, 967, 967, 967, 967, 967, - - 967, 631, 631, 631, 1024, 1024, 1024, 648, 1003, 650, - 650, 650, 650, 650, 650, 650, 650, 650, 1014, 1014, - 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1015, 1016, 1016, - 1016, 1016, 1016, 1016, 1016, 1016, 1017, 1017, 1017, 1017, - 1017, 1017, 1017, 1017, 1017, 1018, 1018, 1018, 1018, 1018, - 1018, 1018, 1019, 1020, 1021, 1021, 1021, 1021, 1021, 1021, - 1021, 1021, 1021, 657, 657, 657, 657, 657, 657, 657, - 657, 657, 672, 672, 672, 672, 672, 672, 672, 672, - 672, 1022, 674, 674, 674, 674, 674, 674, 674, 674, - 1245, 635, 649, 649, 1025, 1242, 649, 649, 1121, 359, - - 649, 649, 649, 649, 649, 649, 649, 649, 649, 1029, - 1427, 649, 649, 649, 649, 649, 675, 675, 675, 675, - 675, 675, 675, 675, 675, 676, 676, 676, 676, 676, - 676, 676, 1023, 678, 776, 681, 681, 681, 1029, 1427, - 1031, 1428, 649, 782, 649, 679, 679, 679, 679, 679, - 679, 679, 679, 679, 769, 658, 659, 660, 661, 662, - 663, 1030, 718, 719, 720, 721, 722, 723, 1032, 1031, - 1428, 649, 649, 649, 649, 649, 649, 649, 649, 649, - 649, 651, 652, 653, 654, 655, 656, 1033, 775, 1071, - 1030, 658, 659, 660, 661, 662, 663, 1032, 1034, 745, - - 746, 747, 748, 749, 750, 1045, 658, 659, 660, 661, - 662, 663, 1302, 681, 1302, 686, 1033, 1303, 1303, 658, - 659, 660, 661, 662, 663, 682, 1013, 1034, 1012, 1040, - 1040, 1040, 1011, 1010, 658, 659, 660, 661, 662, 663, - 1007, 658, 659, 660, 661, 662, 663, 657, 657, 657, - 657, 657, 657, 657, 657, 657, 647, 1035, 1035, 1035, - 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, - 1035, 1035, 1035, 1035, 657, 657, 657, 657, 657, 657, - 657, 657, 657, 1036, 1036, 1036, 1036, 1036, 1036, 1036, - 1036, 1036, 1036, 1036, 1037, 1006, 1036, 1005, 1036, 1036, - - 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1041, - 688, 688, 688, 691, 691, 691, 691, 691, 691, 691, - 691, 691, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - 1046, 1047, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, - 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1050, - 1050, 1050, 1050, 1050, 1050, 1050, 1051, 1052, 1053, 1053, - 1053, 1053, 1053, 1053, 1053, 1053, 1053, 698, 698, 698, - 698, 698, 698, 698, 698, 698, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 1054, 711, 711, 711, 711, - - 711, 711, 711, 711, 378, 379, 380, 381, 382, 383, - 689, 690, 690, 1002, 1001, 690, 690, 1000, 997, 690, - 690, 690, 690, 690, 690, 690, 690, 690, 1058, 1429, - 690, 690, 690, 690, 690, 712, 712, 712, 712, 712, - 712, 712, 712, 712, 713, 713, 713, 713, 713, 713, - 713, 1055, 715, 1056, 1056, 1056, 996, 1058, 1429, 1059, - 1430, 690, 995, 690, 716, 716, 716, 716, 716, 716, - 716, 716, 716, 699, 700, 701, 702, 703, 704, 1304, - 994, 1304, 993, 1060, 1305, 1305, 989, 597, 1059, 1430, - 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, - - 692, 693, 694, 695, 696, 697, 699, 700, 701, 702, - 703, 704, 1060, 698, 698, 698, 698, 698, 698, 698, - 698, 698, 980, 979, 978, 977, 699, 700, 701, 702, - 703, 704, 688, 1061, 1061, 1061, 1061, 1061, 1061, 1061, - 1061, 976, 786, 1057, 1061, 1061, 1061, 1061, 1061, 1061, - 1061, 1061, 1061, 698, 698, 698, 698, 698, 698, 698, - 698, 698, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, - 1062, 1062, 1062, 1063, 1064, 1062, 782, 1062, 1062, 1062, - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1065, - 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 717, 717, - - 717, 717, 717, 717, 717, 717, 717, 725, 725, 725, - 725, 725, 725, 725, 725, 725, 726, 727, 727, 727, - 727, 727, 727, 727, 727, 728, 728, 728, 728, 728, + 575, 575, 575, 576, 576, 576, 576, 576, 576, 576, + 577, 578, 579, 579, 579, 579, 579, 579, 579, 579, + 579, 553, 552, 552, 552, 552, 552, 552, 552, 552, + 552, 956, 956, 956, 956, 956, 956, 956, 956, 956, + 957, 958, 958, 958, 958, 958, 958, 958, 958, 959, + 959, 959, 959, 959, 959, 959, 959, 959, 960, 960, + 960, 960, 960, 960, 960, 961, 962, 963, 963, 963, + 963, 963, 963, 963, 963, 963, 1509, 1108, 964, 965, + 564, 564, 564, 564, 564, 564, 564, 564, 564, 966, + + 966, 966, 966, 966, 966, 966, 966, 966, 1507, 1325, + 1325, 554, 555, 556, 557, 558, 559, 964, 965, 967, + 968, 968, 968, 968, 968, 968, 968, 968, 719, 720, + 721, 722, 723, 724, 1323, 1323, 546, 547, 548, 549, + 550, 551, 969, 969, 969, 969, 969, 969, 969, 969, + 969, 1321, 1092, 546, 547, 548, 549, 550, 551, 970, + 970, 970, 970, 970, 970, 970, 971, 972, 973, 973, + 973, 973, 973, 973, 973, 973, 973, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 545, 545, 545, 545, 545, + + 545, 545, 545, 545, 975, 975, 975, 975, 975, 975, + 975, 975, 975, 975, 975, 975, 975, 975, 975, 975, + 975, 975, 976, 976, 976, 976, 976, 976, 976, 976, + 976, 651, 651, 1502, 1501, 651, 651, 1065, 1497, 651, + 651, 651, 651, 651, 651, 651, 651, 651, 1049, 651, + 651, 651, 651, 651, 652, 652, 652, 652, 652, 652, + 652, 652, 652, 1025, 1025, 1025, 1025, 1025, 1025, 1025, + 1025, 1025, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, + 651, 1495, 651, 1026, 1027, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, + + 1028, 746, 747, 748, 749, 750, 751, 1485, 1035, 651, + 651, 651, 651, 651, 651, 651, 651, 651, 651, 653, + 654, 655, 656, 657, 658, 1029, 1029, 1029, 1029, 1029, + 1029, 1029, 1030, 1031, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 659, 659, 659, 659, 659, 659, 659, + 659, 659, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 1033, 675, 675, 675, 675, 675, 675, 675, 675, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 677, + 677, 677, 677, 677, 677, 677, 1034, 679, 680, 680, + 680, 680, 680, 680, 680, 680, 680, 1039, 1040, 1465, + + 1466, 1483, 1482, 1477, 1041, 659, 659, 659, 659, 659, + 659, 659, 659, 659, 1071, 1071, 1072, 1073, 1071, 1042, + 1071, 1071, 1071, 1472, 1463, 1431, 1039, 1040, 1465, 1466, + 1077, 1077, 1043, 1041, 1077, 1138, 1077, 1077, 1077, 1138, + 1136, 1136, 660, 661, 662, 663, 664, 665, 1042, 660, + 661, 662, 663, 664, 665, 660, 661, 662, 663, 664, + 665, 1043, 682, 682, 682, 1134, 660, 661, 662, 663, + 664, 665, 1049, 1049, 1049, 660, 661, 662, 663, 664, + 665, 649, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, + 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 659, + + 659, 659, 659, 659, 659, 659, 659, 659, 1045, 1045, + 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, + 1045, 1045, 1045, 1045, 1045, 1045, 1047, 1047, 1047, 1047, + 1047, 1047, 1047, 1047, 1047, 689, 689, 689, 692, 692, + 692, 692, 692, 692, 692, 692, 692, 815, 1345, 1344, + 1338, 683, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, + 1055, 1050, 1056, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + 1057, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, + 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1060, 1061, 1062, + 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 699, 699, + + 699, 699, 699, 699, 699, 699, 699, 710, 710, 710, + 710, 710, 710, 710, 710, 710, 1119, 1119, 1119, 1119, + 1119, 1119, 1119, 1119, 690, 691, 691, 1332, 1321, 691, + 691, 1319, 1315, 691, 691, 691, 691, 691, 691, 691, + 691, 691, 1467, 691, 691, 691, 691, 691, 1063, 712, + 712, 712, 712, 712, 712, 712, 712, 713, 713, 713, + 713, 713, 713, 713, 713, 713, 1065, 1065, 1065, 1484, + 735, 1467, 1494, 1496, 691, 1306, 691, 714, 714, 714, + 714, 714, 714, 714, 1064, 716, 717, 717, 717, 717, + 717, 717, 717, 717, 717, 1067, 1508, 1569, 1484, 1068, + + 689, 1494, 1496, 691, 691, 691, 691, 691, 691, 691, + 691, 691, 691, 693, 694, 695, 696, 697, 698, 1298, + 1286, 649, 639, 1069, 1067, 1508, 1569, 1021, 1068, 699, + 699, 699, 699, 699, 699, 699, 699, 699, 1021, 633, + 700, 701, 702, 703, 704, 705, 700, 701, 702, 703, + 704, 705, 1069, 1016, 1016, 1066, 689, 1070, 1070, 1070, + 1070, 1070, 1070, 1070, 1070, 626, 700, 701, 702, 703, + 704, 705, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, + 1070, 699, 699, 699, 699, 699, 699, 699, 699, 699, + 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, + + 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1074, 1074, + 1074, 1074, 1074, 1074, 1074, 1074, 1074, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 726, 726, 726, 726, + 726, 726, 726, 726, 726, 727, 728, 728, 728, 728, 728, 728, 728, 728, 729, 729, 729, 729, 729, 729, - 729, 730, 731, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 1066, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, - 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 779, - 775, 1066, 717, 717, 717, 717, 717, 717, 717, 717, - 717, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, - - 734, 734, 734, 718, 719, 720, 721, 722, 723, 1068, - 1068, 772, 757, 1068, 705, 1068, 1068, 1068, 1068, 1068, - 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1069, 1069, 1069, - 1069, 1069, 1069, 1069, 1069, 1069, 737, 737, 737, 737, - 737, 737, 737, 737, 737, 1072, 1072, 1072, 1072, 1072, - 1072, 1072, 1072, 1072, 1073, 1074, 1074, 1074, 1074, 1074, - 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1075, 1075, 1075, - 1075, 1075, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1077, - 1078, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 735, 736, 736, 687, 686, 736, 736, 1085, 1085, 736, - - 736, 736, 736, 736, 736, 736, 736, 736, 1086, 1431, - 736, 736, 736, 736, 736, 744, 744, 744, 744, 744, - 744, 744, 744, 744, 761, 761, 761, 761, 761, 761, - 761, 761, 761, 1082, 1082, 1082, 1432, 1086, 1431, 684, - 1433, 736, 665, 736, 1080, 763, 763, 763, 763, 763, - 763, 763, 763, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 1087, 664, 1087, 1432, 646, 1088, 1088, 1433, - 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, - 738, 739, 740, 741, 742, 743, 765, 765, 765, 765, - 765, 765, 765, 1081, 767, 768, 768, 768, 768, 768, - - 768, 768, 768, 768, 754, 1091, 755, 755, 1092, 1109, - 1109, 1109, 1109, 1109, 1109, 1109, 1109, 756, 1093, 1434, - 1435, 1436, 644, 1083, 744, 744, 744, 744, 744, 744, - 744, 744, 744, 622, 1091, 621, 618, 1092, 617, 745, - 746, 747, 748, 749, 750, 614, 756, 1093, 1434, 1435, - 1436, 745, 746, 747, 748, 749, 750, 613, 612, 745, - 746, 747, 748, 749, 750, 745, 746, 747, 748, 749, - 750, 769, 769, 769, 1098, 1098, 1098, 611, 745, 746, - 747, 748, 749, 750, 734, 1094, 1094, 1094, 1094, 1094, - 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, - - 1094, 1094, 744, 744, 744, 744, 744, 744, 744, 744, - 744, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, - 1095, 1095, 599, 598, 1095, 1096, 1095, 1095, 1095, 1095, - 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1097, 1097, - 1097, 1097, 1097, 1097, 1097, 1097, 1097, 776, 776, 776, - 1102, 1102, 1102, 1112, 1112, 1112, 1112, 1112, 1112, 1112, - 1112, 770, 595, 594, 1099, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 1109, 1109, 1109, 1109, 1109, 1109, - 1109, 1109, 1109, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, - - 1110, 1110, 1110, 591, 590, 1110, 395, 1110, 1110, 1110, - 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1111, - 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 777, 2596, 243, - 1103, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, - 243, 241, 1113, 241, 1113, 1113, 1113, 1113, 1113, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1114, 1114, 1114, 1114, - 1114, 1114, 1114, 1114, 1114, 906, 906, 906, 906, 906, - - 906, 906, 906, 907, 907, 2596, 2596, 907, 2596, 907, - 907, 907, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 1116, 1116, 1116, - 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 819, 819, - 1116, 1127, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, - 1116, 1116, 1116, 1116, 1117, 1117, 1117, 1117, 1117, 1117, - 1117, 1117, 1117, 1119, 813, 813, 1128, 2596, 2596, 2596, - 1127, 378, 379, 380, 381, 382, 383, 2596, 2596, 1129, - - 1130, 378, 379, 380, 381, 382, 383, 1131, 1437, 1132, - 1255, 1255, 1255, 2596, 2596, 1128, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1129, 1130, - 378, 379, 380, 381, 382, 383, 1131, 1437, 1132, 2596, - 378, 379, 380, 381, 382, 383, 2596, 378, 379, 380, - 381, 382, 383, 1133, 1257, 1257, 1257, 378, 379, 380, - 381, 382, 383, 1134, 378, 379, 380, 381, 382, 383, - 1439, 2596, 1440, 1120, 378, 379, 380, 381, 382, 383, - 2596, 2596, 1133, 2596, 1137, 2596, 1138, 2596, 2596, 1259, - 1259, 1259, 1134, 1135, 2596, 2596, 2596, 1441, 1136, 1439, - - 1256, 1440, 1458, 1139, 1459, 1470, 2596, 378, 379, 380, - 381, 382, 383, 1137, 1140, 1138, 378, 379, 380, 381, - 382, 383, 1135, 1265, 1024, 1024, 1441, 1136, 2596, 2596, - 2596, 1458, 1139, 1459, 1470, 1143, 378, 379, 380, 381, - 382, 383, 2596, 1140, 1258, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 1141, 1143, 1144, 1472, 1142, 378, 379, - 380, 381, 382, 383, 1209, 1209, 1478, 1146, 1209, 1260, - 1209, 1209, 1209, 1145, 1208, 1208, 1208, 1208, 1208, 1208, - 1208, 1208, 1141, 1147, 1144, 1472, 1142, 1479, 378, 379, - - 380, 381, 382, 383, 2596, 1478, 1146, 2596, 2596, 1279, - 1040, 1040, 1145, 1266, 2596, 378, 379, 380, 381, 382, - 383, 2596, 1147, 2596, 1148, 1149, 1479, 2596, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 2596, 378, 379, 380, - 381, 382, 383, 1148, 1149, 1150, 1152, 1484, 1538, 1539, - 920, 920, 1151, 1153, 920, 1540, 920, 920, 920, 1155, - 2596, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 2596, 1150, 1152, 1484, 1538, 1539, 2596, - 2596, 1151, 1153, 2596, 1540, 2596, 2596, 1154, 1155, 1280, - - 2596, 378, 379, 380, 381, 382, 383, 1156, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 1154, 378, 379, 380, - 381, 382, 383, 1164, 2596, 1157, 1156, 1159, 1541, 1184, - 1542, 1158, 2596, 2596, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2596, 1160, 1162, 2596, 2596, 378, 379, - 380, 381, 382, 383, 1157, 1163, 1159, 1541, 2596, 1542, - 1158, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 1160, 1162, 1161, 1165, 2596, 378, 379, - 380, 381, 382, 383, 1163, 2596, 378, 379, 380, 381, - - 382, 383, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 1161, 1165, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1166, 1167, - 1543, 378, 379, 380, 381, 382, 383, 1172, 1168, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 1166, 1167, 1543, - 2596, 2596, 1169, 1170, 1171, 2596, 1172, 1168, 2596, 2596, - 1287, 1056, 1056, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 1169, 1170, 1171, 1173, 2596, 378, 379, 380, 381, - - 382, 383, 1174, 378, 379, 380, 381, 382, 383, 2596, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, - 2596, 1175, 1176, 1173, 378, 379, 380, 381, 382, 383, - 1177, 1174, 455, 455, 455, 455, 455, 455, 455, 455, - 455, 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, - 1175, 1176, 1178, 1179, 1180, 1583, 1186, 1186, 1186, 1177, - 1288, 378, 379, 380, 381, 382, 383, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 1181, 2596, 2596, - 2596, 1178, 1179, 1180, 1583, 378, 379, 380, 381, 382, - 383, 2596, 378, 379, 380, 381, 382, 383, 1182, 2596, - - 378, 379, 380, 381, 382, 383, 1181, 1185, 378, 379, - 380, 381, 382, 383, 1183, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 1182, 378, 379, - 380, 381, 382, 383, 2596, 1536, 1185, 1188, 1189, 2596, - 2596, 2596, 2596, 1183, 378, 379, 1187, 381, 382, 383, - 1537, 2596, 378, 379, 380, 381, 382, 383, 1192, 2596, - 378, 379, 380, 381, 382, 383, 1188, 1189, 378, 379, - 380, 381, 382, 383, 1190, 1193, 1191, 1584, 1196, 1537, - 378, 379, 380, 381, 382, 383, 2596, 1192, 378, 379, - 380, 381, 382, 383, 1229, 1229, 2596, 2596, 1229, 1199, - - 1229, 1229, 1229, 1190, 1193, 1191, 1584, 1196, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1194, 1197, - 2596, 1198, 378, 379, 380, 381, 382, 383, 1199, 1195, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2596, 2596, 1194, 1197, 1200, - 1198, 1201, 472, 473, 474, 475, 476, 477, 1195, 1586, - 1203, 1588, 1589, 1214, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 2596, 2596, 1200, 2596, - 1201, 378, 379, 380, 381, 382, 383, 1202, 1586, 1203, - 1588, 1589, 1214, 2596, 1204, 1207, 2596, 378, 379, 380, - - 381, 382, 383, 378, 379, 380, 381, 382, 383, 1205, - 1591, 1593, 1594, 1206, 2596, 2596, 1202, 378, 379, 380, - 381, 382, 383, 1204, 1207, 472, 473, 474, 475, 476, - 477, 1595, 378, 379, 380, 381, 382, 383, 1205, 1591, - 1593, 1594, 1206, 1299, 1082, 1082, 378, 379, 380, 381, - 382, 383, 2596, 378, 379, 380, 381, 382, 383, 2596, - 1595, 378, 379, 380, 381, 382, 383, 1208, 1208, 1208, - 1208, 1208, 1208, 1208, 1208, 1208, 455, 455, 455, 455, - 455, 455, 455, 455, 455, 1209, 1209, 1209, 1209, 1209, - 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, - - 1209, 1209, 1209, 1210, 1210, 1210, 1210, 1210, 1210, 1210, - 1210, 1210, 377, 377, 377, 377, 377, 377, 377, 377, - 377, 1211, 1212, 1213, 2596, 1600, 1215, 472, 473, 474, - 475, 476, 477, 1300, 2596, 2596, 501, 2596, 1216, 471, - 471, 471, 471, 471, 471, 471, 471, 471, 2596, 501, - 1211, 1212, 1213, 1221, 1600, 1215, 2596, 2596, 2596, 2596, - 1217, 472, 473, 474, 475, 476, 477, 1216, 2596, 2596, - 2596, 472, 473, 474, 475, 476, 477, 472, 473, 474, - 475, 476, 477, 472, 473, 474, 475, 476, 477, 1217, - 501, 1601, 1602, 472, 473, 474, 475, 476, 477, 936, - - 936, 936, 936, 936, 936, 936, 936, 501, 2596, 2596, - 508, 509, 514, 511, 512, 513, 1218, 1219, 501, 1625, - 1601, 1602, 1629, 508, 509, 514, 511, 512, 513, 2596, - 501, 1232, 1232, 2596, 1630, 1232, 501, 1232, 1232, 1232, - 2596, 2596, 501, 2596, 1658, 1218, 1219, 1220, 1625, 1237, - 1237, 1629, 2596, 1237, 501, 1237, 1237, 1237, 1222, 2596, - 501, 2596, 1224, 1630, 508, 509, 514, 511, 512, 513, - 501, 1227, 1223, 1658, 1659, 2596, 1220, 501, 2596, 2596, - 2596, 508, 509, 514, 511, 512, 513, 1222, 501, 2596, - 1226, 1224, 508, 509, 514, 511, 512, 513, 1225, 2596, - - 1227, 2596, 2596, 1659, 508, 509, 514, 511, 512, 513, - 508, 509, 514, 511, 512, 513, 508, 509, 514, 511, - 512, 513, 2596, 2596, 2596, 2596, 2596, 1225, 508, 509, - 514, 511, 512, 513, 508, 509, 514, 511, 512, 513, - 2596, 2596, 2596, 2596, 508, 509, 514, 511, 512, 513, - 2596, 508, 509, 514, 511, 512, 513, 2596, 2596, 2596, - 2596, 2596, 508, 509, 514, 511, 512, 513, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 537, 537, 537, - 537, 537, 537, 537, 537, 537, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, - - 1228, 1228, 1228, 537, 537, 537, 537, 537, 537, 537, - 537, 537, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, - 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, - 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 551, - 551, 551, 551, 551, 551, 551, 551, 551, 1231, 1231, - 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, - 1231, 1231, 1231, 1231, 1231, 551, 551, 551, 551, 551, - 551, 551, 551, 551, 1232, 1232, 1232, 1232, 1232, 1232, - 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, - 1232, 1232, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, - - 1233, 1234, 1235, 563, 563, 563, 563, 563, 563, 563, - 563, 563, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 2596, - 1234, 1235, 563, 563, 563, 563, 563, 563, 563, 563, - 563, 545, 546, 547, 548, 549, 550, 545, 546, 547, - 548, 549, 550, 2596, 2596, 2596, 545, 546, 547, 548, - 549, 550, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, - 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, - 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 545, - 546, 547, 548, 549, 550, 544, 544, 544, 544, 544, - - 544, 544, 544, 544, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - 650, 650, 650, 650, 650, 650, 650, 650, 650, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, - 2596, 2596, 1262, 2596, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 1263, 1263, 1263, 1263, - 1263, 1263, 1263, 1263, 1263, 1035, 1035, 1035, 1035, 1035, - 1035, 1035, 1035, 1036, 1036, 1271, 2596, 1036, 2596, 1036, - 1036, 1036, 1272, 1274, 1669, 1683, 2596, 1273, 658, 659, - - 660, 661, 662, 663, 658, 659, 660, 661, 662, 663, - 2596, 1284, 1284, 1684, 1271, 1284, 2596, 1284, 1284, 1284, - 2596, 1272, 1274, 1669, 1683, 1276, 1273, 1275, 1283, 1283, - 1283, 1283, 1283, 1283, 1283, 1283, 658, 659, 660, 661, - 662, 663, 1684, 2596, 658, 659, 660, 661, 662, 663, - 658, 659, 660, 661, 662, 663, 1275, 658, 659, 660, - 661, 662, 663, 658, 659, 660, 661, 662, 663, 2596, - 1313, 1098, 1098, 658, 659, 660, 661, 662, 663, 657, - 657, 657, 657, 657, 657, 657, 657, 657, 691, 691, - 691, 691, 691, 691, 691, 691, 691, 1283, 1283, 1283, - - 1283, 1283, 1283, 1283, 1283, 1283, 691, 691, 691, 691, - 691, 691, 691, 691, 691, 1284, 1284, 1284, 1284, 1284, - 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, - 1284, 1284, 1284, 1285, 1285, 1285, 1285, 1285, 1285, 1285, - 1285, 1285, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, - 1062, 1062, 1290, 2596, 1062, 2596, 1062, 1062, 1062, 1292, - 1314, 2596, 1685, 1293, 1291, 699, 700, 701, 702, 703, - 704, 699, 700, 701, 702, 703, 704, 2596, 2596, 2596, - 2596, 1290, 698, 698, 698, 698, 698, 698, 698, 698, - 698, 1685, 1293, 1291, 2596, 2596, 2596, 699, 700, 701, - - 702, 703, 704, 2596, 699, 700, 701, 702, 703, 704, - 699, 700, 701, 702, 703, 704, 718, 719, 720, 721, - 722, 723, 718, 719, 720, 721, 722, 723, 718, 719, - 720, 721, 722, 723, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, - 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 737, - 737, 737, 737, 737, 737, 737, 737, 737, 1296, 1296, - 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1088, - 1088, 1296, 2596, 1296, 1296, 1296, 1296, 1296, 1296, 1296, - - 1296, 1296, 1296, 1296, 1296, 1297, 1297, 1297, 1297, 1297, - 1297, 1297, 1297, 1297, 1094, 1094, 1094, 1094, 1094, 1094, - 1094, 1094, 1095, 1095, 1309, 1310, 1095, 361, 1095, 1095, - 1095, 745, 746, 747, 748, 749, 750, 745, 746, 747, - 748, 749, 750, 744, 744, 744, 744, 744, 744, 744, - 744, 744, 1311, 1309, 1310, 1319, 1102, 1102, 385, 1686, - 2596, 745, 746, 747, 748, 749, 750, 361, 2596, 1119, - 813, 813, 2596, 2596, 2596, 745, 746, 747, 748, 749, - 750, 1311, 378, 379, 380, 381, 382, 383, 1686, 745, - 746, 747, 748, 749, 750, 1265, 1024, 1024, 2596, 745, - - 746, 747, 748, 749, 750, 385, 1688, 1692, 1693, 1696, - 2596, 363, 364, 365, 366, 367, 368, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 1688, 1692, 1693, 1696, 386, - 387, 388, 389, 390, 391, 1320, 2596, 2596, 2596, 2596, - 2596, 363, 364, 365, 366, 367, 368, 369, 369, 1120, - 2596, 369, 369, 2596, 2596, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 1328, 1329, 369, 369, 369, 369, - 369, 2596, 2596, 2596, 1331, 1266, 386, 387, 388, 389, - 390, 391, 384, 384, 384, 384, 384, 384, 384, 384, - - 384, 2596, 2596, 1328, 1329, 2596, 2596, 369, 2596, 369, - 1453, 1259, 1259, 1331, 1454, 2596, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 2596, 1330, - 378, 379, 380, 381, 382, 383, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 371, 372, 373, 374, - 375, 376, 369, 369, 1332, 1697, 369, 369, 1330, 2596, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 1333, - 2596, 369, 369, 369, 369, 369, 378, 379, 380, 381, - 382, 383, 2596, 1332, 1697, 1694, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 1334, 2596, 1695, 1333, 1335, - - 1455, 1336, 369, 2596, 369, 2596, 378, 379, 380, 381, - 382, 383, 2596, 2596, 1694, 2596, 2596, 378, 379, 380, - 381, 382, 383, 1337, 1334, 1338, 1695, 2596, 1335, 2596, - 1336, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 371, 372, 373, 374, 375, 376, 2596, 1339, 1340, - 1341, 2596, 1337, 2596, 1338, 2596, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1279, 1040, - 1040, 378, 379, 380, 381, 382, 383, 1339, 1340, 1341, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 1342, 1343, 378, 379, 380, 381, 382, 383, - - 1344, 1347, 1348, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 1342, 1343, 2596, 2596, 1345, 2596, 1349, 1698, 1344, - 1347, 1348, 2596, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 1345, 1346, 1349, 1698, 1280, 1351, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 2596, 378, 379, 380, 381, 382, 383, 1350, - 1353, 2596, 2596, 2596, 1346, 2596, 1352, 1699, 1351, 378, - 379, 380, 381, 382, 383, 2596, 2596, 1357, 1357, 1357, - - 378, 379, 380, 381, 382, 383, 1354, 2596, 1350, 378, - 379, 380, 381, 382, 383, 1352, 1699, 2596, 378, 379, - 380, 381, 382, 383, 1355, 378, 379, 380, 381, 382, - 383, 1356, 1700, 1690, 1359, 1354, 1691, 2596, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 1355, 378, 379, 380, 381, 382, 383, - 1356, 1700, 1690, 2596, 2596, 1691, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1360, 378, - 379, 380, 381, 382, 383, 378, 379, 1358, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 1287, 1056, 1056, - - 2596, 1361, 1362, 1701, 1372, 1702, 1364, 1360, 1363, 378, - 379, 380, 381, 382, 383, 1365, 1368, 1368, 1368, 2596, - 1299, 1082, 1082, 2596, 378, 379, 380, 381, 382, 383, - 1361, 1362, 1701, 1372, 1702, 1364, 2596, 1363, 2596, 2596, - 1366, 1313, 1098, 1098, 1365, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 378, 379, 380, 381, 382, 383, 1366, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 1367, 1370, 1724, 1725, 1393, 1288, 378, 379, - 380, 381, 382, 383, 1371, 378, 379, 380, 381, 382, - - 383, 1374, 2596, 2596, 378, 379, 1369, 381, 382, 383, - 1300, 1367, 1370, 1724, 1725, 1393, 1373, 378, 379, 380, - 381, 382, 383, 1371, 2596, 1375, 1319, 1102, 1102, 2596, - 1374, 1314, 1376, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 1373, 2596, 2596, 378, 379, - 380, 381, 382, 383, 1375, 378, 379, 380, 381, 382, - 383, 1376, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 378, 379, 380, 381, 382, 383, 1377, 378, 379, - 380, 381, 382, 383, 1378, 1379, 1726, 2596, 1729, 1730, - 1731, 1380, 2596, 1391, 1391, 1391, 2596, 378, 379, 380, - - 381, 382, 383, 2596, 2596, 2596, 1377, 2596, 2596, 1381, - 1732, 1733, 2596, 1378, 1379, 1726, 1320, 1729, 1730, 1731, - 1380, 1390, 465, 465, 465, 465, 465, 465, 465, 465, - 2596, 1734, 378, 379, 380, 381, 382, 383, 1381, 1732, - 1733, 1394, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 1734, 2596, 2596, 2596, 1396, 2596, 1735, 1453, 1259, 1259, - 1394, 1454, 378, 379, 380, 381, 382, 383, 1186, 1186, - 1186, 378, 379, 1392, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 1396, 1397, 1735, 2596, 2596, 2596, 2596, - - 1382, 2596, 1736, 1383, 1384, 1395, 1680, 2596, 1398, 2596, - 1681, 1682, 1400, 1737, 1385, 1386, 1387, 1443, 1255, 1255, - 1388, 2596, 2596, 1397, 1444, 378, 379, 380, 381, 382, - 383, 1736, 1383, 1384, 1395, 1680, 1399, 1398, 1401, 1681, - 1682, 1400, 1737, 1385, 1386, 1387, 2596, 2596, 2596, 1388, - 378, 379, 380, 381, 382, 383, 2596, 1455, 2596, 378, - 379, 380, 381, 382, 383, 1399, 2596, 1401, 1389, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 1402, 1404, 378, 379, 380, 381, 382, 383, 1403, - 378, 379, 380, 381, 382, 383, 1405, 378, 379, 380, - - 381, 382, 383, 1406, 456, 1407, 2596, 1445, 2596, 2596, - 1402, 1404, 472, 473, 474, 475, 476, 477, 1403, 2596, - 2596, 2596, 2596, 2596, 1408, 1405, 378, 379, 380, 381, - 382, 383, 1406, 1409, 1407, 378, 379, 380, 381, 382, - 383, 457, 458, 459, 460, 461, 462, 378, 379, 380, - 381, 382, 383, 1408, 2596, 378, 379, 380, 381, 382, - 383, 1410, 1409, 456, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 501, 2596, 2596, 2596, - 1415, 378, 379, 380, 381, 382, 383, 1411, 1738, 1744, - 1410, 2596, 1747, 2596, 378, 379, 380, 381, 382, 383, - - 457, 458, 459, 460, 461, 462, 455, 455, 455, 455, - 455, 455, 455, 455, 455, 1412, 1411, 1738, 1744, 2596, - 1414, 1747, 472, 473, 474, 475, 476, 477, 1413, 472, - 473, 474, 475, 476, 477, 501, 2596, 2596, 2596, 2596, - 2596, 501, 2596, 2596, 1412, 2596, 1756, 1756, 1756, 1414, - 508, 509, 514, 511, 512, 513, 472, 473, 474, 475, - 476, 477, 1416, 1763, 2596, 1418, 472, 473, 474, 475, - 476, 477, 472, 473, 474, 475, 476, 477, 501, 2596, - 2596, 2596, 2596, 2596, 2596, 501, 1448, 1257, 1257, 2596, - 2596, 1416, 1763, 1449, 1418, 501, 1727, 536, 1764, 2596, - - 1767, 1728, 1784, 2596, 536, 2596, 1417, 2596, 1421, 508, - 509, 514, 511, 512, 513, 508, 509, 514, 511, 512, - 513, 1419, 501, 2596, 2596, 1727, 2596, 1764, 501, 1767, - 1728, 1784, 2596, 2596, 501, 1417, 1757, 1421, 2596, 1420, - 2596, 2596, 2596, 2596, 2596, 501, 2596, 2596, 1422, 2596, - 1785, 1423, 508, 509, 514, 511, 512, 513, 1424, 508, - 509, 514, 511, 512, 513, 552, 1793, 2596, 1420, 508, - 509, 514, 511, 512, 513, 552, 1450, 1422, 2596, 1785, - 1423, 538, 539, 540, 541, 542, 543, 1424, 538, 539, - 540, 541, 542, 543, 2596, 1793, 508, 509, 514, 511, - - 512, 513, 508, 509, 514, 511, 512, 513, 508, 509, - 514, 511, 512, 513, 2596, 2596, 1805, 2596, 2596, 508, - 509, 514, 511, 512, 513, 537, 537, 537, 537, 537, - 537, 537, 537, 537, 551, 551, 551, 551, 551, 551, - 551, 551, 551, 1425, 1426, 1805, 553, 554, 555, 556, - 557, 558, 564, 2596, 2596, 2596, 553, 554, 555, 556, - 557, 558, 564, 563, 563, 563, 563, 563, 563, 563, - 563, 563, 2596, 1426, 718, 719, 720, 721, 722, 723, - 2596, 545, 546, 547, 548, 549, 550, 2596, 1461, 565, - 566, 567, 568, 569, 570, 2596, 2041, 2041, 2041, 565, - - 566, 567, 568, 569, 570, 545, 546, 547, 548, 549, - 550, 649, 649, 2596, 2596, 649, 649, 1461, 1462, 649, - 649, 649, 649, 649, 649, 649, 649, 649, 1468, 1806, - 649, 649, 649, 649, 649, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 1463, 1463, 1463, 1462, 2596, 1464, - 2596, 658, 659, 660, 661, 662, 663, 1465, 1806, 1807, - 1808, 649, 2596, 649, 2596, 2596, 658, 659, 660, 661, - 662, 663, 472, 473, 474, 475, 476, 477, 2596, 1467, - 658, 659, 660, 661, 662, 663, 2042, 2596, 1807, 1808, - 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, - - 651, 652, 653, 654, 655, 656, 649, 649, 1467, 1469, - 649, 649, 1475, 2596, 649, 649, 649, 649, 649, 649, - 649, 649, 649, 2596, 2596, 649, 649, 649, 649, 649, - 2596, 2596, 658, 659, 1466, 661, 662, 663, 1469, 1809, - 1810, 1368, 1368, 1368, 658, 659, 660, 661, 662, 663, - 699, 700, 701, 702, 703, 704, 649, 2596, 649, 691, - 691, 691, 691, 691, 691, 691, 691, 691, 1809, 1810, - 2596, 2596, 658, 659, 660, 661, 662, 663, 1474, 1524, - 2596, 2596, 2051, 2051, 2051, 649, 649, 649, 649, 649, - 649, 649, 649, 649, 649, 651, 652, 653, 654, 655, - - 656, 690, 690, 1476, 2596, 690, 690, 1474, 1524, 690, - 690, 690, 690, 690, 690, 690, 690, 690, 1811, 1812, - 690, 690, 690, 690, 690, 545, 546, 547, 548, 549, - 550, 1525, 1476, 1486, 1486, 1486, 1570, 2596, 2596, 2596, - 699, 700, 701, 702, 703, 704, 2596, 1811, 1812, 2596, - 2596, 690, 2596, 690, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 2596, 2596, 2596, 699, 700, 701, 702, - 703, 704, 2052, 1480, 472, 473, 474, 475, 476, 477, - 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, - 692, 693, 694, 695, 696, 697, 690, 690, 1481, 1482, - - 690, 690, 1480, 2596, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 2596, 2596, 690, 690, 690, 690, 690, - 2596, 378, 379, 1487, 381, 382, 383, 1481, 1482, 2596, - 2596, 2596, 2596, 1813, 2596, 2596, 745, 746, 747, 748, - 749, 750, 2596, 2596, 2596, 1814, 690, 2596, 690, 472, - 473, 474, 475, 476, 477, 2596, 745, 746, 747, 748, - 749, 750, 1813, 745, 746, 747, 748, 749, 750, 2596, - 2596, 2596, 2596, 501, 1814, 690, 690, 690, 690, 690, - 690, 690, 690, 690, 690, 692, 693, 694, 695, 696, - 697, 736, 736, 2596, 2596, 736, 736, 2596, 2596, 736, - - 736, 736, 736, 736, 736, 736, 736, 736, 1815, 1575, - 736, 736, 736, 736, 736, 1816, 1817, 1488, 378, 379, - 380, 381, 382, 383, 472, 473, 474, 475, 476, 477, - 378, 379, 380, 381, 382, 383, 2596, 1815, 2596, 2596, - 2596, 736, 2596, 736, 1816, 1817, 1488, 508, 509, 514, - 511, 512, 513, 2596, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 1493, 2596, 2596, 2596, 2596, 2596, 2596, - 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, - 738, 739, 740, 741, 742, 743, 736, 736, 1489, 1491, - 736, 736, 1493, 1818, 736, 736, 736, 736, 736, 736, - - 736, 736, 736, 2596, 2596, 736, 736, 736, 736, 736, - 1819, 2596, 2596, 2596, 2596, 2596, 2596, 1489, 1491, 2596, - 2596, 2596, 1818, 2077, 2077, 2077, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2596, 736, 2078, 736, 1819, - 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1490, 2596, - 2596, 1492, 2596, 2596, 2596, 736, 736, 736, 736, 736, - 736, 736, 736, 736, 736, 738, 739, 740, 741, 742, - 743, 2596, 2596, 2596, 2596, 2596, 2596, 1490, 1494, 1495, - 1492, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 378, - - 379, 380, 381, 382, 383, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2079, 1517, 1517, 1517, 1494, 1495, 1496, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 1518, - 2596, 1497, 2596, 2596, 2596, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 2596, 2596, 2596, 1820, 1496, 1821, - 378, 379, 380, 381, 382, 383, 1822, 1500, 1823, 1498, - 1497, 1824, 1443, 1255, 1255, 2596, 2596, 2596, 1499, 1444, - 378, 379, 380, 381, 382, 383, 1820, 2596, 1821, 378, - 379, 380, 381, 382, 383, 1822, 1500, 1823, 1498, 2596, - 1824, 1448, 1257, 1257, 2596, 2596, 2596, 1499, 1449, 2596, - - 2596, 2596, 2596, 2596, 1663, 2596, 1501, 2596, 2596, 2596, - 2596, 1486, 1486, 1486, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 1501, 1502, 1825, 1503, 2596, - 2596, 2596, 1826, 1827, 1847, 2596, 2596, 2596, 2596, 1634, - 1504, 1505, 1445, 378, 379, 380, 381, 382, 383, 2596, - 2596, 2596, 2596, 2596, 2596, 1502, 1825, 1503, 2596, 2596, - 2596, 1826, 1827, 1847, 1507, 2596, 2596, 2596, 1634, 1504, - 2596, 1450, 378, 379, 380, 381, 382, 383, 2596, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - - 383, 1635, 2596, 1507, 2596, 2596, 2596, 2596, 2596, 1506, - 1849, 1850, 1851, 1508, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 2596, 1357, 1357, 1357, 378, 379, 380, - 381, 382, 383, 378, 379, 380, 381, 382, 383, 1849, - 1850, 1851, 1508, 2596, 2596, 2596, 1510, 378, 379, 380, - 381, 382, 383, 1511, 1852, 2596, 378, 379, 380, 381, - 382, 383, 1512, 378, 379, 380, 381, 382, 383, 1853, - 1509, 2596, 2596, 2596, 2596, 1510, 2596, 2596, 2596, 2596, - 2596, 2596, 1511, 1852, 2596, 2596, 2596, 1854, 1855, 2596, - 2596, 1512, 378, 379, 380, 381, 382, 383, 1853, 1509, - - 1514, 465, 465, 465, 465, 465, 465, 465, 465, 1515, - 1517, 1517, 1517, 2596, 1513, 1856, 1854, 1855, 2596, 2596, - 2596, 2596, 2596, 2596, 1516, 1518, 1857, 2596, 2596, 2596, - 2596, 378, 379, 380, 381, 382, 383, 2596, 1515, 2596, - 2596, 2596, 2596, 2596, 1856, 2596, 2596, 2596, 2596, 1520, - 2596, 2596, 2596, 1516, 2596, 1857, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 1521, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1520, 2596, - 2596, 2596, 2596, 1522, 1526, 465, 465, 465, 465, 465, - 465, 465, 465, 2596, 1521, 1858, 1527, 2596, 378, 379, - - 1519, 381, 382, 383, 2596, 2596, 378, 379, 380, 381, - 382, 383, 1522, 2596, 2596, 2596, 378, 379, 380, 381, - 382, 383, 1523, 2596, 1858, 1527, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 1859, 1523, 2596, 2596, 2596, 1860, 1861, 2596, 2596, 2596, - 2596, 1866, 2596, 1870, 2596, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 2596, 2596, 1859, - 2596, 2596, 2596, 1530, 1860, 1861, 2596, 2596, 2596, 2596, - 1866, 1529, 1870, 1528, 2596, 2596, 2596, 2596, 2596, 2596, - - 1886, 378, 379, 380, 381, 382, 383, 1531, 1887, 1532, - 1533, 2596, 1530, 2596, 378, 379, 380, 381, 382, 383, - 1529, 2596, 1528, 378, 379, 380, 381, 382, 383, 1886, - 1889, 1534, 2596, 2596, 2596, 2596, 1531, 1887, 1532, 1533, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 2596, 1889, - 1534, 2596, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 1186, 906, 906, 906, 906, 906, 906, 906, 906, - - 1557, 465, 465, 465, 465, 465, 465, 465, 465, 2596, - 2596, 2596, 1604, 2596, 1713, 2596, 1906, 1907, 1915, 1920, - 378, 379, 380, 381, 382, 383, 2596, 1921, 2596, 1922, - 1535, 1463, 1463, 1463, 2596, 2596, 1605, 1928, 1930, 1558, - 2596, 2596, 2596, 1713, 1465, 1906, 1907, 1915, 1920, 2596, - 658, 659, 660, 661, 662, 663, 1921, 1606, 1922, 1535, - 472, 473, 474, 475, 476, 477, 1928, 1930, 1558, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 378, 379, 380, 381, - 382, 383, 1391, 1391, 1391, 2596, 1606, 2596, 2596, 2596, - 2596, 2596, 2596, 1933, 2596, 2596, 2596, 378, 379, 380, - - 381, 382, 383, 2596, 2596, 2596, 1934, 1545, 1546, 1547, - 1548, 1549, 1559, 1550, 1560, 1551, 2596, 2596, 2596, 1935, - 1552, 1607, 1933, 1553, 1554, 1936, 1561, 1555, 378, 379, - 380, 381, 382, 383, 2596, 1934, 1545, 1546, 1547, 1548, - 1549, 1559, 1550, 1560, 1551, 2596, 2596, 2596, 1935, 1552, - 2596, 2596, 1553, 1554, 1936, 1561, 1555, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 1562, 1911, - 1911, 1911, 1556, 2596, 2596, 2596, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 378, 379, 380, 381, 382, 383, 1562, 2596, 1912, - - 1563, 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 1582, 1937, 1564, 2596, 2596, 2596, 1938, - 1939, 1940, 2596, 2596, 2596, 1941, 1942, 1565, 1912, 1563, - 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, - 2596, 2596, 1582, 1937, 1564, 1943, 1567, 2596, 1938, 1939, - 1940, 2596, 2596, 2596, 1941, 1942, 1565, 1566, 2596, 1913, - 2596, 378, 379, 380, 381, 382, 383, 1571, 545, 546, - 547, 548, 549, 550, 1943, 1567, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2596, 1566, 1568, 2596, 378, - 379, 380, 381, 382, 383, 1569, 1571, 1572, 378, 379, - - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 1568, 501, 378, 379, - 380, 381, 382, 383, 1569, 2596, 1572, 2596, 2596, 501, - 472, 473, 474, 475, 476, 477, 501, 1944, 1945, 378, - 379, 380, 381, 382, 383, 1573, 1574, 472, 473, 474, - 475, 476, 477, 501, 1931, 1576, 472, 473, 474, 475, - 476, 477, 501, 2596, 2596, 2596, 1944, 1945, 501, 2596, - 1603, 1946, 1932, 1949, 1573, 1574, 501, 2596, 2596, 2596, - 1577, 2596, 2596, 1931, 1576, 2596, 2596, 1950, 1580, 1578, - 1951, 508, 509, 514, 511, 512, 513, 501, 1581, 1603, - - 1946, 1932, 1949, 508, 509, 514, 511, 512, 513, 1577, - 508, 509, 514, 511, 512, 513, 1950, 1580, 2596, 1951, - 1579, 658, 659, 660, 661, 662, 663, 508, 509, 514, - 511, 512, 513, 2596, 2596, 2596, 508, 509, 514, 511, - 512, 513, 508, 509, 514, 511, 512, 513, 2596, 1579, - 508, 509, 514, 511, 512, 513, 1621, 674, 674, 674, - 674, 674, 674, 674, 674, 378, 379, 380, 381, 382, - 383, 508, 509, 514, 511, 512, 513, 1608, 1609, 1463, - 1463, 1608, 1608, 1610, 1611, 1608, 1608, 1608, 1608, 1608, - 1608, 1612, 1608, 1608, 1611, 1611, 1608, 1608, 1608, 1608, - - 1608, 1611, 1611, 1611, 1613, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1608, 1611, 1608, - 1611, 1611, 1611, 1613, 1611, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1608, 1608, 1608, 1608, - 1608, 1608, 1608, 1608, 1608, 1608, 1614, 1615, 1616, 1617, - 1618, 1619, 1622, 1964, 1965, 1623, 2596, 2596, 2596, 1626, - 658, 659, 660, 661, 662, 663, 2596, 1624, 745, 746, - 747, 748, 749, 750, 1627, 745, 746, 747, 748, 749, - - 750, 1622, 1964, 1965, 1623, 1636, 465, 465, 465, 465, - 465, 465, 465, 465, 2596, 1628, 1624, 699, 700, 701, - 702, 703, 704, 1627, 2596, 2596, 658, 659, 660, 661, - 662, 663, 658, 659, 660, 661, 662, 663, 658, 659, - 660, 661, 662, 663, 1628, 1631, 1966, 1968, 1632, 1969, - 1970, 699, 700, 701, 702, 703, 704, 1633, 2596, 2596, - 2596, 1971, 1975, 1983, 2596, 501, 699, 700, 701, 702, - 703, 704, 2596, 2596, 1631, 1966, 1968, 1632, 1969, 1970, - 2596, 2596, 2596, 2596, 2596, 1637, 1633, 2596, 2596, 2596, - 1971, 1975, 1983, 2596, 2596, 2596, 745, 746, 747, 748, - - 749, 750, 745, 746, 747, 748, 749, 750, 745, 746, - 747, 748, 749, 750, 1637, 2596, 1996, 2596, 2596, 2596, - 2596, 2596, 2596, 1638, 2596, 2596, 2596, 1997, 1999, 1639, - 2596, 2596, 2596, 2014, 2015, 2020, 2596, 2596, 2596, 508, - 509, 514, 511, 512, 513, 1996, 378, 379, 380, 381, - 382, 383, 1638, 2596, 2596, 2596, 1997, 1999, 1639, 1640, - 2022, 1642, 2014, 2015, 2020, 2027, 1641, 2596, 378, 379, - 380, 381, 382, 383, 2596, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 2596, 1640, 2022, - 1642, 2596, 2596, 2596, 2027, 1641, 1357, 906, 906, 906, - - 906, 906, 906, 906, 906, 378, 379, 380, 381, 382, - 383, 2028, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 2596, 2029, 2596, 2596, 2596, 2596, 1947, - 2028, 2034, 2035, 1645, 1645, 1645, 2596, 2596, 2036, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2037, 1643, 1646, 2038, - 1948, 2039, 1644, 2029, 2596, 2596, 2596, 2040, 1947, 2596, - 2034, 2035, 2596, 1648, 2596, 2596, 2596, 2036, 2596, 378, - 379, 380, 381, 382, 383, 2037, 1643, 1651, 2038, 1948, - 2039, 1644, 2596, 2596, 2596, 2596, 2040, 2596, 2596, 2596, - - 2596, 1649, 1648, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 1651, 2596, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 1649, 378, 379, 1647, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 1650, 2596, 2596, 2596, 2043, 2044, 1653, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 2596, 1650, 2596, 2596, 2596, 2043, 2044, 1653, 1655, - 1655, 1655, 2045, 2046, 1652, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 1656, 378, 379, 380, 381, 382, - - 383, 378, 379, 380, 381, 382, 383, 2596, 2596, 1654, - 2596, 2045, 2046, 1652, 2596, 2596, 2596, 1665, 465, 465, - 465, 465, 465, 465, 465, 465, 2047, 1661, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1654, 2596, - 2596, 2596, 2596, 2596, 1758, 1662, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2047, 1661, 378, 379, 380, - 381, 382, 383, 1667, 2596, 2596, 2596, 378, 379, 1657, - 381, 382, 383, 1758, 1662, 2596, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 1667, 2596, 1666, 1668, 658, 659, 660, 661, - - 662, 663, 378, 379, 380, 381, 382, 383, 1368, 906, - 906, 906, 906, 906, 906, 906, 906, 378, 379, 380, - 381, 382, 383, 1666, 1668, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 1671, 2048, 2049, 378, 379, 380, 381, 382, 383, 2596, - 2596, 2596, 2596, 2596, 2050, 2053, 1672, 378, 379, 380, - 381, 382, 383, 2054, 2596, 2596, 2596, 2596, 2596, 1671, - 2048, 2049, 2596, 2596, 2596, 2596, 2596, 2596, 1673, 2596, - - 2596, 2596, 2596, 2050, 2053, 1672, 2596, 2596, 2596, 2596, - 2596, 1674, 2054, 1677, 1677, 1677, 2596, 2596, 2055, 1675, - 2596, 378, 379, 380, 381, 382, 383, 1673, 1678, 2596, - 2596, 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, - 1674, 2596, 1676, 1704, 2596, 2596, 2596, 2055, 1675, 1391, - 906, 906, 906, 906, 906, 906, 906, 906, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, 2596, - 2596, 1676, 1704, 2596, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 2596, 378, 379, 380, - 381, 382, 383, 2596, 378, 379, 380, 381, 382, 383, - - 1759, 378, 379, 1679, 381, 382, 383, 2596, 2596, 2596, - 1706, 501, 2596, 2596, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2596, 2596, 1707, 1707, 1707, 2596, 1759, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1705, 1706, - 1708, 2596, 2596, 2596, 2596, 658, 659, 660, 661, 662, - 663, 2596, 2596, 2596, 2056, 2057, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2596, 2596, 1705, 545, 546, - 547, 548, 549, 550, 2596, 2596, 2596, 2596, 1710, 1645, - 1645, 1645, 501, 2056, 2057, 508, 509, 514, 511, 512, - 513, 1712, 2058, 1716, 1646, 378, 379, 380, 381, 382, - - 383, 378, 379, 380, 381, 382, 383, 1710, 1711, 1655, - 1655, 1655, 2596, 378, 379, 1709, 381, 382, 383, 1714, - 1712, 2058, 1716, 2596, 1656, 2596, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 501, 1711, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 1714, 1715, - 378, 379, 380, 381, 382, 383, 508, 509, 514, 511, - 512, 513, 378, 379, 380, 381, 382, 383, 501, 1773, - 472, 473, 474, 475, 476, 477, 501, 1721, 1715, 1740, - 2059, 2596, 501, 1463, 1035, 1035, 1035, 1035, 1035, 1035, - 1035, 1035, 2070, 1717, 2071, 1718, 2072, 2073, 2596, 1781, - - 2596, 2596, 501, 2596, 2596, 2074, 1721, 1723, 1740, 2059, - 508, 509, 514, 511, 512, 513, 501, 2596, 2596, 1722, - 2075, 2070, 1717, 2071, 1718, 2072, 2073, 658, 659, 660, - 661, 662, 663, 1719, 2074, 2076, 1723, 2093, 1720, 2596, - 2596, 2596, 508, 509, 514, 511, 512, 513, 1722, 2075, - 508, 509, 514, 511, 512, 513, 508, 509, 514, 511, - 512, 513, 1719, 2596, 2076, 2596, 2093, 1720, 545, 546, - 547, 548, 549, 550, 1739, 2098, 508, 509, 514, 511, - 512, 513, 2596, 1609, 1463, 1463, 2101, 2596, 1741, 2106, - 508, 509, 514, 511, 512, 513, 1612, 1609, 1463, 1463, - - 2596, 2596, 1741, 1739, 2098, 1760, 2108, 1761, 2596, 1742, - 1612, 1609, 1463, 1463, 2596, 2101, 1741, 2596, 2106, 2109, - 1609, 1463, 1463, 1742, 1612, 1741, 2596, 658, 659, 660, - 661, 662, 663, 1746, 1760, 2108, 1761, 1742, 1742, 2596, - 2596, 1765, 2113, 1762, 2596, 2118, 1742, 2119, 2109, 2120, - 1766, 2596, 1742, 699, 700, 701, 702, 703, 704, 699, - 700, 701, 702, 703, 704, 2596, 1742, 2596, 2596, 2596, - 1765, 2113, 1762, 1743, 2118, 1742, 2119, 2596, 2120, 1766, - 2596, 2596, 2596, 2596, 2596, 2123, 1837, 1743, 699, 700, - 701, 702, 703, 704, 745, 746, 747, 748, 749, 750, - - 2596, 1743, 745, 746, 747, 748, 749, 750, 2596, 2596, - 1743, 1609, 1463, 1463, 2123, 1837, 1741, 2596, 2596, 2004, - 2004, 2004, 1769, 2596, 1612, 1486, 906, 906, 906, 906, - 906, 906, 906, 906, 2596, 2596, 2596, 1742, 472, 473, - 474, 475, 476, 477, 2596, 2596, 2596, 2596, 2125, 2005, - 2596, 1769, 2596, 2596, 2596, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 2596, 2596, 1742, 2596, 378, 379, - 380, 381, 382, 383, 2596, 2596, 1770, 2125, 2005, 1771, - 2596, 2596, 2596, 2126, 1772, 2127, 2596, 2596, 2596, 2128, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 2596, - - 2129, 1743, 1609, 1463, 1463, 1770, 2596, 1741, 1771, 2006, - 2130, 2596, 2126, 1772, 2127, 1612, 2596, 2596, 2128, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1742, 2129, - 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, 2130, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 1742, 1775, 465, - 465, 465, 465, 465, 465, 465, 465, 2131, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 2596, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, - 2596, 2596, 1743, 1609, 1463, 1463, 2131, 2596, 1741, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 1612, 378, 379, 380, - 381, 382, 383, 2596, 2596, 2596, 2596, 2596, 2596, 1742, - 1783, 465, 465, 465, 465, 465, 465, 465, 465, 1776, - 2596, 2596, 2596, 2133, 378, 379, 380, 381, 382, 383, - 1777, 2596, 2596, 2596, 2596, 2041, 2041, 2041, 1742, 1517, - 906, 906, 906, 906, 906, 906, 906, 906, 1776, 2596, - 2596, 2596, 2133, 2596, 2596, 2596, 2596, 1778, 2596, 1777, - 2596, 2596, 1749, 1750, 1750, 1750, 1750, 1750, 1750, 1750, - 1750, 2596, 1779, 1743, 1609, 1463, 1463, 2596, 2596, 1741, - 378, 379, 380, 381, 382, 383, 1778, 1612, 2134, 1707, - - 1707, 1707, 2596, 378, 379, 380, 381, 382, 383, 2596, - 1742, 1779, 2135, 2136, 1708, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 2134, 2596, 378, - 379, 380, 381, 382, 383, 2042, 2596, 2596, 2596, 1742, - 2596, 2135, 2136, 2596, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2137, 2138, 1780, 1786, 2596, 2596, 2596, - 2596, 2139, 2140, 1751, 1751, 1751, 1751, 1751, 1751, 1751, - 1751, 1751, 2596, 1787, 1743, 1609, 1463, 1463, 2596, 2596, - 1741, 2596, 2137, 2138, 1780, 1786, 2596, 2596, 1612, 1831, - 2139, 2140, 2145, 2146, 1792, 2596, 2596, 2596, 2596, 2596, - - 2596, 1742, 1787, 378, 379, 380, 381, 382, 383, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 2145, 2146, 1792, 378, 379, 380, 381, 382, 383, - 1742, 378, 379, 380, 381, 382, 383, 1794, 1794, 1794, - 2147, 2156, 2596, 2596, 2596, 378, 379, 380, 381, 382, - 383, 1797, 1795, 2157, 1752, 1752, 1752, 1752, 1752, 1752, - 1752, 1753, 1754, 2596, 2158, 1743, 1609, 1463, 1463, 2147, - 2156, 1741, 2596, 2596, 2596, 2596, 1794, 1794, 1794, 1612, - 1797, 2596, 2157, 378, 379, 380, 381, 382, 383, 2596, - 2162, 1795, 1742, 2158, 2167, 2168, 2596, 378, 379, 380, - - 381, 382, 383, 2596, 2596, 2596, 378, 379, 380, 381, - 382, 383, 2169, 2596, 2170, 2176, 1677, 1677, 1677, 2162, - 2596, 1742, 2596, 2167, 2168, 378, 379, 1796, 381, 382, - 383, 1678, 2596, 2596, 2596, 2596, 2596, 2596, 1799, 1798, - 2184, 2169, 1800, 2170, 2176, 1755, 1755, 1755, 1755, 1755, - 1755, 1755, 1755, 1755, 1801, 2596, 1743, 2596, 2596, 2596, - 378, 379, 380, 381, 382, 383, 1916, 2596, 1798, 2184, - 2596, 1800, 1804, 465, 465, 465, 465, 465, 465, 465, - 465, 2596, 2596, 1801, 2596, 2596, 2596, 1881, 2018, 2018, - 2018, 378, 379, 380, 381, 382, 383, 2596, 2596, 1828, - - 2596, 2596, 2596, 1518, 1836, 501, 1802, 1833, 465, 465, - 465, 465, 465, 465, 465, 465, 1881, 2596, 2596, 2596, - 378, 379, 380, 381, 382, 383, 1829, 1830, 1828, 2596, - 2596, 2596, 2596, 1836, 658, 659, 660, 661, 662, 663, - 2596, 1839, 2195, 2596, 2596, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 2596, 1829, 1830, 1834, 1835, 501, - 2596, 472, 473, 474, 475, 476, 477, 501, 2011, 2011, - 2011, 2195, 378, 379, 380, 381, 382, 383, 2019, 508, - 509, 514, 511, 512, 513, 1838, 1834, 1835, 378, 379, - 380, 381, 382, 383, 2596, 1911, 1911, 1911, 2012, 501, - - 1841, 2596, 2198, 2199, 2596, 378, 379, 380, 381, 382, - 383, 1840, 501, 2596, 1838, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 1842, 1912, 1862, 2012, 2596, 1841, - 501, 2198, 2199, 508, 509, 514, 511, 512, 513, 1843, - 1840, 508, 509, 514, 511, 512, 513, 2596, 2596, 2596, - 2596, 501, 2596, 1842, 1912, 1862, 2596, 501, 2013, 2218, - 2218, 2218, 2596, 1844, 2200, 2203, 1863, 2206, 1843, 1845, - 1846, 2208, 2209, 508, 509, 514, 511, 512, 513, 658, - 659, 660, 661, 662, 663, 1913, 508, 509, 514, 511, - 512, 513, 1844, 2200, 2203, 1863, 2206, 2596, 1845, 1846, - - 2208, 2209, 2596, 2596, 508, 509, 514, 511, 512, 513, - 2596, 545, 546, 547, 548, 549, 550, 658, 659, 660, - 661, 662, 663, 2596, 2596, 508, 509, 514, 511, 512, - 513, 508, 509, 514, 511, 512, 513, 1609, 1463, 1463, - 2596, 2210, 1741, 1609, 1463, 1463, 2596, 2596, 1741, 2219, - 1612, 2212, 1609, 1463, 1463, 1992, 1612, 1741, 2596, 1867, - 1868, 1868, 2596, 1742, 1741, 1612, 1882, 2596, 2213, 1742, - 2210, 2596, 1746, 2596, 1609, 1463, 1463, 2596, 1742, 1741, - 2212, 2192, 2596, 2596, 1992, 1742, 1864, 1612, 2596, 2596, - 2596, 2596, 1742, 2596, 2596, 1882, 2193, 2213, 1742, 2214, - - 1742, 658, 659, 660, 661, 662, 663, 1742, 2596, 2596, - 2192, 1875, 1868, 1868, 1742, 1864, 1876, 1883, 658, 659, - 660, 661, 662, 663, 1877, 2193, 2596, 1743, 2214, 1742, - 2596, 1865, 2596, 1743, 2596, 2596, 1884, 1878, 1885, 2596, - 2596, 2596, 1743, 2596, 2596, 2215, 1883, 2596, 2596, 1869, - 1609, 1463, 1463, 1872, 1872, 1741, 2596, 1872, 2596, 1872, - 1872, 1872, 2596, 1612, 1743, 1884, 1878, 1885, 699, 700, - 701, 702, 703, 704, 2215, 2216, 1742, 378, 379, 380, - 381, 382, 383, 699, 700, 701, 702, 703, 704, 2596, - 699, 700, 701, 702, 703, 704, 2596, 2596, 2596, 2217, - - 2596, 1879, 2596, 2596, 2216, 1742, 2596, 2094, 2094, 2094, - 2596, 2596, 2596, 2596, 2596, 1888, 2223, 2596, 2596, 2596, - 2596, 2095, 2596, 1890, 2596, 2596, 2596, 2596, 2217, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 2596, 2596, - 1743, 1609, 1463, 1463, 1888, 2223, 1741, 1891, 2225, 2099, - 2099, 2099, 1890, 1892, 1612, 1645, 906, 906, 906, 906, - 906, 906, 906, 906, 1646, 2228, 1893, 1742, 745, 746, - 747, 748, 749, 750, 501, 2229, 1891, 2225, 2596, 2596, - 2596, 2596, 1892, 2596, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 2596, 2228, 1893, 1742, 2096, 378, 379, - - 380, 381, 382, 383, 2229, 378, 379, 380, 381, 382, - 383, 1898, 378, 379, 380, 381, 382, 383, 1690, 2596, - 1609, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 2596, - 1694, 1743, 1609, 1463, 1463, 1899, 2230, 1741, 2596, 2100, - 1898, 2596, 2596, 2596, 2596, 1612, 2596, 1690, 508, 509, - 514, 511, 512, 513, 2596, 2596, 2596, 2596, 1742, 1694, - 2231, 2232, 2596, 2596, 1899, 2230, 378, 379, 380, 381, - 382, 383, 2596, 2104, 2104, 2104, 1900, 2233, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 1742, 1656, 2231, - 2232, 1901, 1655, 906, 906, 906, 906, 906, 906, 906, - - 906, 2596, 2596, 2596, 2596, 1900, 2233, 2596, 2596, 2596, - 2596, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, - 1901, 2596, 1743, 1609, 1463, 1463, 2596, 2596, 1741, 378, - 379, 380, 381, 382, 383, 1908, 1612, 2236, 2596, 2596, - 2596, 1909, 378, 379, 380, 381, 382, 383, 2596, 1742, - 1918, 465, 465, 465, 465, 465, 465, 465, 465, 2596, - 2596, 2596, 2596, 2105, 1908, 2596, 2236, 2596, 2596, 2596, - 1909, 2596, 378, 379, 380, 381, 382, 383, 1742, 2596, - 2220, 2220, 2220, 2596, 2596, 2596, 2596, 2596, 1958, 378, - 379, 380, 381, 382, 383, 1914, 378, 379, 380, 381, - - 382, 383, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, - 1611, 2596, 2596, 1743, 1609, 1463, 1463, 1958, 2596, 1741, - 2596, 2226, 2226, 2226, 1914, 1919, 2596, 1612, 1677, 906, - 906, 906, 906, 906, 906, 906, 906, 2596, 2596, 2596, - 1742, 472, 473, 474, 475, 476, 477, 378, 379, 380, - 381, 382, 383, 2596, 1919, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 2596, 2185, 2185, 2185, 2596, 1742, - 2221, 378, 379, 380, 381, 382, 383, 1707, 906, 906, - 906, 906, 906, 906, 906, 906, 2596, 2237, 2186, 2596, - 2596, 2596, 1952, 1872, 1872, 1872, 1872, 1872, 1872, 1872, - - 1872, 1872, 2596, 2238, 1743, 1609, 1463, 1463, 2596, 2596, - 1741, 2227, 2234, 2244, 1959, 2235, 2237, 2186, 1612, 2245, - 2596, 1952, 2596, 2596, 2596, 378, 379, 380, 381, 382, - 383, 1742, 2238, 2596, 2596, 2596, 2596, 2596, 501, 2246, - 2247, 2234, 2244, 1959, 2235, 2596, 2249, 2596, 2245, 378, - 379, 380, 381, 382, 383, 2187, 501, 2018, 2018, 2018, - 1742, 472, 473, 474, 475, 476, 477, 501, 2246, 2247, - 2253, 2254, 1518, 1961, 1960, 2249, 1957, 378, 379, 380, - 381, 382, 383, 501, 1872, 1872, 1872, 1872, 1872, 1872, - 1872, 1872, 1872, 2596, 2596, 1743, 1609, 1463, 1463, 2253, - - 2254, 1741, 1961, 2596, 2596, 1957, 2596, 2596, 2255, 1612, - 2596, 2239, 508, 509, 514, 511, 512, 513, 501, 2256, - 2257, 2240, 1742, 378, 379, 380, 381, 382, 383, 501, - 508, 509, 514, 511, 512, 513, 501, 2255, 2596, 1962, - 2239, 508, 509, 514, 511, 512, 513, 2019, 2256, 2257, - 2240, 1742, 2121, 2121, 2121, 2259, 2268, 508, 509, 514, - 511, 512, 513, 2596, 2596, 2596, 2596, 1678, 1962, 1972, - 2269, 2276, 2277, 1973, 2596, 1873, 1873, 1873, 1873, 1873, - 1873, 1873, 1873, 1873, 2259, 2268, 1743, 2596, 2596, 2177, - 2177, 2177, 508, 509, 514, 511, 512, 513, 1972, 2269, - - 2276, 2277, 1973, 508, 509, 514, 511, 512, 513, 2178, - 508, 509, 514, 511, 512, 513, 658, 659, 660, 661, - 662, 663, 2596, 2031, 2031, 2031, 658, 659, 660, 661, - 662, 663, 1609, 1463, 1463, 2596, 2596, 1741, 1609, 1463, - 1463, 2596, 2122, 1741, 2596, 1612, 2596, 1977, 1868, 1868, - 2596, 1612, 1978, 2032, 2278, 1974, 2280, 2281, 1742, 2596, - 1979, 2282, 2596, 2287, 1742, 1875, 1868, 1868, 2596, 2288, - 1876, 2596, 2596, 1980, 2289, 1609, 1463, 1463, 1877, 2260, - 1741, 2596, 2032, 2278, 1974, 2280, 2281, 1742, 1612, 2596, - 2282, 1878, 2287, 1742, 2291, 1984, 1463, 1463, 2288, 2596, - - 1876, 1742, 1980, 2289, 2596, 1875, 1868, 1868, 1877, 2596, - 1876, 2596, 2596, 2033, 1986, 1463, 1463, 1609, 1877, 1978, - 1878, 1878, 1743, 2291, 2160, 2160, 2160, 1979, 1743, 2292, - 1742, 1878, 2293, 1984, 1463, 1463, 2596, 1981, 1876, 1708, - 1980, 2261, 2261, 2261, 2596, 2596, 1988, 1991, 2596, 2294, - 1878, 1984, 1463, 1463, 1982, 1879, 1876, 2262, 2292, 1878, - 1878, 2293, 2596, 2596, 1877, 1743, 1609, 1463, 1463, 1980, - 2296, 1741, 1994, 2077, 2077, 2077, 1991, 1878, 2294, 1612, - 2596, 2596, 2596, 2596, 2596, 1985, 2596, 2078, 1878, 1984, - 1463, 1463, 1742, 2299, 1876, 1879, 2596, 2302, 2305, 2296, - - 2307, 1994, 1877, 2596, 1987, 2596, 1878, 2596, 658, 659, - 660, 661, 662, 663, 2161, 1878, 2596, 2596, 2284, 2284, - 2284, 1742, 2299, 1985, 2596, 1993, 2302, 2305, 1998, 2307, - 1990, 2263, 1989, 699, 700, 701, 702, 703, 704, 2596, - 2596, 1985, 2596, 2596, 1878, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1993, 1995, 1743, 1998, 2596, 2596, - 2596, 1989, 2596, 2079, 2596, 2596, 2596, 2596, 699, 700, - 701, 702, 703, 704, 2596, 2596, 2596, 2596, 2596, 1985, - 2596, 2596, 2596, 2596, 1995, 745, 746, 747, 748, 749, - 750, 2596, 2596, 2596, 658, 659, 660, 661, 662, 663, - - 2000, 699, 700, 701, 702, 703, 704, 2002, 2285, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2001, 2596, 2596, 2596, - 1794, 906, 906, 906, 906, 906, 906, 906, 906, 2000, - 2596, 2308, 2596, 2596, 2596, 2596, 2002, 2218, 2218, 2218, - 2596, 2596, 2596, 2596, 2596, 2001, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 2007, 2008, - 2308, 2596, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2007, 2008, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 378, 379, - - 380, 381, 382, 383, 2596, 378, 379, 380, 381, 382, - 383, 2062, 2062, 2062, 2009, 2596, 2596, 2596, 2596, 2596, - 378, 379, 380, 381, 382, 383, 2017, 2219, 2065, 2016, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, - 2596, 2063, 501, 2009, 699, 700, 701, 702, 703, 704, - 2596, 2596, 2189, 2189, 2189, 2017, 501, 2065, 2016, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2068, 2067, - 2063, 2309, 2190, 2060, 2220, 2220, 2220, 378, 379, 380, - 381, 382, 383, 378, 379, 380, 381, 382, 383, 472, - 473, 474, 475, 476, 477, 2596, 2596, 2068, 2067, 501, - - 2309, 2064, 2060, 378, 379, 380, 381, 382, 383, 2066, - 2081, 2310, 2069, 2004, 2004, 2004, 508, 509, 514, 511, - 512, 513, 2596, 2596, 378, 379, 380, 381, 382, 383, - 508, 509, 514, 511, 512, 513, 2082, 2596, 2066, 2081, - 2310, 2069, 2271, 2005, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2311, 2596, 2596, 658, 659, 660, 661, - 662, 663, 2596, 2312, 2221, 2082, 472, 473, 474, 475, - 476, 477, 2005, 508, 509, 514, 511, 512, 513, 2596, - 2596, 2313, 2311, 658, 659, 660, 661, 662, 663, 1609, - 1463, 1463, 2312, 2314, 1741, 1986, 1463, 1463, 2596, 2596, - - 1978, 2596, 1612, 2006, 1977, 1868, 1868, 2596, 1979, 1978, - 2313, 1986, 1463, 1463, 2596, 1742, 1978, 1979, 2596, 2315, - 2316, 1980, 2314, 2083, 1979, 2596, 2596, 1986, 1463, 1463, - 1980, 2596, 1978, 2317, 1986, 1463, 1463, 1980, 2596, 1978, - 2084, 1986, 1463, 1463, 1742, 2318, 1978, 1979, 2315, 2316, - 1980, 2319, 2083, 1980, 1979, 2300, 2300, 2300, 2596, 1980, - 1980, 2320, 2317, 2011, 2011, 2011, 1980, 1980, 2115, 2115, - 2115, 1609, 1463, 1463, 2318, 2596, 1741, 2085, 2596, 1743, - 2319, 2596, 1980, 2596, 1612, 1987, 1984, 1463, 1463, 1980, - 2320, 1876, 2596, 2012, 1981, 2596, 1980, 1742, 2116, 1877, - - 2321, 1987, 1984, 1463, 1463, 2596, 2085, 1876, 1986, 1463, - 1463, 2596, 1878, 1978, 2596, 1877, 2596, 1987, 2596, 2596, - 2086, 1979, 2012, 2596, 1987, 2596, 1742, 2116, 1878, 2321, - 2596, 1987, 2596, 2322, 1980, 2596, 2090, 2326, 1986, 1463, - 1463, 1878, 2596, 1978, 2596, 2301, 2327, 1875, 1868, 1868, - 1867, 1979, 1876, 2013, 1984, 1463, 1463, 1878, 2117, 1876, - 1988, 1743, 2322, 1980, 1980, 2090, 2326, 1877, 2329, 1984, - 1463, 1463, 2596, 1878, 1876, 2327, 1985, 2089, 2596, 2334, - 1878, 2087, 1877, 2091, 658, 659, 660, 661, 662, 663, - 2092, 2596, 1985, 1980, 2337, 1878, 2338, 2329, 1987, 2596, - - 2596, 2596, 1878, 2596, 2596, 2596, 2089, 2097, 2334, 1878, - 2596, 2596, 2091, 2596, 2596, 2596, 2596, 2088, 2596, 2092, - 2596, 2596, 2596, 2337, 1878, 2338, 2596, 2596, 1987, 2596, - 699, 700, 701, 702, 703, 704, 2097, 1879, 699, 700, - 701, 702, 703, 704, 1985, 2596, 2596, 2596, 1875, 2272, - 2272, 2272, 501, 745, 746, 747, 748, 749, 750, 1985, - 2596, 2596, 2596, 2596, 2596, 2273, 2031, 2031, 2031, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 658, 659, 660, 661, 662, 663, 378, 379, 380, - 381, 382, 383, 2103, 2343, 2344, 2032, 2596, 2339, 2339, - - 2339, 378, 379, 380, 381, 382, 383, 2596, 378, 379, - 380, 381, 382, 383, 2110, 501, 2596, 2062, 2062, 2062, - 2111, 2596, 2103, 2343, 2344, 2032, 508, 509, 514, 511, - 512, 513, 2596, 378, 379, 380, 381, 382, 383, 2274, - 2596, 2596, 2596, 2110, 2596, 2596, 2596, 2063, 2347, 2111, - 378, 379, 380, 381, 382, 383, 2033, 2051, 2051, 2051, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 2165, 2348, 2349, 2350, 2063, 2347, 2596, 2358, - 2159, 2596, 2141, 2361, 2363, 2142, 2364, 2164, 2340, 508, - 509, 514, 511, 512, 513, 2596, 2094, 2094, 2094, 2143, - - 2596, 2165, 2348, 2349, 2350, 2596, 2596, 2064, 2358, 2159, - 2095, 2141, 2361, 2363, 2142, 2364, 2164, 2365, 2596, 472, - 473, 474, 475, 476, 477, 501, 2366, 2596, 2143, 2177, - 2177, 2177, 378, 379, 380, 381, 382, 383, 472, 473, - 474, 475, 476, 477, 2596, 2367, 2365, 2052, 2148, 2178, - 2368, 2369, 2370, 2166, 2149, 2171, 2171, 2171, 2150, 2151, - 2596, 2596, 2596, 2152, 2153, 2154, 2371, 2155, 699, 700, - 701, 702, 703, 704, 2367, 2596, 2374, 2148, 2172, 2368, - 2369, 2370, 2166, 2149, 2372, 2373, 2096, 2150, 2151, 2226, - 2226, 2226, 2152, 2153, 2154, 2371, 2155, 2173, 2596, 508, - - 509, 514, 511, 512, 513, 2374, 2596, 2172, 2375, 2596, - 1609, 1463, 1463, 2372, 2373, 1741, 2596, 658, 659, 2179, - 661, 662, 663, 1612, 2596, 2596, 2173, 1977, 1868, 1868, - 2596, 2303, 1978, 1986, 1463, 1463, 1742, 2375, 1978, 2596, - 2084, 2596, 1986, 1463, 1463, 2174, 1979, 1978, 2596, 1984, - 1463, 1463, 2596, 1980, 1876, 1979, 2180, 2376, 2596, 1980, - 2303, 2596, 1877, 2596, 2182, 1742, 2596, 2377, 1980, 2099, - 2099, 2099, 2104, 2104, 2104, 1878, 1986, 1463, 1463, 2227, - 2378, 1978, 1980, 2596, 1646, 2180, 2376, 1656, 1980, 1979, - 1984, 1463, 1463, 2182, 2596, 1876, 2377, 1980, 2379, 2596, - - 1743, 2183, 1980, 1877, 1878, 2189, 2189, 2189, 2380, 2378, - 658, 659, 660, 661, 662, 663, 1878, 1981, 2596, 2596, - 2596, 1977, 2596, 1987, 2181, 2190, 2596, 2379, 1984, 2596, - 2183, 1980, 1987, 2596, 2596, 2596, 2596, 2380, 2596, 1985, - 2596, 2596, 2596, 2385, 2386, 1878, 2596, 699, 700, 701, - 702, 703, 704, 2181, 2596, 1986, 2204, 2204, 2204, 2100, - 2196, 2266, 2105, 2121, 2121, 2121, 1987, 2160, 2160, 2160, - 2596, 1795, 2385, 2386, 2596, 2115, 2115, 2115, 1678, 2596, - 1985, 2596, 1708, 2201, 2596, 2596, 2596, 2202, 2387, 2196, - 2250, 2596, 2596, 745, 746, 2191, 748, 749, 750, 658, - - 659, 660, 661, 662, 663, 2116, 378, 379, 380, 381, - 382, 383, 2241, 2251, 2596, 2388, 2202, 2387, 2391, 2250, - 2242, 378, 379, 380, 381, 382, 383, 2243, 378, 379, - 380, 381, 382, 383, 2116, 472, 473, 474, 475, 476, - 477, 2241, 2251, 501, 2388, 2596, 2205, 2391, 2596, 2242, - 2392, 2393, 2252, 2122, 2596, 2596, 2243, 2161, 2596, 472, - 473, 474, 475, 476, 477, 2117, 472, 473, 474, 475, - 476, 477, 378, 379, 380, 381, 382, 383, 2596, 2392, - 2393, 2252, 2171, 2171, 2171, 2264, 674, 674, 674, 674, - 674, 674, 674, 674, 2204, 2204, 2204, 1986, 1463, 1463, - - 2596, 2267, 1978, 2396, 2397, 2172, 2185, 2185, 2185, 1795, - 1979, 2596, 2596, 2596, 2596, 2596, 2400, 508, 509, 514, - 511, 512, 513, 1980, 2173, 1984, 1463, 1463, 2324, 2186, - 1876, 2265, 2396, 2397, 2172, 2596, 2596, 2596, 1877, 699, - 700, 701, 702, 703, 704, 2400, 2596, 2596, 2596, 2401, - 2402, 1878, 1980, 2173, 2177, 2177, 2177, 2324, 2186, 2279, - 2265, 2275, 763, 763, 763, 763, 763, 763, 763, 763, - 2323, 2596, 2174, 2596, 2178, 2596, 2596, 2283, 2401, 2402, - 1878, 2404, 2596, 501, 2205, 2410, 2596, 1987, 2279, 472, - 473, 474, 475, 476, 477, 2596, 2187, 2596, 2596, 2323, - - 378, 379, 380, 381, 382, 383, 2283, 2596, 2596, 2596, - 2404, 2325, 2332, 2411, 2410, 1985, 472, 473, 474, 475, - 476, 477, 2596, 378, 379, 380, 381, 382, 383, 2261, - 2261, 2261, 2596, 2596, 378, 379, 380, 381, 382, 383, - 2325, 2332, 2411, 2596, 2260, 2262, 2177, 1035, 1035, 1035, - 1035, 1035, 1035, 1035, 1035, 2333, 2596, 508, 509, 514, - 511, 512, 513, 1986, 1463, 1463, 2596, 2596, 1978, 658, - 659, 660, 661, 662, 663, 2596, 1979, 2189, 2189, 2189, - 2272, 2272, 2272, 2596, 2333, 2596, 2596, 2596, 2596, 1980, - 2341, 2341, 2341, 2284, 2284, 2284, 2273, 2190, 2189, 1094, - - 1094, 1094, 1094, 1094, 1094, 1094, 1094, 2596, 2596, 2596, - 2596, 2414, 699, 700, 701, 702, 703, 704, 1980, 2263, - 2351, 2351, 2351, 2354, 2354, 2354, 2359, 2359, 2359, 2300, - 2300, 2300, 2383, 2345, 2381, 2381, 2381, 2355, 2596, 2389, - 2414, 2596, 2339, 2339, 2339, 2341, 2341, 2341, 2596, 2596, - 2415, 2596, 2416, 1987, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2383, 2345, 501, 2390, 2417, 2596, 2271, 2389, 2596, - 2274, 2596, 2596, 378, 379, 380, 381, 382, 383, 2415, - 2342, 2416, 2418, 2285, 472, 473, 474, 475, 476, 477, - 2596, 2419, 2384, 2390, 2417, 378, 379, 380, 381, 382, - - 383, 658, 659, 660, 661, 662, 663, 2398, 2398, 2398, - 2352, 2418, 2596, 2356, 2596, 2596, 2360, 2596, 2596, 2301, - 2419, 2384, 2596, 2596, 2382, 2596, 699, 700, 701, 702, - 703, 704, 2340, 2420, 2421, 2342, 2422, 508, 509, 514, - 511, 512, 513, 378, 379, 380, 381, 382, 383, 2351, - 2351, 2351, 2354, 2354, 2354, 2423, 2405, 2405, 2405, 2359, - 2359, 2359, 2420, 2421, 2596, 2422, 2355, 2424, 2596, 2596, - 2425, 2596, 2426, 2427, 2428, 2429, 2381, 2381, 2381, 2433, - 2596, 2434, 501, 2435, 2423, 2436, 2437, 2431, 2438, 2439, - 2440, 2445, 2446, 2406, 2447, 2448, 2424, 2399, 2407, 2425, - - 2412, 2426, 2427, 2428, 2429, 2398, 2398, 2398, 2433, 2432, - 2434, 2450, 2435, 2596, 2436, 2437, 2431, 2438, 2439, 2440, - 2445, 2446, 2406, 2447, 2448, 2596, 2596, 2407, 2596, 2412, - 658, 659, 660, 661, 662, 663, 2451, 2596, 2432, 2352, - 2450, 2596, 2356, 2405, 2405, 2405, 2408, 2452, 2453, 2360, - 472, 473, 474, 475, 476, 477, 508, 509, 514, 511, - 512, 513, 2454, 2455, 2456, 2451, 2382, 699, 700, 701, - 702, 703, 704, 2457, 2458, 2459, 2452, 2453, 2460, 2461, - 2406, 2462, 2463, 2464, 2465, 2407, 2466, 501, 2467, 2468, - 2469, 2454, 2455, 2456, 2470, 2399, 2471, 2472, 2486, 2486, - - 2486, 2596, 2457, 2458, 2459, 2473, 2474, 2460, 2461, 2406, - 2462, 2463, 2464, 2465, 2407, 2466, 2478, 2467, 2468, 2469, - 2479, 2482, 2483, 2470, 2484, 2471, 2472, 472, 473, 474, - 475, 476, 477, 2408, 2473, 2474, 2596, 2596, 2485, 2488, - 2489, 2490, 2491, 2492, 2493, 2478, 2494, 2495, 2496, 2479, - 2482, 2483, 2497, 2484, 472, 473, 474, 475, 476, 477, - 2498, 508, 509, 514, 511, 512, 513, 2485, 2488, 2489, - 2490, 2491, 2492, 2493, 2499, 2494, 2495, 2496, 2500, 2502, - 2503, 2497, 2504, 2505, 2506, 2507, 2510, 2512, 2487, 2498, - 2508, 2508, 2508, 2486, 2486, 2486, 2513, 2514, 2515, 2516, - - 2518, 2519, 2520, 2499, 2521, 2522, 2523, 2500, 2502, 2503, - 2524, 2504, 2505, 2506, 2507, 2510, 2512, 2486, 2486, 2486, - 2508, 2508, 2508, 2527, 2528, 2513, 2514, 2515, 2516, 2518, - 2519, 2520, 2529, 2521, 2522, 2523, 2530, 2531, 2532, 2524, - 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, - 2543, 2596, 2527, 2528, 2596, 2544, 2545, 2579, 2579, 2579, - 2550, 2529, 2551, 2552, 2553, 2530, 2531, 2532, 2554, 2533, - 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, - 2509, 2596, 2555, 2487, 2544, 2545, 2546, 2546, 2546, 2550, - 2556, 2551, 2552, 2553, 2547, 2562, 2565, 2554, 2177, 2177, - - 2177, 2189, 2189, 2189, 2546, 2546, 2546, 2487, 2566, 2567, - 2509, 2555, 2547, 2568, 2570, 2571, 2572, 2573, 2178, 2556, - 2574, 2190, 2575, 2576, 2562, 2565, 2577, 2578, 2581, 2582, - 2583, 2584, 2579, 2579, 2579, 2586, 2587, 2566, 2567, 2579, - 2579, 2579, 2568, 2570, 2571, 2572, 2573, 2580, 2588, 2574, - 2589, 2575, 2576, 2590, 2591, 2577, 2578, 2581, 2582, 2583, - 2584, 2486, 2486, 2486, 2586, 2587, 2592, 2596, 2593, 2594, - 2595, 2579, 2579, 2579, 2596, 2596, 2548, 2588, 2549, 2589, - 2596, 2596, 2590, 2591, 2596, 2596, 2596, 2596, 2260, 2596, - 2596, 2271, 2596, 2596, 2548, 2592, 2549, 2593, 2594, 2595, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2580, 2596, 2596, 2596, 2596, 2596, 2596, 2580, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2487, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2580, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - - 187, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 215, 215, 215, 215, 215, 215, - 215, 215, 215, 215, 215, 215, 215, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 237, 237, 237, 237, - 237, 237, 237, 237, 237, 237, 237, 237, 237, 240, - 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - 240, 240, 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 338, 338, 338, 338, 338, 338, - 338, 338, 338, 338, 338, 338, 338, 347, 347, 347, - 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, - 362, 362, 362, 370, 370, 2596, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 377, 377, 384, 384, - 384, 455, 455, 2596, 2596, 2596, 2596, 2596, 2596, 455, - - 471, 471, 499, 499, 2596, 499, 499, 2596, 499, 499, - 499, 537, 537, 537, 544, 544, 551, 551, 551, 563, - 563, 2596, 2596, 2596, 2596, 2596, 2596, 563, 579, 2596, - 2596, 579, 600, 2596, 2596, 600, 623, 623, 623, 623, - 623, 623, 2596, 623, 623, 623, 623, 2596, 623, 629, - 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, - 629, 629, 630, 630, 630, 630, 630, 630, 2596, 630, - 630, 630, 630, 2596, 630, 636, 636, 636, 636, 636, - 636, 636, 636, 636, 636, 636, 636, 636, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - - 642, 643, 643, 643, 643, 643, 643, 643, 643, 643, - 643, 643, 643, 645, 645, 645, 645, 645, 645, 645, - 645, 645, 645, 645, 645, 650, 650, 2596, 650, 650, - 650, 650, 650, 650, 650, 650, 650, 650, 657, 657, - 683, 683, 2596, 683, 683, 683, 683, 683, 683, 683, - 683, 683, 683, 691, 691, 2596, 691, 691, 691, 691, - 691, 691, 691, 691, 691, 691, 698, 698, 717, 717, - 737, 737, 2596, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 744, 744, 771, 771, 2596, 771, 771, - 771, 771, 771, 771, 771, 771, 771, 771, 778, 778, - - 2596, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 362, 362, 362, 369, 369, 2596, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 370, 370, 2596, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 377, 377, 384, 384, 384, 455, 455, 2596, 2596, 2596, - 2596, 2596, 2596, 455, 471, 471, 499, 499, 2596, 499, - 499, 2596, 499, 499, 499, 537, 537, 537, 544, 544, - 551, 551, 551, 563, 563, 2596, 2596, 2596, 2596, 2596, - 2596, 563, 579, 2596, 2596, 579, 600, 2596, 2596, 600, - 623, 623, 623, 623, 623, 623, 2596, 623, 623, 623, - - 623, 2596, 623, 999, 999, 2596, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 630, 630, 630, 630, - 630, 630, 2596, 630, 630, 630, 630, 2596, 630, 1004, - 1004, 2596, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, - 1004, 1004, 1009, 1009, 2596, 1009, 1009, 1009, 1009, 1009, - 1009, 1009, 1009, 1009, 1009, 643, 643, 643, 643, 643, - 643, 643, 643, 643, 643, 643, 643, 645, 645, 645, - 645, 645, 645, 645, 645, 645, 645, 645, 645, 649, - 649, 2596, 649, 649, 649, 649, 649, 649, 649, 649, - 649, 649, 650, 650, 2596, 650, 650, 650, 650, 650, - - 650, 650, 650, 650, 650, 657, 657, 683, 683, 2596, - 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, - 690, 690, 2596, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 691, 691, 2596, 691, 691, 691, 691, - 691, 691, 691, 691, 691, 691, 698, 698, 717, 717, - 736, 736, 2596, 736, 736, 736, 736, 736, 736, 736, - 736, 736, 736, 737, 737, 2596, 737, 737, 737, 737, - 737, 737, 737, 737, 737, 737, 744, 744, 771, 771, - 2596, 771, 771, 771, 771, 771, 771, 771, 771, 771, - 771, 778, 778, 2596, 778, 778, 778, 778, 778, 778, - - 778, 778, 778, 778, 369, 369, 2596, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 1118, 1118, 1118, - 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, - 377, 377, 471, 471, 499, 499, 2596, 2596, 2596, 499, - 544, 544, 579, 2596, 2596, 579, 600, 2596, 2596, 600, - 999, 999, 2596, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 1004, 1004, 2596, 1004, 1004, 1004, 1004, - 1004, 1004, 1004, 1004, 1004, 1004, 1009, 1009, 2596, 1009, - 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 649, - 649, 2596, 649, 649, 649, 649, 649, 649, 649, 649, - - 649, 649, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, - 1264, 1264, 1264, 1264, 1264, 657, 657, 1278, 1278, 1278, - 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, - 690, 690, 2596, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 1286, 1286, 1286, 1286, 1286, 1286, 1286, - 1286, 1286, 1286, 1286, 1286, 1286, 698, 698, 717, 717, - 736, 736, 2596, 736, 736, 736, 736, 736, 736, 736, - 736, 736, 736, 1298, 1298, 1298, 1298, 1298, 1298, 1298, - 1298, 1298, 1298, 1298, 1298, 1298, 744, 744, 1312, 1312, - 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, - - 1312, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, - 1318, 1318, 1318, 1318, 362, 362, 362, 370, 370, 2596, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 369, 369, 2596, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 384, 384, 384, 1118, 1118, 2596, 1118, - 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 377, - 377, 455, 455, 2596, 2596, 2596, 2596, 2596, 2596, 455, - 471, 471, 499, 499, 2596, 2596, 2596, 499, 499, 537, - 537, 537, 551, 551, 551, 544, 544, 563, 563, 2596, - 2596, 2596, 2596, 2596, 2596, 563, 579, 2596, 2596, 579, - - 600, 2596, 2596, 600, 1442, 1442, 1442, 1442, 1442, 1442, - 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1447, 1447, 1447, - 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, - 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, - 1452, 1452, 1452, 650, 650, 2596, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 650, 649, 649, 2596, 649, - 649, 649, 649, 649, 649, 649, 649, 649, 649, 1264, - 1264, 2596, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, - 1264, 1264, 657, 657, 1278, 1278, 2596, 1278, 1278, 1278, - 1278, 1278, 1278, 1278, 1278, 1278, 1278, 691, 691, 2596, - + 729, 729, 729, 730, 730, 730, 730, 730, 730, 730, + 731, 732, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 1075, 718, 718, 718, 718, 718, 718, 718, 718, + 718, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, + 718, 718, 718, 718, 718, 718, 718, 718, 718, 1011, + + 1075, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, + 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 735, + 735, 735, 719, 720, 721, 722, 723, 724, 1078, 1078, + 1078, 1078, 1078, 1078, 1078, 1078, 1078, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 1081, 1081, 1081, 1081, + 1081, 1081, 1081, 1081, 1081, 1082, 1083, 1083, 1083, 1083, + 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1084, + 1084, 1084, 1084, 1085, 1085, 1085, 1085, 1085, 1085, 1085, + 1086, 1087, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 745, 745, 745, 745, 745, 745, 745, 745, 745, + + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 736, 737, + 737, 1567, 1011, 737, 737, 1263, 1259, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 1568, 737, 737, 737, + 737, 737, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 1089, 764, 764, 764, 764, 764, 764, 764, 764, + 1092, 1092, 1092, 1225, 1100, 1568, 1100, 1134, 737, 1101, + 737, 765, 765, 765, 765, 765, 765, 765, 765, 765, + 766, 766, 766, 766, 766, 766, 766, 1090, 768, 912, + 912, 912, 912, 912, 912, 912, 912, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 739, 740, 741, + + 742, 743, 744, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 757, 1102, 1099, 473, 474, 475, 476, 477, + 478, 1105, 1105, 1103, 759, 1105, 1106, 1105, 1105, 1105, + 746, 747, 748, 749, 750, 751, 1132, 1128, 358, 1093, + 777, 783, 1102, 745, 745, 745, 745, 745, 745, 745, + 745, 745, 1103, 759, 735, 1104, 1104, 1104, 1104, 1104, + 1104, 1104, 1104, 770, 746, 747, 748, 749, 750, 751, + 746, 747, 748, 749, 750, 751, 1104, 1104, 1104, 1104, + 1104, 1104, 1104, 1104, 1104, 746, 747, 748, 749, 750, + 751, 745, 745, 745, 745, 745, 745, 745, 745, 745, + + 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, + 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1107, 1107, + 1107, 1107, 1107, 1107, 1107, 1107, 1107, 770, 770, 770, + 1108, 1108, 1108, 777, 777, 777, 1112, 1112, 1112, 361, + 361, 361, 361, 361, 361, 361, 361, 361, 1119, 1119, + 1119, 1119, 1119, 1119, 1119, 1119, 1119, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 776, 756, 1120, + 1091, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + + 1121, 1121, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 1080, 1054, 682, 687, 1024, 771, 1023, 1022, 1109, + 1021, 1018, 778, 1017, 1016, 1113, 1122, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1013, 1570, 1123, 1012, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 913, 913, 1011, 1008, 913, 1570, 913, 913, 913, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 1125, 1125, + + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 1126, 1126, 1126, 1126, 1126, 1126, + 1126, 1126, 1126, 1126, 1126, 1228, 2786, 1126, 824, 1126, + 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, + 1126, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, + 1130, 815, 815, 397, 1228, 1139, 1223, 1223, 1007, 2786, + 1223, 1006, 1223, 1223, 1223, 399, 1571, 2786, 928, 928, + 1005, 1004, 928, 2786, 928, 928, 928, 1572, 1000, 1140, + 598, 757, 990, 1503, 2786, 989, 473, 474, 475, 476, + + 477, 478, 1141, 1095, 399, 1571, 988, 2786, 987, 377, + 378, 379, 380, 381, 382, 986, 1572, 2786, 1140, 1142, + 473, 474, 475, 476, 477, 478, 919, 2786, 395, 814, + 787, 1141, 1095, 1143, 783, 1145, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1142, 1131, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 1143, 2786, 1145, 780, 776, 377, 378, 379, + 380, 381, 382, 773, 756, 752, 706, 2786, 688, 1144, + 377, 378, 379, 380, 381, 382, 2786, 687, 685, 1573, + 377, 378, 379, 380, 381, 382, 1146, 1274, 1274, 1274, + + 377, 378, 379, 380, 381, 382, 1147, 2786, 1144, 456, + 456, 456, 456, 456, 456, 456, 456, 456, 1573, 667, + 666, 2786, 1276, 1276, 1276, 1146, 648, 1574, 1150, 646, + 2786, 624, 623, 620, 619, 1147, 377, 378, 379, 380, + 381, 382, 1148, 1278, 1278, 1278, 397, 1149, 1511, 1152, + 377, 378, 379, 380, 381, 382, 1574, 1150, 818, 377, + 378, 379, 380, 381, 382, 2786, 616, 615, 1284, 1035, + 1035, 1148, 2786, 1151, 614, 613, 1149, 600, 1152, 599, + 377, 378, 379, 380, 381, 382, 1275, 818, 596, 1619, + 2786, 1153, 595, 592, 377, 378, 379, 380, 381, 382, + + 1156, 2786, 1151, 377, 378, 379, 380, 381, 382, 1246, + 1246, 1277, 591, 1246, 2786, 1246, 1246, 1246, 1619, 481, + 1153, 2786, 1154, 396, 1157, 395, 1155, 391, 2786, 1156, + 2786, 1159, 1279, 1620, 245, 245, 243, 2786, 377, 378, + 379, 380, 381, 382, 1622, 377, 378, 379, 380, 381, + 382, 1154, 1158, 1157, 2786, 1155, 1160, 1285, 243, 2786, + 1159, 2786, 1620, 377, 378, 379, 380, 381, 382, 2786, + 2786, 1624, 2786, 1622, 377, 378, 379, 380, 381, 382, + 1161, 1158, 2786, 2786, 2786, 1160, 2786, 377, 378, 379, + 380, 381, 382, 1162, 377, 378, 379, 380, 381, 382, + + 1624, 2786, 2786, 377, 378, 379, 380, 381, 382, 1161, + 377, 378, 379, 380, 381, 382, 2786, 2786, 1296, 1049, + 1049, 2786, 1162, 1164, 2786, 2786, 2786, 377, 378, 379, + 380, 381, 382, 1249, 1249, 1625, 1163, 1249, 2786, 1249, + 1249, 1249, 1626, 1628, 2786, 377, 378, 379, 380, 381, + 382, 2786, 1164, 1165, 1166, 377, 378, 379, 380, 381, + 382, 2786, 2786, 2786, 1625, 1163, 1168, 1167, 2786, 2786, + 2786, 1626, 1628, 2786, 2786, 377, 378, 379, 380, 381, + 382, 1170, 1165, 1166, 2786, 2786, 2786, 2786, 2786, 377, + 378, 379, 380, 381, 382, 1168, 1167, 2786, 377, 378, + + 379, 380, 381, 382, 2786, 2786, 1169, 1297, 2786, 1171, + 1170, 377, 378, 379, 380, 381, 382, 377, 378, 379, + 380, 381, 382, 2786, 377, 378, 379, 380, 381, 382, + 2786, 2786, 2786, 1254, 1254, 1169, 2786, 1254, 1171, 1254, + 1254, 1254, 377, 378, 379, 380, 381, 382, 2786, 1630, + 1174, 2786, 1172, 1631, 1632, 1173, 1633, 377, 378, 379, + 380, 381, 382, 1175, 2786, 1638, 2786, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 2786, 2786, 1630, 1174, + 2786, 1172, 1631, 1632, 1173, 1633, 1304, 1065, 1065, 2786, + 2786, 2786, 1175, 1176, 1638, 2786, 377, 378, 379, 380, + + 381, 382, 1177, 377, 378, 379, 380, 381, 382, 377, + 378, 379, 380, 381, 382, 2786, 2786, 1179, 1180, 1317, + 1092, 1092, 1176, 2786, 377, 378, 379, 380, 381, 382, + 1178, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 2786, + 377, 378, 379, 380, 381, 382, 1179, 1180, 2786, 1181, + 377, 378, 379, 380, 381, 382, 2786, 2786, 1639, 1178, + 2786, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 2786, 1305, 1661, 1697, 1181, 2786, + 1182, 1698, 1708, 1184, 2786, 1728, 1183, 1639, 1729, 377, + 378, 379, 380, 381, 382, 2786, 377, 378, 379, 380, + + 381, 382, 2786, 2786, 2786, 1661, 1697, 1186, 1318, 1182, + 1698, 1708, 1184, 2786, 1728, 1183, 1185, 1729, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 1187, 2786, 377, + 378, 379, 380, 381, 382, 2786, 1186, 2786, 1189, 1730, + 1731, 1733, 2786, 1192, 1188, 1185, 2786, 377, 378, 379, + 380, 381, 382, 1190, 1735, 1738, 1187, 377, 378, 379, + 380, 381, 382, 2786, 2786, 2786, 2786, 1189, 1730, 1731, + 1733, 1739, 1192, 1188, 2786, 377, 378, 379, 380, 381, + 382, 2786, 1190, 1735, 1738, 1193, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1226, 1191, + + 1739, 377, 378, 379, 380, 381, 382, 2786, 377, 378, + 379, 380, 381, 382, 1193, 377, 378, 379, 380, 381, + 382, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 1191, 1195, + 2786, 2786, 2786, 1194, 2786, 1330, 1108, 1108, 2786, 377, + 378, 379, 380, 381, 382, 2786, 1196, 377, 378, 379, + 380, 381, 382, 2786, 1200, 1200, 1200, 1199, 1195, 1281, + 1281, 1197, 1194, 1281, 1742, 1281, 1281, 1281, 2786, 473, + 474, 475, 476, 477, 478, 1196, 2786, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 1199, 1743, 1198, 2786, + 1197, 2786, 2786, 1742, 377, 378, 379, 380, 381, 382, + + 377, 378, 379, 380, 381, 382, 1202, 377, 378, 379, + 380, 381, 382, 2786, 2786, 2786, 1743, 2786, 377, 378, + 379, 380, 381, 382, 1331, 2786, 377, 378, 379, 380, + 381, 382, 1744, 1251, 1745, 1202, 1203, 2786, 2786, 2786, + 2786, 377, 378, 1201, 380, 381, 382, 1746, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 2786, 2786, 2786, + 2786, 1744, 1251, 1745, 1204, 1203, 1205, 1206, 1207, 2786, + 546, 547, 548, 549, 550, 551, 1746, 1213, 2786, 546, + 547, 548, 549, 550, 551, 2786, 377, 378, 379, 380, + 381, 382, 2786, 1204, 2786, 1205, 1206, 1207, 2786, 1210, + + 546, 547, 548, 549, 550, 551, 1213, 1211, 1208, 1212, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 1209, + 2786, 377, 378, 379, 380, 381, 382, 2786, 1210, 377, + 378, 379, 380, 381, 382, 1214, 1211, 1208, 1212, 1336, + 1112, 1112, 377, 378, 379, 380, 381, 382, 1209, 2786, + 2786, 377, 378, 379, 380, 381, 382, 2786, 377, 378, + 379, 380, 381, 382, 1214, 377, 378, 379, 380, 381, + 382, 377, 378, 379, 380, 381, 382, 1216, 1215, 2786, + 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 1747, 2786, 377, 378, 379, 380, 381, 382, 2786, + + 1218, 2786, 2786, 2786, 2786, 2786, 1216, 1215, 1217, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1221, 1227, + 1747, 2786, 377, 378, 379, 380, 381, 382, 1337, 1218, + 377, 378, 379, 380, 381, 382, 2786, 1217, 2786, 2786, + 2786, 2786, 1219, 1750, 1775, 1776, 1220, 1221, 1227, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 473, + 474, 475, 476, 477, 478, 377, 378, 379, 380, 381, + 382, 1219, 1750, 1775, 1776, 1220, 377, 378, 379, 380, + 381, 382, 456, 456, 456, 456, 456, 456, 456, 456, + 456, 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, + + 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1224, 1224, + 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1229, 1230, 2786, + 1231, 377, 378, 379, 380, 381, 382, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 2786, 1229, 1230, 1232, 1231, + 945, 945, 945, 945, 945, 945, 945, 945, 1130, 815, + 815, 2786, 1777, 502, 2786, 473, 474, 475, 476, 477, + 478, 473, 474, 475, 476, 477, 478, 1232, 2786, 502, + 473, 474, 475, 476, 477, 478, 1233, 1234, 502, 1045, + + 1045, 1777, 1781, 1045, 502, 1045, 1045, 1045, 2786, 1782, + 2786, 1740, 502, 473, 474, 475, 476, 477, 478, 502, + 2786, 2786, 1237, 1741, 1235, 1233, 1234, 1783, 2786, 1301, + 1301, 1781, 1236, 1301, 502, 1301, 1301, 1301, 1782, 1238, + 1740, 502, 2786, 2786, 2786, 2786, 509, 510, 515, 512, + 513, 514, 1741, 1235, 2786, 1241, 1783, 1131, 2786, 502, + 2786, 1236, 509, 510, 515, 512, 513, 514, 1238, 1239, + 502, 509, 510, 515, 512, 513, 514, 509, 510, 515, + 512, 513, 514, 502, 1241, 509, 510, 515, 512, 513, + 514, 502, 509, 510, 515, 512, 513, 514, 502, 2786, + + 1784, 1244, 1240, 2786, 502, 1243, 2786, 509, 510, 515, + 512, 513, 514, 1785, 509, 510, 515, 512, 513, 514, + 1071, 1071, 1786, 1788, 1071, 1242, 1071, 1071, 1071, 1784, + 1244, 1240, 509, 510, 515, 512, 513, 514, 2786, 2786, + 2786, 1789, 1785, 509, 510, 515, 512, 513, 514, 2786, + 2786, 1786, 1788, 2786, 1242, 2786, 509, 510, 515, 512, + 513, 514, 2786, 2786, 509, 510, 515, 512, 513, 514, + 1789, 509, 510, 515, 512, 513, 514, 509, 510, 515, + 512, 513, 514, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 538, 538, 538, 538, 538, 538, 538, 538, + + 538, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, + 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 1246, 1246, 1246, + 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, + 1246, 1246, 1246, 1246, 1246, 1247, 1247, 1247, 1247, 1247, + 1247, 1247, 1247, 1247, 552, 552, 552, 552, 552, 552, + 552, 552, 552, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 552, 552, 552, 552, 552, 552, 552, 552, 552, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1250, 1250, 1250, + 1250, 1250, 1250, 1250, 1250, 1250, 1252, 564, 564, 564, + 564, 564, 564, 564, 564, 564, 1253, 1253, 1253, 1253, + 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, + 1253, 1253, 1253, 2786, 2786, 1252, 564, 564, 564, 564, + 564, 564, 564, 564, 564, 1254, 1254, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 660, 661, 662, 663, 664, 665, + 546, 547, 548, 549, 550, 551, 1254, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 1254, 1255, 1255, 1255, 1255, 1255, + 1255, 1255, 1255, 1255, 545, 545, 545, 545, 545, 545, + + 545, 545, 545, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 652, + 652, 652, 652, 652, 652, 652, 652, 652, 1281, 1281, + 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + 1281, 1281, 1281, 1281, 1281, 1281, 1282, 1282, 1282, 1282, + 1282, 1282, 1282, 1282, 1282, 1044, 1044, 1044, 1044, 1044, + 1044, 1044, 1044, 1289, 1291, 1293, 1790, 1795, 1290, 660, + 661, 662, 663, 664, 665, 659, 659, 659, 659, 659, + 659, 659, 659, 659, 1300, 1300, 1300, 1300, 1300, 1300, + + 1300, 1300, 1289, 1291, 2786, 1790, 1795, 1290, 1292, 2786, + 2786, 2786, 2786, 660, 661, 662, 663, 664, 665, 700, + 701, 702, 703, 704, 705, 660, 661, 662, 663, 664, + 665, 660, 661, 662, 663, 664, 665, 1292, 660, 661, + 662, 663, 664, 665, 692, 692, 692, 692, 692, 692, + 692, 692, 692, 2786, 660, 661, 662, 663, 664, 665, + 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 692, + 692, 692, 692, 692, 692, 692, 692, 692, 1301, 1301, + 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, + 1301, 1301, 1301, 1301, 1301, 1301, 1302, 1302, 1302, 1302, + + 1302, 1302, 1302, 1302, 1302, 1070, 1070, 1070, 1070, 1070, + 1070, 1070, 1070, 1307, 2786, 2786, 2786, 1309, 700, 701, + 702, 703, 704, 705, 1310, 1308, 699, 699, 699, 699, + 699, 699, 699, 699, 699, 719, 720, 721, 722, 723, + 724, 2786, 1307, 719, 720, 721, 722, 723, 724, 1284, + 1035, 1035, 2786, 1310, 1308, 700, 701, 702, 703, 704, + 705, 2786, 2786, 2786, 2786, 700, 701, 702, 703, 704, + 705, 700, 701, 702, 703, 704, 705, 719, 720, 721, + 722, 723, 724, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 738, 738, 738, 738, 738, 738, 738, 738, + + 738, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, + 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 1313, 1313, 1313, + 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1285, 2786, + 1313, 2786, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, + 1313, 1313, 1313, 1313, 1314, 1314, 1314, 1314, 1314, 1314, + 1314, 1314, 1314, 1104, 1104, 1104, 1104, 1104, 1104, 1104, + 1104, 1105, 1105, 2786, 757, 1105, 1326, 1105, 1105, 1105, + 2786, 2786, 1101, 1469, 1274, 1274, 759, 2786, 2786, 2786, + 1470, 2786, 2786, 2786, 2786, 2786, 1327, 473, 474, 475, + + 476, 477, 478, 457, 2786, 2786, 360, 2786, 2786, 2786, + 2786, 2786, 360, 2786, 2786, 759, 745, 745, 745, 745, + 745, 745, 745, 745, 745, 1327, 2786, 2786, 2786, 2786, + 1328, 361, 361, 361, 361, 361, 361, 361, 361, 361, + 458, 459, 460, 461, 462, 463, 1798, 746, 747, 748, + 749, 750, 751, 746, 747, 748, 749, 750, 751, 1328, + 746, 747, 748, 749, 750, 751, 746, 747, 748, 749, + 750, 751, 1471, 384, 1821, 1798, 2786, 746, 747, 748, + 749, 750, 751, 746, 747, 748, 749, 750, 751, 362, + 363, 364, 365, 366, 367, 362, 363, 364, 365, 366, + + 367, 368, 368, 1821, 1838, 368, 368, 2786, 2786, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 2786, 368, + 368, 368, 368, 368, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 1838, 2786, 1296, 1049, 1049, 384, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 2786, 2786, + 368, 2786, 368, 385, 386, 387, 388, 389, 390, 2786, + 397, 2786, 1347, 1411, 466, 466, 466, 466, 466, 466, + 466, 466, 399, 2786, 1479, 1278, 1278, 2786, 1480, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 370, + 371, 372, 373, 374, 375, 368, 368, 1839, 1748, 368, + + 368, 399, 1348, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 1749, 368, 368, 368, 368, 368, 385, 386, + 387, 388, 389, 390, 1297, 2786, 1839, 1748, 2786, 1847, + 2786, 1348, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 1749, 2786, 1848, 368, 2786, 368, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 2786, 757, 1847, 1666, + 1349, 1350, 1736, 1481, 1853, 1737, 1351, 2786, 2786, 1095, + 1863, 2786, 1848, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 370, 371, 372, 373, 374, 375, 1349, + 1350, 1736, 2786, 1853, 1737, 1351, 1353, 2786, 1095, 1863, + + 2786, 377, 378, 379, 380, 381, 382, 2786, 1864, 1356, + 1435, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 2786, 1353, 2786, 2786, 1352, 377, + 378, 379, 380, 381, 382, 2786, 1354, 1864, 1356, 1435, + 1355, 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, + 2786, 473, 474, 475, 476, 477, 478, 1352, 1357, 2786, + 2786, 1865, 1358, 1866, 1867, 1354, 2786, 1868, 2786, 1355, + 377, 378, 379, 380, 381, 382, 1361, 1359, 1360, 2786, + 377, 378, 379, 380, 381, 382, 2786, 1357, 2786, 2786, + 1865, 1358, 1866, 1867, 2786, 2786, 1868, 377, 378, 379, + + 380, 381, 382, 2786, 2786, 1361, 1359, 1360, 377, 378, + 379, 380, 381, 382, 2786, 377, 378, 379, 380, 381, + 382, 1362, 1363, 377, 378, 379, 380, 381, 382, 1364, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 1367, 2786, 2786, + 1362, 1363, 377, 378, 379, 380, 381, 382, 1364, 1366, + 2786, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 1365, 2786, 1367, 377, 378, 379, + 380, 381, 382, 2786, 2786, 2786, 2786, 2786, 1366, 2786, + 1368, 2786, 1474, 1276, 1276, 2786, 2786, 2786, 2786, 1475, + + 1369, 1869, 1870, 1365, 377, 378, 379, 380, 381, 382, + 1370, 2786, 377, 378, 379, 380, 381, 382, 1371, 1368, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 1369, + 1869, 1870, 2786, 377, 378, 379, 380, 381, 382, 1370, + 2786, 2786, 2786, 2786, 1304, 1065, 1065, 1371, 377, 378, + 379, 380, 381, 382, 2786, 1373, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 1375, 1372, 2786, 2786, 1871, 2786, + 2786, 1476, 2786, 1437, 377, 378, 379, 380, 381, 382, + 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, + + 1377, 1377, 1377, 1375, 1372, 1374, 2786, 1871, 457, 2786, + 2786, 397, 1437, 1671, 2786, 1376, 377, 378, 379, 380, + 381, 382, 2786, 818, 1317, 1092, 1092, 377, 378, 379, + 380, 381, 382, 1305, 1374, 473, 474, 475, 476, 477, + 478, 1379, 1872, 2786, 1376, 458, 459, 460, 461, 462, + 463, 2786, 818, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 1872, 377, 378, 379, 380, 381, 382, 1380, 377, + 378, 379, 380, 381, 382, 1381, 2786, 377, 378, 1378, + 380, 381, 382, 2786, 1873, 377, 378, 379, 380, 381, + + 382, 2786, 1330, 1108, 1108, 1382, 2786, 1380, 2786, 1336, + 1112, 1112, 1383, 1318, 1381, 1469, 1274, 1274, 2786, 2786, + 2786, 2786, 1470, 1873, 377, 378, 379, 380, 381, 382, + 1384, 1385, 2786, 2786, 1382, 377, 378, 379, 380, 381, + 382, 1383, 377, 378, 379, 380, 381, 382, 1388, 1388, + 1388, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 1386, 1384, + 1385, 757, 2786, 1815, 2786, 2786, 377, 378, 379, 380, + 381, 382, 1387, 1095, 377, 378, 379, 380, 381, 382, + 2786, 377, 378, 379, 380, 381, 382, 1386, 1390, 2786, + 2786, 1331, 377, 378, 379, 380, 381, 382, 1337, 1874, + + 2786, 1387, 1095, 2786, 1471, 2786, 377, 378, 379, 380, + 381, 382, 1391, 2786, 1807, 1807, 1807, 1390, 1474, 1276, + 1276, 1392, 1875, 2786, 2786, 1475, 2786, 2786, 1874, 377, + 378, 379, 380, 381, 382, 377, 378, 1389, 380, 381, + 382, 1391, 1393, 1876, 2786, 2786, 2786, 2786, 2786, 2786, + 1392, 1875, 1396, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 2786, + 2786, 1393, 1876, 377, 378, 379, 380, 381, 382, 1395, + 1394, 1396, 2786, 2786, 1877, 2786, 377, 378, 379, 380, + 381, 382, 2786, 2786, 2786, 1878, 2786, 377, 378, 379, + + 380, 381, 382, 1808, 2786, 2786, 2786, 1476, 1395, 1394, + 1397, 1398, 2786, 1877, 2786, 2786, 2786, 377, 378, 379, + 380, 381, 382, 1399, 1878, 2786, 1879, 2786, 2786, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 1397, + 1398, 377, 378, 379, 380, 381, 382, 1400, 1401, 1412, + 1412, 1412, 1399, 1416, 2786, 1879, 377, 378, 379, 380, + 381, 382, 2786, 2786, 1402, 1880, 377, 378, 379, 380, + 381, 382, 2786, 1432, 2786, 2786, 1400, 1401, 2786, 2786, + 2786, 1881, 1416, 2786, 2786, 2786, 2786, 377, 378, 379, + 380, 381, 382, 1402, 1880, 2786, 2786, 2786, 377, 378, + + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 1881, 377, 378, 379, 380, 381, 382, 2786, 456, 456, + 456, 456, 456, 456, 456, 456, 456, 377, 378, 379, + 380, 381, 382, 1200, 1200, 1200, 377, 378, 1413, 380, + 381, 382, 1436, 1414, 473, 474, 475, 476, 477, 478, + 2786, 2786, 2786, 2786, 1403, 2786, 2786, 1404, 1405, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 1434, 1406, 1407, + 1408, 1417, 1414, 1418, 1409, 1882, 2786, 1415, 1883, 2786, + 473, 474, 475, 476, 477, 478, 1404, 1405, 1419, 2786, + 377, 378, 379, 380, 381, 382, 1434, 1406, 1407, 1408, + + 1417, 2786, 1418, 1409, 1882, 2786, 1415, 1883, 2786, 473, + 474, 475, 476, 477, 478, 1420, 2786, 1419, 1421, 2122, + 2122, 2122, 1410, 377, 378, 379, 380, 381, 382, 1423, + 1426, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 1420, 2786, 2786, 1421, 2786, 377, + 378, 379, 380, 381, 382, 2786, 537, 2786, 1423, 1426, + 2786, 2786, 377, 378, 379, 380, 381, 382, 1778, 1422, + 1884, 2786, 2786, 1779, 377, 378, 379, 380, 381, 382, + 1425, 377, 378, 379, 380, 381, 382, 1424, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 1778, 1422, 1884, + + 1427, 2786, 1779, 1428, 2786, 2786, 2786, 2786, 2123, 1425, + 2786, 2786, 2786, 2786, 2786, 2786, 1424, 2786, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 1429, 2786, 1427, + 1430, 1885, 1428, 377, 378, 379, 380, 381, 382, 539, + 540, 541, 542, 543, 544, 377, 378, 379, 380, 381, + 382, 1433, 502, 1886, 1887, 1438, 1429, 2786, 2786, 1430, + 1885, 377, 378, 379, 380, 381, 382, 2786, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 1433, 2786, 1886, 1887, 377, 378, 379, 380, 381, 382, + 2786, 377, 378, 379, 380, 381, 382, 502, 2786, 2786, + + 2786, 377, 378, 379, 380, 381, 382, 502, 1888, 2786, + 2786, 1911, 473, 474, 475, 476, 477, 478, 502, 553, + 397, 2786, 1819, 1439, 2786, 509, 510, 515, 512, 513, + 514, 1913, 818, 1914, 1440, 502, 1915, 1888, 2786, 1916, + 1911, 502, 2786, 2786, 2786, 2786, 2786, 502, 1917, 1918, + 2786, 2786, 1439, 1442, 2786, 2786, 2786, 1443, 1441, 1444, + 1913, 818, 1914, 1440, 502, 1915, 537, 2786, 1916, 2786, + 509, 510, 515, 512, 513, 514, 1445, 1917, 1918, 2786, + 509, 510, 515, 512, 513, 514, 1443, 1441, 1444, 2786, + 2786, 509, 510, 515, 512, 513, 514, 2786, 553, 554, + + 555, 556, 557, 558, 559, 1445, 2786, 1919, 509, 510, + 515, 512, 513, 514, 509, 510, 515, 512, 513, 514, + 509, 510, 515, 512, 513, 514, 502, 2786, 2786, 2786, + 2786, 2786, 502, 2786, 2786, 2786, 1919, 509, 510, 515, + 512, 513, 514, 502, 2786, 1446, 2786, 1449, 1447, 539, + 540, 541, 542, 543, 544, 1448, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 552, 552, 552, 552, 552, + 552, 552, 552, 552, 1446, 2786, 2786, 1447, 554, 555, + 556, 557, 558, 559, 1448, 546, 547, 548, 549, 550, + 551, 565, 2786, 1450, 1920, 1921, 1922, 565, 1923, 509, + + 510, 515, 512, 513, 514, 509, 510, 515, 512, 513, + 514, 2786, 2786, 2786, 2786, 2786, 509, 510, 515, 512, + 513, 514, 1450, 1920, 1921, 1922, 2786, 1923, 566, 567, + 568, 569, 570, 571, 566, 567, 568, 569, 570, 571, + 564, 564, 564, 564, 564, 564, 564, 564, 564, 2786, + 2786, 2786, 2786, 2786, 546, 547, 548, 549, 550, 551, + 651, 651, 1492, 1486, 651, 651, 2786, 1491, 651, 651, + 651, 651, 651, 651, 651, 651, 651, 2786, 651, 651, + 651, 651, 651, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 1486, 1487, 1487, 1487, 1491, 2786, 1488, 2786, + + 660, 661, 662, 663, 664, 665, 1489, 2786, 2786, 651, + 2786, 651, 692, 692, 692, 692, 692, 692, 692, 692, + 692, 2786, 2786, 2786, 2786, 660, 661, 662, 663, 664, + 665, 1493, 660, 661, 662, 663, 664, 665, 651, 651, + 651, 651, 651, 651, 651, 651, 651, 651, 653, 654, + 655, 656, 657, 658, 651, 651, 2786, 1498, 651, 651, + 1493, 2786, 651, 651, 651, 651, 651, 651, 651, 651, + 651, 1499, 651, 651, 651, 651, 651, 1924, 1925, 1926, + 660, 661, 1490, 663, 664, 665, 1498, 719, 720, 721, + 722, 723, 724, 2786, 660, 661, 662, 663, 664, 665, + + 2786, 2786, 2786, 651, 2786, 651, 1924, 1925, 1926, 700, + 701, 702, 703, 704, 705, 2786, 2786, 2786, 2786, 700, + 701, 702, 703, 704, 705, 1500, 473, 474, 475, 476, + 477, 478, 651, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 653, 654, 655, 656, 657, 658, 691, 691, + 2786, 2786, 691, 691, 1500, 1930, 691, 691, 691, 691, + 691, 691, 691, 691, 691, 2786, 691, 691, 691, 691, + 691, 738, 738, 738, 738, 738, 738, 738, 738, 738, + 1513, 1513, 1513, 1934, 1930, 1544, 1544, 1544, 700, 701, + 702, 703, 704, 705, 2786, 1956, 1973, 691, 2786, 691, + + 1545, 2786, 2786, 757, 757, 1504, 1951, 2786, 397, 2786, + 1954, 2786, 1934, 2786, 2786, 759, 1095, 2786, 2786, 1505, + 818, 2786, 2786, 2786, 1956, 1973, 691, 691, 691, 691, + 691, 691, 691, 691, 691, 691, 693, 694, 695, 696, + 697, 698, 691, 691, 759, 1095, 691, 691, 1505, 818, + 691, 691, 691, 691, 691, 691, 691, 691, 691, 2786, + 691, 691, 691, 691, 691, 2786, 1605, 377, 378, 1514, + 380, 381, 382, 1974, 1702, 2786, 746, 747, 748, 749, + 750, 751, 1982, 1983, 746, 747, 748, 749, 750, 751, + 1603, 691, 2786, 691, 2786, 377, 378, 379, 380, 381, + + 382, 397, 1974, 1512, 473, 474, 475, 476, 477, 478, + 1506, 1982, 1983, 399, 1987, 2786, 1388, 1388, 1388, 2786, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, - 690, 690, 2596, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 1286, 1286, 2596, 1286, 1286, 1286, 1286, - 1286, 1286, 1286, 1286, 1286, 1286, 698, 698, 717, 717, - 737, 737, 2596, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 736, 736, 2596, 736, 736, 736, 736, - 736, 736, 736, 736, 736, 736, 1298, 1298, 2596, 1298, - 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 744, - 744, 1312, 1312, 2596, 1312, 1312, 1312, 1312, 1312, 1312, - 1312, 1312, 1312, 1312, 1318, 1318, 2596, 1318, 1318, 1318, - - 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1118, 1118, 2596, - 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, - 377, 377, 2596, 377, 377, 471, 471, 499, 499, 2596, - 2596, 2596, 499, 544, 544, 579, 2596, 2596, 579, 600, - 2596, 2596, 600, 1442, 1442, 2596, 1442, 1442, 1442, 1442, - 1442, 1442, 1442, 1442, 1442, 1442, 1447, 1447, 2596, 1447, - 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1452, - 1452, 2596, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, - 1452, 1452, 1264, 1264, 2596, 1264, 1264, 1264, 1264, 1264, - 1264, 1264, 1264, 1264, 1264, 657, 657, 1278, 1278, 2596, - - 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, - 1286, 1286, 2596, 1286, 1286, 1286, 1286, 1286, 1286, 1286, - 1286, 1286, 1286, 698, 698, 1608, 1608, 1608, 1608, 1608, - 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1789, 1789, - 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, - 1789, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, - 1874, 1874, 1874, 1874, 1895, 1895, 1895, 1895, 1895, 1895, - 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1903, 1903, 1903, - 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, - 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, - - 1924, 1924, 1924, 1954, 1954, 1954, 1954, 1954, 1954, 1954, - 1954, 1954, 1954, 1954, 1954, 1954, 1976, 1976, 1976, 1976, - 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 2024, - 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, - 2024, 2024, 57, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596 + 693, 694, 695, 696, 697, 698, 737, 737, 2786, 1506, + 737, 737, 399, 1987, 737, 737, 737, 737, 737, 737, + 737, 737, 737, 1551, 737, 737, 737, 737, 737, 2786, + 2786, 473, 474, 475, 476, 477, 478, 746, 747, 748, + 749, 750, 751, 2786, 377, 378, 379, 380, 381, 382, + 1989, 2786, 1551, 1990, 1991, 737, 2786, 737, 377, 378, + 379, 380, 381, 382, 2786, 2786, 2786, 2786, 2786, 2786, + + 1479, 1278, 1278, 2786, 1480, 1552, 2786, 2786, 1519, 1989, + 2786, 2786, 1990, 1991, 737, 737, 737, 737, 737, 737, + 737, 737, 737, 737, 739, 740, 741, 742, 743, 744, + 737, 737, 1515, 2786, 737, 737, 1521, 1519, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 2786, 737, 737, + 737, 737, 737, 2786, 377, 378, 379, 380, 381, 382, + 2786, 1515, 1516, 2786, 1997, 1521, 2786, 1999, 2786, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2002, 737, + 2786, 737, 2786, 377, 378, 379, 380, 381, 382, 1481, + 2786, 1516, 2786, 1997, 2786, 1517, 1999, 1513, 1513, 1513, + + 2786, 2786, 2786, 1518, 1520, 2786, 2786, 2002, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 739, 740, + 741, 742, 743, 744, 1517, 1524, 377, 378, 379, 380, + 381, 382, 1518, 1520, 1673, 2000, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 2786, 2786, + 2786, 2003, 2004, 2001, 1524, 377, 378, 379, 380, 381, + 382, 1522, 2786, 1673, 2000, 2005, 2006, 377, 378, 379, + 380, 381, 382, 377, 378, 379, 380, 381, 382, 2786, + 2003, 2004, 2001, 2786, 1523, 2009, 1674, 2786, 2010, 2786, + 1522, 1525, 2011, 2786, 2005, 2006, 2786, 2786, 2786, 1526, + + 2786, 2012, 2786, 2786, 2007, 2013, 2786, 2786, 2786, 2786, + 2786, 2786, 1527, 1523, 2009, 2008, 2014, 2010, 1531, 2786, + 1525, 2011, 377, 378, 379, 380, 381, 382, 1526, 1528, + 2012, 2786, 2786, 2007, 2013, 377, 378, 379, 380, 381, + 382, 1527, 2786, 2786, 2008, 2014, 1529, 1531, 2786, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 1528, 1530, + 377, 378, 379, 380, 381, 382, 1532, 2786, 2786, 377, + 378, 379, 380, 381, 382, 1529, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1530, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 2786, + + 2015, 2016, 1533, 1534, 377, 378, 379, 380, 381, 382, + 1536, 2786, 2786, 2786, 2786, 2786, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 2786, 2015, + 2016, 2786, 1534, 2786, 2786, 2786, 1560, 1560, 1560, 1536, + 377, 378, 379, 380, 381, 382, 1555, 1555, 1555, 2786, + 2017, 1535, 1541, 466, 466, 466, 466, 466, 466, 466, + 466, 1537, 377, 378, 379, 380, 381, 382, 2786, 1711, + 1716, 377, 378, 379, 380, 381, 382, 2786, 2786, 2017, + 1535, 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, + 1537, 1377, 1377, 1377, 1542, 2786, 2786, 2018, 1711, 1716, + + 2786, 377, 378, 379, 380, 381, 382, 377, 378, 379, + 380, 381, 382, 2786, 2786, 1544, 1544, 1544, 2786, 1538, + 1543, 2021, 2786, 1542, 2786, 1717, 2018, 2786, 1539, 2786, + 1545, 2022, 2023, 1725, 1547, 1712, 2786, 1726, 1727, 2786, + 2786, 377, 378, 379, 380, 381, 382, 2786, 1538, 1543, + 2021, 377, 378, 379, 380, 381, 382, 1539, 1548, 2786, + 2022, 2023, 1725, 1547, 2786, 2786, 1726, 1727, 377, 378, + 379, 380, 381, 382, 2786, 1555, 1555, 1555, 2786, 2019, + 1540, 2786, 2786, 2786, 2786, 2786, 1549, 1548, 2024, 2786, + 2040, 377, 378, 379, 380, 381, 382, 2786, 2041, 2786, + + 2020, 1550, 377, 378, 1546, 380, 381, 382, 2019, 377, + 378, 379, 380, 381, 382, 1549, 2786, 2024, 2786, 2040, + 377, 378, 379, 380, 381, 382, 2786, 2041, 2786, 2020, + 1550, 2786, 377, 378, 379, 380, 381, 382, 1553, 466, + 466, 466, 466, 466, 466, 466, 466, 377, 378, 379, + 380, 381, 382, 1554, 377, 378, 379, 380, 381, 382, + 2786, 2786, 377, 378, 1556, 380, 381, 382, 2786, 2042, + 377, 378, 379, 380, 381, 382, 2786, 2786, 2043, 2045, + 1558, 2786, 1554, 1560, 1560, 1560, 1557, 1559, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 2786, 2042, 2046, + + 1562, 377, 378, 379, 380, 381, 382, 2043, 2045, 1558, + 2786, 2786, 2786, 2786, 2786, 1557, 1559, 2786, 1563, 2786, + 546, 547, 548, 549, 550, 551, 2786, 2047, 2046, 1562, + 2048, 2786, 2786, 377, 378, 379, 380, 381, 382, 2051, + 1564, 377, 378, 379, 380, 381, 382, 1563, 1565, 2786, + 377, 378, 379, 380, 381, 382, 2047, 2786, 2786, 2048, + 1618, 377, 378, 379, 380, 381, 382, 2786, 2051, 1564, + 377, 378, 1561, 380, 381, 382, 1566, 1565, 2134, 2134, + 2134, 2786, 2786, 377, 378, 379, 380, 381, 382, 1618, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 377, + + 378, 379, 380, 381, 382, 1566, 1200, 912, 912, 912, + 912, 912, 912, 912, 912, 546, 547, 548, 549, 550, + 551, 2059, 377, 378, 379, 380, 381, 382, 1412, 1412, + 1412, 1590, 466, 466, 466, 466, 466, 466, 466, 466, + 377, 378, 379, 380, 381, 382, 2786, 1607, 2078, 2786, + 2059, 1576, 1577, 1578, 1579, 1580, 1581, 2786, 1582, 2093, + 1583, 1591, 1584, 2786, 2094, 1585, 2099, 2135, 1586, 1587, + 2786, 2786, 1588, 2101, 1593, 2102, 1607, 2078, 2786, 2786, + 1576, 1577, 1578, 1579, 1580, 1581, 1594, 1582, 2093, 1583, + 1591, 1584, 2786, 2094, 1585, 2099, 1592, 1586, 1587, 2786, + + 1595, 1588, 2101, 1593, 2102, 2786, 473, 474, 475, 476, + 477, 478, 1684, 1684, 1684, 1594, 2786, 1589, 2786, 377, + 378, 379, 380, 381, 382, 1592, 2786, 1685, 1596, 1595, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 377, 378, 379, 380, 381, 382, 1596, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 377, 378, 379, 380, 381, + 382, 1597, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 2786, 757, 397, 2073, 2076, 377, + 378, 379, 380, 381, 382, 1598, 2786, 1095, 818, 2786, + + 1597, 1827, 2786, 1640, 2786, 2786, 2786, 2786, 2786, 2786, + 2107, 1600, 2786, 2786, 2786, 2786, 2786, 2786, 2108, 2109, + 2110, 2115, 1599, 2116, 1598, 2117, 1095, 818, 502, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 1601, 2107, + 1600, 660, 661, 662, 663, 664, 665, 2108, 2109, 2110, + 2115, 1599, 2116, 2786, 2117, 2786, 2786, 377, 378, 379, + 380, 381, 382, 1610, 2786, 2786, 2786, 1601, 1604, 377, + 378, 379, 380, 381, 382, 377, 378, 379, 380, 381, + 382, 377, 378, 379, 380, 381, 382, 1606, 502, 2118, + 377, 378, 379, 380, 381, 382, 502, 1604, 2786, 2786, + + 2119, 509, 510, 515, 512, 513, 514, 2120, 2121, 502, + 2124, 2125, 1609, 2126, 2127, 1608, 1606, 502, 2118, 2786, + 473, 474, 475, 476, 477, 478, 2786, 1611, 1612, 2119, + 2128, 2786, 502, 2786, 2786, 2786, 2120, 2121, 502, 2124, + 2125, 1609, 2126, 2127, 1608, 2786, 2786, 2129, 502, 2130, + 473, 474, 475, 476, 477, 478, 1611, 1612, 1662, 2128, + 1615, 509, 510, 515, 512, 513, 514, 1613, 502, 509, + 510, 515, 512, 513, 514, 1614, 2129, 502, 2130, 2786, + 2786, 2786, 509, 510, 515, 512, 513, 514, 1616, 1615, + 509, 510, 515, 512, 513, 514, 700, 701, 702, 703, + + 704, 705, 2131, 1617, 1614, 509, 510, 515, 512, 513, + 514, 509, 510, 515, 512, 513, 514, 1616, 2786, 1658, + 2132, 509, 510, 515, 512, 513, 514, 2786, 1660, 2133, + 2786, 2131, 2786, 2786, 1487, 1487, 1487, 2786, 2786, 1641, + 1659, 509, 510, 515, 512, 513, 514, 1489, 1658, 2132, + 509, 510, 515, 512, 513, 514, 1663, 1660, 2133, 1642, + 1657, 675, 675, 675, 675, 675, 675, 675, 675, 1659, + 2786, 2786, 2786, 660, 661, 662, 663, 664, 665, 660, + 661, 662, 663, 664, 665, 1663, 2786, 2786, 1642, 2786, + 2136, 377, 378, 379, 380, 381, 382, 660, 661, 662, + + 663, 664, 665, 1675, 466, 466, 466, 466, 466, 466, + 466, 466, 2786, 700, 701, 702, 703, 704, 705, 2136, + 2786, 2786, 2786, 1643, 1644, 1645, 1487, 1487, 1644, 1644, + 1646, 1647, 1644, 1644, 1644, 1644, 1644, 1644, 1648, 1644, + 1644, 1647, 1644, 1644, 1644, 1644, 1644, 1647, 1647, 1647, + 1649, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 1647, 1644, 1647, 1644, 1647, 1647, 1647, 1649, + 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + + 1647, 1647, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, + 1644, 1644, 1650, 1651, 1652, 1653, 1654, 1655, 1664, 757, + 2137, 1667, 2786, 2138, 2139, 2786, 2786, 2786, 2786, 2140, + 2141, 759, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 397, + 2786, 1672, 2786, 2786, 2786, 2786, 1668, 1664, 2786, 2137, + 2142, 399, 2138, 2139, 2786, 1669, 2143, 1676, 2140, 2141, + 759, 473, 474, 475, 476, 477, 478, 2786, 2786, 700, + 701, 702, 703, 704, 705, 1668, 1694, 1694, 1694, 2142, + 399, 2786, 2786, 2786, 1669, 2143, 1676, 2786, 2122, 2122, + 2122, 1695, 746, 747, 748, 749, 750, 751, 2786, 2786, + + 746, 747, 748, 749, 750, 751, 746, 747, 748, 749, + 750, 751, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 2786, 2144, 1677, 377, 378, 379, + 380, 381, 382, 2786, 2158, 2786, 2786, 2786, 2159, 2786, + 377, 378, 379, 380, 381, 382, 2786, 1684, 1684, 1684, + 2160, 1678, 2786, 2162, 2144, 1677, 1681, 2163, 2164, 2165, + 1679, 2786, 1685, 2158, 1682, 1835, 1680, 2159, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 2123, 2786, 2160, + 1678, 2786, 2162, 2786, 2786, 1681, 2163, 2164, 2165, 1679, + 2786, 2786, 2786, 1682, 2786, 1680, 2786, 377, 378, 379, + + 380, 381, 382, 1683, 2786, 2786, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 2786, 377, + 378, 379, 380, 381, 382, 377, 378, 379, 380, 381, + 382, 2187, 1683, 2786, 377, 378, 1686, 380, 381, 382, + 2786, 2786, 1687, 377, 378, 379, 380, 381, 382, 2190, + 2195, 2786, 1688, 2197, 377, 378, 379, 380, 381, 382, + 2187, 757, 2786, 2182, 2786, 377, 378, 379, 380, 381, + 382, 1687, 1689, 1095, 2786, 2786, 2786, 2786, 2190, 2195, + 2786, 1688, 2197, 1690, 1694, 1694, 1694, 2786, 1755, 1755, + 1755, 377, 378, 379, 380, 381, 382, 2786, 2786, 1695, + + 2786, 1689, 1095, 1756, 2198, 2786, 377, 378, 379, 380, + 381, 382, 1690, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, + 1691, 2786, 2786, 2198, 2786, 2786, 2786, 2786, 2786, 2786, + 1692, 473, 474, 475, 476, 477, 478, 2786, 377, 378, + 379, 380, 381, 382, 2786, 2786, 1693, 2202, 1700, 1691, + 1377, 912, 912, 912, 912, 912, 912, 912, 912, 1692, + 1701, 377, 378, 1696, 380, 381, 382, 1892, 377, 378, + 379, 380, 381, 382, 2786, 1693, 2202, 1700, 2786, 2166, + 2166, 2166, 377, 378, 379, 380, 381, 382, 2786, 1701, + + 2786, 2786, 2786, 2167, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 1704, 466, 466, 466, + 466, 466, 466, 466, 466, 1705, 2786, 377, 378, 379, + 380, 381, 382, 2786, 2203, 2208, 2786, 2209, 1710, 2786, + 1388, 912, 912, 912, 912, 912, 912, 912, 912, 2786, + 2786, 2210, 1706, 2211, 1705, 1707, 2786, 377, 378, 379, + 380, 381, 382, 2203, 2208, 1714, 2209, 1710, 2214, 2216, + 2786, 377, 378, 379, 380, 381, 382, 2786, 2168, 2786, + 2210, 1706, 2211, 2786, 1707, 1713, 466, 466, 466, 466, + 466, 466, 466, 466, 1714, 2786, 2786, 2214, 2216, 377, + + 378, 379, 380, 381, 382, 2786, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 2786, 2217, + 2218, 2786, 2786, 377, 378, 379, 380, 381, 382, 377, + 378, 379, 380, 381, 382, 2786, 1718, 466, 466, 466, + 466, 466, 466, 466, 466, 2786, 2786, 1715, 2217, 2218, + 377, 378, 379, 380, 381, 382, 1719, 2786, 2786, 2786, + 1722, 1722, 1722, 2786, 2786, 397, 2219, 2185, 2786, 1720, + 2220, 2221, 2222, 2224, 2786, 1723, 1715, 818, 377, 378, + 379, 380, 381, 382, 2786, 1719, 1412, 912, 912, 912, + 912, 912, 912, 912, 912, 2219, 1721, 2786, 1720, 2220, + + 2221, 2222, 2224, 2786, 2786, 2786, 818, 1753, 377, 378, + 379, 380, 381, 382, 2786, 2786, 2786, 2786, 2786, 377, + 378, 379, 380, 381, 382, 1721, 1752, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 1753, 2786, 2225, 2226, + 2227, 377, 378, 379, 380, 381, 382, 377, 378, 1724, + 380, 381, 382, 2786, 1754, 1752, 2786, 377, 378, 379, + 380, 381, 382, 1762, 2228, 1758, 2786, 2225, 2226, 2227, + 377, 378, 379, 380, 381, 382, 2786, 377, 378, 379, + 380, 381, 382, 1754, 1755, 1755, 1755, 377, 378, 379, + 380, 381, 382, 2228, 1758, 1759, 1763, 2786, 2786, 1756, + + 377, 378, 379, 380, 381, 382, 2786, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 1759, 1763, 377, 378, 379, 380, + 381, 382, 1760, 1764, 473, 474, 475, 476, 477, 478, + 2229, 2230, 473, 474, 475, 476, 477, 478, 502, 377, + 378, 379, 380, 381, 382, 2786, 502, 2786, 2786, 2786, + 2786, 1760, 1764, 1850, 1850, 1850, 2786, 502, 1765, 2229, + 2230, 377, 378, 1757, 380, 381, 382, 1766, 1851, 2231, + 2232, 2233, 502, 2238, 473, 474, 475, 476, 477, 478, + 2239, 377, 378, 379, 380, 381, 382, 1765, 1767, 502, + + 2786, 2786, 2786, 2786, 2786, 502, 1766, 1772, 2231, 2232, + 2233, 2786, 2238, 502, 2786, 2786, 2786, 1768, 2786, 2239, + 2240, 509, 510, 515, 512, 513, 514, 1767, 502, 509, + 510, 515, 512, 513, 514, 2786, 1772, 2241, 2250, 2786, + 509, 510, 515, 512, 513, 514, 1768, 502, 1771, 2240, + 2786, 2786, 1984, 502, 2786, 509, 510, 515, 512, 513, + 514, 2786, 2786, 1769, 1791, 2786, 2241, 2250, 1770, 1773, + 2786, 1774, 509, 510, 515, 512, 513, 514, 509, 510, + 515, 512, 513, 514, 2786, 2786, 509, 510, 515, 512, + 513, 514, 1769, 1791, 1645, 1487, 1487, 1770, 1773, 1792, + + 1774, 509, 510, 515, 512, 513, 514, 1648, 2786, 2786, + 2786, 2786, 660, 661, 662, 663, 664, 665, 2786, 1793, + 509, 510, 515, 512, 513, 514, 509, 510, 515, 512, + 513, 514, 546, 547, 548, 549, 550, 551, 1645, 1487, + 1487, 2786, 2786, 1792, 1645, 1487, 1487, 1809, 1793, 1792, + 2251, 1648, 2252, 1645, 1487, 1487, 2253, 1648, 1792, 2257, + 2786, 2265, 2266, 1793, 2267, 2268, 1797, 2269, 2274, 1793, + 660, 661, 662, 663, 664, 665, 1809, 2288, 1793, 2251, + 2786, 2252, 2786, 1794, 2786, 2253, 2786, 2786, 2257, 1810, + 2265, 2266, 1793, 2267, 2268, 2786, 2269, 2274, 1793, 660, + + 661, 662, 663, 664, 665, 2786, 2288, 1793, 1487, 1044, + 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1813, 1810, 2786, + 2786, 1811, 2291, 1812, 1899, 2292, 2293, 1794, 2296, 2786, + 2786, 2297, 2786, 1794, 660, 661, 662, 663, 664, 665, + 2786, 2786, 1794, 1645, 1487, 1487, 1813, 757, 1792, 2280, + 1811, 2291, 1812, 1899, 2292, 2293, 1648, 2296, 2300, 1095, + 2297, 1817, 700, 701, 702, 703, 704, 705, 1793, 700, + 701, 702, 703, 704, 705, 700, 701, 702, 703, 704, + 705, 473, 474, 475, 476, 477, 478, 2300, 1095, 757, + 1817, 1816, 2786, 2786, 2786, 2786, 397, 1793, 1820, 2786, + + 2786, 759, 746, 747, 748, 749, 750, 751, 399, 2786, + 2313, 2313, 2313, 746, 747, 748, 749, 750, 751, 2786, + 2786, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 759, 2786, 1794, 1645, 1487, 1487, 2786, 399, 1792, 546, + 547, 548, 549, 550, 551, 2786, 1648, 1513, 912, 912, + 912, 912, 912, 912, 912, 912, 2302, 2303, 1793, 2786, + 2304, 2305, 746, 747, 748, 749, 750, 751, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 2786, 2786, 397, + 2786, 2283, 2786, 2786, 2786, 2302, 2303, 1793, 2786, 2304, + 2305, 818, 377, 378, 379, 380, 381, 382, 1824, 2314, + + 1825, 2307, 2308, 1823, 377, 378, 379, 380, 381, 382, + 2786, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, + 818, 2786, 1794, 1645, 1487, 1487, 2786, 1824, 1792, 1825, + 2307, 2308, 1823, 2786, 2786, 2786, 1648, 2786, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 2786, 1793, 377, + 378, 379, 380, 381, 382, 377, 378, 379, 380, 381, + 382, 377, 378, 379, 380, 381, 382, 660, 661, 662, + 663, 664, 665, 2786, 2315, 2315, 2315, 1793, 2786, 2786, + 2786, 1826, 2786, 377, 378, 379, 380, 381, 382, 1829, + 466, 466, 466, 466, 466, 466, 466, 466, 2786, 2786, + + 2786, 1800, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, + 1826, 1830, 1794, 1645, 1487, 1487, 2309, 2786, 1792, 2786, + 377, 378, 379, 380, 381, 382, 1648, 1837, 466, 466, + 466, 466, 466, 466, 466, 466, 2786, 2786, 1793, 1910, + 1830, 2320, 2320, 2320, 2786, 2309, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1832, 2310, + 1834, 2786, 2786, 2316, 2097, 2097, 2097, 1793, 1910, 2786, + 2786, 1831, 377, 378, 379, 380, 381, 382, 1833, 1545, + 546, 547, 548, 549, 550, 551, 2311, 1832, 2310, 1834, + 2786, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, + + 1831, 2786, 1794, 1645, 1487, 1487, 2786, 1833, 1792, 377, + 378, 379, 380, 381, 382, 2311, 1648, 377, 378, 379, + 380, 381, 382, 2312, 2786, 2285, 2786, 1840, 1793, 2786, + 2321, 2270, 2270, 2270, 377, 378, 379, 380, 381, 382, + 2286, 2318, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 2312, 2098, 2285, 2786, 1840, 1793, 1544, 912, + 912, 912, 912, 912, 912, 912, 912, 2786, 2324, 2286, + 2318, 1841, 2271, 2327, 377, 378, 379, 380, 381, 382, + 2786, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1804, 1805, + 2328, 2786, 1794, 1645, 1487, 1487, 2786, 2324, 1792, 2786, + + 1841, 2271, 2327, 2786, 2786, 2786, 1648, 2786, 2786, 2786, + 1736, 2786, 2786, 2786, 2786, 2786, 2786, 1740, 1793, 2328, + 2272, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 1846, 1850, 1850, 1850, 2786, 1736, + 377, 378, 379, 380, 381, 382, 1740, 1793, 2786, 2786, + 1851, 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 2786, 1846, 377, 378, 379, 380, 381, 382, + 2786, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, + 1855, 2786, 1794, 2786, 2786, 377, 378, 379, 380, 381, + 382, 1555, 912, 912, 912, 912, 912, 912, 912, 912, + + 1560, 912, 912, 912, 912, 912, 912, 912, 912, 1855, + 2786, 377, 378, 379, 380, 381, 382, 2786, 2786, 2786, + 2786, 2329, 377, 378, 1852, 380, 381, 382, 1722, 1722, + 1722, 1856, 2786, 2330, 2786, 377, 378, 379, 380, 381, + 382, 2786, 2786, 1723, 2786, 2322, 2322, 2322, 2786, 1857, + 2329, 2331, 2334, 1858, 377, 378, 379, 380, 381, 382, + 1856, 1889, 2330, 2337, 2786, 1859, 1862, 466, 466, 466, + 466, 466, 466, 466, 466, 1890, 1891, 2786, 2786, 2786, + 2331, 2334, 1858, 377, 378, 379, 380, 381, 382, 1895, + 1889, 2786, 2337, 2786, 1859, 1894, 466, 466, 466, 466, + + 466, 466, 466, 466, 1890, 1891, 1898, 377, 378, 379, + 380, 381, 382, 2786, 2786, 2786, 2786, 1860, 1895, 1896, + 502, 377, 378, 379, 380, 381, 382, 502, 2188, 2188, + 2188, 1900, 2335, 502, 2323, 2336, 2338, 377, 378, 379, + 380, 381, 382, 1685, 1903, 1901, 2339, 2345, 1896, 2786, + 377, 378, 379, 380, 381, 382, 2786, 502, 2786, 2786, + 1900, 2335, 1902, 2346, 2336, 2338, 377, 378, 379, 380, + 381, 382, 2786, 1903, 1901, 2339, 2345, 473, 474, 475, + 476, 477, 478, 473, 474, 475, 476, 477, 478, 1904, + 2786, 502, 2346, 509, 510, 515, 512, 513, 514, 1906, + + 509, 510, 515, 512, 513, 514, 509, 510, 515, 512, + 513, 514, 502, 2786, 2193, 2193, 2193, 2189, 1904, 1927, + 2786, 2347, 2786, 1905, 2786, 2786, 2786, 2786, 1906, 1695, + 509, 510, 515, 512, 513, 514, 502, 2786, 2786, 2786, + 2786, 2786, 502, 2786, 2786, 2786, 2786, 1907, 1927, 1945, + 2347, 502, 1905, 1908, 700, 701, 702, 703, 704, 705, + 2786, 2786, 1909, 2786, 509, 510, 515, 512, 513, 514, + 660, 661, 662, 663, 664, 665, 1907, 2348, 1945, 1645, + 1487, 1487, 1908, 2786, 1792, 509, 510, 515, 512, 513, + 514, 1909, 1648, 1978, 1978, 1978, 660, 661, 662, 663, + + 664, 665, 2786, 2194, 1793, 2349, 2348, 2786, 2786, 509, + 510, 515, 512, 513, 514, 509, 510, 515, 512, 513, + 514, 2786, 1979, 2786, 509, 510, 515, 512, 513, 514, + 1645, 1487, 1487, 1793, 2349, 1792, 1645, 1487, 1487, 2786, + 1946, 1792, 2351, 1648, 2786, 1931, 1932, 1932, 2786, 1648, + 1792, 1979, 1939, 1932, 1932, 1793, 1947, 1940, 1797, 2358, + 2359, 1793, 2360, 2786, 2786, 1941, 2786, 2786, 1794, 1946, + 1793, 2351, 1928, 1645, 1487, 1487, 1949, 1942, 1792, 2786, + 2786, 2786, 1980, 2786, 1793, 1947, 1648, 2786, 2358, 2359, + 1793, 2360, 660, 661, 662, 663, 664, 665, 1793, 1793, + + 2786, 1928, 2097, 2097, 2097, 1949, 1942, 700, 701, 702, + 703, 704, 705, 2786, 1929, 2786, 1948, 1545, 2361, 1794, + 2362, 2364, 2325, 2325, 2325, 1794, 2786, 1793, 700, 701, + 702, 703, 704, 705, 1933, 1645, 1487, 1487, 2786, 2786, + 1792, 1943, 2166, 2166, 2166, 1948, 2786, 2361, 1648, 2362, + 2364, 1936, 1936, 2786, 2786, 1936, 2167, 1936, 1936, 1936, + 1793, 2032, 1794, 700, 701, 702, 703, 704, 705, 757, + 2374, 1952, 2786, 746, 747, 748, 749, 750, 751, 2786, + 2786, 759, 397, 2340, 1955, 2786, 2786, 2786, 2786, 1793, + 2786, 2098, 2786, 2341, 399, 2786, 2786, 2786, 2786, 2374, + + 1957, 1684, 912, 912, 912, 912, 912, 912, 912, 912, + 759, 2326, 2340, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 2341, 399, 1794, 1645, 1487, 1487, 2786, 1957, + 1792, 2168, 473, 474, 475, 476, 477, 478, 1648, 2786, + 2049, 2786, 746, 747, 748, 749, 750, 751, 2786, 2375, + 1793, 2786, 2376, 2378, 2786, 377, 378, 379, 380, 381, + 382, 377, 378, 379, 380, 381, 382, 2786, 2786, 2049, + 1958, 2379, 2786, 2786, 2786, 2332, 2332, 2332, 2375, 1793, + 2786, 2376, 2378, 660, 661, 662, 663, 664, 665, 1959, + 1694, 912, 912, 912, 912, 912, 912, 912, 912, 1958, + + 2379, 1960, 2786, 1645, 1935, 1935, 1935, 1935, 1935, 1935, + 1935, 1935, 2786, 2786, 1794, 1645, 1487, 1487, 1959, 2786, + 1792, 377, 378, 379, 380, 381, 382, 2786, 1648, 2786, + 1960, 1965, 1966, 660, 661, 662, 663, 664, 665, 2786, + 1793, 377, 378, 379, 380, 381, 382, 377, 378, 379, + 380, 381, 382, 377, 378, 379, 380, 381, 382, 2786, + 1965, 1966, 2786, 2786, 2333, 2786, 2212, 2212, 2212, 1793, + 2786, 2786, 2786, 2786, 2380, 377, 378, 379, 380, 381, + 382, 1723, 1967, 2786, 2786, 2786, 377, 378, 379, 380, + 381, 382, 1968, 1935, 1935, 1935, 1935, 1935, 1935, 1935, + + 1935, 1935, 2786, 2380, 1794, 1645, 1487, 1487, 2786, 2786, + 1792, 1967, 377, 378, 379, 380, 381, 382, 1648, 2786, + 2387, 1968, 2786, 2388, 2389, 2391, 2786, 1976, 2786, 2786, + 1793, 2786, 2382, 2382, 2382, 377, 378, 379, 380, 381, + 382, 1975, 2392, 377, 378, 379, 380, 381, 382, 2387, + 2786, 2786, 2388, 2389, 2391, 2213, 1976, 2786, 2786, 1793, + 1986, 466, 466, 466, 466, 466, 466, 466, 466, 2393, + 1975, 2392, 1981, 2786, 2786, 377, 378, 379, 380, 381, + 382, 2786, 2786, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 2786, 2034, 1794, 1645, 1487, 1487, 2393, 2786, + + 1792, 1981, 377, 378, 379, 380, 381, 382, 1648, 1988, + 1722, 912, 912, 912, 912, 912, 912, 912, 912, 2394, + 1793, 2383, 2034, 2786, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 2786, 2786, 1988, 2786, + 473, 474, 475, 476, 477, 478, 2786, 2786, 2394, 1793, + 2786, 757, 397, 2369, 2372, 377, 378, 379, 380, 381, + 382, 2786, 2025, 1095, 818, 377, 378, 379, 380, 381, + 382, 2786, 2786, 1936, 1936, 1936, 1936, 1936, 1936, 1936, + 1936, 1936, 2396, 2786, 1794, 1645, 1487, 1487, 2786, 2786, + 1792, 2025, 1095, 818, 2786, 2786, 2399, 2030, 1648, 1755, + + 912, 912, 912, 912, 912, 912, 912, 912, 2786, 2786, + 1793, 2396, 377, 378, 379, 380, 381, 382, 502, 377, + 378, 379, 380, 381, 382, 2399, 2030, 2786, 2033, 2786, + 2402, 2083, 2083, 2083, 502, 2786, 2255, 2255, 2255, 1793, + 502, 2188, 2188, 2188, 377, 378, 379, 380, 381, 382, + 2036, 1756, 2786, 2035, 2786, 2786, 1685, 2033, 502, 2402, + 2084, 2410, 2786, 1936, 1936, 1936, 1936, 1936, 1936, 1936, + 1936, 1936, 502, 2786, 1794, 1645, 1487, 1487, 2786, 2036, + 1792, 473, 474, 475, 476, 477, 478, 2786, 1648, 2084, + 2410, 509, 510, 515, 512, 513, 514, 2412, 2413, 2786, + + 1793, 2786, 502, 2786, 2786, 2786, 2786, 509, 510, 515, + 512, 513, 514, 509, 510, 515, 512, 513, 514, 502, + 2085, 2786, 2037, 2068, 2786, 2256, 2412, 2413, 502, 1793, + 2189, 509, 510, 515, 512, 513, 514, 2038, 502, 700, + 701, 702, 703, 704, 705, 509, 510, 515, 512, 513, + 514, 2037, 2068, 1937, 1937, 1937, 1937, 1937, 1937, 1937, + 1937, 1937, 2416, 2786, 1794, 2786, 2038, 2786, 2786, 660, + 661, 662, 663, 664, 665, 509, 510, 515, 512, 513, + 514, 2384, 2384, 2384, 2786, 1645, 1487, 1487, 2786, 2786, + 1792, 2416, 509, 510, 515, 512, 513, 514, 1648, 2786, + + 2786, 509, 510, 515, 512, 513, 514, 2050, 2786, 2786, + 1793, 509, 510, 515, 512, 513, 514, 1645, 1487, 1487, + 2786, 2786, 1792, 2786, 2053, 1932, 1932, 2786, 2067, 2054, + 1648, 2786, 2786, 1939, 1932, 1932, 2050, 2055, 1940, 1793, + 2417, 2786, 1793, 1645, 1487, 1487, 1941, 2418, 1792, 2056, + 2060, 1487, 1487, 2419, 2420, 1940, 1648, 2067, 1942, 2421, + 1939, 1932, 1932, 1941, 2786, 1940, 2786, 2422, 1793, 2417, + 2385, 1793, 2423, 1941, 1794, 1942, 2418, 2786, 2056, 2090, + 2090, 2090, 2419, 2420, 2786, 1942, 2786, 1942, 2421, 660, + 661, 662, 663, 664, 665, 1645, 2422, 1793, 2070, 2786, + + 2424, 2423, 2425, 2786, 1942, 2786, 1794, 2426, 2091, 2786, + 2786, 2786, 2427, 2057, 1942, 2062, 1487, 1487, 2786, 2428, + 2054, 2058, 1943, 2786, 2786, 2786, 2786, 2070, 2055, 2424, + 2786, 2425, 1794, 1645, 1487, 1487, 2426, 2091, 1792, 2061, + 2056, 2427, 2060, 1487, 1487, 2069, 1648, 1940, 2428, 1943, + 2429, 2071, 2060, 1487, 1487, 2064, 2430, 1940, 1793, 700, + 701, 702, 703, 704, 705, 1941, 2786, 1942, 2092, 2056, + 2060, 1487, 1487, 2786, 2069, 1940, 2437, 1942, 2786, 2429, + 2071, 2786, 2786, 1941, 2786, 2430, 2786, 1793, 700, 701, + 702, 703, 704, 705, 2065, 1942, 1942, 700, 701, 702, + + 703, 704, 705, 2438, 2063, 2437, 1942, 2152, 757, 2439, + 2074, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 759, 2786, 1794, 2065, 1942, 397, 2786, 2077, 2786, 2441, + 2786, 2061, 2438, 1978, 1978, 1978, 2152, 399, 2439, 2786, + 2786, 2061, 2786, 2786, 2786, 2450, 2786, 2451, 2066, 759, + 2786, 377, 378, 379, 380, 381, 382, 2786, 2441, 2061, + 2079, 2786, 1979, 2786, 2456, 2457, 399, 2462, 473, 474, + 475, 476, 477, 478, 2450, 2081, 2451, 2080, 2786, 2463, + 2464, 746, 747, 748, 749, 750, 751, 2151, 2786, 2079, + 2087, 1979, 2786, 2456, 2457, 2786, 2462, 2786, 377, 378, + + 379, 380, 381, 382, 2081, 2786, 2080, 2786, 2463, 2464, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2086, 2087, + 2786, 2096, 1980, 377, 378, 379, 380, 381, 382, 2786, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 2786, 2465, 2473, 2088, 2786, 2086, 2786, 2786, + 2096, 377, 378, 379, 380, 381, 382, 2786, 473, 474, + 475, 476, 477, 478, 2786, 377, 378, 379, 380, 381, + 382, 2095, 2465, 2473, 2088, 2786, 2786, 2786, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, 2145, + + 2095, 1850, 912, 912, 912, 912, 912, 912, 912, 912, + 2112, 2112, 2112, 2147, 2147, 2147, 2786, 2153, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 2786, 2145, 2786, + 377, 378, 379, 380, 381, 382, 2786, 2786, 2476, 2113, + 502, 2478, 2148, 2479, 2480, 2786, 2153, 502, 2786, 2786, + 377, 378, 379, 380, 381, 382, 2170, 502, 2155, 2313, + 2313, 2313, 2786, 2786, 2786, 502, 2154, 2476, 2113, 2156, + 2478, 2148, 2479, 2480, 473, 474, 475, 476, 477, 478, + 2481, 2482, 2193, 2193, 2193, 2170, 2786, 2155, 2786, 377, + 378, 379, 380, 381, 382, 2154, 2786, 1695, 2156, 2114, + + 2157, 2786, 2149, 660, 661, 662, 663, 664, 665, 2481, + 2482, 2786, 2786, 509, 510, 515, 512, 513, 514, 2786, + 509, 510, 515, 512, 513, 514, 2315, 2315, 2315, 2485, + 509, 510, 515, 512, 513, 514, 2786, 2786, 509, 510, + 515, 512, 513, 514, 1645, 1487, 1487, 2483, 2314, 1792, + 2062, 1487, 1487, 2786, 2486, 2054, 2484, 1648, 2485, 2053, + 1932, 1932, 2786, 2055, 2054, 2062, 1487, 1487, 2786, 1793, + 2054, 2194, 2055, 2487, 2488, 2056, 2483, 2171, 2055, 2786, + 2062, 1487, 1487, 2486, 2056, 2054, 2062, 1487, 1487, 2786, + 2056, 2054, 2786, 2172, 2786, 2062, 1487, 1487, 1793, 2055, + + 2054, 2489, 2487, 2488, 2056, 2056, 2171, 2490, 2055, 2493, + 2786, 2056, 2786, 2056, 2494, 2316, 1645, 1487, 1487, 2056, + 2056, 1792, 2060, 1487, 1487, 2786, 2495, 1940, 2173, 1648, + 2489, 2786, 2496, 1794, 2056, 1941, 2490, 2786, 2493, 2063, + 2056, 1793, 2786, 2494, 757, 2497, 2445, 1942, 2057, 2056, + 2786, 2298, 2298, 2298, 2063, 2495, 1095, 2173, 2060, 1487, + 1487, 2496, 2786, 1940, 2786, 2786, 1851, 2786, 2498, 2063, + 1793, 1941, 2499, 2174, 2497, 2063, 1942, 2062, 1487, 1487, + 2786, 2786, 2054, 1942, 2063, 1095, 397, 2786, 2448, 2786, + 2055, 2062, 1487, 1487, 1931, 2786, 2054, 2498, 818, 2786, + + 2786, 2499, 2056, 2178, 2055, 1794, 2507, 2786, 1939, 1932, + 1932, 2061, 1942, 1940, 2491, 2492, 2056, 2060, 1487, 1487, + 2786, 2064, 1940, 2786, 2060, 1487, 1487, 818, 2786, 1940, + 1941, 2056, 2178, 1942, 2179, 2507, 2175, 1941, 2508, 2177, + 2299, 2180, 1942, 2491, 2492, 2056, 757, 2061, 2183, 1942, + 2786, 660, 661, 662, 663, 664, 665, 2786, 759, 2083, + 2083, 2083, 1942, 2179, 2786, 2786, 2063, 2508, 2177, 2176, + 2180, 1942, 377, 378, 379, 380, 381, 382, 1942, 2786, + 2063, 700, 701, 702, 703, 704, 705, 759, 2084, 700, + 701, 702, 703, 704, 705, 2786, 397, 1943, 2186, 2212, + + 2212, 2212, 1939, 2786, 2786, 2786, 2061, 2786, 399, 2786, + 2786, 2786, 2786, 2061, 1723, 2786, 2509, 2084, 2510, 746, + 747, 748, 749, 750, 751, 2786, 2786, 2400, 2400, 2400, + 377, 378, 379, 380, 381, 382, 2786, 399, 377, 378, + 379, 380, 381, 382, 2786, 2509, 2511, 2510, 2085, 2255, + 2255, 2255, 377, 378, 379, 380, 381, 382, 2520, 2786, + 2192, 2786, 2521, 2199, 1756, 2090, 2090, 2090, 2786, 377, + 378, 379, 380, 381, 382, 2511, 377, 378, 379, 380, + 381, 382, 2452, 2452, 2452, 2786, 2200, 2520, 2213, 2192, + 2260, 2521, 2199, 2786, 2091, 2205, 2205, 2205, 2112, 2112, + + 2112, 2786, 2134, 2134, 2134, 2454, 2454, 2454, 2786, 377, + 378, 379, 380, 381, 382, 2200, 2401, 377, 378, 379, + 380, 381, 382, 2091, 2206, 2786, 2234, 2113, 2524, 2235, + 2262, 2786, 377, 378, 379, 380, 381, 382, 2256, 2786, + 2382, 2382, 2382, 2236, 2525, 2786, 2147, 2147, 2147, 2786, + 2466, 2466, 2466, 2206, 2092, 2234, 2113, 2524, 2235, 2262, + 2254, 473, 474, 475, 476, 477, 478, 2526, 2529, 2786, + 2786, 2453, 2236, 2525, 502, 2148, 2530, 473, 474, 475, + 476, 477, 478, 502, 2207, 2786, 2786, 2114, 2786, 2254, + 2261, 2135, 2242, 502, 2455, 2786, 2526, 2529, 2243, 502, + + 2786, 2263, 2244, 2245, 2148, 2530, 2786, 2246, 2247, 2248, + 2786, 2249, 377, 378, 379, 380, 381, 382, 2786, 2261, + 2786, 2242, 2270, 2270, 2270, 2264, 2531, 2243, 2786, 2383, + 2263, 2244, 2245, 2533, 2786, 2149, 2246, 2247, 2248, 2467, + 2249, 473, 474, 475, 476, 477, 478, 509, 510, 515, + 512, 513, 514, 2539, 2264, 2531, 509, 510, 515, 512, + 513, 514, 2533, 2271, 2786, 2786, 509, 510, 515, 512, + 513, 514, 509, 510, 515, 512, 513, 514, 1645, 1487, + 1487, 2540, 2539, 1792, 2053, 1932, 1932, 2543, 2786, 2054, + 2786, 1648, 2271, 2062, 1487, 1487, 2786, 2172, 2054, 2062, + + 1487, 1487, 2786, 1793, 2054, 2544, 2055, 2786, 2786, 2056, + 2540, 2272, 2055, 2545, 2546, 2275, 2543, 757, 2056, 2281, + 2060, 1487, 1487, 2547, 2056, 1940, 2062, 1487, 1487, 759, + 2786, 2054, 1793, 1941, 2544, 2060, 1487, 1487, 2056, 2055, + 1940, 2786, 2545, 2546, 2275, 1942, 2786, 2056, 1941, 2548, + 2786, 2056, 2547, 2056, 2549, 2786, 2550, 2551, 759, 397, + 1942, 2284, 2786, 2786, 2786, 2786, 2786, 1794, 2276, 2786, + 2277, 399, 2786, 2057, 1942, 2786, 2552, 2053, 2548, 2278, + 2056, 2553, 2063, 2549, 2786, 2550, 2551, 2786, 2063, 1942, + 746, 747, 748, 749, 750, 751, 2786, 2276, 2060, 2277, + + 399, 2294, 2289, 2786, 2062, 2552, 2786, 2786, 2278, 2061, + 2553, 2786, 2786, 2786, 2786, 2063, 660, 661, 662, 663, + 664, 665, 2786, 2353, 2061, 700, 701, 702, 703, 704, + 705, 2289, 377, 378, 379, 380, 381, 382, 2295, 377, + 378, 379, 380, 381, 382, 2205, 2205, 2205, 377, 378, + 379, 380, 381, 382, 2786, 2786, 2342, 377, 378, 379, + 380, 381, 382, 2354, 2343, 502, 2786, 2295, 2786, 2786, + 2786, 2344, 2355, 2356, 2206, 502, 2298, 2298, 2298, 377, + 378, 379, 380, 381, 382, 2342, 2366, 2357, 2554, 2786, + 2786, 1851, 2354, 2343, 473, 474, 475, 476, 477, 478, + + 2344, 2355, 2356, 2206, 2786, 2474, 2474, 2474, 473, 474, + 475, 476, 477, 478, 2786, 2786, 2357, 2554, 473, 474, + 475, 476, 477, 478, 660, 661, 662, 663, 664, 665, + 2786, 2062, 1487, 1487, 2207, 2367, 2054, 2555, 509, 510, + 515, 512, 513, 514, 2055, 2400, 2400, 2400, 509, 510, + 515, 512, 513, 514, 2433, 2786, 2056, 2060, 1487, 1487, + 2556, 2786, 1940, 2557, 2365, 2299, 2555, 757, 2786, 2370, + 1941, 2786, 2786, 700, 701, 702, 703, 704, 705, 759, + 2786, 2558, 1942, 2433, 397, 2056, 2373, 2377, 2786, 2556, + 2786, 2786, 2557, 2365, 2475, 2786, 399, 2786, 2559, 2786, + + 473, 474, 475, 476, 477, 478, 2381, 2786, 759, 2432, + 2558, 1942, 2469, 2469, 2469, 2786, 2377, 2320, 2320, 2320, + 2063, 2786, 2500, 2500, 2500, 399, 2470, 2559, 377, 378, + 379, 380, 381, 382, 2401, 2381, 2332, 2332, 2332, 2786, + 746, 747, 748, 749, 750, 751, 2061, 2325, 2325, 2325, + 2403, 2786, 2322, 2322, 2322, 2786, 2786, 377, 378, 379, + 380, 381, 382, 377, 378, 379, 380, 381, 382, 2434, + 377, 378, 379, 380, 381, 382, 2414, 2786, 2405, 2403, + 473, 474, 475, 476, 477, 478, 502, 2786, 2408, 2062, + 1487, 1487, 2406, 502, 2054, 2442, 2786, 2560, 2434, 2786, + + 2561, 2471, 2055, 2786, 2786, 2414, 2321, 2405, 757, 2786, + 2446, 2501, 2786, 2435, 2056, 2443, 2786, 2408, 2436, 2562, + 759, 2406, 2569, 2786, 2442, 2333, 2560, 2786, 2503, 2561, + 473, 474, 475, 476, 477, 478, 2326, 2786, 397, 2786, + 2449, 2323, 2435, 2056, 2443, 2786, 2786, 2436, 2562, 759, + 399, 2569, 660, 661, 662, 663, 664, 665, 2786, 509, + 510, 515, 512, 513, 514, 2786, 509, 510, 515, 512, + 513, 514, 700, 701, 702, 703, 704, 705, 2063, 399, + 2786, 746, 747, 748, 749, 750, 751, 2786, 2504, 377, + 378, 379, 380, 381, 382, 2384, 2384, 2384, 2458, 473, + + 474, 475, 476, 477, 478, 473, 474, 475, 476, 477, + 478, 377, 378, 379, 380, 381, 382, 2504, 502, 2786, + 2786, 2570, 2571, 2512, 502, 2578, 2579, 2458, 2460, 2452, + 2452, 2452, 2454, 2454, 2454, 2786, 757, 2786, 2515, 2786, + 473, 474, 475, 476, 477, 478, 2505, 2513, 1095, 2786, + 2570, 2571, 2512, 2506, 2578, 2579, 2786, 2460, 2786, 2786, + 377, 378, 379, 380, 381, 382, 757, 397, 2516, 2518, + 2527, 2527, 2527, 2786, 2580, 2505, 2513, 1095, 759, 818, + 2786, 2786, 2506, 2786, 2385, 660, 661, 662, 663, 664, + 665, 509, 510, 515, 512, 513, 514, 509, 510, 515, + + 512, 513, 514, 2580, 397, 2786, 2519, 759, 818, 700, + 701, 702, 703, 704, 705, 2786, 399, 2565, 2453, 2786, + 2786, 2455, 377, 378, 379, 380, 381, 382, 2466, 2466, + 2466, 2566, 2469, 2469, 2469, 2534, 2534, 2534, 2581, 746, + 747, 748, 749, 750, 751, 399, 2470, 2474, 2474, 2474, + 2500, 2500, 2500, 2786, 2527, 2527, 2527, 502, 2786, 2528, + 2566, 660, 661, 662, 663, 664, 665, 2581, 2786, 2786, + 2786, 2535, 502, 757, 2582, 2573, 2536, 377, 378, 379, + 380, 381, 382, 2567, 2568, 1095, 2587, 2541, 473, 474, + 475, 476, 477, 478, 473, 474, 475, 476, 477, 478, + + 2535, 2786, 2786, 2582, 2786, 2536, 700, 701, 702, 703, + 704, 705, 2567, 2568, 1095, 2587, 2541, 2467, 2534, 2534, + 2534, 2471, 2588, 2786, 2537, 757, 397, 2574, 2576, 2589, + 509, 510, 515, 512, 513, 514, 2475, 759, 818, 2501, + 397, 2590, 2577, 2528, 2592, 509, 510, 515, 512, 513, + 514, 2588, 399, 2593, 2535, 2594, 2595, 2596, 2589, 2536, + 2597, 2598, 2599, 2600, 2601, 2602, 759, 818, 2603, 2613, + 2590, 2786, 2786, 2592, 2786, 2604, 2605, 2606, 502, 2607, + 2608, 399, 2593, 2535, 2594, 2595, 2596, 2786, 2536, 2597, + 2598, 2599, 2600, 2601, 2602, 2609, 2610, 2603, 746, 747, + + 748, 749, 750, 751, 2604, 2605, 2606, 2537, 2607, 2608, + 2611, 2786, 502, 377, 378, 379, 380, 381, 382, 2614, + 2616, 2617, 2786, 2786, 2609, 2610, 757, 2786, 2619, 2624, + 2641, 2641, 2641, 2786, 757, 2786, 2620, 2615, 1095, 2611, + 473, 474, 475, 476, 477, 478, 759, 2625, 2614, 2616, + 2617, 509, 510, 515, 512, 513, 514, 397, 2624, 2622, + 473, 474, 475, 476, 477, 478, 2615, 1095, 2626, 818, + 2627, 2628, 397, 2629, 2623, 759, 2625, 2633, 473, 474, + 475, 476, 477, 478, 399, 509, 510, 515, 512, 513, + 514, 2634, 2637, 2638, 2639, 2640, 2643, 2626, 818, 2627, + + 2628, 2644, 2629, 2645, 2646, 2647, 2633, 746, 747, 748, + 749, 750, 751, 399, 2648, 2649, 2654, 2786, 2786, 2642, + 2634, 2637, 2638, 2639, 2640, 2643, 2650, 2651, 2652, 502, + 2644, 2655, 2645, 2646, 2647, 2662, 2663, 2664, 2786, 757, + 757, 2657, 2658, 2648, 2649, 377, 378, 379, 380, 381, + 382, 1095, 759, 2666, 2667, 2650, 2651, 2652, 2786, 397, + 2655, 2660, 2786, 2786, 2662, 2663, 2664, 397, 2668, 2661, + 2669, 818, 2670, 2672, 2672, 2672, 2641, 2641, 2641, 399, + 1095, 759, 2666, 2667, 2641, 2641, 2641, 473, 474, 475, + 476, 477, 478, 2671, 2674, 2676, 2677, 2668, 2678, 2669, + + 818, 2670, 509, 510, 515, 512, 513, 514, 399, 2679, + 2680, 2786, 2786, 746, 747, 748, 749, 750, 751, 2681, + 2682, 2691, 2671, 2674, 2676, 2677, 2692, 2678, 473, 474, + 475, 476, 477, 478, 757, 757, 2686, 2687, 2679, 2680, + 377, 378, 379, 380, 381, 382, 1095, 759, 2681, 2682, + 2691, 397, 397, 2689, 2690, 2692, 2693, 2694, 2695, 2696, + 2699, 2702, 2673, 818, 399, 2642, 2672, 2672, 2672, 2700, + 2700, 2700, 2703, 2642, 2704, 1095, 759, 2786, 2786, 757, + 2786, 2706, 2786, 2786, 2786, 2693, 2694, 2695, 2696, 2699, + 2702, 1095, 818, 399, 757, 397, 2707, 2709, 2786, 2786, + + 2786, 2703, 397, 2704, 2690, 2710, 759, 818, 746, 747, + 748, 749, 750, 751, 399, 2711, 2712, 2713, 2714, 2715, + 1095, 2716, 2719, 2720, 2721, 377, 378, 379, 380, 381, + 382, 2724, 2786, 2729, 2710, 759, 818, 2700, 2700, 2700, + 2786, 2786, 2786, 399, 2711, 2712, 2713, 2714, 2715, 2786, + 2716, 2719, 2720, 2721, 757, 2673, 2723, 2730, 2701, 2786, + 2724, 757, 2729, 2707, 2717, 2786, 1095, 746, 747, 748, + 749, 750, 751, 759, 2731, 377, 378, 379, 380, 381, + 382, 2732, 397, 2733, 2709, 2734, 2730, 2735, 2725, 2725, + 2725, 2736, 2742, 2717, 818, 1095, 2726, 2786, 2745, 757, + + 2746, 2723, 759, 2731, 2747, 2725, 2725, 2725, 2786, 2786, + 2732, 1095, 2733, 2726, 2734, 2748, 2735, 2749, 2751, 2752, + 2736, 2742, 2753, 818, 2754, 2755, 2701, 2745, 2758, 2746, + 2756, 2756, 2756, 2747, 746, 747, 748, 749, 750, 751, + 1095, 2759, 2760, 2761, 2748, 2766, 2749, 2751, 2752, 2767, + 2786, 2753, 2768, 2754, 2755, 2769, 2771, 2758, 2762, 2762, + 2762, 2756, 2756, 2756, 2762, 2762, 2762, 2786, 2772, 2773, + 2759, 2760, 2761, 2786, 2766, 2774, 2775, 2727, 2767, 2728, + 2776, 2768, 2777, 2778, 2769, 2771, 2762, 2762, 2762, 2641, + 2641, 2641, 2779, 2780, 2727, 2781, 2728, 2772, 2773, 2782, + + 2783, 2784, 2764, 2785, 2774, 2775, 2762, 2762, 2762, 2776, + 2786, 2777, 2778, 2786, 2786, 2786, 2786, 2786, 2786, 2757, + 2786, 2779, 2780, 2786, 2781, 2786, 2786, 2786, 2782, 2783, + 2784, 2764, 2785, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2763, 2786, 2786, + 2757, 2786, 2786, 2763, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2763, 2786, 2786, 2642, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2763, 125, 125, 125, 125, + + 125, 125, 125, 125, 125, 125, 125, 125, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, + + 239, 239, 239, 239, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 337, 337, 337, 337, 337, 337, + 337, 337, 337, 337, 337, 337, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, 361, 361, + 361, 369, 369, 2786, 369, 369, 369, 369, 369, 369, + + 369, 369, 369, 376, 376, 383, 383, 383, 456, 456, + 2786, 2786, 2786, 2786, 2786, 456, 472, 472, 500, 500, + 2786, 500, 500, 2786, 500, 500, 538, 538, 538, 545, + 545, 552, 552, 552, 564, 564, 2786, 2786, 2786, 2786, + 2786, 564, 580, 2786, 580, 601, 2786, 601, 625, 625, + 625, 625, 625, 625, 2786, 625, 625, 625, 2786, 625, + 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 632, 632, 632, 632, 632, 632, 2786, 632, + 632, 632, 2786, 632, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 644, 644, 644, 644, + + 644, 644, 644, 644, 644, 644, 644, 644, 645, 645, + 645, 645, 645, 645, 645, 645, 645, 645, 645, 647, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 652, 652, 2786, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 659, 659, 684, 684, 2786, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 692, 692, 2786, 692, + 692, 692, 692, 692, 692, 692, 692, 692, 699, 699, + 718, 718, 738, 738, 2786, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 745, 745, 772, 772, 2786, 772, + 772, 772, 772, 772, 772, 772, 772, 772, 779, 779, + + 2786, 779, 779, 779, 779, 779, 779, 779, 779, 779, + 361, 361, 361, 368, 368, 2786, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 369, 369, 2786, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 376, 376, 383, + 383, 383, 456, 456, 2786, 2786, 2786, 2786, 2786, 456, + 472, 472, 500, 500, 2786, 500, 500, 2786, 500, 500, + 538, 538, 538, 545, 545, 552, 552, 552, 564, 564, + 2786, 2786, 2786, 2786, 2786, 564, 580, 2786, 580, 601, + 2786, 601, 625, 625, 625, 625, 625, 625, 2786, 625, + 625, 625, 2786, 625, 1010, 1010, 2786, 1010, 1010, 1010, + + 1010, 1010, 1010, 1010, 1010, 1010, 632, 632, 632, 632, + 632, 632, 2786, 632, 632, 632, 2786, 632, 1015, 1015, + 2786, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, + 1020, 1020, 2786, 1020, 1020, 1020, 1020, 1020, 1020, 1020, + 1020, 1020, 645, 645, 645, 645, 645, 645, 645, 645, + 645, 645, 645, 647, 647, 647, 647, 647, 647, 647, + 647, 647, 647, 647, 651, 651, 2786, 651, 651, 651, + 651, 651, 651, 651, 651, 651, 652, 652, 2786, 652, + 652, 652, 652, 652, 652, 652, 652, 652, 659, 659, + 684, 684, 2786, 684, 684, 684, 684, 684, 684, 684, + + 684, 684, 691, 691, 2786, 691, 691, 691, 691, 691, + 691, 691, 691, 691, 692, 692, 2786, 692, 692, 692, + 692, 692, 692, 692, 692, 692, 699, 699, 718, 718, + 737, 737, 2786, 737, 737, 737, 737, 737, 737, 737, + 737, 737, 738, 738, 2786, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 745, 745, 772, 772, 2786, 772, + 772, 772, 772, 772, 772, 772, 772, 772, 779, 779, + 2786, 779, 779, 779, 779, 779, 779, 779, 779, 779, + 368, 368, 2786, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + + 1129, 1129, 1129, 1129, 376, 376, 2786, 2786, 376, 472, + 472, 500, 500, 2786, 2786, 500, 545, 545, 580, 2786, + 580, 601, 2786, 601, 1010, 1010, 2786, 1010, 1010, 1010, + 1010, 1010, 1010, 1010, 1010, 1010, 1015, 1015, 2786, 1015, + 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1020, 1020, + 2786, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, + 651, 651, 2786, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + 1283, 1283, 1283, 1283, 659, 659, 1295, 1295, 1295, 1295, + 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 691, 691, + + 2786, 691, 691, 691, 691, 691, 691, 691, 691, 691, + 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, + 1303, 1303, 699, 699, 718, 718, 737, 737, 2786, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 1316, 1316, + 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, + 745, 745, 2786, 2786, 745, 1329, 1329, 1329, 1329, 1329, + 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1335, 1335, 1335, + 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 361, + 361, 361, 369, 369, 2786, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 368, 368, 2786, 368, 368, 368, + + 368, 368, 368, 368, 368, 368, 383, 383, 383, 1129, + 1129, 2786, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + 1129, 376, 376, 2786, 2786, 376, 456, 456, 2786, 2786, + 2786, 2786, 2786, 456, 472, 472, 500, 500, 2786, 2786, + 500, 500, 538, 538, 538, 552, 552, 552, 545, 545, + 564, 564, 2786, 2786, 2786, 2786, 2786, 564, 580, 2786, + 580, 601, 2786, 601, 1468, 1468, 1468, 1468, 1468, 1468, + 1468, 1468, 1468, 1468, 1468, 1468, 1473, 1473, 1473, 1473, + 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1478, 1478, + 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, + + 652, 652, 2786, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 651, 651, 2786, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 1283, 1283, 2786, 1283, 1283, 1283, + 1283, 1283, 1283, 1283, 1283, 1283, 659, 659, 1295, 1295, + 2786, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, + 692, 692, 2786, 692, 692, 692, 692, 692, 692, 692, + 692, 692, 691, 691, 2786, 691, 691, 691, 691, 691, + 691, 691, 691, 691, 1303, 1303, 2786, 1303, 1303, 1303, + 1303, 1303, 1303, 1303, 1303, 1303, 699, 699, 718, 718, + 738, 738, 2786, 738, 738, 738, 738, 738, 738, 738, + + 738, 738, 737, 737, 2786, 737, 737, 737, 737, 737, + 737, 737, 737, 737, 1316, 1316, 2786, 1316, 1316, 1316, + 1316, 1316, 1316, 1316, 1316, 1316, 745, 745, 2786, 2786, + 745, 1329, 1329, 2786, 1329, 1329, 1329, 1329, 1329, 1329, + 1329, 1329, 1329, 1335, 1335, 2786, 1335, 1335, 1335, 1335, + 1335, 1335, 1335, 1335, 1335, 1129, 1129, 2786, 1129, 1129, + 1129, 1129, 1129, 1129, 1129, 1129, 1129, 376, 376, 2786, + 2786, 376, 472, 472, 500, 500, 2786, 2786, 500, 545, + 545, 580, 2786, 580, 601, 2786, 601, 1468, 1468, 2786, + 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1473, + + 1473, 2786, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, + 1473, 1478, 1478, 2786, 1478, 1478, 1478, 1478, 1478, 1478, + 1478, 1478, 1478, 1283, 1283, 2786, 1283, 1283, 1283, 1283, + 1283, 1283, 1283, 1283, 1283, 659, 659, 1295, 1295, 2786, + 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1303, + 1303, 2786, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, + 1303, 699, 699, 1644, 1644, 1644, 1644, 1644, 1644, 1644, + 1644, 1644, 1644, 1644, 1644, 1843, 1843, 1843, 1843, 1843, + 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1938, 1938, 1938, + 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1962, + + 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, + 1962, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, + 1970, 1970, 1970, 1993, 1993, 1993, 1993, 1993, 1993, 1993, + 1993, 1993, 1993, 1993, 1993, 2027, 2027, 2027, 2027, 2027, + 2027, 2027, 2027, 2027, 2027, 2027, 2027, 2052, 2052, 2052, + 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2104, + 2104, 2104, 2104, 2104, 2104, 2104, 2104, 2104, 2104, 2104, + 2104, 59, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786 } ; -static yyconst flex_int16_t yy_chk[17539] = +static yyconst flex_int16_t yy_chk[17967] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -3252,7 +3361,7 @@ static yyconst flex_int16_t yy_chk[17539] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -3262,10 +3371,9 @@ static yyconst flex_int16_t yy_chk[17539] = 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 5, 6, 64, 64, 64, 64, 64, 64, 2585, 5, + 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, + 66, 66, 66, 66, 66, 66, 2770, 5, 6, 7, - 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -3274,7 +3382,8 @@ static yyconst flex_int16_t yy_chk[17539] = 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -3284,8 +3393,8 @@ static yyconst flex_int16_t yy_chk[17539] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, @@ -3295,19 +3404,19 @@ static yyconst flex_int16_t yy_chk[17539] = 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 13, 13, 13, 27, - 14, 14, 14, 13, 28, 29, 13, 14, 13, 30, - - 14, 31, 14, 15, 15, 15, 32, 16, 16, 16, - 15, 39, 40, 15, 16, 15, 55, 16, 47, 16, - 48, 67, 67, 69, 55, 108, 69, 69, 70, 70, - 108, 27, 2580, 55, 39, 40, 28, 29, 89, 109, - 109, 30, 125, 132, 56, 55, 31, 125, 47, 2569, - 48, 32, 56, 55, 106, 106, 106, 106, 106, 106, - 130, 56, 55, 39, 40, 130, 151, 89, 2561, 137, - 166, 151, 132, 56, 2560, 166, 13, 47, 13, 48, - 14, 56, 14, 89, 89, 89, 89, 89, 89, 183, - 56, 191, 2559, 15, 183, 15, 191, 16, 137, 16, + 11, 13, 13, 13, 27, 14, 14, 14, 13, 28, + 29, 13, 14, 13, 30, 14, 31, 14, 15, 15, + + 15, 32, 16, 16, 16, 15, 39, 40, 15, 16, + 15, 110, 16, 47, 16, 48, 110, 71, 71, 57, + 71, 85, 99, 134, 139, 27, 2765, 57, 39, 40, + 28, 29, 127, 2763, 132, 30, 57, 127, 58, 132, + 31, 2757, 47, 2750, 48, 32, 58, 2741, 57, 153, + 85, 2740, 134, 139, 153, 58, 57, 39, 40, 99, + 99, 99, 99, 99, 99, 57, 2739, 58, 624, 624, + 13, 47, 13, 48, 14, 58, 14, 2731, 85, 85, + 85, 85, 85, 85, 58, 168, 2730, 15, 2728, 15, + 168, 16, 2727, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, @@ -3317,45 +3426,44 @@ static yyconst flex_int16_t yy_chk[17539] = 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 21, 21, 21, 22, 22, - - 22, 2552, 72, 21, 72, 72, 22, 23, 23, 23, - 65, 2551, 23, 2549, 23, 72, 23, 23, 24, 24, - 24, 97, 172, 24, 173, 24, 2548, 24, 24, 25, - 25, 25, 320, 320, 25, 135, 25, 25, 25, 25, - 26, 26, 26, 135, 72, 26, 174, 26, 26, 26, - 26, 172, 2545, 173, 83, 136, 1455, 76, 97, 97, - 97, 97, 97, 97, 135, 200, 323, 323, 2526, 136, - 200, 76, 135, 175, 76, 174, 72, 72, 72, 72, - 72, 72, 2511, 83, 136, 21, 76, 21, 22, 205, - 22, 65, 65, 65, 65, 65, 65, 23, 136, 23, - - 76, 221, 175, 76, 228, 2509, 221, 2507, 24, 228, - 24, 83, 83, 83, 83, 83, 83, 2501, 205, 25, - 2496, 25, 76, 76, 76, 76, 76, 76, 392, 392, - 26, 1455, 26, 37, 37, 37, 37, 37, 37, 37, + 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, + 21, 22, 22, 22, 688, 688, 21, 174, 2724, 22, + + 23, 23, 23, 67, 2722, 23, 2718, 23, 82, 23, + 23, 24, 24, 24, 1703, 1703, 24, 175, 24, 80, + 24, 24, 25, 25, 25, 80, 174, 25, 2708, 25, + 25, 25, 25, 26, 26, 26, 176, 82, 26, 2705, + 26, 26, 26, 26, 87, 177, 175, 136, 80, 78, + 185, 2701, 136, 2698, 80, 185, 82, 82, 82, 82, + 82, 82, 2688, 78, 2685, 176, 78, 80, 80, 80, + 80, 80, 80, 87, 177, 207, 136, 21, 78, 21, + 22, 136, 22, 67, 67, 67, 67, 67, 67, 23, + 2675, 23, 78, 193, 202, 78, 223, 2673, 193, 202, + + 24, 223, 24, 2671, 207, 87, 87, 87, 87, 87, + 87, 25, 2665, 25, 78, 78, 78, 78, 78, 78, + 323, 323, 26, 323, 26, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 41, 41, - 41, 77, 41, 41, 2443, 41, 41, 41, 42, 42, - 42, 41, 42, 42, 77, 42, 42, 42, 75, 134, - 2487, 42, 75, 78, 134, 138, 197, 197, 138, 78, - 77, 85, 149, 149, 149, 149, 149, 149, 2477, 41, - 206, 268, 322, 77, 2476, 322, 322, 75, 134, 42, - 2449, 75, 78, 134, 138, 197, 197, 138, 78, 2448, - 85, 2447, 77, 77, 77, 77, 77, 77, 41, 206, - - 268, 78, 78, 78, 78, 78, 78, 2444, 42, 75, - 75, 75, 75, 75, 75, 2441, 478, 2443, 41, 2430, - 41, 478, 85, 85, 85, 85, 85, 85, 42, 2413, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 41, + 41, 41, 2659, 41, 41, 2585, 41, 41, 41, 42, + 42, 42, 41, 42, 42, 230, 42, 42, 42, 74, + 230, 74, 42, 141, 91, 137, 81, 199, 199, 81, + 94, 74, 81, 137, 138, 141, 208, 94, 94, 41, + 108, 108, 108, 108, 108, 108, 269, 94, 138, 42, + 94, 2656, 141, 91, 137, 81, 199, 199, 81, 94, + 74, 81, 137, 138, 141, 208, 94, 94, 41, 91, + 91, 91, 91, 91, 91, 269, 94, 138, 42, 94, + + 81, 81, 81, 81, 81, 81, 479, 2585, 41, 2655, + 41, 479, 74, 74, 74, 74, 74, 74, 42, 2653, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, @@ -3363,21 +3471,20 @@ static yyconst flex_int16_t yy_chk[17539] = 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 45, 45, 45, 45, + 43, 43, 43, 43, 43, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 49, 49, 49, 49, 49, 49, 49, 49, 49, + + 45, 45, 45, 45, 45, 45, 45, 45, 45, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, @@ -3385,1793 +3492,1842 @@ static yyconst flex_int16_t yy_chk[17539] = 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 51, 51, 51, 480, - 480, 51, 2409, 52, 52, 52, 2408, 278, 52, 51, - 1599, 59, 59, 59, 312, 51, 52, 60, 60, 60, - 344, 496, 52, 139, 51, 62, 496, 53, 53, 53, - 80, 52, 53, 345, 1445, 139, 278, 54, 54, 54, - 53, 51, 54, 312, 622, 622, 53, 353, 52, 344, - 54, 2403, 139, 51, 2400, 53, 54, 687, 687, 80, - 52, 53, 345, 207, 139, 54, 2399, 354, 207, 356, - 51, 54, 245, 245, 245, 357, 353, 52, 80, 80, - - 80, 80, 80, 80, 53, 1599, 51, 81, 2395, 358, - 53, 81, 207, 52, 54, 81, 354, 207, 356, 2394, - 54, 59, 94, 515, 357, 582, 1445, 60, 515, 62, - 62, 62, 62, 62, 62, 2382, 81, 53, 358, 2362, - 81, 559, 612, 612, 81, 612, 559, 54, 63, 63, - 86, 94, 63, 63, 582, 90, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 90, 583, 63, 63, 63, - 63, 63, 81, 81, 81, 81, 81, 81, 580, 86, - 592, 148, 245, 580, 90, 592, 2360, 94, 94, 94, - 94, 94, 94, 584, 90, 583, 2356, 585, 63, 1450, - - 63, 86, 86, 86, 86, 86, 86, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 90, 90, 90, 90, - 90, 90, 584, 246, 246, 246, 585, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 74, 208, 74, 270, 270, 270, 526, - 74, 74, 74, 79, 82, 503, 79, 82, 503, 79, - 526, 208, 586, 587, 82, 148, 148, 148, 148, 148, - 148, 1450, 74, 208, 74, 271, 271, 271, 526, 74, - 74, 74, 79, 82, 503, 79, 82, 503, 79, 526, - 208, 586, 587, 82, 751, 751, 2352, 74, 74, 74, - - 74, 74, 74, 282, 282, 282, 2346, 79, 79, 79, - 79, 79, 79, 246, 84, 2342, 82, 82, 82, 82, - 82, 82, 84, 87, 92, 96, 505, 87, 84, 88, - 518, 92, 92, 96, 505, 87, 270, 88, 504, 87, - 518, 92, 96, 84, 92, 96, 88, 504, 2340, 88, - 2336, 84, 87, 92, 96, 505, 87, 84, 88, 518, - 92, 92, 96, 505, 87, 271, 88, 504, 87, 518, - 92, 96, 2335, 92, 96, 88, 504, 519, 88, 84, - 84, 84, 84, 84, 84, 519, 2331, 87, 87, 87, - 87, 87, 87, 282, 88, 88, 88, 88, 88, 88, - - 91, 506, 93, 91, 93, 517, 519, 93, 506, 91, - 110, 110, 517, 2330, 519, 91, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 818, 818, 1087, 1087, 91, - 506, 93, 91, 93, 517, 2304, 93, 506, 91, 2301, - 588, 517, 111, 589, 91, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 93, 93, 93, 93, 93, 93, - 95, 91, 91, 91, 91, 91, 91, 95, 95, 588, - 596, 111, 589, 2298, 603, 596, 601, 95, 114, 603, - 95, 2297, 110, 110, 110, 110, 110, 110, 2294, 95, - 111, 111, 111, 111, 111, 111, 95, 95, 249, 249, - - 249, 249, 249, 249, 2292, 601, 95, 114, 112, 95, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 112, 113, 114, - 114, 114, 114, 114, 114, 115, 116, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 1122, 1122, 1123, 1123, - 112, 112, 112, 112, 112, 112, 2286, 113, 238, 238, - 238, 150, 238, 238, 115, 116, 283, 283, 283, 1124, - 1124, 238, 2285, 113, 113, 113, 113, 113, 113, 1125, - 1125, 115, 115, 115, 115, 115, 115, 118, 118, 118, - - 118, 118, 118, 118, 118, 118, 2274, 116, 116, 116, - 116, 116, 116, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 127, - 127, 127, 150, 150, 150, 150, 150, 150, 238, 602, - 127, 2271, 127, 127, 1126, 1126, 283, 2270, 394, 394, - 129, 129, 129, 176, 605, 127, 127, 176, 127, 394, - 2263, 129, 2260, 129, 129, 606, 176, 127, 602, 127, - 176, 127, 286, 286, 286, 286, 286, 286, 131, 131, - - 131, 2258, 176, 605, 127, 127, 176, 127, 394, 131, - 154, 131, 131, 2257, 606, 176, 127, 615, 127, 176, - 127, 2248, 615, 2229, 131, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 2227, 396, 396, 127, 127, 127, - 127, 127, 127, 128, 128, 128, 396, 154, 154, 154, - 154, 154, 154, 131, 128, 152, 128, 128, 129, 129, - 129, 129, 129, 129, 1302, 1302, 232, 232, 232, 128, - 128, 232, 128, 232, 2221, 396, 1303, 1303, 2219, 232, - 2216, 128, 153, 128, 152, 128, 131, 131, 131, 131, - 131, 131, 301, 301, 301, 301, 301, 301, 128, 128, - - 527, 128, 318, 318, 318, 318, 318, 318, 527, 520, - 128, 153, 128, 140, 128, 520, 140, 140, 1304, 1304, - 152, 152, 152, 152, 152, 152, 140, 2211, 607, 527, - 140, 128, 128, 128, 128, 128, 128, 527, 520, 1305, - 1305, 2210, 140, 2207, 520, 140, 140, 153, 153, 153, - 153, 153, 153, 619, 2205, 140, 232, 607, 619, 140, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 146, 146, 146, 146, - - 146, 146, 146, 146, 146, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 156, 156, 156, 156, 156, 156, - 156, 156, 156, 157, 157, 157, 157, 157, 157, 157, - 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 159, 159, 159, 159, 159, 159, 159, 159, - 160, 160, 160, 160, 160, 160, 160, 160, 160, 235, - 235, 235, 255, 608, 235, 256, 235, 258, 256, 257, - 1306, 1306, 235, 261, 261, 261, 261, 261, 261, 261, - 261, 261, 262, 262, 262, 262, 262, 262, 262, 262, - 262, 255, 608, 609, 256, 2197, 258, 256, 257, 362, - - 377, 377, 377, 377, 377, 377, 2194, 255, 255, 255, - 255, 255, 255, 1664, 1664, 2401, 256, 256, 256, 256, - 256, 256, 609, 257, 257, 257, 257, 257, 257, 1597, - 1774, 1774, 258, 258, 258, 258, 258, 258, 259, 263, - 263, 263, 263, 263, 263, 263, 263, 263, 2188, 235, - 248, 248, 1782, 1782, 248, 248, 1789, 1789, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 259, 610, 248, - 248, 248, 248, 248, 264, 264, 264, 264, 264, 264, - 264, 264, 264, 362, 362, 362, 362, 362, 362, 259, - 259, 259, 259, 259, 259, 680, 685, 610, 1598, 2401, - - 248, 1597, 248, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 2187, 291, 292, 680, 685, 314, 314, 314, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 285, 285, 1803, 1803, 285, - 285, 291, 292, 285, 285, 285, 285, 285, 285, 285, - 285, 285, 1832, 1832, 285, 285, 285, 285, 285, 2175, - 1598, 1895, 1895, 291, 291, 291, 291, 291, 291, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 292, 292, - 292, 292, 292, 292, 293, 285, 2174, 285, 295, 295, - - 295, 295, 295, 295, 295, 295, 295, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 314, 401, 401, 401, - 401, 401, 401, 293, 285, 285, 285, 285, 285, 285, - 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, - 1903, 1903, 1917, 1917, 2163, 293, 293, 293, 293, 293, - 293, 297, 297, 297, 297, 297, 297, 297, 297, 297, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 51, 51, 51, 279, 497, 51, 52, + 52, 52, 497, 2642, 52, 313, 51, 61, 61, 61, + 140, 51, 52, 140, 55, 55, 55, 52, 2632, 55, + 51, 62, 62, 62, 2631, 279, 52, 55, 98, 77, + 343, 64, 55, 77, 313, 516, 98, 51, 344, 140, + 516, 55, 140, 52, 2621, 98, 352, 55, 98, 51, + 353, 56, 56, 56, 355, 52, 56, 98, 77, 343, + 79, 2618, 77, 2612, 56, 98, 51, 344, 356, 56, + 55, 2591, 52, 79, 98, 352, 55, 98, 56, 353, + 357, 2590, 51, 355, 56, 247, 247, 247, 52, 79, + + 77, 77, 77, 77, 77, 77, 61, 356, 504, 583, + 83, 504, 79, 55, 83, 2589, 560, 56, 83, 357, + 62, 560, 2586, 56, 64, 64, 64, 64, 64, 64, + 1471, 79, 79, 79, 79, 79, 79, 504, 583, 83, + 504, 581, 394, 83, 394, 96, 581, 83, 1828, 1828, + 56, 65, 65, 88, 394, 65, 65, 584, 92, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 92, 65, + 65, 65, 65, 65, 96, 83, 83, 83, 83, 83, + 83, 2583, 88, 394, 247, 1481, 584, 92, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 92, 585, 2575, + + 65, 1471, 65, 2530, 88, 88, 88, 88, 88, 88, + 96, 96, 96, 96, 96, 96, 395, 2572, 397, 92, + 92, 92, 92, 92, 92, 1476, 395, 585, 397, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 76, 84, 76, 586, 84, + 86, 527, 76, 76, 76, 395, 84, 397, 86, 1481, + 2726, 150, 527, 588, 86, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 76, 84, 76, 586, 84, 86, + 527, 76, 76, 76, 2564, 84, 2530, 86, 248, 248, + 248, 527, 588, 86, 614, 614, 1476, 614, 2563, 76, + + 76, 76, 76, 76, 76, 210, 90, 1635, 84, 84, + 84, 84, 84, 84, 90, 86, 86, 86, 86, 86, + 86, 89, 210, 90, 507, 89, 90, 95, 506, 95, + 520, 507, 95, 89, 210, 90, 506, 89, 520, 271, + 271, 271, 2726, 90, 150, 150, 150, 150, 150, 150, + 89, 210, 90, 507, 89, 90, 95, 506, 95, 520, + 507, 95, 89, 593, 597, 506, 89, 520, 593, 597, + 589, 90, 90, 90, 90, 90, 90, 248, 1635, 95, + 95, 95, 95, 95, 95, 89, 89, 89, 89, 89, + 89, 93, 505, 209, 93, 97, 2542, 113, 209, 589, + + 93, 505, 97, 97, 518, 523, 93, 521, 590, 602, + 209, 518, 97, 521, 523, 97, 272, 272, 272, 2538, + 93, 505, 209, 93, 97, 112, 113, 209, 271, 93, + 505, 97, 97, 518, 523, 93, 521, 590, 602, 209, + 518, 97, 521, 523, 97, 113, 113, 113, 113, 113, + 113, 1636, 93, 93, 93, 93, 93, 93, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 114, 115, 112, 112, 112, 112, + + 112, 112, 116, 603, 2537, 272, 117, 606, 118, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 1836, 1836, + 1843, 1843, 1636, 114, 115, 151, 151, 151, 151, 151, + 151, 116, 603, 604, 617, 117, 606, 118, 604, 617, + 115, 115, 115, 115, 115, 115, 114, 114, 114, 114, + 114, 114, 117, 117, 117, 117, 117, 117, 283, 283, + 283, 1861, 1861, 116, 116, 116, 116, 116, 116, 118, + 118, 118, 118, 118, 118, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 122, 122, 122, 122, 122, 122, 122, + + 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 129, 129, 129, 621, 607, 156, 2532, 608, 621, 609, + 818, 129, 818, 129, 129, 818, 152, 1893, 1893, 1962, + 1962, 131, 131, 131, 522, 129, 129, 283, 129, 610, + 2529, 522, 131, 607, 131, 131, 608, 129, 609, 129, + 587, 129, 156, 156, 156, 156, 156, 156, 133, 133, + 133, 1970, 1970, 522, 129, 129, 587, 129, 610, 133, + 522, 133, 133, 1985, 1985, 2528, 129, 1637, 129, 587, + 129, 1993, 1993, 133, 143, 143, 143, 143, 143, 143, + + 143, 143, 143, 2027, 2027, 587, 154, 129, 129, 129, + 129, 129, 129, 130, 130, 130, 152, 152, 152, 152, + 152, 152, 133, 2523, 130, 2522, 130, 130, 131, 131, + 131, 131, 131, 131, 611, 154, 612, 257, 130, 130, + 257, 130, 251, 251, 251, 251, 251, 251, 667, 667, + 130, 155, 130, 2517, 130, 133, 133, 133, 133, 133, + 133, 1637, 2514, 611, 2502, 612, 257, 130, 130, 257, + 130, 154, 154, 154, 154, 154, 154, 667, 667, 130, + 155, 130, 142, 130, 519, 142, 142, 2501, 257, 257, + 257, 257, 257, 257, 519, 142, 681, 686, 734, 142, + + 130, 130, 130, 130, 130, 130, 2477, 819, 2475, 819, + 2471, 142, 819, 519, 142, 142, 155, 155, 155, 155, + 155, 155, 2467, 519, 142, 681, 686, 734, 142, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 159, 159, 159, 159, 159, 159, 159, 159, + + 159, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 178, 234, + 234, 234, 178, 756, 234, 2461, 234, 2104, 2104, 258, + 259, 178, 234, 756, 774, 178, 237, 237, 237, 1844, + 821, 237, 821, 237, 1844, 821, 775, 178, 781, 237, + 260, 178, 240, 240, 240, 2459, 240, 240, 258, 259, + 178, 2455, 756, 774, 178, 240, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 775, 1963, 781, 782, 260, + 2453, 1963, 2447, 258, 258, 258, 258, 258, 258, 287, + + 287, 287, 287, 287, 287, 259, 259, 259, 259, 259, + 259, 260, 260, 260, 260, 260, 260, 782, 234, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 284, 284, + 284, 2444, 2431, 2415, 2409, 237, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 302, 302, 302, 302, 302, + 302, 240, 250, 250, 1971, 2407, 250, 250, 2404, 1971, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 292, + 250, 250, 250, 250, 250, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 315, 315, 315, 2401, 784, 292, 785, + + 786, 250, 2398, 250, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 1095, 2397, 1095, 2394, 284, 1095, 293, + 292, 292, 292, 292, 292, 292, 784, 2392, 785, 786, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 286, 286, 293, 294, + 286, 286, 977, 757, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 757, 286, 286, 286, 286, 286, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 294, 2386, + 2385, 977, 315, 2383, 293, 293, 293, 293, 293, 293, + 2371, 1096, 757, 1096, 1994, 286, 1096, 286, 2368, 1994, + + 294, 294, 294, 294, 294, 294, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 297, 297, 297, 297, 297, + 297, 297, 297, 297, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 298, 298, 298, 298, 298, 298, 298, 298, 298, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 304, 305, - 305, 305, 305, 305, 305, 305, 305, 305, 306, 306, + 299, 299, 299, 299, 299, 299, 299, 299, 300, 300, + 300, 300, 300, 300, 300, 300, 300, 305, 306, 306, 306, 306, 306, 306, 306, 306, 306, 307, 307, 307, - - 307, 307, 307, 307, 307, 307, 2161, 304, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 309, 309, 309, - 309, 309, 309, 309, 309, 309, 304, 304, 304, 304, - 304, 304, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 315, 315, 315, 324, 328, 324, 324, 329, 330, - 454, 454, 454, 454, 454, 454, 2144, 324, 332, 332, - 332, 332, 332, 332, 332, 332, 332, 733, 773, 2135, - 1790, 399, 774, 2133, 328, 1790, 2132, 329, 330, 399, - 471, 471, 471, 471, 471, 471, 324, 339, 339, 339, - 328, 328, 328, 328, 328, 328, 733, 773, 753, 753, - - 399, 774, 329, 329, 329, 329, 329, 329, 399, 753, - 330, 330, 330, 330, 330, 330, 1924, 1924, 324, 324, - 324, 324, 324, 324, 2124, 399, 399, 399, 399, 399, - 399, 315, 317, 317, 1896, 2122, 317, 317, 753, 1896, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 1954, - 1954, 317, 317, 317, 317, 317, 333, 333, 333, 333, - 333, 333, 333, 333, 333, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 340, 340, 340, 339, 348, 348, - 348, 780, 317, 2117, 317, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 336, 336, 336, 336, 336, 336, - - 336, 336, 336, 349, 349, 349, 359, 359, 359, 2112, - 780, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 781, 340, 2107, 783, 384, 348, 366, - 366, 366, 366, 366, 366, 366, 366, 366, 367, 367, - 367, 367, 367, 367, 367, 367, 367, 393, 393, 393, - 2024, 2024, 781, 349, 537, 783, 359, 368, 368, 368, - - 368, 368, 368, 368, 368, 368, 370, 370, 1904, 2105, - 370, 370, 2102, 1904, 370, 370, 370, 370, 370, 370, - 370, 370, 370, 2100, 2096, 370, 370, 370, 370, 370, - 371, 371, 371, 371, 371, 371, 371, 371, 371, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 384, 384, - 384, 384, 384, 384, 2079, 784, 370, 2064, 370, 373, - 373, 373, 373, 373, 373, 373, 373, 373, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 393, 537, 537, - 537, 537, 537, 537, 784, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - - 370, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 376, 376, 376, 376, 376, 376, 376, 376, 376, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 379, 379, - 379, 379, 379, 379, 379, 379, 379, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 386, 386, 386, 386, 386, 386, 386, - 386, 386, 387, 387, 387, 387, 387, 387, 387, 387, - 387, 388, 388, 388, 388, 388, 388, 388, 388, 388, - - 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 397, 400, 397, - 397, 398, 402, 398, 405, 455, 398, 398, 785, 968, - 397, 457, 457, 457, 457, 457, 457, 457, 457, 457, - 2052, 2042, 533, 533, 2033, 403, 533, 400, 533, 533, - 533, 402, 2023, 405, 624, 624, 624, 785, 968, 397, - 404, 624, 455, 455, 455, 455, 455, 455, 402, 402, - 402, 402, 402, 402, 403, 406, 405, 405, 405, 405, - 405, 405, 2021, 400, 400, 400, 400, 400, 400, 404, - - 2019, 397, 397, 397, 397, 397, 397, 408, 398, 398, - 398, 398, 398, 398, 406, 2013, 521, 403, 403, 403, - 403, 403, 403, 521, 969, 2006, 970, 407, 407, 404, - 404, 404, 404, 404, 404, 407, 408, 410, 972, 406, - 406, 406, 406, 406, 406, 521, 973, 409, 411, 409, - 1971, 1953, 521, 969, 624, 970, 407, 407, 409, 1923, - 1916, 1913, 2547, 1902, 407, 409, 410, 972, 408, 408, - 408, 408, 408, 408, 413, 973, 409, 411, 409, 453, - 407, 407, 407, 407, 407, 407, 1894, 409, 410, 410, - 410, 410, 410, 410, 409, 412, 411, 411, 411, 411, - - 411, 411, 414, 413, 1880, 414, 412, 975, 453, 418, - 1857, 1847, 409, 409, 409, 409, 409, 409, 415, 416, - 1831, 1807, 1805, 1802, 412, 453, 453, 453, 453, 453, - 453, 414, 1925, 416, 414, 412, 975, 1925, 418, 413, - 413, 413, 413, 413, 413, 2547, 417, 415, 416, 419, - 414, 414, 414, 414, 414, 414, 412, 412, 412, 412, - 412, 412, 416, 418, 418, 418, 418, 418, 418, 415, - 415, 415, 415, 415, 415, 417, 420, 421, 419, 1795, - 1788, 1781, 1773, 1768, 416, 416, 416, 416, 416, 416, - 417, 417, 417, 417, 417, 417, 576, 576, 424, 423, - - 576, 1757, 576, 576, 576, 420, 421, 422, 419, 419, - 419, 419, 419, 419, 489, 489, 489, 489, 489, 489, - 489, 489, 422, 422, 1745, 1725, 1708, 424, 423, 421, - 421, 421, 421, 421, 421, 425, 422, 425, 426, 420, - 420, 420, 420, 420, 420, 424, 424, 424, 424, 424, - 424, 422, 422, 423, 423, 423, 423, 423, 423, 427, - 428, 1703, 1678, 1670, 425, 1663, 425, 426, 441, 422, - 422, 422, 422, 422, 422, 429, 981, 430, 1660, 1656, - 1646, 426, 426, 426, 426, 426, 426, 432, 427, 428, - 425, 425, 425, 425, 425, 425, 1635, 441, 544, 544, - - 544, 544, 544, 544, 429, 981, 430, 427, 427, 427, - 427, 427, 427, 1955, 431, 982, 432, 435, 1955, 441, - 441, 441, 441, 441, 441, 428, 428, 428, 428, 428, - 428, 429, 429, 429, 429, 429, 429, 430, 430, 430, - 430, 430, 430, 431, 982, 433, 435, 434, 525, 432, - 432, 432, 432, 432, 432, 437, 523, 436, 525, 437, - 983, 815, 523, 815, 1607, 1556, 815, 815, 431, 431, - 431, 431, 431, 431, 433, 1544, 434, 525, 435, 435, - 435, 435, 435, 435, 437, 523, 436, 525, 437, 983, - 1543, 523, 1541, 433, 433, 433, 433, 433, 433, 434, - - 434, 434, 434, 434, 434, 436, 436, 436, 436, 436, - 436, 665, 984, 1525, 1518, 522, 437, 437, 437, 437, - 437, 437, 438, 439, 522, 1513, 524, 438, 757, 665, - 665, 985, 439, 524, 439, 438, 442, 438, 986, 440, - 665, 984, 443, 438, 522, 987, 757, 440, 1485, 1483, - 1477, 438, 439, 522, 444, 524, 438, 757, 665, 665, - 985, 439, 524, 439, 438, 442, 438, 986, 440, 1473, - 1471, 443, 438, 1465, 987, 757, 440, 439, 439, 439, - 439, 439, 439, 444, 445, 1457, 452, 438, 438, 438, - 438, 438, 438, 440, 440, 440, 440, 440, 440, 447, - - 1456, 442, 442, 442, 442, 442, 442, 443, 443, 443, - 443, 443, 443, 445, 448, 452, 988, 448, 444, 444, - 444, 444, 444, 444, 446, 637, 637, 637, 447, 637, - 1454, 1452, 445, 445, 445, 445, 445, 445, 449, 1451, - 1449, 1447, 449, 448, 446, 988, 448, 452, 452, 452, - 452, 452, 452, 446, 482, 1026, 447, 447, 447, 447, - 447, 447, 493, 493, 493, 493, 493, 449, 493, 493, - 493, 449, 1446, 446, 754, 754, 448, 448, 448, 448, - 448, 448, 450, 482, 1026, 754, 1444, 1027, 450, 446, - 446, 446, 446, 446, 446, 451, 1442, 1440, 1436, 449, - - 449, 449, 449, 449, 449, 482, 482, 482, 482, 482, - 482, 450, 1434, 1028, 754, 637, 1027, 450, 657, 657, - 657, 657, 657, 657, 451, 458, 458, 458, 458, 458, - 458, 458, 458, 458, 1431, 1429, 450, 450, 450, 450, - 450, 450, 1028, 451, 451, 451, 451, 451, 451, 459, + 307, 307, 307, 307, 307, 307, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 2363, 305, 309, 309, 309, + + 309, 309, 309, 309, 309, 309, 310, 310, 310, 310, + 310, 310, 310, 310, 310, 305, 305, 305, 305, 305, + 305, 311, 311, 311, 311, 311, 311, 311, 311, 311, + 316, 316, 316, 319, 319, 319, 319, 319, 319, 325, + 328, 325, 329, 2362, 2352, 2350, 2333, 2328, 338, 338, + 338, 325, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 376, 376, 376, 376, 376, 376, 2326, 2323, 328, + 2321, 329, 339, 339, 339, 347, 347, 347, 2316, 2314, + 325, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 2311, 2306, 2305, 978, 328, 328, 328, 328, 328, 328, + + 2301, 2299, 2290, 329, 329, 329, 329, 329, 329, 2287, + 2282, 2279, 325, 325, 325, 325, 325, 325, 2028, 316, + 318, 318, 978, 2028, 318, 318, 2273, 2272, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 338, 318, 318, + 318, 318, 318, 333, 333, 333, 333, 333, 333, 333, + 333, 333, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 339, 361, 2259, 347, 348, 348, 348, 979, 318, + 2258, 318, 335, 335, 335, 335, 335, 335, 335, 335, + 335, 336, 336, 336, 336, 336, 336, 336, 336, 336, + 358, 358, 358, 383, 2256, 2237, 2226, 979, 318, 318, + + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 362, 362, 362, 362, 362, 362, + 362, 362, 362, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 392, 392, 392, 2224, 361, 361, 361, 361, 361, + 361, 2223, 2215, 2213, 348, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 383, 383, 383, 383, 383, 383, 358, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 369, + 369, 2105, 2207, 369, 369, 2201, 2105, 369, 369, 369, + + 369, 369, 369, 369, 369, 369, 2196, 369, 369, 369, + 369, 369, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 392, 402, 402, 402, 402, 402, 402, 981, 369, 2194, + 369, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 455, + 455, 455, 455, 455, 455, 2191, 981, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 375, 375, 375, 375, 375, 375, 375, 375, + + 375, 377, 377, 377, 377, 377, 377, 377, 377, 377, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 380, 380, + 380, 380, 380, 380, 380, 380, 380, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 387, 387, 387, 387, 387, 387, 387, + 387, 387, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 389, 389, 389, 389, 389, 389, 389, 389, 389, + + 390, 390, 390, 390, 390, 390, 390, 390, 390, 398, + 400, 398, 399, 755, 399, 755, 2189, 399, 400, 2184, + 524, 398, 2181, 982, 403, 755, 524, 983, 985, 401, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 400, + 472, 472, 472, 472, 472, 472, 2168, 400, 404, 524, + 398, 414, 982, 403, 755, 524, 983, 985, 401, 2150, + 2149, 649, 649, 649, 400, 400, 400, 400, 400, 400, + 403, 403, 403, 403, 403, 403, 405, 404, 418, 445, + 414, 2135, 398, 398, 398, 398, 398, 398, 399, 399, + 399, 399, 399, 399, 401, 401, 401, 401, 401, 401, + + 406, 991, 992, 409, 407, 405, 2123, 418, 445, 2114, + 404, 404, 404, 404, 404, 404, 414, 414, 414, 414, + 414, 414, 418, 418, 418, 418, 418, 418, 2103, 406, + 991, 992, 409, 407, 2100, 405, 405, 405, 405, 405, + 405, 408, 408, 445, 445, 445, 445, 445, 445, 408, + 649, 993, 406, 406, 406, 406, 406, 406, 407, 407, + 407, 407, 407, 407, 409, 409, 409, 409, 409, 409, + 408, 408, 410, 411, 410, 2098, 528, 2092, 408, 994, + 993, 2085, 412, 410, 528, 494, 494, 494, 494, 494, + 410, 494, 494, 494, 408, 408, 408, 408, 408, 408, + + 2075, 410, 411, 410, 817, 528, 817, 413, 994, 2072, + 820, 412, 410, 528, 415, 995, 817, 415, 413, 410, + 820, 996, 997, 416, 411, 411, 411, 411, 411, 411, + 412, 412, 412, 412, 412, 412, 413, 410, 410, 410, + 410, 410, 410, 415, 995, 817, 415, 413, 2048, 820, + 996, 997, 416, 2042, 2031, 998, 419, 420, 456, 2026, + 999, 421, 415, 415, 415, 415, 415, 415, 413, 413, + 413, 413, 413, 413, 416, 416, 416, 416, 416, 416, + 417, 626, 626, 626, 998, 419, 420, 1992, 626, 999, + 421, 1984, 1980, 538, 417, 456, 456, 456, 456, 456, + + 456, 422, 1037, 1038, 1048, 424, 1051, 1079, 1969, 417, + 419, 419, 419, 419, 419, 419, 420, 420, 420, 420, + 420, 420, 423, 417, 421, 421, 421, 421, 421, 421, + 422, 1037, 1038, 1048, 424, 1051, 1079, 423, 423, 1110, + 429, 1961, 426, 425, 426, 417, 417, 417, 417, 417, + 417, 423, 1953, 422, 422, 422, 422, 422, 422, 424, + 424, 424, 424, 424, 424, 1950, 423, 423, 1110, 429, + 626, 426, 425, 426, 427, 428, 538, 538, 538, 538, + 538, 538, 430, 433, 423, 423, 423, 423, 423, 423, + 425, 425, 425, 425, 425, 425, 482, 426, 426, 426, + + 426, 426, 426, 427, 428, 429, 429, 429, 429, 429, + 429, 430, 433, 1944, 1922, 431, 1911, 427, 427, 427, + 427, 427, 427, 428, 428, 428, 428, 428, 428, 432, + 545, 545, 545, 545, 545, 545, 1111, 435, 430, 430, + 430, 430, 430, 430, 431, 433, 433, 433, 433, 433, + 433, 1897, 434, 436, 1892, 534, 534, 1865, 432, 534, + 1863, 534, 534, 534, 1860, 1111, 435, 482, 482, 482, + 482, 482, 482, 1854, 1851, 431, 431, 431, 431, 431, + 431, 434, 436, 432, 432, 432, 432, 432, 432, 435, + 435, 435, 435, 435, 435, 437, 443, 526, 1097, 442, + + 434, 434, 434, 434, 434, 434, 438, 526, 1097, 440, + 438, 440, 1114, 1115, 436, 436, 436, 436, 436, 436, + 440, 666, 666, 666, 437, 443, 526, 440, 442, 440, + 444, 440, 1849, 1842, 1835, 438, 526, 1097, 440, 438, + 440, 1114, 1115, 437, 437, 437, 437, 437, 437, 440, + 442, 442, 442, 442, 442, 442, 440, 1827, 440, 444, + 440, 443, 443, 443, 443, 443, 443, 438, 438, 438, + 438, 438, 438, 439, 441, 439, 441, 446, 439, 639, + 639, 639, 448, 639, 439, 441, 439, 1822, 439, 447, + 1818, 439, 441, 441, 439, 444, 444, 444, 444, 444, + + 444, 1814, 439, 441, 439, 441, 446, 439, 1808, 447, + 666, 448, 1796, 439, 441, 439, 449, 439, 447, 449, + 439, 441, 441, 439, 1116, 446, 446, 446, 446, 446, + 446, 450, 1098, 1117, 1098, 450, 452, 1098, 447, 448, + 448, 448, 448, 448, 448, 449, 1776, 453, 449, 1094, + 1761, 1094, 1756, 1116, 447, 447, 447, 447, 447, 447, + 450, 1094, 1117, 1751, 450, 452, 1723, 1717, 639, 451, + 454, 1118, 1256, 1257, 1258, 451, 453, 1259, 449, 449, + 449, 449, 449, 449, 452, 452, 452, 452, 452, 452, + 1094, 1712, 450, 450, 450, 450, 450, 450, 451, 454, + + 1118, 1256, 1257, 1258, 451, 1709, 1259, 1702, 453, 453, + 453, 453, 453, 453, 1699, 1695, 454, 454, 454, 454, + 454, 454, 1685, 451, 451, 451, 451, 451, 451, 459, 459, 459, 459, 459, 459, 459, 459, 459, 460, 460, 460, 460, 460, 460, 460, 460, 460, 461, 461, 461, 461, 461, 461, 461, 461, 461, 462, 462, 462, 462, 462, 462, 462, 462, 462, 463, 463, 463, 463, 463, 463, 463, 463, 463, 464, 464, 464, 464, 464, 464, - 464, 464, 464, 465, 465, 465, 465, 465, 465, 465, 465, 465, 466, 466, 466, 466, 466, 466, 466, 466, + 466, 467, 467, 467, 467, 467, 467, 467, 467, 467, 468, 468, 468, 468, 468, 468, 468, 468, 468, 469, 469, 469, 469, 469, 469, 469, 469, 469, 470, 470, - 470, 470, 470, 470, 470, 470, 470, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 473, 473, 473, 473, + 470, 470, 470, 470, 470, 470, 470, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 473, 473, 473, 473, 473, 473, 473, 473, 473, 474, 474, 474, 474, 474, 474, 474, 474, 474, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 476, 476, 476, 476, 476, 476, - 476, 476, 477, 477, 477, 477, 477, 477, 477, 477, - 477, 481, 481, 483, 486, 488, 488, 488, 488, 488, - 488, 488, 488, 488, 1039, 1042, 1070, 1089, 484, 1090, - 485, 1100, 563, 698, 698, 698, 698, 698, 698, 487, - 1389, 1327, 483, 486, 490, 490, 490, 490, 490, 490, - 490, 490, 490, 1039, 1042, 1070, 1089, 484, 1090, 485, - 1100, 1321, 486, 486, 486, 486, 486, 486, 487, 563, - 563, 563, 563, 563, 563, 483, 483, 483, 483, 483, - 483, 1320, 1315, 481, 481, 481, 481, 481, 481, 484, - 484, 484, 484, 484, 484, 485, 485, 485, 485, 485, - - 485, 1314, 1301, 1300, 487, 487, 487, 487, 487, 487, - 491, 491, 491, 491, 491, 491, 491, 491, 491, 492, - 492, 492, 492, 492, 492, 492, 492, 492, 494, 494, - 494, 494, 494, 494, 494, 494, 494, 495, 495, 495, - 495, 495, 495, 495, 495, 495, 498, 498, 498, 1289, - 816, 816, 499, 499, 499, 1288, 1101, 498, 1281, 498, - 498, 816, 1280, 499, 1270, 499, 499, 500, 500, 500, - 1104, 2025, 498, 498, 1267, 498, 2025, 1266, 500, 1105, - 500, 500, 1106, 507, 498, 1101, 498, 507, 498, 1107, - 816, 507, 502, 502, 502, 1108, 507, 1260, 561, 1104, - - 507, 498, 498, 502, 498, 502, 502, 1258, 1105, 1256, - 1251, 1106, 507, 498, 1121, 498, 507, 498, 1107, 1120, - 507, 1103, 1099, 502, 1108, 507, 817, 561, 817, 507, - 1083, 817, 817, 1071, 498, 498, 498, 498, 498, 498, - 499, 499, 499, 499, 499, 499, 561, 561, 561, 561, - 561, 561, 502, 1057, 1045, 500, 500, 500, 500, 500, - 500, 508, 508, 508, 508, 508, 508, 508, 508, 508, - 509, 509, 509, 509, 509, 509, 509, 509, 509, 1041, - 502, 502, 502, 502, 502, 502, 510, 510, 510, 510, - 510, 510, 510, 510, 510, 511, 511, 511, 511, 511, - - 511, 511, 511, 511, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 513, 513, 513, 513, 513, 513, 513, - 513, 513, 514, 514, 514, 514, 514, 514, 514, 514, - 514, 528, 528, 528, 528, 528, 528, 528, 528, 528, - 529, 529, 529, 529, 529, 529, 529, 529, 529, 530, + 477, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 483, 484, 659, 659, 659, 659, 659, 659, 485, 487, + 486, 1674, 1670, 1665, 1260, 1643, 488, 489, 489, 489, + 489, 489, 489, 489, 489, 489, 1633, 577, 577, 483, + 484, 577, 1624, 577, 577, 577, 1602, 485, 487, 486, + 678, 678, 678, 1260, 678, 488, 678, 678, 678, 1589, + 1575, 483, 483, 483, 483, 483, 483, 487, 487, 487, + 487, 487, 487, 484, 484, 484, 484, 484, 484, 485, + 485, 485, 485, 485, 485, 486, 486, 486, 486, 486, + 486, 488, 488, 488, 488, 488, 488, 490, 490, 490, + 490, 490, 490, 490, 490, 491, 491, 491, 491, 491, + + 491, 491, 491, 491, 492, 492, 492, 492, 492, 492, + 492, 492, 492, 493, 493, 493, 493, 493, 493, 493, + 493, 493, 495, 495, 495, 495, 495, 495, 495, 495, + 495, 496, 496, 496, 496, 496, 496, 496, 496, 496, + 499, 499, 499, 1574, 1572, 1552, 500, 500, 500, 1261, + 1545, 499, 1540, 499, 499, 1510, 1509, 500, 1507, 500, + 500, 501, 501, 501, 1502, 499, 499, 1501, 499, 1497, + 1495, 1133, 501, 1133, 501, 501, 508, 499, 1261, 499, + 508, 499, 1262, 1133, 508, 503, 503, 503, 1263, 508, + 1264, 1265, 1267, 508, 499, 499, 503, 499, 503, 503, + + 1489, 1483, 1482, 1480, 1478, 508, 499, 1477, 499, 508, + 499, 1262, 1133, 508, 1268, 503, 1270, 1263, 508, 1264, + 1265, 1267, 508, 1475, 1473, 1472, 1470, 499, 499, 499, + 499, 499, 499, 500, 500, 500, 500, 500, 500, 633, + 633, 633, 1468, 1268, 503, 1270, 633, 1466, 501, 501, + 501, 501, 501, 501, 509, 509, 509, 509, 509, 509, + 509, 509, 509, 510, 510, 510, 510, 510, 510, 510, + 510, 510, 503, 503, 503, 503, 503, 503, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 513, 513, 513, 513, + + 513, 513, 513, 513, 513, 514, 514, 514, 514, 514, + 514, 514, 514, 514, 515, 515, 515, 515, 515, 515, + 515, 515, 515, 525, 564, 1461, 1459, 1455, 633, 1453, + 525, 573, 573, 573, 573, 573, 573, 573, 573, 525, + 529, 529, 529, 529, 529, 529, 529, 529, 529, 1431, + 1410, 1345, 525, 699, 699, 699, 699, 699, 699, 525, + 1344, 564, 564, 564, 564, 564, 564, 1338, 525, 530, 530, 530, 530, 530, 530, 530, 530, 530, 531, 531, 531, 531, 531, 531, 531, 531, 531, 532, 532, 532, - 532, 532, 532, 532, 532, 532, 534, 534, 534, 534, - 534, 534, 534, 534, 534, 535, 535, 535, 535, 535, - 535, 535, 535, 535, 538, 538, 538, 538, 538, 538, + 532, 532, 532, 532, 532, 532, 533, 533, 533, 533, - 538, 538, 538, 539, 539, 539, 539, 539, 539, 539, + 533, 533, 533, 533, 533, 535, 535, 535, 535, 535, + 535, 535, 535, 535, 536, 536, 536, 536, 536, 536, + 536, 536, 536, 539, 539, 539, 539, 539, 539, 539, 539, 539, 540, 540, 540, 540, 540, 540, 540, 540, 540, 541, 541, 541, 541, 541, 541, 541, 541, 541, 542, 542, 542, 542, 542, 542, 542, 542, 542, 543, - 543, 543, 543, 543, 543, 543, 543, 543, 545, 545, - 545, 545, 545, 545, 545, 545, 545, 546, 546, 546, + 543, 543, 543, 543, 543, 543, 543, 543, 544, 544, + 544, 544, 544, 544, 544, 544, 544, 546, 546, 546, 546, 546, 546, 546, 546, 546, 547, 547, 547, 547, 547, 547, 547, 547, 547, 548, 548, 548, 548, 548, + 548, 548, 548, 548, 549, 549, 549, 549, 549, 549, 549, 549, 549, 550, 550, 550, 550, 550, 550, 550, - - 550, 550, 551, 553, 553, 553, 553, 553, 553, 553, - 553, 553, 554, 554, 554, 554, 554, 554, 554, 554, + 550, 550, 551, 551, 551, 551, 551, 551, 551, 551, + 551, 552, 554, 554, 554, 554, 554, 554, 554, 554, 554, 555, 555, 555, 555, 555, 555, 555, 555, 555, 556, 556, 556, 556, 556, 556, 556, 556, 556, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558, 558, - 558, 558, 558, 558, 558, 558, 558, 1025, 1013, 1012, - 562, 565, 565, 565, 565, 565, 565, 565, 565, 565, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 1010, - 1009, 1007, 1005, 551, 551, 551, 551, 551, 551, 562, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 568, - - 568, 568, 568, 568, 568, 568, 568, 568, 569, 569, - 569, 569, 569, 569, 569, 569, 569, 647, 647, 647, - 1004, 1002, 1000, 999, 562, 562, 562, 562, 562, 562, - 570, 570, 570, 570, 570, 570, 570, 570, 570, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 572, 572, - 572, 572, 572, 572, 572, 572, 573, 573, 573, 573, - 573, 573, 573, 573, 573, 574, 574, 574, 574, 574, - 574, 574, 574, 574, 575, 575, 575, 575, 575, 575, - 575, 575, 575, 577, 577, 577, 577, 577, 577, 577, - 577, 577, 578, 578, 578, 578, 578, 578, 578, 578, - - 578, 631, 631, 631, 664, 664, 664, 647, 631, 651, - 651, 651, 651, 651, 651, 651, 651, 651, 652, 652, - 652, 652, 652, 652, 652, 652, 652, 653, 653, 653, - 653, 653, 653, 653, 653, 653, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 655, 655, 655, 655, 655, - 655, 655, 655, 655, 656, 656, 656, 656, 656, 656, - 656, 656, 656, 658, 658, 658, 658, 658, 658, 658, - 658, 658, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 660, 660, 660, 660, 660, 660, 660, 660, 660, - 974, 631, 650, 650, 664, 971, 650, 650, 814, 786, - - 650, 650, 650, 650, 650, 650, 650, 650, 650, 666, - 1239, 650, 650, 650, 650, 650, 661, 661, 661, 661, - 661, 661, 661, 661, 661, 662, 662, 662, 662, 662, - 662, 662, 662, 662, 782, 681, 681, 681, 666, 1239, - 668, 1240, 650, 777, 650, 663, 663, 663, 663, 663, - 663, 663, 663, 663, 775, 666, 666, 666, 666, 666, - 666, 667, 717, 717, 717, 717, 717, 717, 669, 668, - 1240, 650, 650, 650, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 650, 650, 670, 770, 735, - 667, 668, 668, 668, 668, 668, 668, 669, 671, 744, - - 744, 744, 744, 744, 744, 689, 667, 667, 667, 667, - 667, 667, 1084, 686, 1084, 682, 670, 1084, 1084, 669, - 669, 669, 669, 669, 669, 681, 648, 671, 641, 684, - 684, 684, 640, 639, 670, 670, 670, 670, 670, 670, - 635, 671, 671, 671, 671, 671, 671, 672, 672, 672, - 672, 672, 672, 672, 672, 672, 673, 673, 673, 673, - 673, 673, 673, 673, 673, 674, 674, 674, 674, 674, - 674, 674, 674, 674, 675, 675, 675, 675, 675, 675, - 675, 675, 675, 676, 676, 676, 676, 676, 676, 676, - 676, 676, 677, 677, 677, 634, 677, 632, 677, 677, - - 677, 678, 678, 678, 678, 678, 678, 678, 678, 678, - 679, 679, 679, 679, 679, 679, 679, 679, 679, 684, - 688, 688, 688, 692, 692, 692, 692, 692, 692, 692, - 692, 692, 693, 693, 693, 693, 693, 693, 693, 693, - 693, 694, 694, 694, 694, 694, 694, 694, 694, 694, - 695, 695, 695, 695, 695, 695, 695, 695, 695, 696, - 696, 696, 696, 696, 696, 696, 696, 696, 697, 697, - 697, 697, 697, 697, 697, 697, 697, 699, 699, 699, - 699, 699, 699, 699, 699, 699, 700, 700, 700, 700, - 700, 700, 700, 700, 700, 701, 701, 701, 701, 701, - - 701, 701, 701, 701, 820, 820, 820, 820, 820, 820, - 688, 691, 691, 628, 627, 691, 691, 625, 621, 691, - 691, 691, 691, 691, 691, 691, 691, 691, 706, 1241, - 691, 691, 691, 691, 691, 702, 702, 702, 702, 702, - 702, 702, 702, 702, 703, 703, 703, 703, 703, 703, - 703, 703, 703, 705, 705, 705, 618, 706, 1241, 707, - 1242, 691, 617, 691, 704, 704, 704, 704, 704, 704, - 704, 704, 704, 706, 706, 706, 706, 706, 706, 1086, - 614, 1086, 613, 708, 1086, 1086, 611, 599, 707, 1242, - 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, - - 691, 691, 691, 691, 691, 691, 707, 707, 707, 707, - 707, 707, 708, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 598, 595, 594, 591, 708, 708, 708, 708, - 708, 708, 710, 710, 710, 710, 710, 710, 710, 710, - 710, 590, 360, 705, 711, 711, 711, 711, 711, 711, - 711, 711, 711, 712, 712, 712, 712, 712, 712, 712, - 712, 712, 713, 713, 713, 713, 713, 713, 713, 713, - 713, 714, 714, 714, 714, 714, 355, 714, 714, 714, - 715, 715, 715, 715, 715, 715, 715, 715, 715, 716, - 716, 716, 716, 716, 716, 716, 716, 716, 718, 718, - - 718, 718, 718, 718, 718, 718, 718, 719, 719, 719, + 558, 558, 558, 558, 558, 558, 558, 559, 559, 559, + 559, 559, 559, 559, 559, 559, 1337, 1332, 562, 563, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 567, + + 567, 567, 567, 567, 567, 567, 567, 567, 1331, 1325, + 1324, 552, 552, 552, 552, 552, 552, 562, 563, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 718, 718, + 718, 718, 718, 718, 1323, 1322, 562, 562, 562, 562, + 562, 562, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 1321, 1319, 563, 563, 563, 563, 563, 563, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 574, 574, 574, 574, + 574, 574, 574, 574, 574, 575, 575, 575, 575, 575, + + 575, 575, 575, 575, 576, 576, 576, 576, 576, 576, + 576, 576, 576, 578, 578, 578, 578, 578, 578, 578, + 578, 578, 579, 579, 579, 579, 579, 579, 579, 579, + 579, 652, 652, 1318, 1315, 652, 652, 1306, 1305, 652, + 652, 652, 652, 652, 652, 652, 652, 652, 1298, 652, + 652, 652, 652, 652, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 654, 654, 654, 654, 654, 654, 654, + 654, 654, 727, 727, 727, 727, 727, 727, 727, 727, + 652, 1297, 652, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 656, 656, 656, 656, 656, 656, 656, 656, + + 656, 745, 745, 745, 745, 745, 745, 1288, 1286, 652, + 652, 652, 652, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 652, 652, 652, 657, 657, 657, 657, 657, + 657, 657, 657, 657, 658, 658, 658, 658, 658, 658, + 658, 658, 658, 660, 660, 660, 660, 660, 660, 660, + 660, 660, 661, 661, 661, 661, 661, 661, 661, 661, + 661, 662, 662, 662, 662, 662, 662, 662, 662, 662, + 663, 663, 663, 663, 663, 663, 663, 663, 663, 664, + 664, 664, 664, 664, 664, 664, 664, 664, 665, 665, + 665, 665, 665, 665, 665, 665, 665, 668, 669, 1271, + + 1272, 1285, 1279, 1277, 670, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 715, 715, 715, 715, 715, 671, + 715, 715, 715, 1275, 1269, 1225, 668, 669, 1271, 1272, + 731, 731, 672, 670, 731, 1138, 731, 731, 731, 1137, + 1136, 1135, 668, 668, 668, 668, 668, 668, 671, 669, + 669, 669, 669, 669, 669, 670, 670, 670, 670, 670, + 670, 672, 682, 682, 682, 1134, 671, 671, 671, 671, + 671, 671, 685, 685, 685, 672, 672, 672, 672, 672, + 672, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 675, 675, 675, 675, 675, 675, 675, 675, 675, 676, + + 676, 676, 676, 676, 676, 676, 676, 676, 677, 677, + 677, 677, 677, 677, 677, 677, 677, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 680, 680, 680, 680, + 680, 680, 680, 680, 680, 689, 689, 689, 693, 693, + 693, 693, 693, 693, 693, 693, 693, 1132, 1131, 1128, + 1113, 682, 694, 694, 694, 694, 694, 694, 694, 694, + 694, 685, 695, 695, 695, 695, 695, 695, 695, 695, + 695, 696, 696, 696, 696, 696, 696, 696, 696, 696, + 697, 697, 697, 697, 697, 697, 697, 697, 697, 698, + 698, 698, 698, 698, 698, 698, 698, 698, 700, 700, + + 700, 700, 700, 700, 700, 700, 700, 701, 701, 701, + 701, 701, 701, 701, 701, 701, 789, 789, 789, 789, + 789, 789, 789, 789, 689, 692, 692, 1109, 1100, 692, + 692, 1093, 1091, 692, 692, 692, 692, 692, 692, 692, + 692, 692, 1273, 692, 692, 692, 692, 692, 702, 702, + 702, 702, 702, 702, 702, 702, 702, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 706, 706, 706, 1287, + 1080, 1273, 1294, 1299, 692, 1066, 692, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 705, 705, 705, 705, + 705, 705, 705, 705, 705, 707, 1334, 1404, 1287, 708, + + 1054, 1294, 1299, 692, 692, 692, 692, 692, 692, 692, + 692, 692, 692, 692, 692, 692, 692, 692, 692, 1050, + 1036, 1024, 1023, 709, 707, 1334, 1404, 1021, 708, 710, + 710, 710, 710, 710, 710, 710, 710, 710, 1020, 1018, + 707, 707, 707, 707, 707, 707, 708, 708, 708, 708, + 708, 708, 709, 1016, 1015, 706, 711, 711, 711, 711, + 711, 711, 711, 711, 711, 1013, 709, 709, 709, 709, + 709, 709, 712, 712, 712, 712, 712, 712, 712, 712, + 712, 713, 713, 713, 713, 713, 713, 713, 713, 713, + 714, 714, 714, 714, 714, 714, 714, 714, 714, 716, + + 716, 716, 716, 716, 716, 716, 716, 716, 717, 717, + 717, 717, 717, 717, 717, 717, 717, 719, 719, 719, 719, 719, 719, 719, 719, 719, 720, 720, 720, 720, 720, 720, 720, 720, 720, 721, 721, 721, 721, 721, 721, 721, 721, 721, 722, 722, 722, 722, 722, 722, 722, 722, 722, 723, 723, 723, 723, 723, 723, 723, - 723, 723, 724, 725, 725, 725, 725, 725, 725, 725, - 725, 725, 726, 726, 726, 726, 726, 726, 726, 726, - 727, 727, 727, 727, 727, 727, 727, 727, 727, 351, - 346, 724, 728, 728, 728, 728, 728, 728, 728, 728, - 728, 729, 729, 729, 729, 729, 729, 729, 729, 729, - - 734, 734, 734, 724, 724, 724, 724, 724, 724, 730, - 730, 342, 327, 730, 290, 730, 730, 730, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 739, 739, 739, 739, 739, - 739, 739, 739, 739, 740, 740, 740, 740, 740, 740, - 740, 740, 740, 741, 741, 741, 741, 741, 741, 741, - 741, 741, 742, 742, 742, 742, 742, 742, 742, 742, - 742, 743, 743, 743, 743, 743, 743, 743, 743, 743, - 734, 737, 737, 280, 279, 737, 737, 1085, 1085, 737, - - 737, 737, 737, 737, 737, 737, 737, 737, 1085, 1243, - 737, 737, 737, 737, 737, 745, 745, 745, 745, 745, - 745, 745, 745, 745, 746, 746, 746, 746, 746, 746, - 746, 746, 746, 752, 752, 752, 1244, 1085, 1243, 277, - 1245, 737, 254, 737, 747, 747, 747, 747, 747, 747, - 747, 747, 747, 748, 748, 748, 748, 748, 748, 748, - 748, 748, 756, 252, 756, 1244, 243, 756, 756, 1245, - 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 737, 737, 737, 749, 749, 749, 749, - 749, 749, 749, 749, 749, 750, 750, 750, 750, 750, - - 750, 750, 750, 750, 755, 758, 755, 755, 759, 788, - 788, 788, 788, 788, 788, 788, 788, 755, 760, 1246, - 1247, 1249, 241, 752, 761, 761, 761, 761, 761, 761, - 761, 761, 761, 230, 758, 229, 223, 759, 222, 756, - 756, 756, 756, 756, 756, 214, 755, 760, 1246, 1247, - 1249, 758, 758, 758, 758, 758, 758, 213, 210, 759, - 759, 759, 759, 759, 759, 760, 760, 760, 760, 760, - 760, 769, 769, 769, 772, 772, 772, 209, 755, 755, - 755, 755, 755, 755, 762, 762, 762, 762, 762, 762, - 762, 762, 762, 763, 763, 763, 763, 763, 763, 763, - - 763, 763, 764, 764, 764, 764, 764, 764, 764, 764, - 764, 765, 765, 765, 765, 765, 765, 765, 765, 765, - 766, 766, 193, 192, 766, 766, 766, 766, 766, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 768, 768, - 768, 768, 768, 768, 768, 768, 768, 776, 776, 776, - 779, 779, 779, 796, 796, 796, 796, 796, 796, 796, - 796, 769, 186, 185, 772, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 789, 789, 789, 789, 789, 789, - 789, 789, 789, 790, 790, 790, 790, 790, 790, 790, - 790, 790, 791, 791, 791, 791, 791, 791, 791, 791, - - 791, 792, 792, 178, 177, 792, 71, 792, 792, 792, - 793, 793, 793, 793, 793, 793, 793, 793, 793, 794, - 794, 794, 794, 794, 794, 794, 794, 794, 795, 795, - 795, 795, 795, 795, 795, 795, 795, 776, 57, 36, - 779, 797, 797, 797, 797, 797, 797, 797, 797, 797, - 798, 798, 798, 798, 798, 798, 798, 798, 798, 799, - 799, 799, 799, 799, 799, 799, 799, 799, 800, 800, - 35, 34, 800, 33, 800, 800, 800, 801, 801, 801, - 801, 801, 801, 801, 801, 801, 802, 802, 802, 802, - 802, 802, 802, 802, 802, 803, 803, 803, 803, 803, - - 803, 803, 803, 804, 804, 0, 0, 804, 0, 804, - 804, 804, 805, 805, 805, 805, 805, 805, 805, 805, - 805, 806, 806, 806, 806, 806, 806, 806, 806, 807, - 807, 807, 807, 807, 807, 807, 807, 807, 808, 808, - 808, 808, 808, 808, 808, 808, 808, 809, 809, 809, - 809, 809, 809, 809, 809, 809, 810, 810, 819, 819, - 810, 821, 810, 810, 810, 811, 811, 811, 811, 811, - 811, 811, 811, 811, 812, 812, 812, 812, 812, 812, - 812, 812, 812, 813, 813, 813, 822, 0, 0, 0, - 821, 841, 841, 841, 841, 841, 841, 0, 0, 823, - - 824, 849, 849, 849, 849, 849, 849, 825, 1250, 826, - 1001, 1001, 1001, 0, 0, 822, 891, 891, 891, 891, - 891, 891, 821, 821, 821, 821, 821, 821, 823, 824, - 819, 819, 819, 819, 819, 819, 825, 1250, 826, 0, - 822, 822, 822, 822, 822, 822, 0, 823, 823, 823, - 823, 823, 823, 827, 1006, 1006, 1006, 824, 824, 824, - 824, 824, 824, 828, 825, 825, 825, 825, 825, 825, - 1252, 0, 1253, 813, 826, 826, 826, 826, 826, 826, - 0, 0, 827, 0, 830, 0, 831, 0, 0, 1011, - 1011, 1011, 828, 829, 0, 0, 0, 1254, 829, 1252, - - 1001, 1253, 1268, 832, 1269, 1277, 0, 827, 827, 827, - 827, 827, 827, 830, 833, 831, 828, 828, 828, 828, - 828, 828, 829, 1024, 1024, 1024, 1254, 829, 0, 0, - 0, 1268, 832, 1269, 1277, 835, 830, 830, 830, 830, - 830, 830, 0, 833, 1006, 829, 829, 829, 829, 829, - 829, 831, 831, 831, 831, 831, 831, 832, 832, 832, - 832, 832, 832, 834, 835, 836, 1282, 834, 833, 833, - 833, 833, 833, 833, 903, 903, 1307, 838, 903, 1011, - 903, 903, 903, 837, 899, 899, 899, 899, 899, 899, - 899, 899, 834, 839, 836, 1282, 834, 1308, 835, 835, - - 835, 835, 835, 835, 0, 1307, 838, 0, 0, 1040, - 1040, 1040, 837, 1024, 0, 836, 836, 836, 836, 836, - 836, 0, 839, 0, 840, 842, 1308, 0, 834, 834, - 834, 834, 834, 834, 837, 837, 837, 837, 837, 837, - 838, 838, 838, 838, 838, 838, 0, 839, 839, 839, - 839, 839, 839, 840, 842, 843, 845, 1317, 1383, 1384, - 912, 912, 844, 846, 912, 1385, 912, 912, 912, 848, - 0, 840, 840, 840, 840, 840, 840, 842, 842, 842, - 842, 842, 842, 0, 843, 845, 1317, 1383, 1384, 0, - 0, 844, 846, 0, 1385, 0, 0, 847, 848, 1040, - - 0, 845, 845, 845, 845, 845, 845, 850, 843, 843, - 843, 843, 843, 843, 844, 844, 844, 844, 844, 844, - 846, 846, 846, 846, 846, 846, 847, 848, 848, 848, - 848, 848, 848, 858, 0, 851, 850, 853, 1386, 878, - 1387, 852, 0, 0, 0, 0, 0, 847, 847, 847, - 847, 847, 847, 0, 854, 856, 0, 0, 850, 850, - 850, 850, 850, 850, 851, 857, 853, 1386, 0, 1387, - 852, 858, 858, 858, 858, 858, 858, 878, 878, 878, - 878, 878, 878, 854, 856, 855, 859, 0, 853, 853, - 853, 853, 853, 853, 857, 0, 851, 851, 851, 851, - - 851, 851, 852, 852, 852, 852, 852, 852, 854, 854, - 854, 854, 854, 854, 855, 859, 856, 856, 856, 856, - 856, 856, 857, 857, 857, 857, 857, 857, 860, 861, - 1388, 855, 855, 855, 855, 855, 855, 866, 862, 906, - 906, 906, 906, 906, 906, 859, 859, 859, 859, 859, - 859, 907, 907, 907, 907, 907, 907, 860, 861, 1388, - 0, 0, 863, 864, 865, 0, 866, 862, 0, 0, - 1056, 1056, 1056, 860, 860, 860, 860, 860, 860, 861, - 861, 861, 861, 861, 861, 862, 862, 862, 862, 862, - 862, 863, 864, 865, 867, 0, 866, 866, 866, 866, - - 866, 866, 868, 863, 863, 863, 863, 863, 863, 0, - 865, 865, 865, 865, 865, 865, 0, 0, 0, 0, - 0, 869, 870, 867, 864, 864, 864, 864, 864, 864, - 871, 868, 898, 898, 898, 898, 898, 898, 898, 898, - 898, 0, 0, 0, 867, 867, 867, 867, 867, 867, - 869, 870, 872, 873, 874, 1427, 880, 880, 880, 871, - 1056, 868, 868, 868, 868, 868, 868, 0, 0, 869, - 869, 869, 869, 869, 869, 0, 0, 875, 0, 0, - 0, 872, 873, 874, 1427, 870, 870, 870, 870, 870, - 870, 0, 871, 871, 871, 871, 871, 871, 876, 0, - - 872, 872, 872, 872, 872, 872, 875, 879, 874, 874, - 874, 874, 874, 874, 877, 0, 0, 0, 873, 873, - 873, 873, 873, 873, 0, 0, 0, 876, 875, 875, - 875, 875, 875, 875, 0, 1382, 879, 881, 882, 0, - 0, 0, 0, 877, 880, 880, 880, 880, 880, 880, - 1382, 0, 876, 876, 876, 876, 876, 876, 884, 0, - 877, 877, 877, 877, 877, 877, 881, 882, 879, 879, - 879, 879, 879, 879, 883, 885, 883, 1428, 887, 1382, - 881, 881, 881, 881, 881, 881, 0, 884, 882, 882, - 882, 882, 882, 882, 944, 944, 0, 0, 944, 889, - - 944, 944, 944, 883, 885, 883, 1428, 887, 0, 0, - 0, 0, 884, 884, 884, 884, 884, 884, 886, 888, - 0, 888, 883, 883, 883, 883, 883, 883, 889, 886, - 887, 887, 887, 887, 887, 887, 885, 885, 885, 885, - 885, 885, 0, 0, 0, 0, 0, 886, 888, 890, - 888, 892, 919, 919, 919, 919, 919, 919, 886, 1430, - 894, 1432, 1433, 916, 889, 889, 889, 889, 889, 889, - 888, 888, 888, 888, 888, 888, 0, 0, 890, 0, - 892, 886, 886, 886, 886, 886, 886, 893, 1430, 894, - 1432, 1433, 916, 0, 895, 897, 0, 890, 890, 890, - - 890, 890, 890, 892, 892, 892, 892, 892, 892, 896, - 1435, 1437, 1438, 896, 0, 0, 893, 894, 894, 894, - 894, 894, 894, 895, 897, 916, 916, 916, 916, 916, - 916, 1439, 893, 893, 893, 893, 893, 893, 896, 1435, - 1437, 1438, 896, 1082, 1082, 1082, 895, 895, 895, 895, - 895, 895, 0, 897, 897, 897, 897, 897, 897, 0, - 1439, 896, 896, 896, 896, 896, 896, 900, 900, 900, - 900, 900, 900, 900, 900, 900, 901, 901, 901, 901, - 901, 901, 901, 901, 901, 902, 902, 902, 902, 902, - 902, 902, 902, 902, 904, 904, 904, 904, 904, 904, - - 904, 904, 904, 905, 905, 905, 905, 905, 905, 905, - 905, 905, 911, 911, 911, 911, 911, 911, 911, 911, - 911, 913, 914, 915, 0, 1458, 917, 920, 920, 920, - 920, 920, 920, 1082, 0, 0, 925, 0, 918, 923, - 923, 923, 923, 923, 923, 923, 923, 923, 0, 929, - 913, 914, 915, 929, 1458, 917, 0, 0, 0, 0, - 925, 913, 913, 913, 913, 913, 913, 918, 0, 0, - 0, 915, 915, 915, 915, 915, 915, 917, 917, 917, - 917, 917, 917, 914, 914, 914, 914, 914, 914, 925, - 927, 1459, 1460, 918, 918, 918, 918, 918, 918, 924, - - 924, 924, 924, 924, 924, 924, 924, 926, 0, 0, - 925, 925, 925, 925, 925, 925, 926, 927, 928, 1472, - 1459, 1460, 1478, 929, 929, 929, 929, 929, 929, 0, - 930, 952, 952, 0, 1479, 952, 931, 952, 952, 952, - 0, 0, 932, 0, 1511, 926, 927, 928, 1472, 962, - 962, 1478, 0, 962, 934, 962, 962, 962, 930, 0, - 935, 0, 932, 1479, 927, 927, 927, 927, 927, 927, - 933, 935, 931, 1511, 1512, 0, 928, 936, 0, 0, - 0, 926, 926, 926, 926, 926, 926, 930, 937, 0, - 934, 932, 928, 928, 928, 928, 928, 928, 933, 0, - - 935, 0, 0, 1512, 930, 930, 930, 930, 930, 930, - 931, 931, 931, 931, 931, 931, 932, 932, 932, 932, - 932, 932, 0, 0, 0, 0, 0, 933, 934, 934, - 934, 934, 934, 934, 935, 935, 935, 935, 935, 935, - 0, 0, 0, 0, 933, 933, 933, 933, 933, 933, - 0, 936, 936, 936, 936, 936, 936, 0, 0, 0, - 0, 0, 937, 937, 937, 937, 937, 937, 938, 938, - 938, 938, 938, 938, 938, 938, 938, 939, 939, 939, - 939, 939, 939, 939, 939, 939, 940, 940, 940, 940, - 940, 940, 940, 940, 941, 941, 941, 941, 941, 941, - - 941, 941, 941, 942, 942, 942, 942, 942, 942, 942, - 942, 942, 943, 943, 943, 943, 943, 943, 943, 943, - 943, 945, 945, 945, 945, 945, 945, 945, 945, 945, - 946, 946, 946, 946, 946, 946, 946, 946, 946, 947, - 947, 947, 947, 947, 947, 947, 947, 947, 948, 948, - 948, 948, 948, 948, 948, 948, 949, 949, 949, 949, - 949, 949, 949, 949, 949, 950, 950, 950, 950, 950, - 950, 950, 950, 950, 951, 951, 951, 951, 951, 951, - 951, 951, 951, 953, 953, 953, 953, 953, 953, 953, - 953, 953, 954, 954, 954, 954, 954, 954, 954, 954, - - 954, 955, 956, 957, 957, 957, 957, 957, 957, 957, - 957, 957, 958, 958, 958, 958, 958, 958, 958, 958, - 959, 959, 959, 959, 959, 959, 959, 959, 959, 0, - 955, 956, 960, 960, 960, 960, 960, 960, 960, 960, - 960, 965, 965, 965, 965, 965, 965, 955, 955, 955, - 955, 955, 955, 0, 0, 0, 956, 956, 956, 956, - 956, 956, 961, 961, 961, 961, 961, 961, 961, 961, - 961, 963, 963, 963, 963, 963, 963, 963, 963, 963, - 964, 964, 964, 964, 964, 964, 964, 964, 964, 966, - 966, 966, 966, 966, 966, 967, 967, 967, 967, 967, - - 967, 967, 967, 967, 1014, 1014, 1014, 1014, 1014, 1014, - 1014, 1014, 1014, 1015, 1015, 1015, 1015, 1015, 1015, 1015, - 1015, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, - 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1018, - 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1019, 1019, - 0, 0, 1019, 0, 1019, 1019, 1019, 1020, 1020, 1020, - 1020, 1020, 1020, 1020, 1020, 1020, 1021, 1021, 1021, 1021, - 1021, 1021, 1021, 1021, 1021, 1022, 1022, 1022, 1022, 1022, - 1022, 1022, 1022, 1023, 1023, 1029, 0, 1023, 0, 1023, - 1023, 1023, 1030, 1032, 1524, 1537, 0, 1031, 1035, 1035, - - 1035, 1035, 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1036, - 0, 1051, 1051, 1538, 1029, 1051, 0, 1051, 1051, 1051, - 0, 1030, 1032, 1524, 1537, 1034, 1031, 1033, 1047, 1047, - 1047, 1047, 1047, 1047, 1047, 1047, 1029, 1029, 1029, 1029, - 1029, 1029, 1538, 0, 1030, 1030, 1030, 1030, 1030, 1030, - 1031, 1031, 1031, 1031, 1031, 1031, 1033, 1032, 1032, 1032, - 1032, 1032, 1032, 1034, 1034, 1034, 1034, 1034, 1034, 0, - 1098, 1098, 1098, 1033, 1033, 1033, 1033, 1033, 1033, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1046, 1046, - 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1048, 1048, 1048, - - 1048, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, - 1049, 1049, 1049, 1049, 1049, 1050, 1050, 1050, 1050, 1050, - 1050, 1050, 1050, 1050, 1052, 1052, 1052, 1052, 1052, 1052, - 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1053, 1053, 1053, - 1053, 1053, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, - 1055, 1055, 1058, 0, 1055, 0, 1055, 1055, 1055, 1060, - 1098, 0, 1539, 1066, 1059, 1061, 1061, 1061, 1061, 1061, - 1061, 1062, 1062, 1062, 1062, 1062, 1062, 0, 0, 0, - 0, 1058, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, - 1065, 1539, 1066, 1059, 0, 0, 0, 1060, 1060, 1060, - - 1060, 1060, 1060, 0, 1058, 1058, 1058, 1058, 1058, 1058, - 1059, 1059, 1059, 1059, 1059, 1059, 1066, 1066, 1066, 1066, - 1066, 1066, 1067, 1067, 1067, 1067, 1067, 1067, 1068, 1068, - 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, 1069, 1069, - 1069, 1069, 1069, 1072, 1072, 1072, 1072, 1072, 1072, 1072, - 1072, 1072, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1075, - 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1076, 1076, - 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1077, 1077, 1088, - 1088, 1077, 0, 1077, 1077, 1077, 1078, 1078, 1078, 1078, - - 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1080, 1080, - 1080, 1080, 1081, 1081, 1091, 1092, 1081, 1109, 1081, 1081, - 1081, 1094, 1094, 1094, 1094, 1094, 1094, 1095, 1095, 1095, - 1095, 1095, 1095, 1097, 1097, 1097, 1097, 1097, 1097, 1097, - 1097, 1097, 1093, 1091, 1092, 1102, 1102, 1102, 1115, 1540, - 0, 1088, 1088, 1088, 1088, 1088, 1088, 1110, 0, 1119, - 1119, 1119, 0, 0, 0, 1091, 1091, 1091, 1091, 1091, - 1091, 1093, 1133, 1133, 1133, 1133, 1133, 1133, 1540, 1092, - 1092, 1092, 1092, 1092, 1092, 1265, 1265, 1265, 0, 1093, - - 1093, 1093, 1093, 1093, 1093, 1116, 1542, 1546, 1547, 1549, - 0, 1109, 1109, 1109, 1109, 1109, 1109, 1111, 1111, 1111, - 1111, 1111, 1111, 1111, 1111, 1111, 1114, 1114, 1114, 1114, - 1114, 1114, 1114, 1114, 1114, 1542, 1546, 1547, 1549, 1115, - 1115, 1115, 1115, 1115, 1115, 1102, 0, 0, 0, 0, - 0, 1110, 1110, 1110, 1110, 1110, 1110, 1112, 1112, 1119, - 0, 1112, 1112, 0, 0, 1112, 1112, 1112, 1112, 1112, - 1112, 1112, 1112, 1112, 1127, 1128, 1112, 1112, 1112, 1112, - 1112, 0, 0, 0, 1130, 1265, 1116, 1116, 1116, 1116, - 1116, 1116, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, - - 1117, 0, 0, 1127, 1128, 0, 0, 1112, 0, 1112, - 1259, 1259, 1259, 1130, 1259, 0, 1128, 1128, 1128, 1128, - 1128, 1128, 1127, 1127, 1127, 1127, 1127, 1127, 0, 1129, - 1130, 1130, 1130, 1130, 1130, 1130, 1112, 1112, 1112, 1112, - 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, - 1112, 1112, 1113, 1113, 1131, 1550, 1113, 1113, 1129, 0, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1132, - 0, 1113, 1113, 1113, 1113, 1113, 1144, 1144, 1144, 1144, - 1144, 1144, 0, 1131, 1550, 1548, 1129, 1129, 1129, 1129, - 1129, 1129, 0, 0, 0, 1134, 0, 1548, 1132, 1134, - - 1259, 1135, 1113, 0, 1113, 0, 1131, 1131, 1131, 1131, - 1131, 1131, 0, 0, 1548, 0, 0, 1132, 1132, 1132, - 1132, 1132, 1132, 1136, 1134, 1137, 1548, 0, 1134, 0, - 1135, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 0, 1138, 1139, - 1140, 0, 1136, 0, 1137, 0, 1134, 1134, 1134, 1134, - 1134, 1134, 1135, 1135, 1135, 1135, 1135, 1135, 1279, 1279, - 1279, 1137, 1137, 1137, 1137, 1137, 1137, 1138, 1139, 1140, - 1136, 1136, 1136, 1136, 1136, 1136, 1150, 1150, 1150, 1150, - 1150, 1150, 1141, 1142, 1138, 1138, 1138, 1138, 1138, 1138, - - 1143, 1147, 1148, 1139, 1139, 1139, 1139, 1139, 1139, 1154, - 1154, 1154, 1154, 1154, 1154, 1140, 1140, 1140, 1140, 1140, - 1140, 1141, 1142, 0, 0, 1145, 0, 1149, 1551, 1143, - 1147, 1148, 0, 1141, 1141, 1141, 1141, 1141, 1141, 1142, - 1142, 1142, 1142, 1142, 1142, 0, 0, 0, 1143, 1143, - 1143, 1143, 1143, 1143, 1145, 1146, 1149, 1551, 1279, 1152, - 1148, 1148, 1148, 1148, 1148, 1148, 1147, 1147, 1147, 1147, - 1147, 1147, 0, 1145, 1145, 1145, 1145, 1145, 1145, 1151, - 1155, 0, 0, 0, 1146, 0, 1153, 1552, 1152, 1149, - 1149, 1149, 1149, 1149, 1149, 0, 0, 1160, 1160, 1160, - - 1146, 1146, 1146, 1146, 1146, 1146, 1156, 0, 1151, 1152, - 1152, 1152, 1152, 1152, 1152, 1153, 1552, 0, 1155, 1155, - 1155, 1155, 1155, 1155, 1157, 1151, 1151, 1151, 1151, 1151, - 1151, 1158, 1553, 1545, 1161, 1156, 1545, 0, 1153, 1153, - 1153, 1153, 1153, 1153, 1159, 1159, 1159, 1159, 1159, 1159, - 0, 0, 0, 1157, 1156, 1156, 1156, 1156, 1156, 1156, - 1158, 1553, 1545, 0, 0, 1545, 1157, 1157, 1157, 1157, - 1157, 1157, 1161, 1161, 1161, 1161, 1161, 1161, 1163, 1158, - 1158, 1158, 1158, 1158, 1158, 1160, 1160, 1160, 1160, 1160, - 1160, 1162, 1162, 1162, 1162, 1162, 1162, 1287, 1287, 1287, - - 0, 1164, 1165, 1554, 1175, 1555, 1167, 1163, 1166, 1169, - 1169, 1169, 1169, 1169, 1169, 1168, 1172, 1172, 1172, 0, - 1299, 1299, 1299, 0, 1163, 1163, 1163, 1163, 1163, 1163, - 1164, 1165, 1554, 1175, 1555, 1167, 0, 1166, 0, 0, - 1170, 1313, 1313, 1313, 1168, 1175, 1175, 1175, 1175, 1175, - 1175, 1164, 1164, 1164, 1164, 1164, 1164, 1167, 1167, 1167, - 1167, 1167, 1167, 1165, 1165, 1165, 1165, 1165, 1165, 1170, - 1166, 1166, 1166, 1166, 1166, 1166, 1168, 1168, 1168, 1168, - 1168, 1168, 1171, 1173, 1583, 1584, 1189, 1287, 1170, 1170, - 1170, 1170, 1170, 1170, 1174, 1177, 1177, 1177, 1177, 1177, - - 1177, 1178, 0, 0, 1172, 1172, 1172, 1172, 1172, 1172, - 1299, 1171, 1173, 1583, 1584, 1189, 1176, 1205, 1205, 1205, - 1205, 1205, 1205, 1174, 0, 1179, 1319, 1319, 1319, 0, - 1178, 1313, 1180, 1189, 1189, 1189, 1189, 1189, 1189, 1171, - 1171, 1171, 1171, 1171, 1171, 1176, 0, 0, 1173, 1173, - 1173, 1173, 1173, 1173, 1179, 1174, 1174, 1174, 1174, 1174, - 1174, 1180, 1178, 1178, 1178, 1178, 1178, 1178, 0, 0, - 0, 1176, 1176, 1176, 1176, 1176, 1176, 1181, 1179, 1179, - 1179, 1179, 1179, 1179, 1182, 1183, 1585, 0, 1588, 1590, - 1592, 1184, 0, 1188, 1188, 1188, 0, 1180, 1180, 1180, - - 1180, 1180, 1180, 0, 0, 0, 1181, 0, 0, 1185, - 1593, 1594, 0, 1182, 1183, 1585, 1319, 1588, 1590, 1592, - 1184, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, - 0, 1595, 1181, 1181, 1181, 1181, 1181, 1181, 1185, 1593, - 1594, 1190, 1183, 1183, 1183, 1183, 1183, 1183, 1182, 1182, - 1182, 1182, 1182, 1182, 1184, 1184, 1184, 1184, 1184, 1184, - 1595, 0, 0, 0, 1192, 0, 1596, 1453, 1453, 1453, - 1190, 1453, 1185, 1185, 1185, 1185, 1185, 1185, 1186, 1186, - 1186, 1188, 1188, 1188, 1188, 1188, 1188, 1190, 1190, 1190, - 1190, 1190, 1190, 1192, 1193, 1596, 0, 0, 0, 0, - - 1186, 0, 1600, 1186, 1186, 1191, 1536, 0, 1194, 0, - 1536, 1536, 1196, 1601, 1186, 1186, 1186, 1255, 1255, 1255, - 1186, 0, 0, 1193, 1255, 1192, 1192, 1192, 1192, 1192, - 1192, 1600, 1186, 1186, 1191, 1536, 1195, 1194, 1197, 1536, - 1536, 1196, 1601, 1186, 1186, 1186, 0, 0, 0, 1186, - 1191, 1191, 1191, 1191, 1191, 1191, 0, 1453, 0, 1193, - 1193, 1193, 1193, 1193, 1193, 1195, 0, 1197, 1186, 1194, - 1194, 1194, 1194, 1194, 1194, 1196, 1196, 1196, 1196, 1196, - 1196, 1198, 1200, 1195, 1195, 1195, 1195, 1195, 1195, 1199, - 1197, 1197, 1197, 1197, 1197, 1197, 1201, 1207, 1207, 1207, - - 1207, 1207, 1207, 1202, 1208, 1203, 0, 1255, 0, 0, - 1198, 1200, 1216, 1216, 1216, 1216, 1216, 1216, 1199, 0, - 0, 0, 0, 0, 1204, 1201, 1198, 1198, 1198, 1198, - 1198, 1198, 1202, 1206, 1203, 1199, 1199, 1199, 1199, 1199, - 1199, 1208, 1208, 1208, 1208, 1208, 1208, 1200, 1200, 1200, - 1200, 1200, 1200, 1204, 0, 1201, 1201, 1201, 1201, 1201, - 1201, 1211, 1206, 1209, 1202, 1202, 1202, 1202, 1202, 1202, - 1203, 1203, 1203, 1203, 1203, 1203, 1217, 0, 0, 0, - 1217, 1204, 1204, 1204, 1204, 1204, 1204, 1212, 1602, 1606, - 1211, 0, 1613, 0, 1206, 1206, 1206, 1206, 1206, 1206, - - 1209, 1209, 1209, 1209, 1209, 1209, 1210, 1210, 1210, 1210, - 1210, 1210, 1210, 1210, 1210, 1213, 1212, 1602, 1606, 0, - 1215, 1613, 1211, 1211, 1211, 1211, 1211, 1211, 1214, 1212, - 1212, 1212, 1212, 1212, 1212, 1218, 0, 0, 0, 1218, - 0, 1220, 0, 0, 1213, 1220, 1620, 1620, 1620, 1215, - 1217, 1217, 1217, 1217, 1217, 1217, 1213, 1213, 1213, 1213, - 1213, 1213, 1218, 1629, 0, 1220, 1214, 1214, 1214, 1214, - 1214, 1214, 1215, 1215, 1215, 1215, 1215, 1215, 1219, 0, - 0, 0, 1219, 0, 0, 1222, 1257, 1257, 1257, 1222, - 0, 1218, 1629, 1257, 1220, 1224, 1587, 1228, 1630, 1224, - - 1634, 1587, 1658, 0, 1229, 0, 1219, 0, 1224, 1218, - 1218, 1218, 1218, 1218, 1218, 1220, 1220, 1220, 1220, 1220, - 1220, 1222, 1223, 0, 0, 1587, 1223, 1630, 1225, 1634, - 1587, 1658, 1225, 0, 1226, 1219, 1620, 1224, 1226, 1223, - 0, 0, 0, 0, 0, 1227, 0, 0, 1225, 1227, - 1659, 1226, 1219, 1219, 1219, 1219, 1219, 1219, 1227, 1222, - 1222, 1222, 1222, 1222, 1222, 1231, 1669, 0, 1223, 1224, - 1224, 1224, 1224, 1224, 1224, 1232, 1257, 1225, 0, 1659, - 1226, 1228, 1228, 1228, 1228, 1228, 1228, 1227, 1229, 1229, - 1229, 1229, 1229, 1229, 0, 1669, 1223, 1223, 1223, 1223, - - 1223, 1223, 1225, 1225, 1225, 1225, 1225, 1225, 1226, 1226, - 1226, 1226, 1226, 1226, 0, 0, 1680, 0, 0, 1227, - 1227, 1227, 1227, 1227, 1227, 1230, 1230, 1230, 1230, 1230, - 1230, 1230, 1230, 1230, 1233, 1233, 1233, 1233, 1233, 1233, - 1233, 1233, 1233, 1234, 1235, 1680, 1231, 1231, 1231, 1231, - 1231, 1231, 1236, 0, 0, 0, 1232, 1232, 1232, 1232, - 1232, 1232, 1237, 1238, 1238, 1238, 1238, 1238, 1238, 1238, - 1238, 1238, 0, 1235, 1293, 1293, 1293, 1293, 1293, 1293, - 0, 1234, 1234, 1234, 1234, 1234, 1234, 0, 1271, 1236, - 1236, 1236, 1236, 1236, 1236, 0, 1934, 1934, 1934, 1237, - - 1237, 1237, 1237, 1237, 1237, 1235, 1235, 1235, 1235, 1235, - 1235, 1261, 1261, 0, 0, 1261, 1261, 1271, 1272, 1261, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1275, 1681, - 1261, 1261, 1261, 1261, 1261, 1263, 1263, 1263, 1263, 1263, - 1263, 1263, 1263, 1263, 1273, 1273, 1273, 1272, 0, 1273, - 0, 1271, 1271, 1271, 1271, 1271, 1271, 1273, 1681, 1682, - 1683, 1261, 0, 1261, 0, 0, 1275, 1275, 1275, 1275, - 1275, 1275, 1411, 1411, 1411, 1411, 1411, 1411, 0, 1274, - 1272, 1272, 1272, 1272, 1272, 1272, 1934, 0, 1682, 1683, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - - 1261, 1261, 1261, 1261, 1261, 1261, 1262, 1262, 1274, 1276, - 1262, 1262, 1291, 0, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 0, 0, 1262, 1262, 1262, 1262, 1262, - 0, 0, 1273, 1273, 1273, 1273, 1273, 1273, 1276, 1684, - 1685, 1368, 1368, 1368, 1274, 1274, 1274, 1274, 1274, 1274, - 1291, 1291, 1291, 1291, 1291, 1291, 1262, 0, 1262, 1285, - 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1684, 1685, - 0, 0, 1276, 1276, 1276, 1276, 1276, 1276, 1290, 1368, - 0, 0, 1943, 1943, 1943, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, - - 1262, 1283, 1283, 1292, 0, 1283, 1283, 1290, 1368, 1283, - 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1686, 1687, - 1283, 1283, 1283, 1283, 1283, 1426, 1426, 1426, 1426, 1426, - 1426, 1368, 1292, 1328, 1328, 1328, 1412, 0, 0, 0, - 1290, 1290, 1290, 1290, 1290, 1290, 0, 1686, 1687, 0, - 0, 1283, 0, 1283, 1297, 1297, 1297, 1297, 1297, 1297, - 1297, 1297, 1297, 0, 0, 0, 1292, 1292, 1292, 1292, - 1292, 1292, 1943, 1309, 1412, 1412, 1412, 1412, 1412, 1412, - 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, - 1283, 1283, 1283, 1283, 1283, 1283, 1284, 1284, 1310, 1311, - - 1284, 1284, 1309, 0, 1284, 1284, 1284, 1284, 1284, 1284, - 1284, 1284, 1284, 0, 0, 1284, 1284, 1284, 1284, 1284, - 0, 1328, 1328, 1328, 1328, 1328, 1328, 1310, 1311, 0, - 1331, 1331, 1331, 1688, 0, 0, 1309, 1309, 1309, 1309, - 1309, 1309, 1332, 1332, 1332, 1689, 1284, 0, 1284, 1569, - 1569, 1569, 1569, 1569, 1569, 0, 1311, 1311, 1311, 1311, - 1311, 1311, 1688, 1310, 1310, 1310, 1310, 1310, 1310, 1329, - 1329, 1329, 0, 1418, 1689, 1284, 1284, 1284, 1284, 1284, - 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, - 1284, 1295, 1295, 0, 0, 1295, 1295, 0, 0, 1295, - - 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1690, 1418, - 1295, 1295, 1295, 1295, 1295, 1691, 1692, 1329, 1331, 1331, - 1331, 1331, 1331, 1331, 1572, 1572, 1572, 1572, 1572, 1572, - 1332, 1332, 1332, 1332, 1332, 1332, 0, 1690, 1336, 1336, - 1336, 1295, 0, 1295, 1691, 1692, 1329, 1418, 1418, 1418, - 1418, 1418, 1418, 1334, 1334, 1334, 0, 1329, 1329, 1329, - 1329, 1329, 1329, 1336, 1330, 1330, 1330, 0, 0, 0, - 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, - 1295, 1295, 1295, 1295, 1295, 1295, 1296, 1296, 1330, 1334, - 1296, 1296, 1336, 1693, 1296, 1296, 1296, 1296, 1296, 1296, - - 1296, 1296, 1296, 0, 0, 1296, 1296, 1296, 1296, 1296, - 1694, 1333, 1333, 1333, 0, 0, 0, 1330, 1334, 1335, - 1335, 1335, 1693, 1970, 1970, 1970, 1336, 1336, 1336, 1336, - 1336, 1336, 1338, 1338, 1338, 0, 1296, 1970, 1296, 1694, - 0, 1334, 1334, 1334, 1334, 1334, 1334, 1337, 1337, 1337, - 0, 0, 1330, 1330, 1330, 1330, 1330, 1330, 1333, 0, - 0, 1335, 1339, 1339, 1339, 1296, 1296, 1296, 1296, 1296, - 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, - 1296, 0, 1340, 1340, 1340, 0, 0, 1333, 1337, 1339, - 1335, 1341, 1341, 1341, 0, 0, 0, 0, 0, 1333, - - 1333, 1333, 1333, 1333, 1333, 0, 0, 1335, 1335, 1335, - 1335, 1335, 1335, 1970, 1517, 1517, 1517, 1337, 1339, 1340, - 1338, 1338, 1338, 1338, 1338, 1338, 1344, 1344, 1344, 1517, - 0, 1341, 1342, 1342, 1342, 1337, 1337, 1337, 1337, 1337, - 1337, 1343, 1343, 1343, 0, 0, 0, 1695, 1340, 1696, - 1339, 1339, 1339, 1339, 1339, 1339, 1697, 1344, 1698, 1342, - 1341, 1699, 1443, 1443, 1443, 1345, 1345, 1345, 1343, 1443, - 1340, 1340, 1340, 1340, 1340, 1340, 1695, 0, 1696, 1341, - 1341, 1341, 1341, 1341, 1341, 1697, 1344, 1698, 1342, 0, - 1699, 1448, 1448, 1448, 1346, 1346, 1346, 1343, 1448, 0, - - 0, 1349, 1349, 1349, 1517, 0, 1345, 1347, 1347, 1347, - 0, 1486, 1486, 1486, 1344, 1344, 1344, 1344, 1344, 1344, - 1342, 1342, 1342, 1342, 1342, 1342, 1348, 1348, 1348, 1343, - 1343, 1343, 1343, 1343, 1343, 1345, 1346, 1700, 1347, 1350, - 1350, 1350, 1701, 1702, 1724, 1352, 1352, 1352, 0, 1486, - 1348, 1349, 1443, 1345, 1345, 1345, 1345, 1345, 1345, 1351, - 1351, 1351, 0, 0, 0, 1346, 1700, 1347, 1355, 1355, - 1355, 1701, 1702, 1724, 1352, 1353, 1353, 1353, 1486, 1348, - 0, 1448, 1346, 1346, 1346, 1346, 1346, 1346, 0, 1349, - 1349, 1349, 1349, 1349, 1349, 1347, 1347, 1347, 1347, 1347, - - 1347, 1486, 0, 1352, 1356, 1356, 1356, 0, 0, 1351, - 1726, 1727, 1728, 1353, 1348, 1348, 1348, 1348, 1348, 1348, - 0, 0, 0, 0, 1357, 1357, 1357, 1350, 1350, 1350, - 1350, 1350, 1350, 1352, 1352, 1352, 1352, 1352, 1352, 1726, - 1727, 1728, 1353, 1354, 1354, 1354, 1356, 1351, 1351, 1351, - 1351, 1351, 1351, 1357, 1729, 0, 1355, 1355, 1355, 1355, - 1355, 1355, 1357, 1353, 1353, 1353, 1353, 1353, 1353, 1730, - 1354, 1360, 1360, 1360, 0, 1356, 0, 0, 1359, 1359, - 1359, 0, 1357, 1729, 1361, 1361, 1361, 1731, 1732, 0, - 0, 1357, 1356, 1356, 1356, 1356, 1356, 1356, 1730, 1354, - - 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1359, - 1362, 1362, 1362, 0, 1357, 1733, 1731, 1732, 1363, 1363, - 1363, 0, 0, 0, 1361, 1362, 1734, 0, 1364, 1364, - 1364, 1354, 1354, 1354, 1354, 1354, 1354, 0, 1359, 0, - 0, 1365, 1365, 1365, 1733, 0, 0, 0, 0, 1363, - 1366, 1366, 1366, 1361, 0, 1734, 1370, 1370, 1370, 1360, - 1360, 1360, 1360, 1360, 1360, 1364, 1359, 1359, 1359, 1359, - 1359, 1359, 1361, 1361, 1361, 1361, 1361, 1361, 1363, 0, - 1367, 1367, 1367, 1365, 1369, 1369, 1369, 1369, 1369, 1369, - 1369, 1369, 1369, 0, 1364, 1735, 1370, 0, 1362, 1362, - - 1362, 1362, 1362, 1362, 0, 0, 1363, 1363, 1363, 1363, - 1363, 1363, 1365, 1371, 1371, 1371, 1364, 1364, 1364, 1364, - 1364, 1364, 1367, 0, 1735, 1370, 1372, 1372, 1372, 1365, - 1365, 1365, 1365, 1365, 1365, 1373, 1373, 1373, 1366, 1366, - 1366, 1366, 1366, 1366, 1370, 1370, 1370, 1370, 1370, 1370, - 1736, 1367, 1374, 1374, 1374, 1737, 1738, 0, 1376, 1376, - 1376, 1744, 0, 1747, 1375, 1375, 1375, 0, 1367, 1367, - 1367, 1367, 1367, 1367, 1379, 1379, 1379, 0, 0, 1736, - 1377, 1377, 1377, 1376, 1737, 1738, 1378, 1378, 1378, 0, - 1744, 1375, 1747, 1374, 1380, 1380, 1380, 0, 0, 0, - - 1763, 1371, 1371, 1371, 1371, 1371, 1371, 1377, 1764, 1378, - 1379, 0, 1376, 0, 1372, 1372, 1372, 1372, 1372, 1372, - 1375, 0, 1374, 1373, 1373, 1373, 1373, 1373, 1373, 1763, - 1767, 1380, 1394, 1394, 1394, 0, 1377, 1764, 1378, 1379, - 1374, 1374, 1374, 1374, 1374, 1374, 1376, 1376, 1376, 1376, - 1376, 1376, 1375, 1375, 1375, 1375, 1375, 1375, 0, 1767, - 1380, 0, 1379, 1379, 1379, 1379, 1379, 1379, 1377, 1377, - 1377, 1377, 1377, 1377, 1378, 1378, 1378, 1378, 1378, 1378, - 0, 0, 1380, 1380, 1380, 1380, 1380, 1380, 1381, 1381, - 1381, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, - - 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1393, - 1393, 1393, 1462, 0, 1570, 0, 1784, 1785, 1793, 1799, - 1394, 1394, 1394, 1394, 1394, 1394, 0, 1800, 0, 1801, - 1381, 1463, 1463, 1463, 0, 0, 1463, 1806, 1808, 1393, - 1396, 1396, 1396, 1570, 1463, 1784, 1785, 1793, 1799, 0, - 1462, 1462, 1462, 1462, 1462, 1462, 1800, 1463, 1801, 1381, - 1570, 1570, 1570, 1570, 1570, 1570, 1806, 1808, 1393, 0, - 0, 1395, 1395, 1395, 0, 0, 1381, 1381, 1381, 1381, - 1381, 1381, 1391, 1391, 1391, 0, 1463, 0, 1397, 1397, - 1397, 0, 0, 1810, 1398, 1398, 1398, 1393, 1393, 1393, - - 1393, 1393, 1393, 1399, 1399, 1399, 1811, 1391, 1391, 1391, - 1391, 1391, 1395, 1391, 1397, 1391, 1401, 1401, 1401, 1812, - 1391, 1463, 1810, 1391, 1391, 1813, 1399, 1391, 1396, 1396, - 1396, 1396, 1396, 1396, 0, 1811, 1391, 1391, 1391, 1391, - 1391, 1395, 1391, 1397, 1391, 1400, 1400, 1400, 1812, 1391, - 0, 0, 1391, 1391, 1813, 1399, 1391, 0, 0, 1395, - 1395, 1395, 1395, 1395, 1395, 0, 0, 0, 1400, 1791, - 1791, 1791, 1391, 1402, 1402, 1402, 1397, 1397, 1397, 1397, - 1397, 1397, 1398, 1398, 1398, 1398, 1398, 1398, 1403, 1403, - 1403, 1399, 1399, 1399, 1399, 1399, 1399, 1400, 0, 1791, - - 1402, 1404, 1404, 1404, 1401, 1401, 1401, 1401, 1401, 1401, - 1405, 1405, 1405, 1425, 1814, 1403, 1406, 1406, 1406, 1815, - 1816, 1817, 1407, 1407, 1407, 1818, 1819, 1404, 1791, 1402, - 1409, 1409, 1409, 1400, 1400, 1400, 1400, 1400, 1400, 0, - 0, 0, 1425, 1814, 1403, 1820, 1407, 0, 1815, 1816, - 1817, 1408, 1408, 1408, 1818, 1819, 1404, 1406, 0, 1791, - 0, 1402, 1402, 1402, 1402, 1402, 1402, 1413, 1425, 1425, - 1425, 1425, 1425, 1425, 1820, 1407, 1403, 1403, 1403, 1403, - 1403, 1403, 0, 0, 0, 0, 1406, 1408, 0, 1404, - 1404, 1404, 1404, 1404, 1404, 1410, 1413, 1414, 1405, 1405, - - 1405, 1405, 1405, 1405, 1406, 1406, 1406, 1406, 1406, 1406, - 1407, 1407, 1407, 1407, 1407, 1407, 1408, 1416, 1409, 1409, - 1409, 1409, 1409, 1409, 1410, 0, 1414, 0, 0, 1417, - 1413, 1413, 1413, 1413, 1413, 1413, 1419, 1821, 1822, 1408, - 1408, 1408, 1408, 1408, 1408, 1416, 1417, 1410, 1410, 1410, - 1410, 1410, 1410, 1421, 1809, 1419, 1414, 1414, 1414, 1414, - 1414, 1414, 1424, 0, 0, 0, 1821, 1822, 1420, 0, - 1461, 1823, 1809, 1825, 1416, 1417, 1423, 1490, 1490, 1490, - 1420, 0, 0, 1809, 1419, 0, 0, 1826, 1423, 1421, - 1827, 1416, 1416, 1416, 1416, 1416, 1416, 1422, 1424, 1461, - - 1823, 1809, 1825, 1417, 1417, 1417, 1417, 1417, 1417, 1420, - 1419, 1419, 1419, 1419, 1419, 1419, 1826, 1423, 0, 1827, - 1422, 1461, 1461, 1461, 1461, 1461, 1461, 1421, 1421, 1421, - 1421, 1421, 1421, 0, 0, 0, 1424, 1424, 1424, 1424, - 1424, 1424, 1420, 1420, 1420, 1420, 1420, 1420, 0, 1422, - 1423, 1423, 1423, 1423, 1423, 1423, 1466, 1466, 1466, 1466, - 1466, 1466, 1466, 1466, 1466, 1490, 1490, 1490, 1490, 1490, - 1490, 1422, 1422, 1422, 1422, 1422, 1422, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1467, 1848, 1851, 1468, 0, 0, 0, 1474, - 1622, 1622, 1622, 1622, 1622, 1622, 0, 1469, 1632, 1632, - 1632, 1632, 1632, 1632, 1475, 1766, 1766, 1766, 1766, 1766, - - 1766, 1467, 1848, 1851, 1468, 1487, 1487, 1487, 1487, 1487, - 1487, 1487, 1487, 1487, 0, 1476, 1469, 1474, 1474, 1474, - 1474, 1474, 1474, 1475, 0, 0, 1467, 1467, 1467, 1467, - 1467, 1467, 1468, 1468, 1468, 1468, 1468, 1468, 1469, 1469, - 1469, 1469, 1469, 1469, 1476, 1480, 1855, 1858, 1481, 1859, - 1860, 1475, 1475, 1475, 1475, 1475, 1475, 1482, 1488, 1488, - 1488, 1861, 1866, 1870, 0, 1577, 1476, 1476, 1476, 1476, - 1476, 1476, 0, 0, 1480, 1855, 1858, 1481, 1859, 1860, - 1489, 1489, 1489, 0, 0, 1488, 1482, 1491, 1491, 1491, - 1861, 1866, 1870, 1492, 1492, 1492, 1480, 1480, 1480, 1480, - - 1480, 1480, 1481, 1481, 1481, 1481, 1481, 1481, 1482, 1482, - 1482, 1482, 1482, 1482, 1488, 0, 1886, 1493, 1493, 1493, - 0, 0, 0, 1489, 1494, 1494, 1494, 1887, 1889, 1491, - 1495, 1495, 1495, 1906, 1907, 1912, 1496, 1496, 1496, 1577, - 1577, 1577, 1577, 1577, 1577, 1886, 1488, 1488, 1488, 1488, - 1488, 1488, 1489, 0, 0, 0, 1887, 1889, 1491, 1493, - 1915, 1496, 1906, 1907, 1912, 1920, 1494, 0, 1489, 1489, - 1489, 1489, 1489, 1489, 0, 1491, 1491, 1491, 1491, 1491, - 1491, 1492, 1492, 1492, 1492, 1492, 1492, 0, 1493, 1915, - 1496, 1501, 1501, 1501, 1920, 1494, 1514, 1514, 1514, 1514, - - 1514, 1514, 1514, 1514, 1514, 1493, 1493, 1493, 1493, 1493, - 1493, 1921, 1494, 1494, 1494, 1494, 1494, 1494, 1495, 1495, - 1495, 1495, 1495, 1495, 1496, 1496, 1496, 1496, 1496, 1496, - 1497, 1497, 1497, 0, 1922, 0, 1498, 1498, 1498, 1824, - 1921, 1927, 1928, 1499, 1499, 1499, 0, 0, 1929, 1500, - 1500, 1500, 0, 0, 0, 0, 1930, 1497, 1499, 1931, - 1824, 1932, 1498, 1922, 1504, 1504, 1504, 1933, 1824, 0, - 1927, 1928, 0, 1500, 1502, 1502, 1502, 1929, 0, 1501, - 1501, 1501, 1501, 1501, 1501, 1930, 1497, 1504, 1931, 1824, - 1932, 1498, 0, 0, 0, 0, 1933, 1507, 1507, 1507, - - 0, 1502, 1500, 0, 0, 0, 0, 1503, 1503, 1503, - 0, 0, 0, 1506, 1506, 1506, 1504, 0, 1497, 1497, - 1497, 1497, 1497, 1497, 1498, 1498, 1498, 1498, 1498, 1498, - 1502, 1499, 1499, 1499, 1499, 1499, 1499, 1500, 1500, 1500, - 1500, 1500, 1500, 1503, 1505, 1505, 1505, 1935, 1936, 1506, - 0, 0, 1504, 1504, 1504, 1504, 1504, 1504, 1509, 1509, - 1509, 0, 1502, 1502, 1502, 1502, 1502, 1502, 0, 1508, - 1508, 1508, 1503, 0, 0, 0, 1935, 1936, 1506, 1510, - 1510, 1510, 1937, 1938, 1505, 1507, 1507, 1507, 1507, 1507, - 1507, 1515, 1515, 1515, 1510, 1503, 1503, 1503, 1503, 1503, - - 1503, 1506, 1506, 1506, 1506, 1506, 1506, 0, 0, 1508, - 0, 1937, 1938, 1505, 1516, 1516, 1516, 1519, 1519, 1519, - 1519, 1519, 1519, 1519, 1519, 1519, 1939, 1515, 0, 1521, - 1521, 1521, 1505, 1505, 1505, 1505, 1505, 1505, 1508, 1522, - 1522, 1522, 0, 0, 1623, 1516, 1509, 1509, 1509, 1509, - 1509, 1509, 1520, 1520, 1520, 1939, 1515, 1508, 1508, 1508, - 1508, 1508, 1508, 1521, 1523, 1523, 1523, 1510, 1510, 1510, - 1510, 1510, 1510, 1623, 1516, 1529, 1529, 1529, 0, 1515, - 1515, 1515, 1515, 1515, 1515, 0, 0, 0, 0, 1531, - 1531, 1531, 1521, 0, 1520, 1523, 1623, 1623, 1623, 1623, - - 1623, 1623, 1516, 1516, 1516, 1516, 1516, 1516, 1526, 1526, - 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1521, 1521, 1521, - 1521, 1521, 1521, 1520, 1523, 0, 0, 1522, 1522, 1522, - 1522, 1522, 1522, 1527, 1527, 1527, 0, 0, 0, 0, - 1520, 1520, 1520, 1520, 1520, 1520, 1528, 1528, 1528, 0, - 0, 0, 1523, 1523, 1523, 1523, 1523, 1523, 0, 0, - 1527, 1940, 1941, 1529, 1529, 1529, 1529, 1529, 1529, 0, - 0, 1530, 1530, 1530, 1942, 1944, 1528, 1531, 1531, 1531, - 1531, 1531, 1531, 1945, 0, 0, 1532, 1532, 1532, 1527, - 1940, 1941, 1533, 1533, 1533, 0, 0, 0, 1530, 1534, - - 1534, 1534, 0, 1942, 1944, 1528, 1558, 1558, 1558, 0, - 0, 1532, 1945, 1535, 1535, 1535, 0, 0, 1947, 1533, - 0, 1527, 1527, 1527, 1527, 1527, 1527, 1530, 1535, 1559, - 1559, 1559, 0, 0, 1528, 1528, 1528, 1528, 1528, 1528, - 1532, 0, 1534, 1558, 1560, 1560, 1560, 1947, 1533, 1557, - 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 0, 1530, - 1530, 1530, 1530, 1530, 1530, 0, 0, 0, 1562, 1562, - 1562, 1534, 1558, 0, 1532, 1532, 1532, 1532, 1532, 1532, - 1533, 1533, 1533, 1533, 1533, 1533, 0, 1534, 1534, 1534, - 1534, 1534, 1534, 0, 1558, 1558, 1558, 1558, 1558, 1558, - - 1624, 1535, 1535, 1535, 1535, 1535, 1535, 1563, 1563, 1563, - 1562, 1580, 0, 1561, 1561, 1561, 0, 1559, 1559, 1559, - 1559, 1559, 1559, 0, 0, 1564, 1564, 1564, 0, 1624, - 0, 0, 1560, 1560, 1560, 1560, 1560, 1560, 1561, 1562, - 1564, 1566, 1566, 1566, 0, 1624, 1624, 1624, 1624, 1624, - 1624, 1565, 1565, 1565, 1948, 1949, 1562, 1562, 1562, 1562, - 1562, 1562, 1568, 1568, 1568, 0, 0, 1561, 1846, 1846, - 1846, 1846, 1846, 1846, 1567, 1567, 1567, 0, 1565, 1645, - 1645, 1645, 1574, 1948, 1949, 1580, 1580, 1580, 1580, 1580, - 1580, 1568, 1950, 1574, 1645, 1563, 1563, 1563, 1563, 1563, - - 1563, 1561, 1561, 1561, 1561, 1561, 1561, 1565, 1567, 1655, - 1655, 1655, 0, 1564, 1564, 1564, 1564, 1564, 1564, 1571, - 1568, 1950, 1574, 0, 1655, 0, 0, 0, 0, 1566, - 1566, 1566, 1566, 1566, 1566, 0, 1573, 1567, 0, 1565, - 1565, 1565, 1565, 1565, 1565, 0, 0, 0, 1571, 1573, - 1568, 1568, 1568, 1568, 1568, 1568, 1574, 1574, 1574, 1574, - 1574, 1574, 1567, 1567, 1567, 1567, 1567, 1567, 1579, 1645, - 1571, 1571, 1571, 1571, 1571, 1571, 1575, 1579, 1573, 1604, - 1951, 0, 1576, 1621, 1621, 1621, 1621, 1621, 1621, 1621, - 1621, 1621, 1963, 1575, 1964, 1576, 1965, 1966, 0, 1655, - - 0, 0, 1581, 0, 0, 1967, 1579, 1582, 1604, 1951, - 1573, 1573, 1573, 1573, 1573, 1573, 1578, 0, 0, 1581, - 1968, 1963, 1575, 1964, 1576, 1965, 1966, 1604, 1604, 1604, - 1604, 1604, 1604, 1578, 1967, 1969, 1582, 1996, 1578, 0, - 0, 0, 1579, 1579, 1579, 1579, 1579, 1579, 1581, 1968, - 1575, 1575, 1575, 1575, 1575, 1575, 1576, 1576, 1576, 1576, - 1576, 1576, 1578, 0, 1969, 0, 1996, 1578, 1582, 1582, - 1582, 1582, 1582, 1582, 1603, 1999, 1581, 1581, 1581, 1581, - 1581, 1581, 0, 1605, 1605, 1605, 2005, 0, 1605, 2012, - 1578, 1578, 1578, 1578, 1578, 1578, 1605, 1608, 1608, 1608, - - 0, 0, 1608, 1603, 1999, 1626, 2014, 1627, 0, 1605, - 1608, 1609, 1609, 1609, 0, 2005, 1609, 0, 2012, 2015, - 1612, 1612, 1612, 1608, 1609, 1612, 0, 1603, 1603, 1603, - 1603, 1603, 1603, 1612, 1626, 2014, 1627, 1609, 1605, 0, - 0, 1631, 2020, 1628, 0, 2027, 1612, 2028, 2015, 2029, - 1633, 0, 1608, 1626, 1626, 1626, 1626, 1626, 1626, 1627, - 1627, 1627, 1627, 1627, 1627, 0, 1609, 1637, 1637, 1637, - 1631, 2020, 1628, 1605, 2027, 1612, 2028, 0, 2029, 1633, - 1638, 1638, 1638, 0, 0, 2032, 1714, 1608, 1628, 1628, - 1628, 1628, 1628, 1628, 1631, 1631, 1631, 1631, 1631, 1631, - - 0, 1609, 1633, 1633, 1633, 1633, 1633, 1633, 0, 0, - 1612, 1614, 1614, 1614, 2032, 1714, 1614, 0, 0, 1897, - 1897, 1897, 1638, 0, 1614, 1636, 1636, 1636, 1636, 1636, - 1636, 1636, 1636, 1636, 1639, 1639, 1639, 1614, 1714, 1714, - 1714, 1714, 1714, 1714, 0, 1640, 1640, 1640, 2034, 1897, - 0, 1638, 1641, 1641, 1641, 1637, 1637, 1637, 1637, 1637, - 1637, 1642, 1642, 1642, 0, 0, 1614, 0, 1638, 1638, - 1638, 1638, 1638, 1638, 0, 0, 1640, 2034, 1897, 1641, - 1643, 1643, 1643, 2035, 1642, 2036, 1644, 1644, 1644, 2037, - 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 0, - - 2038, 1614, 1615, 1615, 1615, 1640, 0, 1615, 1641, 1897, - 2039, 0, 2035, 1642, 2036, 1615, 0, 0, 2037, 1649, - 1649, 1649, 1639, 1639, 1639, 1639, 1639, 1639, 1615, 2038, - 0, 0, 0, 1640, 1640, 1640, 1640, 1640, 1640, 2039, - 1641, 1641, 1641, 1641, 1641, 1641, 1650, 1650, 1650, 1642, - 1642, 1642, 1642, 1642, 1642, 0, 0, 1615, 1647, 1647, - 1647, 1647, 1647, 1647, 1647, 1647, 1647, 2040, 1643, 1643, - 1643, 1643, 1643, 1643, 1644, 1644, 1644, 1644, 1644, 1644, - 0, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, - 0, 0, 1615, 1616, 1616, 1616, 2040, 0, 1616, 0, - - 0, 0, 1648, 1648, 1648, 0, 1616, 1649, 1649, 1649, - 1649, 1649, 1649, 0, 0, 1651, 1651, 1651, 0, 1616, - 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1648, - 1652, 1652, 1652, 2043, 1650, 1650, 1650, 1650, 1650, 1650, - 1651, 1666, 1666, 1666, 0, 2041, 2041, 2041, 1616, 1665, - 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1648, 1653, - 1653, 1653, 2043, 0, 0, 0, 0, 1652, 0, 1651, - 0, 0, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, - 1616, 0, 1653, 1616, 1617, 1617, 1617, 0, 0, 1617, - 1648, 1648, 1648, 1648, 1648, 1648, 1652, 1617, 2044, 1707, - - 1707, 1707, 0, 1651, 1651, 1651, 1651, 1651, 1651, 0, - 1617, 1653, 2045, 2046, 1707, 1661, 1661, 1661, 1652, 1652, - 1652, 1652, 1652, 1652, 1654, 1654, 1654, 2044, 0, 1666, - 1666, 1666, 1666, 1666, 1666, 2041, 1662, 1662, 1662, 1617, - 0, 2045, 2046, 1667, 1667, 1667, 0, 1653, 1653, 1653, - 1653, 1653, 1653, 2047, 2048, 1654, 1661, 1668, 1668, 1668, - 0, 2049, 2050, 1617, 1617, 1617, 1617, 1617, 1617, 1617, - 1617, 1617, 0, 1662, 1617, 1618, 1618, 1618, 0, 0, - 1618, 0, 2047, 2048, 1654, 1661, 0, 0, 1618, 1707, - 2049, 2050, 2053, 2054, 1668, 1671, 1671, 1671, 0, 0, - - 0, 1618, 1662, 1661, 1661, 1661, 1661, 1661, 1661, 1672, - 1672, 1672, 1654, 1654, 1654, 1654, 1654, 1654, 1674, 1674, - 1674, 2053, 2054, 1668, 1662, 1662, 1662, 1662, 1662, 1662, - 1618, 1667, 1667, 1667, 1667, 1667, 1667, 1673, 1673, 1673, - 2055, 2057, 0, 0, 0, 1668, 1668, 1668, 1668, 1668, - 1668, 1674, 1673, 2058, 1618, 1618, 1618, 1618, 1618, 1618, - 1618, 1618, 1618, 0, 2059, 1618, 1619, 1619, 1619, 2055, - 2057, 1619, 1675, 1675, 1675, 0, 1794, 1794, 1794, 1619, - 1674, 0, 2058, 1671, 1671, 1671, 1671, 1671, 1671, 0, - 2063, 1794, 1619, 2059, 2070, 2073, 0, 1672, 1672, 1672, - - 1672, 1672, 1672, 1676, 1676, 1676, 1674, 1674, 1674, 1674, - 1674, 1674, 2074, 0, 2076, 2080, 1677, 1677, 1677, 2063, - 0, 1619, 0, 2070, 2073, 1673, 1673, 1673, 1673, 1673, - 1673, 1677, 1710, 1710, 1710, 0, 0, 0, 1677, 1676, - 2093, 2074, 1677, 2076, 2080, 1619, 1619, 1619, 1619, 1619, - 1619, 1619, 1619, 1619, 1677, 0, 1619, 1704, 1704, 1704, - 1675, 1675, 1675, 1675, 1675, 1675, 1794, 0, 1676, 2093, - 0, 1677, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, - 1679, 0, 0, 1677, 1705, 1705, 1705, 1758, 1910, 1910, - 1910, 1676, 1676, 1676, 1676, 1676, 1676, 0, 0, 1704, - - 1706, 1706, 1706, 1910, 1713, 1716, 1677, 1709, 1709, 1709, - 1709, 1709, 1709, 1709, 1709, 1709, 1758, 1712, 1712, 1712, - 1710, 1710, 1710, 1710, 1710, 1710, 1705, 1706, 1704, 0, - 1711, 1711, 1711, 1713, 1758, 1758, 1758, 1758, 1758, 1758, - 0, 1716, 2101, 0, 0, 1704, 1704, 1704, 1704, 1704, - 1704, 0, 0, 0, 0, 1705, 1706, 1711, 1712, 1715, - 0, 1713, 1713, 1713, 1713, 1713, 1713, 1718, 1905, 1905, - 1905, 2101, 1705, 1705, 1705, 1705, 1705, 1705, 1910, 1716, - 1716, 1716, 1716, 1716, 1716, 1715, 1711, 1712, 1706, 1706, - 1706, 1706, 1706, 1706, 0, 1911, 1911, 1911, 1905, 1717, - - 1718, 0, 2106, 2108, 0, 1712, 1712, 1712, 1712, 1712, - 1712, 1717, 1719, 0, 1715, 0, 0, 0, 1711, 1711, - 1711, 1711, 1711, 1711, 1719, 1911, 1739, 1905, 0, 1718, - 1720, 2106, 2108, 1715, 1715, 1715, 1715, 1715, 1715, 1720, - 1717, 1718, 1718, 1718, 1718, 1718, 1718, 0, 0, 0, - 0, 1721, 0, 1719, 1911, 1739, 0, 1722, 1905, 2130, - 2130, 2130, 0, 1721, 2109, 2113, 1740, 2116, 1720, 1722, - 1723, 2118, 2119, 1717, 1717, 1717, 1717, 1717, 1717, 1739, - 1739, 1739, 1739, 1739, 1739, 1911, 1719, 1719, 1719, 1719, - 1719, 1719, 1721, 2109, 2113, 1740, 2116, 0, 1722, 1723, - - 2118, 2119, 0, 0, 1720, 1720, 1720, 1720, 1720, 1720, - 0, 1723, 1723, 1723, 1723, 1723, 1723, 1740, 1740, 1740, - 1740, 1740, 1740, 0, 0, 1721, 1721, 1721, 1721, 1721, - 1721, 1722, 1722, 1722, 1722, 1722, 1722, 1741, 1741, 1741, - 0, 2120, 1741, 1742, 1742, 1742, 0, 0, 1742, 2130, - 1741, 2123, 1743, 1743, 1743, 1882, 1742, 1743, 0, 1746, - 1746, 1746, 0, 1741, 1746, 1743, 1759, 0, 2125, 1742, - 2120, 0, 1746, 0, 1753, 1753, 1753, 0, 1743, 1753, - 2123, 2098, 0, 0, 1882, 1746, 1742, 1753, 0, 1776, - 1776, 1776, 1741, 0, 0, 1759, 2098, 2125, 1742, 2126, - - 1753, 1882, 1882, 1882, 1882, 1882, 1882, 1743, 0, 0, - 2098, 1756, 1756, 1756, 1746, 1742, 1756, 1760, 1759, 1759, - 1759, 1759, 1759, 1759, 1756, 2098, 0, 1741, 2126, 1753, - 0, 1743, 0, 1742, 0, 0, 1761, 1756, 1762, 0, - 0, 0, 1743, 0, 0, 2127, 1760, 0, 0, 1746, - 1748, 1748, 1748, 1753, 1753, 1748, 0, 1753, 0, 1753, - 1753, 1753, 0, 1748, 1753, 1761, 1756, 1762, 1760, 1760, - 1760, 1760, 1760, 1760, 2127, 2128, 1748, 1776, 1776, 1776, - 1776, 1776, 1776, 1761, 1761, 1761, 1761, 1761, 1761, 0, - 1762, 1762, 1762, 1762, 1762, 1762, 1769, 1769, 1769, 2129, - - 0, 1756, 0, 0, 2128, 1748, 0, 1997, 1997, 1997, - 1770, 1770, 1770, 0, 0, 1765, 2134, 1771, 1771, 1771, - 0, 1997, 0, 1769, 1772, 1772, 1772, 0, 2129, 1748, - 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 0, 0, - 1748, 1749, 1749, 1749, 1765, 2134, 1749, 1770, 2136, 2003, - 2003, 2003, 1769, 1771, 1749, 1775, 1775, 1775, 1775, 1775, - 1775, 1775, 1775, 1775, 2003, 2138, 1772, 1749, 1765, 1765, - 1765, 1765, 1765, 1765, 1840, 2139, 1770, 2136, 1777, 1777, - 1777, 0, 1771, 0, 1769, 1769, 1769, 1769, 1769, 1769, - 1778, 1778, 1778, 0, 2138, 1772, 1749, 1997, 1770, 1770, - - 1770, 1770, 1770, 1770, 2139, 1771, 1771, 1771, 1771, 1771, - 1771, 1777, 1772, 1772, 1772, 1772, 1772, 1772, 2141, 0, - 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 0, - 2142, 1749, 1750, 1750, 1750, 1778, 2143, 1750, 0, 2003, - 1777, 1779, 1779, 1779, 0, 1750, 0, 2141, 1840, 1840, - 1840, 1840, 1840, 1840, 1780, 1780, 1780, 0, 1750, 2142, - 2145, 2146, 0, 0, 1778, 2143, 1777, 1777, 1777, 1777, - 1777, 1777, 0, 2010, 2010, 2010, 1779, 2147, 1778, 1778, - 1778, 1778, 1778, 1778, 1797, 1797, 1797, 1750, 2010, 2145, - 2146, 1780, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - - 1783, 1787, 1787, 1787, 0, 1779, 2147, 0, 1786, 1786, - 1786, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, - 1780, 0, 1750, 1751, 1751, 1751, 0, 0, 1751, 1779, - 1779, 1779, 1779, 1779, 1779, 1786, 1751, 2149, 0, 0, - 0, 1787, 1780, 1780, 1780, 1780, 1780, 1780, 0, 1751, - 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1792, - 1792, 1792, 0, 2010, 1786, 0, 2149, 1828, 1828, 1828, - 1787, 0, 1797, 1797, 1797, 1797, 1797, 1797, 1751, 0, - 2131, 2131, 2131, 1798, 1798, 1798, 0, 0, 1836, 1787, - 1787, 1787, 1787, 1787, 1787, 1792, 1786, 1786, 1786, 1786, - - 1786, 1786, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, - 1751, 0, 0, 1751, 1752, 1752, 1752, 1836, 0, 1752, - 0, 2137, 2137, 2137, 1792, 1798, 0, 1752, 1804, 1804, - 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1830, 1830, 1830, - 1752, 1836, 1836, 1836, 1836, 1836, 1836, 1792, 1792, 1792, - 1792, 1792, 1792, 0, 1798, 1828, 1828, 1828, 1828, 1828, - 1828, 1829, 1829, 1829, 0, 2095, 2095, 2095, 0, 1752, - 2131, 1798, 1798, 1798, 1798, 1798, 1798, 1833, 1833, 1833, - 1833, 1833, 1833, 1833, 1833, 1833, 0, 2150, 2095, 1835, - 1835, 1835, 1829, 1752, 1752, 1752, 1752, 1752, 1752, 1752, - - 1752, 1752, 0, 2151, 1752, 1754, 1754, 1754, 0, 0, - 1754, 2137, 2148, 2154, 1837, 2148, 2150, 2095, 1754, 2155, - 0, 1829, 0, 0, 0, 1830, 1830, 1830, 1830, 1830, - 1830, 1754, 2151, 0, 0, 1834, 1834, 1834, 1838, 2156, - 2158, 2148, 2154, 1837, 2148, 0, 2162, 0, 2155, 1829, - 1829, 1829, 1829, 1829, 1829, 2095, 1839, 2018, 2018, 2018, - 1754, 1837, 1837, 1837, 1837, 1837, 1837, 1841, 2156, 2158, - 2167, 2169, 2018, 1839, 1838, 2162, 1834, 1835, 1835, 1835, - 1835, 1835, 1835, 1842, 1754, 1754, 1754, 1754, 1754, 1754, - 1754, 1754, 1754, 0, 0, 1754, 1755, 1755, 1755, 2167, - - 2169, 1755, 1839, 0, 0, 1834, 0, 0, 2170, 1755, - 0, 2152, 1838, 1838, 1838, 1838, 1838, 1838, 1843, 2172, - 2173, 2152, 1755, 1834, 1834, 1834, 1834, 1834, 1834, 1844, - 1839, 1839, 1839, 1839, 1839, 1839, 1845, 2170, 0, 1843, - 2152, 1841, 1841, 1841, 1841, 1841, 1841, 2018, 2172, 2173, - 2152, 1755, 2030, 2030, 2030, 2176, 2184, 1842, 1842, 1842, - 1842, 1842, 1842, 0, 0, 0, 0, 2030, 1843, 1862, - 2186, 2192, 2193, 1863, 0, 1755, 1755, 1755, 1755, 1755, - 1755, 1755, 1755, 1755, 2176, 2184, 1755, 0, 0, 2177, - 2177, 2177, 1843, 1843, 1843, 1843, 1843, 1843, 1862, 2186, - - 2192, 2193, 1863, 1844, 1844, 1844, 1844, 1844, 1844, 2177, - 1845, 1845, 1845, 1845, 1845, 1845, 1863, 1863, 1863, 1863, - 1863, 1863, 0, 1926, 1926, 1926, 1862, 1862, 1862, 1862, - 1862, 1862, 1864, 1864, 1864, 0, 0, 1864, 1865, 1865, - 1865, 0, 2030, 1865, 0, 1864, 0, 1867, 1867, 1867, - 0, 1865, 1867, 1926, 2195, 1864, 2198, 2199, 1864, 0, - 1867, 2200, 0, 2206, 1865, 1868, 1868, 1868, 0, 2208, - 1868, 0, 0, 1867, 2209, 1869, 1869, 1869, 1868, 2177, - 1869, 0, 1926, 2195, 1864, 2198, 2199, 1864, 1869, 0, - 2200, 1868, 2206, 1865, 2212, 1874, 1874, 1874, 2208, 0, - - 1874, 1869, 1867, 2209, 0, 1875, 1875, 1875, 1874, 0, - 1875, 0, 0, 1926, 1876, 1876, 1876, 1865, 1875, 1876, - 1868, 1874, 1864, 2212, 2061, 2061, 2061, 1876, 1865, 2213, - 1869, 1875, 2214, 1877, 1877, 1877, 0, 1867, 1877, 2061, - 1876, 2178, 2178, 2178, 0, 0, 1877, 1881, 0, 2215, - 1874, 1879, 1879, 1879, 1869, 1868, 1879, 2178, 2213, 1877, - 1875, 2214, 0, 0, 1879, 1869, 1873, 1873, 1873, 1876, - 2217, 1873, 1884, 2077, 2077, 2077, 1881, 1879, 2215, 1873, - 0, 0, 0, 0, 0, 1874, 0, 2077, 1877, 1878, - 1878, 1878, 1873, 2222, 1878, 1875, 0, 2224, 2228, 2217, - - 2230, 1884, 1878, 0, 1876, 0, 1879, 0, 1881, 1881, - 1881, 1881, 1881, 1881, 2061, 1878, 0, 0, 2203, 2203, - 2203, 1873, 2222, 1877, 0, 1883, 2224, 2228, 1888, 2230, - 1879, 2178, 1878, 1884, 1884, 1884, 1884, 1884, 1884, 0, - 0, 1879, 0, 0, 1878, 1873, 1873, 1873, 1873, 1873, - 1873, 1873, 1873, 1873, 1883, 1885, 1873, 1888, 1890, 1890, - 1890, 1878, 0, 2077, 1891, 1891, 1891, 0, 1883, 1883, - 1883, 1883, 1883, 1883, 1892, 1892, 1892, 0, 0, 1878, - 1893, 1893, 1893, 0, 1885, 1888, 1888, 1888, 1888, 1888, - 1888, 1898, 1898, 1898, 1992, 1992, 1992, 1992, 1992, 1992, - - 1891, 1885, 1885, 1885, 1885, 1885, 1885, 1893, 2203, 0, - 1914, 1914, 1914, 0, 0, 0, 1892, 1899, 1899, 1899, - 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1891, - 0, 2231, 1900, 1900, 1900, 0, 1893, 2218, 2218, 2218, - 0, 0, 1919, 1919, 1919, 1892, 1890, 1890, 1890, 1890, - 1890, 1890, 1891, 1891, 1891, 1891, 1891, 1891, 1899, 1900, - 2231, 0, 1892, 1892, 1892, 1892, 1892, 1892, 1893, 1893, - 1893, 1893, 1893, 1893, 1901, 1901, 1901, 0, 0, 1898, - 1898, 1898, 1898, 1898, 1898, 0, 0, 1899, 1900, 1908, - 1908, 1908, 0, 0, 0, 1909, 1909, 1909, 1914, 1914, - - 1914, 1914, 1914, 1914, 0, 1899, 1899, 1899, 1899, 1899, - 1899, 1956, 1956, 1956, 1901, 1957, 1957, 1957, 0, 0, - 1900, 1900, 1900, 1900, 1900, 1900, 1909, 2218, 1958, 1908, - 1919, 1919, 1919, 1919, 1919, 1919, 1952, 1952, 1952, 0, - 0, 1956, 1960, 1901, 1995, 1995, 1995, 1995, 1995, 1995, - 0, 0, 2189, 2189, 2189, 1909, 1961, 1958, 1908, 2000, - 2000, 2000, 1901, 1901, 1901, 1901, 1901, 1901, 1961, 1960, - 1956, 2233, 2189, 1952, 2220, 2220, 2220, 1908, 1908, 1908, - 1908, 1908, 1908, 1909, 1909, 1909, 1909, 1909, 1909, 1958, - 1958, 1958, 1958, 1958, 1958, 0, 0, 1961, 1960, 1962, - - 2233, 1956, 1952, 1957, 1957, 1957, 1957, 1957, 1957, 1959, - 1972, 2234, 1962, 2004, 2004, 2004, 1960, 1960, 1960, 1960, - 1960, 1960, 0, 0, 1952, 1952, 1952, 1952, 1952, 1952, - 1961, 1961, 1961, 1961, 1961, 1961, 1973, 0, 1959, 1972, - 2234, 1962, 2189, 2004, 0, 0, 0, 2000, 2000, 2000, - 2000, 2000, 2000, 2235, 0, 0, 1972, 1972, 1972, 1972, - 1972, 1972, 0, 2236, 2220, 1973, 1959, 1959, 1959, 1959, - 1959, 1959, 2004, 1962, 1962, 1962, 1962, 1962, 1962, 0, - 0, 2237, 2235, 1973, 1973, 1973, 1973, 1973, 1973, 1974, - 1974, 1974, 2236, 2238, 1974, 1976, 1976, 1976, 0, 0, - - 1976, 0, 1974, 2004, 1977, 1977, 1977, 0, 1976, 1977, - 2237, 1978, 1978, 1978, 0, 1974, 1978, 1977, 0, 2239, - 2240, 1976, 2238, 1974, 1978, 0, 0, 1979, 1979, 1979, - 1977, 0, 1979, 2241, 1980, 1980, 1980, 1978, 0, 1980, - 1979, 1981, 1981, 1981, 1974, 2243, 1981, 1980, 2239, 2240, - 1976, 2244, 1974, 1979, 1981, 2223, 2223, 2223, 0, 1977, - 1980, 2245, 2241, 2011, 2011, 2011, 1978, 1981, 2026, 2026, - 2026, 1982, 1982, 1982, 2243, 0, 1982, 1980, 0, 1974, - 2244, 0, 1979, 0, 1982, 1976, 1984, 1984, 1984, 1980, - 2245, 1984, 0, 2011, 1977, 0, 1981, 1982, 2026, 1984, - - 2246, 1978, 1985, 1985, 1985, 0, 1980, 1985, 1986, 1986, - 1986, 0, 1984, 1986, 0, 1985, 0, 1979, 0, 0, - 1981, 1986, 2011, 0, 1980, 0, 1982, 2026, 1985, 2246, - 0, 1981, 0, 2249, 1986, 0, 1991, 2253, 1987, 1987, - 1987, 1984, 0, 1987, 0, 2223, 2256, 1988, 1988, 1988, - 1982, 1987, 1988, 2011, 1989, 1989, 1989, 1985, 2026, 1989, - 1988, 1982, 2249, 1986, 1987, 1991, 2253, 1989, 2259, 1990, - 1990, 1990, 0, 1988, 1990, 2256, 1984, 1989, 0, 2269, - 1989, 1985, 1990, 1993, 1991, 1991, 1991, 1991, 1991, 1991, - 1994, 0, 1985, 1987, 2276, 1990, 2277, 2259, 1986, 2001, - - 2001, 2001, 1988, 0, 0, 0, 1989, 1998, 2269, 1989, - 0, 0, 1993, 2002, 2002, 2002, 0, 1987, 0, 1994, - 2007, 2007, 2007, 2276, 1990, 2277, 0, 0, 1987, 0, - 1993, 1993, 1993, 1993, 1993, 1993, 1998, 1988, 1994, 1994, - 1994, 1994, 1994, 1994, 1989, 2008, 2008, 2008, 1990, 2190, - 2190, 2190, 2068, 1998, 1998, 1998, 1998, 1998, 1998, 1990, - 0, 0, 2009, 2009, 2009, 2190, 2031, 2031, 2031, 0, - 0, 0, 2016, 2016, 2016, 0, 0, 0, 2017, 2017, - 2017, 2082, 2082, 2082, 2082, 2082, 2082, 2001, 2001, 2001, - 2001, 2001, 2001, 2009, 2281, 2282, 2031, 0, 2278, 2278, - - 2278, 2002, 2002, 2002, 2002, 2002, 2002, 0, 2007, 2007, - 2007, 2007, 2007, 2007, 2016, 2069, 0, 2062, 2062, 2062, - 2017, 0, 2009, 2281, 2282, 2031, 2068, 2068, 2068, 2068, - 2068, 2068, 0, 2008, 2008, 2008, 2008, 2008, 2008, 2190, - 0, 0, 0, 2016, 2060, 2060, 2060, 2062, 2287, 2017, - 2009, 2009, 2009, 2009, 2009, 2009, 2031, 2051, 2051, 2051, - 2016, 2016, 2016, 2016, 2016, 2016, 2017, 2017, 2017, 2017, - 2017, 2017, 2066, 2288, 2289, 2290, 2062, 2287, 0, 2295, - 2060, 0, 2051, 2299, 2302, 2051, 2303, 2065, 2278, 2069, - 2069, 2069, 2069, 2069, 2069, 0, 2094, 2094, 2094, 2051, - - 0, 2066, 2288, 2289, 2290, 0, 0, 2062, 2295, 2060, - 2094, 2051, 2299, 2302, 2051, 2303, 2065, 2305, 0, 2066, - 2066, 2066, 2066, 2066, 2066, 2067, 2305, 0, 2051, 2081, - 2081, 2081, 2060, 2060, 2060, 2060, 2060, 2060, 2065, 2065, - 2065, 2065, 2065, 2065, 0, 2306, 2305, 2051, 2056, 2081, - 2307, 2308, 2309, 2067, 2056, 2078, 2078, 2078, 2056, 2056, - 0, 0, 0, 2056, 2056, 2056, 2310, 2056, 2091, 2091, - 2091, 2091, 2091, 2091, 2306, 0, 2312, 2056, 2078, 2307, - 2308, 2309, 2067, 2056, 2311, 2311, 2094, 2056, 2056, 2226, - 2226, 2226, 2056, 2056, 2056, 2310, 2056, 2078, 0, 2067, - - 2067, 2067, 2067, 2067, 2067, 2312, 0, 2078, 2313, 0, - 2083, 2083, 2083, 2311, 2311, 2083, 0, 2081, 2081, 2081, - 2081, 2081, 2081, 2083, 0, 0, 2078, 2084, 2084, 2084, - 0, 2226, 2084, 2085, 2085, 2085, 2083, 2313, 2085, 0, - 2084, 0, 2086, 2086, 2086, 2078, 2085, 2086, 0, 2087, - 2087, 2087, 0, 2084, 2087, 2086, 2085, 2315, 0, 2085, - 2226, 0, 2087, 0, 2090, 2083, 0, 2316, 2086, 2099, - 2099, 2099, 2104, 2104, 2104, 2087, 2088, 2088, 2088, 2226, - 2317, 2088, 2084, 0, 2099, 2085, 2315, 2104, 2085, 2088, - 2089, 2089, 2089, 2090, 0, 2089, 2316, 2086, 2318, 0, - - 2083, 2092, 2088, 2089, 2087, 2097, 2097, 2097, 2319, 2317, - 2090, 2090, 2090, 2090, 2090, 2090, 2089, 2084, 2103, 2103, - 2103, 2086, 0, 2085, 2089, 2097, 0, 2318, 2087, 0, - 2092, 2088, 2086, 2110, 2110, 2110, 0, 2319, 0, 2087, - 2111, 2111, 2111, 2326, 2327, 2089, 0, 2092, 2092, 2092, - 2092, 2092, 2092, 2089, 0, 2088, 2114, 2114, 2114, 2099, - 2103, 2182, 2104, 2121, 2121, 2121, 2088, 2160, 2160, 2160, - 0, 2114, 2326, 2327, 0, 2115, 2115, 2115, 2121, 0, - 2089, 0, 2160, 2110, 2159, 2159, 2159, 2111, 2328, 2103, - 2164, 0, 0, 2097, 2097, 2097, 2097, 2097, 2097, 2182, - - 2182, 2182, 2182, 2182, 2182, 2115, 2103, 2103, 2103, 2103, - 2103, 2103, 2153, 2165, 0, 2329, 2111, 2328, 2334, 2164, - 2153, 2110, 2110, 2110, 2110, 2110, 2110, 2153, 2111, 2111, - 2111, 2111, 2111, 2111, 2115, 2164, 2164, 2164, 2164, 2164, - 2164, 2153, 2165, 2166, 2329, 0, 2114, 2334, 0, 2153, - 2337, 2338, 2166, 2121, 0, 0, 2153, 2160, 0, 2165, - 2165, 2165, 2165, 2165, 2165, 2115, 2323, 2323, 2323, 2323, - 2323, 2323, 2159, 2159, 2159, 2159, 2159, 2159, 0, 2337, - 2338, 2166, 2171, 2171, 2171, 2179, 2179, 2179, 2179, 2179, - 2179, 2179, 2179, 2179, 2204, 2204, 2204, 2180, 2180, 2180, - - 0, 2183, 2180, 2343, 2344, 2171, 2185, 2185, 2185, 2204, - 2180, 0, 2196, 2196, 2196, 0, 2348, 2166, 2166, 2166, - 2166, 2166, 2166, 2180, 2171, 2181, 2181, 2181, 2251, 2185, - 2181, 2180, 2343, 2344, 2171, 2202, 2202, 2202, 2181, 2183, - 2183, 2183, 2183, 2183, 2183, 2348, 2201, 2201, 2201, 2349, - 2350, 2181, 2180, 2171, 2255, 2255, 2255, 2251, 2185, 2196, - 2180, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, - 2250, 0, 2171, 0, 2255, 0, 0, 2201, 2349, 2350, - 2181, 2353, 0, 2252, 2204, 2357, 0, 2180, 2196, 2251, - 2251, 2251, 2251, 2251, 2251, 0, 2185, 0, 0, 2250, - - 2196, 2196, 2196, 2196, 2196, 2196, 2201, 0, 0, 0, - 2353, 2252, 2266, 2358, 2357, 2181, 2250, 2250, 2250, 2250, - 2250, 2250, 0, 2202, 2202, 2202, 2202, 2202, 2202, 2261, - 2261, 2261, 0, 0, 2201, 2201, 2201, 2201, 2201, 2201, - 2252, 2266, 2358, 0, 2255, 2261, 2264, 2264, 2264, 2264, - 2264, 2264, 2264, 2264, 2264, 2267, 0, 2252, 2252, 2252, - 2252, 2252, 2252, 2265, 2265, 2265, 0, 0, 2265, 2266, - 2266, 2266, 2266, 2266, 2266, 0, 2265, 2268, 2268, 2268, - 2272, 2272, 2272, 0, 2267, 2279, 2279, 2279, 0, 2265, - 2280, 2280, 2280, 2284, 2284, 2284, 2272, 2268, 2275, 2275, - - 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2283, 2283, 2283, - 0, 2361, 2267, 2267, 2267, 2267, 2267, 2267, 2265, 2261, - 2291, 2291, 2291, 2293, 2293, 2293, 2296, 2296, 2296, 2300, - 2300, 2300, 2324, 2283, 2322, 2322, 2322, 2293, 0, 2332, - 2361, 0, 2339, 2339, 2339, 2341, 2341, 2341, 0, 0, - 2363, 0, 2364, 2265, 0, 2345, 2345, 2345, 0, 0, - 0, 2324, 2283, 2325, 2333, 2366, 0, 2268, 2332, 0, - 2272, 0, 0, 2279, 2279, 2279, 2279, 2279, 2279, 2363, - 2280, 2364, 2367, 2284, 2324, 2324, 2324, 2324, 2324, 2324, - 0, 2368, 2325, 2333, 2366, 2283, 2283, 2283, 2283, 2283, - - 2283, 2332, 2332, 2332, 2332, 2332, 2332, 2347, 2347, 2347, - 2291, 2367, 0, 2293, 0, 0, 2296, 0, 0, 2300, - 2368, 2325, 0, 0, 2322, 0, 2333, 2333, 2333, 2333, - 2333, 2333, 2339, 2369, 2370, 2341, 2371, 2325, 2325, 2325, - 2325, 2325, 2325, 2345, 2345, 2345, 2345, 2345, 2345, 2351, - 2351, 2351, 2354, 2354, 2354, 2372, 2355, 2355, 2355, 2359, - 2359, 2359, 2369, 2370, 0, 2371, 2354, 2373, 0, 0, - 2375, 0, 2376, 2377, 2378, 2380, 2381, 2381, 2381, 2385, - 0, 2386, 2384, 2387, 2372, 2391, 2392, 2383, 2393, 2396, - 2397, 2402, 2404, 2355, 2406, 2407, 2373, 2347, 2355, 2375, - - 2359, 2376, 2377, 2378, 2380, 2398, 2398, 2398, 2385, 2384, - 2386, 2410, 2387, 0, 2391, 2392, 2383, 2393, 2396, 2397, - 2402, 2404, 2355, 2406, 2407, 0, 0, 2355, 0, 2359, - 2389, 2389, 2389, 2389, 2389, 2389, 2411, 0, 2384, 2351, - 2410, 0, 2354, 2405, 2405, 2405, 2355, 2412, 2414, 2359, - 2383, 2383, 2383, 2383, 2383, 2383, 2384, 2384, 2384, 2384, - 2384, 2384, 2415, 2416, 2417, 2411, 2381, 2390, 2390, 2390, - 2390, 2390, 2390, 2419, 2420, 2421, 2412, 2414, 2422, 2423, - 2405, 2424, 2425, 2426, 2428, 2405, 2431, 2432, 2434, 2435, - 2436, 2415, 2416, 2417, 2437, 2398, 2438, 2439, 2454, 2454, - - 2454, 0, 2419, 2420, 2421, 2440, 2442, 2422, 2423, 2405, - 2424, 2425, 2426, 2428, 2405, 2431, 2445, 2434, 2435, 2436, - 2446, 2450, 2451, 2437, 2452, 2438, 2439, 2431, 2431, 2431, - 2431, 2431, 2431, 2405, 2440, 2442, 0, 0, 2453, 2455, - 2456, 2458, 2460, 2462, 2464, 2445, 2465, 2467, 2468, 2446, - 2450, 2451, 2469, 2452, 2466, 2466, 2466, 2466, 2466, 2466, - 2471, 2432, 2432, 2432, 2432, 2432, 2432, 2453, 2455, 2456, - 2458, 2460, 2462, 2464, 2472, 2465, 2467, 2468, 2474, 2478, - 2479, 2469, 2480, 2481, 2482, 2483, 2485, 2489, 2454, 2471, - 2484, 2484, 2484, 2486, 2486, 2486, 2490, 2492, 2493, 2495, - - 2497, 2498, 2500, 2472, 2502, 2503, 2504, 2474, 2478, 2479, - 2505, 2480, 2481, 2482, 2483, 2485, 2489, 2506, 2506, 2506, - 2508, 2508, 2508, 2510, 2512, 2490, 2492, 2493, 2495, 2497, - 2498, 2500, 2514, 2502, 2503, 2504, 2516, 2517, 2518, 2505, - 2520, 2521, 2522, 2523, 2524, 2525, 2527, 2528, 2529, 2530, - 2531, 0, 2510, 2512, 0, 2532, 2533, 2574, 2574, 2574, - 2535, 2514, 2536, 2537, 2538, 2516, 2517, 2518, 2539, 2520, - 2521, 2522, 2523, 2524, 2525, 2527, 2528, 2529, 2530, 2531, - 2484, 0, 2540, 2486, 2532, 2533, 2534, 2534, 2534, 2535, - 2543, 2536, 2537, 2538, 2534, 2550, 2553, 2539, 2542, 2542, - - 2542, 2544, 2544, 2544, 2546, 2546, 2546, 2506, 2554, 2556, - 2508, 2540, 2546, 2557, 2562, 2563, 2564, 2565, 2542, 2543, - 2566, 2544, 2568, 2570, 2550, 2553, 2571, 2572, 2575, 2576, - 2577, 2578, 2579, 2579, 2579, 2581, 2583, 2554, 2556, 2582, - 2582, 2582, 2557, 2562, 2563, 2564, 2565, 2574, 2584, 2566, - 2587, 2568, 2570, 2589, 2590, 2571, 2572, 2575, 2576, 2577, - 2578, 2588, 2588, 2588, 2581, 2583, 2591, 0, 2592, 2593, - 2594, 2595, 2595, 2595, 0, 0, 2534, 2584, 2534, 2587, - 0, 0, 2589, 2590, 0, 0, 0, 0, 2542, 0, - 0, 2544, 0, 0, 2546, 2591, 2546, 2592, 2593, 2594, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2579, 0, 0, 0, 0, 0, 0, 2582, + 723, 723, 724, 724, 724, 724, 724, 724, 724, 724, + 724, 725, 726, 726, 726, 726, 726, 726, 726, 726, + 726, 728, 728, 728, 728, 728, 728, 728, 728, 728, + 729, 729, 729, 729, 729, 729, 729, 729, 729, 1011, + + 725, 730, 730, 730, 730, 730, 730, 730, 730, 730, + 732, 732, 732, 732, 732, 732, 732, 732, 732, 735, + 735, 735, 725, 725, 725, 725, 725, 725, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 740, 740, 740, 740, + 740, 740, 740, 740, 740, 741, 741, 741, 741, 741, + 741, 741, 741, 741, 742, 742, 742, 742, 742, 742, + 742, 742, 742, 743, 743, 743, 743, 743, 743, 743, + 743, 743, 744, 744, 744, 744, 744, 744, 744, 744, + 744, 746, 746, 746, 746, 746, 746, 746, 746, 746, + + 797, 797, 797, 797, 797, 797, 797, 797, 735, 738, + 738, 1403, 1010, 738, 738, 984, 980, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 1403, 738, 738, 738, + 738, 738, 747, 747, 747, 747, 747, 747, 747, 747, + 747, 748, 748, 748, 748, 748, 748, 748, 748, 748, + 753, 753, 753, 919, 759, 1403, 759, 823, 738, 759, + 738, 749, 749, 749, 749, 749, 749, 749, 749, 749, + 750, 750, 750, 750, 750, 750, 750, 750, 750, 804, + 804, 804, 804, 804, 804, 804, 804, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, + + 738, 738, 738, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 758, 760, 758, 927, 927, 927, 927, 927, + 927, 767, 767, 761, 758, 767, 767, 767, 767, 767, + 759, 759, 759, 759, 759, 759, 816, 814, 787, 753, + 783, 778, 760, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 761, 758, 763, 763, 763, 763, 763, 763, + 763, 763, 763, 776, 760, 760, 760, 760, 760, 760, + 761, 761, 761, 761, 761, 761, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 758, 758, 758, 758, 758, + 758, 765, 765, 765, 765, 765, 765, 765, 765, 765, + + 766, 766, 766, 766, 766, 766, 766, 766, 766, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 770, 770, 770, + 773, 773, 773, 777, 777, 777, 780, 780, 780, 788, + 788, 788, 788, 788, 788, 788, 788, 788, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 791, 791, 791, + 791, 791, 791, 791, 791, 791, 792, 792, 792, 792, + 792, 792, 792, 792, 792, 793, 793, 771, 754, 793, + 752, 793, 793, 793, 794, 794, 794, 794, 794, 794, + 794, 794, 794, 795, 795, 795, 795, 795, 795, 795, + + 795, 795, 796, 796, 796, 796, 796, 796, 796, 796, + 796, 736, 690, 687, 683, 650, 770, 643, 642, 773, + 641, 637, 777, 636, 634, 780, 798, 798, 798, 798, + 798, 798, 798, 798, 798, 799, 799, 799, 799, 799, + 799, 799, 799, 799, 800, 800, 800, 800, 800, 800, + 800, 800, 800, 801, 801, 630, 1405, 801, 629, 801, + 801, 801, 802, 802, 802, 802, 802, 802, 802, 802, + 802, 803, 803, 803, 803, 803, 803, 803, 803, 803, + 805, 805, 627, 623, 805, 1405, 805, 805, 805, 806, + 806, 806, 806, 806, 806, 806, 806, 806, 807, 807, + + 807, 807, 807, 807, 807, 807, 808, 808, 808, 808, + 808, 808, 808, 808, 808, 809, 809, 809, 809, 809, + 809, 809, 809, 809, 810, 810, 810, 810, 810, 810, + 810, 810, 810, 811, 811, 922, 824, 811, 824, 811, + 811, 811, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 815, 815, 815, 822, 922, 822, 909, 909, 620, 825, + 909, 619, 909, 909, 909, 822, 1406, 826, 918, 918, + 616, 615, 918, 827, 918, 918, 918, 1407, 613, 826, + 600, 1320, 599, 1320, 828, 596, 922, 922, 922, 922, + + 922, 922, 827, 1320, 822, 1406, 595, 846, 592, 824, + 824, 824, 824, 824, 824, 591, 1407, 829, 826, 828, + 928, 928, 928, 928, 928, 928, 481, 831, 393, 391, + 359, 827, 1320, 829, 354, 831, 822, 822, 822, 822, + 822, 822, 825, 825, 825, 825, 825, 825, 828, 815, + 826, 826, 826, 826, 826, 826, 827, 827, 827, 827, + 827, 827, 829, 830, 831, 350, 345, 828, 828, 828, + 828, 828, 828, 341, 324, 321, 291, 832, 281, 830, + 846, 846, 846, 846, 846, 846, 833, 280, 278, 1408, + 829, 829, 829, 829, 829, 829, 832, 1012, 1012, 1012, + + 831, 831, 831, 831, 831, 831, 833, 835, 830, 904, + 904, 904, 904, 904, 904, 904, 904, 904, 1408, 256, + 254, 834, 1017, 1017, 1017, 832, 245, 1409, 835, 243, + 837, 232, 231, 225, 224, 833, 830, 830, 830, 830, + 830, 830, 834, 1022, 1022, 1022, 1346, 834, 1346, 837, + 832, 832, 832, 832, 832, 832, 1409, 835, 1346, 833, + 833, 833, 833, 833, 833, 836, 216, 215, 1035, 1035, + 1035, 834, 838, 836, 212, 211, 834, 195, 837, 194, + 835, 835, 835, 835, 835, 835, 1012, 1346, 188, 1451, + 840, 838, 187, 180, 834, 834, 834, 834, 834, 834, + + 840, 841, 836, 837, 837, 837, 837, 837, 837, 953, + 953, 1017, 179, 953, 839, 953, 953, 953, 1451, 111, + 838, 843, 839, 73, 841, 72, 839, 69, 59, 840, + 842, 843, 1022, 1452, 36, 35, 34, 844, 836, 836, + 836, 836, 836, 836, 1454, 838, 838, 838, 838, 838, + 838, 839, 842, 841, 845, 839, 844, 1035, 33, 0, + 843, 0, 1452, 840, 840, 840, 840, 840, 840, 0, + 0, 1456, 847, 1454, 841, 841, 841, 841, 841, 841, + 845, 842, 854, 0, 0, 844, 0, 839, 839, 839, + 839, 839, 839, 847, 843, 843, 843, 843, 843, 843, + + 1456, 0, 849, 842, 842, 842, 842, 842, 842, 845, + 844, 844, 844, 844, 844, 844, 848, 0, 1049, 1049, + 1049, 0, 847, 849, 0, 850, 0, 845, 845, 845, + 845, 845, 845, 961, 961, 1457, 848, 961, 851, 961, + 961, 961, 1458, 1460, 852, 847, 847, 847, 847, 847, + 847, 853, 849, 850, 851, 854, 854, 854, 854, 854, + 854, 0, 0, 0, 1457, 848, 853, 852, 0, 856, + 0, 1458, 1460, 0, 0, 849, 849, 849, 849, 849, + 849, 856, 850, 851, 855, 0, 0, 0, 0, 848, + 848, 848, 848, 848, 848, 853, 852, 857, 850, 850, + + 850, 850, 850, 850, 0, 0, 855, 1049, 0, 857, + 856, 851, 851, 851, 851, 851, 851, 852, 852, 852, + 852, 852, 852, 860, 853, 853, 853, 853, 853, 853, + 858, 0, 0, 971, 971, 855, 859, 971, 857, 971, + 971, 971, 856, 856, 856, 856, 856, 856, 0, 1462, + 860, 861, 858, 1463, 1464, 859, 1465, 855, 855, 855, + 855, 855, 855, 861, 0, 1484, 0, 863, 0, 0, + 857, 857, 857, 857, 857, 857, 0, 862, 1462, 860, + 0, 858, 1463, 1464, 859, 1465, 1065, 1065, 1065, 865, + 0, 0, 861, 862, 1484, 866, 860, 860, 860, 860, + + 860, 860, 863, 858, 858, 858, 858, 858, 858, 859, + 859, 859, 859, 859, 859, 0, 864, 865, 866, 1092, + 1092, 1092, 862, 867, 861, 861, 861, 861, 861, 861, + 864, 905, 905, 905, 905, 905, 905, 905, 905, 0, + 863, 863, 863, 863, 863, 863, 865, 866, 868, 867, + 862, 862, 862, 862, 862, 862, 870, 0, 1485, 864, + 0, 0, 865, 865, 865, 865, 865, 865, 866, 866, + 866, 866, 866, 866, 869, 1065, 1496, 1538, 867, 0, + 868, 1539, 1551, 870, 872, 1568, 869, 1485, 1569, 864, + 864, 864, 864, 864, 864, 0, 867, 867, 867, 867, + + 867, 867, 871, 0, 0, 1496, 1538, 872, 1092, 868, + 1539, 1551, 870, 873, 1568, 869, 871, 1569, 0, 874, + 0, 868, 868, 868, 868, 868, 868, 873, 875, 870, + 870, 870, 870, 870, 870, 878, 872, 0, 875, 1570, + 1571, 1573, 876, 878, 874, 871, 0, 869, 869, 869, + 869, 869, 869, 876, 1576, 1578, 873, 872, 872, 872, + 872, 872, 872, 0, 0, 0, 879, 875, 1570, 1571, + 1573, 1579, 878, 874, 877, 871, 871, 871, 871, 871, + 871, 0, 876, 1576, 1578, 879, 873, 873, 873, 873, + 873, 873, 874, 874, 874, 874, 874, 874, 920, 877, + + 1579, 875, 875, 875, 875, 875, 875, 881, 878, 878, + 878, 878, 878, 878, 879, 876, 876, 876, 876, 876, + 876, 880, 0, 0, 0, 0, 0, 882, 877, 881, + 0, 0, 0, 880, 883, 1108, 1108, 1108, 0, 879, + 879, 879, 879, 879, 879, 885, 882, 877, 877, 877, + 877, 877, 877, 884, 886, 886, 886, 885, 881, 1030, + 1030, 883, 880, 1030, 1581, 1030, 1030, 1030, 886, 920, + 920, 920, 920, 920, 920, 882, 887, 0, 0, 0, + 881, 881, 881, 881, 881, 881, 885, 1582, 884, 0, + 883, 0, 0, 1581, 880, 880, 880, 880, 880, 880, + + 882, 882, 882, 882, 882, 882, 887, 883, 883, 883, + 883, 883, 883, 888, 0, 0, 1582, 0, 885, 885, + 885, 885, 885, 885, 1108, 0, 884, 884, 884, 884, + 884, 884, 1583, 964, 1584, 887, 888, 0, 0, 889, + 0, 886, 886, 886, 886, 886, 886, 1585, 890, 887, + 887, 887, 887, 887, 887, 0, 891, 0, 0, 0, + 0, 1583, 964, 1584, 889, 888, 889, 890, 891, 895, + 974, 974, 974, 974, 974, 974, 1585, 895, 893, 964, + 964, 964, 964, 964, 964, 894, 888, 888, 888, 888, + 888, 888, 897, 889, 0, 889, 890, 891, 892, 893, + + 975, 975, 975, 975, 975, 975, 895, 894, 892, 894, + 896, 0, 889, 889, 889, 889, 889, 889, 0, 892, + 912, 890, 890, 890, 890, 890, 890, 0, 893, 891, + 891, 891, 891, 891, 891, 896, 894, 892, 894, 1112, + 1112, 1112, 895, 895, 895, 895, 895, 895, 892, 899, + 0, 893, 893, 893, 893, 893, 893, 898, 894, 894, + 894, 894, 894, 894, 896, 897, 897, 897, 897, 897, + 897, 892, 892, 892, 892, 892, 892, 899, 898, 901, + 0, 0, 0, 896, 896, 896, 896, 896, 896, 0, + 0, 1586, 900, 912, 912, 912, 912, 912, 912, 0, + + 901, 0, 0, 903, 0, 0, 899, 898, 900, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 903, 921, + 1586, 902, 899, 899, 899, 899, 899, 899, 1112, 901, + 898, 898, 898, 898, 898, 898, 0, 900, 0, 0, + 0, 0, 902, 1588, 1619, 1620, 902, 903, 921, 0, + 0, 0, 901, 901, 901, 901, 901, 901, 913, 921, + 921, 921, 921, 921, 921, 900, 900, 900, 900, 900, + 900, 902, 1588, 1619, 1620, 902, 903, 903, 903, 903, + 903, 903, 907, 907, 907, 907, 907, 907, 907, 907, + 907, 0, 0, 0, 902, 902, 902, 902, 902, 902, + + 908, 908, 908, 908, 908, 908, 908, 908, 908, 910, + 910, 910, 910, 910, 910, 910, 910, 910, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 923, 924, 0, + 925, 913, 913, 913, 913, 913, 913, 917, 917, 917, + 917, 917, 917, 917, 917, 917, 931, 931, 931, 931, + 931, 931, 931, 931, 931, 0, 923, 924, 926, 925, + 932, 932, 932, 932, 932, 932, 932, 932, 1130, 1130, + 1130, 0, 1621, 933, 0, 923, 923, 923, 923, 923, + 923, 925, 925, 925, 925, 925, 925, 926, 0, 934, + 924, 924, 924, 924, 924, 924, 933, 934, 935, 1034, + + 1034, 1621, 1625, 1034, 936, 1034, 1034, 1034, 0, 1627, + 0, 1580, 938, 926, 926, 926, 926, 926, 926, 937, + 0, 0, 937, 1580, 935, 933, 934, 1629, 0, 1060, + 1060, 1625, 936, 1060, 939, 1060, 1060, 1060, 1627, 938, + 1580, 941, 0, 0, 0, 0, 933, 933, 933, 933, + 933, 933, 1580, 935, 0, 941, 1629, 1130, 0, 945, + 0, 936, 934, 934, 934, 934, 934, 934, 938, 939, + 943, 935, 935, 935, 935, 935, 935, 936, 936, 936, + 936, 936, 936, 940, 941, 938, 938, 938, 938, 938, + 938, 944, 937, 937, 937, 937, 937, 937, 942, 0, + + 1630, 944, 940, 0, 946, 943, 0, 939, 939, 939, + 939, 939, 939, 1631, 941, 941, 941, 941, 941, 941, + 1064, 1064, 1632, 1634, 1064, 942, 1064, 1064, 1064, 1630, + 944, 940, 945, 945, 945, 945, 945, 945, 0, 0, + 0, 1638, 1631, 943, 943, 943, 943, 943, 943, 0, + 0, 1632, 1634, 0, 942, 0, 940, 940, 940, 940, + 940, 940, 0, 0, 944, 944, 944, 944, 944, 944, + 1638, 942, 942, 942, 942, 942, 942, 946, 946, 946, + 946, 946, 946, 947, 947, 947, 947, 947, 947, 947, + 947, 947, 948, 948, 948, 948, 948, 948, 948, 948, + + 948, 949, 949, 949, 949, 949, 949, 949, 949, 950, + 950, 950, 950, 950, 950, 950, 950, 950, 951, 951, + 951, 951, 951, 951, 951, 951, 951, 952, 952, 952, + 952, 952, 952, 952, 952, 952, 954, 954, 954, 954, + 954, 954, 954, 954, 954, 955, 955, 955, 955, 955, + 955, 955, 955, 955, 956, 956, 956, 956, 956, 956, + 956, 956, 956, 957, 957, 957, 957, 957, 957, 957, + 957, 958, 958, 958, 958, 958, 958, 958, 958, 958, + 959, 959, 959, 959, 959, 959, 959, 959, 959, 960, + 960, 960, 960, 960, 960, 960, 960, 960, 962, 962, + + 962, 962, 962, 962, 962, 962, 962, 963, 963, 963, + 963, 963, 963, 963, 963, 963, 965, 966, 966, 966, + 966, 966, 966, 966, 966, 966, 967, 967, 967, 967, + 967, 967, 967, 967, 968, 968, 968, 968, 968, 968, + 968, 968, 968, 0, 0, 965, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 970, 970, 970, 970, 970, + 970, 970, 970, 970, 1044, 1044, 1044, 1044, 1044, 1044, + 965, 965, 965, 965, 965, 965, 972, 972, 972, 972, + 972, 972, 972, 972, 972, 973, 973, 973, 973, 973, + 973, 973, 973, 973, 976, 976, 976, 976, 976, 976, + + 976, 976, 976, 1025, 1025, 1025, 1025, 1025, 1025, 1025, + 1025, 1025, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, + 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1029, 1029, + 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1031, 1031, 1031, + 1031, 1031, 1031, 1031, 1031, 1031, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1033, + 1033, 1033, 1033, 1039, 1041, 1043, 1639, 1642, 1040, 1045, + 1045, 1045, 1045, 1045, 1045, 1047, 1047, 1047, 1047, 1047, + 1047, 1047, 1047, 1047, 1056, 1056, 1056, 1056, 1056, 1056, + + 1056, 1056, 1039, 1041, 0, 1639, 1642, 1040, 1042, 0, + 0, 0, 0, 1043, 1043, 1043, 1043, 1043, 1043, 1070, + 1070, 1070, 1070, 1070, 1070, 1039, 1039, 1039, 1039, 1039, + 1039, 1040, 1040, 1040, 1040, 1040, 1040, 1042, 1041, 1041, + 1041, 1041, 1041, 1041, 1055, 1055, 1055, 1055, 1055, 1055, + 1055, 1055, 1055, 0, 1042, 1042, 1042, 1042, 1042, 1042, + 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1058, + 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1059, 1059, + 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1061, 1061, 1061, + 1061, 1061, 1061, 1061, 1061, 1061, 1062, 1062, 1062, 1062, + + 1062, 1062, 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1067, 0, 0, 0, 1069, 1071, 1071, + 1071, 1071, 1071, 1071, 1075, 1068, 1074, 1074, 1074, 1074, + 1074, 1074, 1074, 1074, 1074, 1076, 1076, 1076, 1076, 1076, + 1076, 0, 1067, 1077, 1077, 1077, 1077, 1077, 1077, 1284, + 1284, 1284, 0, 1075, 1068, 1069, 1069, 1069, 1069, 1069, + 1069, 0, 0, 0, 0, 1067, 1067, 1067, 1067, 1067, + 1067, 1068, 1068, 1068, 1068, 1068, 1068, 1075, 1075, 1075, + 1075, 1075, 1075, 1078, 1078, 1078, 1078, 1078, 1078, 1078, + 1078, 1078, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, + + 1081, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1083, + 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1084, 1084, + 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1085, 1085, 1085, + 1085, 1085, 1085, 1085, 1085, 1085, 1086, 1086, 1284, 0, + 1086, 0, 1086, 1086, 1086, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1089, 1089, 1089, 1089, 1089, 1089, 1089, + 1089, 1090, 1090, 0, 1099, 1090, 1099, 1090, 1090, 1090, + 1101, 0, 1101, 1274, 1274, 1274, 1099, 1102, 0, 0, + 1274, 0, 0, 1104, 0, 0, 1102, 1232, 1232, 1232, + + 1232, 1232, 1232, 1222, 1103, 0, 1119, 0, 0, 0, + 1105, 0, 1120, 0, 0, 1099, 1107, 1107, 1107, 1107, + 1107, 1107, 1107, 1107, 1107, 1102, 0, 0, 0, 0, + 1103, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1222, 1222, 1222, 1222, 1222, 1222, 1649, 1099, 1099, 1099, + 1099, 1099, 1099, 1101, 1101, 1101, 1101, 1101, 1101, 1103, + 1102, 1102, 1102, 1102, 1102, 1102, 1104, 1104, 1104, 1104, + 1104, 1104, 1274, 1125, 1673, 1649, 0, 1103, 1103, 1103, + 1103, 1103, 1103, 1105, 1105, 1105, 1105, 1105, 1105, 1119, + 1119, 1119, 1119, 1119, 1119, 1120, 1120, 1120, 1120, 1120, + + 1120, 1122, 1122, 1673, 1697, 1122, 1122, 0, 0, 1122, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 0, 1122, + 1122, 1122, 1122, 1122, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1697, 0, 1296, 1296, 1296, 1126, 1127, + 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 0, 0, + 1122, 0, 1122, 1125, 1125, 1125, 1125, 1125, 1125, 0, + 1139, 0, 1139, 1201, 1201, 1201, 1201, 1201, 1201, 1201, + 1201, 1201, 1139, 0, 1278, 1278, 1278, 1140, 1278, 1122, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 1123, 1123, 1698, 1587, 1123, + + 1123, 1139, 1140, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1587, 1123, 1123, 1123, 1123, 1123, 1126, 1126, + 1126, 1126, 1126, 1126, 1296, 0, 1698, 1587, 1141, 1708, + 0, 1140, 0, 1139, 1139, 1139, 1139, 1139, 1139, 1143, + 0, 1587, 0, 1711, 1123, 1142, 1123, 0, 0, 0, + 1140, 1140, 1140, 1140, 1140, 1140, 1146, 1503, 1708, 1503, + 1141, 1142, 1577, 1278, 1716, 1577, 1143, 0, 0, 1503, + 1725, 1145, 1711, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1141, + 1142, 1577, 0, 1716, 1577, 1143, 1145, 1148, 1503, 1725, + + 0, 1141, 1141, 1141, 1141, 1141, 1141, 1144, 1726, 1148, + 1229, 0, 1143, 1143, 1143, 1143, 1143, 1143, 1142, 1142, + 1142, 1142, 1142, 1142, 1147, 1145, 0, 0, 1144, 1146, + 1146, 1146, 1146, 1146, 1146, 1150, 1147, 1726, 1148, 1229, + 1147, 0, 1149, 0, 1145, 1145, 1145, 1145, 1145, 1145, + 1151, 1229, 1229, 1229, 1229, 1229, 1229, 1144, 1149, 1152, + 0, 1727, 1150, 1728, 1729, 1147, 0, 1730, 1153, 1147, + 1148, 1148, 1148, 1148, 1148, 1148, 1153, 1151, 1152, 1157, + 1144, 1144, 1144, 1144, 1144, 1144, 0, 1149, 0, 1154, + 1727, 1150, 1728, 1729, 0, 1155, 1730, 1147, 1147, 1147, + + 1147, 1147, 1147, 0, 1156, 1153, 1151, 1152, 1150, 1150, + 1150, 1150, 1150, 1150, 0, 1149, 1149, 1149, 1149, 1149, + 1149, 1154, 1155, 1151, 1151, 1151, 1151, 1151, 1151, 1156, + 0, 1159, 1152, 1152, 1152, 1152, 1152, 1152, 0, 1160, + 0, 1153, 1153, 1153, 1153, 1153, 1153, 1160, 0, 1158, + 1154, 1155, 1157, 1157, 1157, 1157, 1157, 1157, 1156, 1159, + 1163, 0, 1154, 1154, 1154, 1154, 1154, 1154, 1155, 1155, + 1155, 1155, 1155, 1155, 1158, 1161, 1160, 1156, 1156, 1156, + 1156, 1156, 1156, 1164, 0, 0, 0, 0, 1159, 1162, + 1161, 0, 1276, 1276, 1276, 1165, 0, 0, 0, 1276, + + 1162, 1731, 1732, 1158, 1159, 1159, 1159, 1159, 1159, 1159, + 1164, 1167, 1160, 1160, 1160, 1160, 1160, 1160, 1165, 1161, + 1168, 0, 1158, 1158, 1158, 1158, 1158, 1158, 0, 1162, + 1731, 1732, 0, 1163, 1163, 1163, 1163, 1163, 1163, 1164, + 0, 0, 0, 1170, 1304, 1304, 1304, 1165, 1161, 1161, + 1161, 1161, 1161, 1161, 1166, 1168, 1164, 1164, 1164, 1164, + 1164, 1164, 1162, 1162, 1162, 1162, 1162, 1162, 1165, 1165, + 1165, 1165, 1165, 1165, 1170, 1166, 0, 0, 1733, 0, + 1169, 1276, 0, 1231, 1167, 1167, 1167, 1167, 1167, 1167, + 1171, 0, 0, 1168, 1168, 1168, 1168, 1168, 1168, 1172, + + 1173, 1173, 1173, 1170, 1166, 1169, 1174, 1733, 1223, 0, + 0, 1511, 1231, 1511, 1173, 1171, 1170, 1170, 1170, 1170, + 1170, 1170, 1175, 1511, 1317, 1317, 1317, 1166, 1166, 1166, + 1166, 1166, 1166, 1304, 1169, 1231, 1231, 1231, 1231, 1231, + 1231, 1174, 1734, 0, 1171, 1223, 1223, 1223, 1223, 1223, + 1223, 1176, 1511, 1169, 1169, 1169, 1169, 1169, 1169, 0, + 0, 0, 1177, 1171, 1171, 1171, 1171, 1171, 1171, 1182, + 0, 1734, 1172, 1172, 1172, 1172, 1172, 1172, 1176, 1174, + 1174, 1174, 1174, 1174, 1174, 1177, 0, 1173, 1173, 1173, + 1173, 1173, 1173, 1178, 1735, 1175, 1175, 1175, 1175, 1175, + + 1175, 1179, 1330, 1330, 1330, 1178, 0, 1176, 1180, 1336, + 1336, 1336, 1179, 1317, 1177, 1469, 1469, 1469, 0, 1181, + 0, 0, 1469, 1735, 1176, 1176, 1176, 1176, 1176, 1176, + 1180, 1181, 0, 1183, 1178, 1177, 1177, 1177, 1177, 1177, + 1177, 1179, 1182, 1182, 1182, 1182, 1182, 1182, 1185, 1185, + 1185, 0, 0, 0, 0, 0, 1184, 0, 1183, 1180, + 1181, 1666, 1185, 1666, 0, 0, 1178, 1178, 1178, 1178, + 1178, 1178, 1184, 1666, 1179, 1179, 1179, 1179, 1179, 1179, + 1186, 1180, 1180, 1180, 1180, 1180, 1180, 1183, 1186, 1188, + 0, 1330, 1181, 1181, 1181, 1181, 1181, 1181, 1336, 1736, + + 1187, 1184, 1666, 0, 1469, 0, 1183, 1183, 1183, 1183, + 1183, 1183, 1187, 1190, 1656, 1656, 1656, 1186, 1474, 1474, + 1474, 1188, 1737, 0, 1189, 1474, 0, 0, 1736, 1184, + 1184, 1184, 1184, 1184, 1184, 1185, 1185, 1185, 1185, 1185, + 1185, 1187, 1189, 1738, 1193, 0, 0, 0, 0, 0, + 1188, 1737, 1193, 1186, 1186, 1186, 1186, 1186, 1186, 1192, + 0, 0, 1188, 1188, 1188, 1188, 1188, 1188, 1191, 0, + 0, 1189, 1738, 1187, 1187, 1187, 1187, 1187, 1187, 1192, + 1191, 1193, 0, 1194, 1739, 0, 1190, 1190, 1190, 1190, + 1190, 1190, 0, 1195, 0, 1740, 0, 1189, 1189, 1189, + + 1189, 1189, 1189, 1656, 0, 0, 0, 1474, 1192, 1191, + 1194, 1195, 0, 1739, 1196, 0, 0, 1193, 1193, 1193, + 1193, 1193, 1193, 1196, 1740, 1205, 1741, 0, 0, 0, + 0, 1197, 1192, 1192, 1192, 1192, 1192, 1192, 1198, 1194, + 1195, 1191, 1191, 1191, 1191, 1191, 1191, 1197, 1198, 1202, + 1202, 1202, 1196, 1205, 1199, 1741, 1194, 1194, 1194, 1194, + 1194, 1194, 0, 1202, 1199, 1742, 1195, 1195, 1195, 1195, + 1195, 1195, 0, 1226, 0, 0, 1197, 1198, 0, 0, + 0, 1743, 1205, 0, 0, 0, 0, 1196, 1196, 1196, + 1196, 1196, 1196, 1199, 1742, 0, 0, 0, 1205, 1205, + + 1205, 1205, 1205, 1205, 1197, 1197, 1197, 1197, 1197, 1197, + 1743, 1198, 1198, 1198, 1198, 1198, 1198, 1203, 1224, 1224, + 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1199, 1199, 1199, + 1199, 1199, 1199, 1200, 1200, 1200, 1202, 1202, 1202, 1202, + 1202, 1202, 1230, 1203, 1226, 1226, 1226, 1226, 1226, 1226, + 1204, 0, 0, 0, 1200, 0, 0, 1200, 1200, 1206, + 0, 0, 0, 0, 0, 1207, 0, 1228, 1200, 1200, + 1200, 1206, 1203, 1207, 1200, 1744, 1208, 1204, 1745, 0, + 1230, 1230, 1230, 1230, 1230, 1230, 1200, 1200, 1208, 1209, + 1203, 1203, 1203, 1203, 1203, 1203, 1228, 1200, 1200, 1200, + + 1206, 1212, 1207, 1200, 1744, 0, 1204, 1745, 1210, 1228, + 1228, 1228, 1228, 1228, 1228, 1209, 1215, 1208, 1210, 2003, + 2003, 2003, 1200, 1204, 1204, 1204, 1204, 1204, 1204, 1212, + 1215, 0, 1206, 1206, 1206, 1206, 1206, 1206, 1207, 1207, + 1207, 1207, 1207, 1207, 1209, 0, 0, 1210, 1211, 1208, + 1208, 1208, 1208, 1208, 1208, 0, 1245, 0, 1212, 1215, + 1213, 0, 1209, 1209, 1209, 1209, 1209, 1209, 1623, 1211, + 1746, 0, 1214, 1623, 1212, 1212, 1212, 1212, 1212, 1212, + 1214, 1210, 1210, 1210, 1210, 1210, 1210, 1213, 1216, 1215, + 1215, 1215, 1215, 1215, 1215, 1217, 0, 1623, 1211, 1746, + + 1216, 1219, 1623, 1217, 0, 0, 0, 0, 2003, 1214, + 0, 1218, 0, 0, 0, 0, 1213, 0, 1220, 0, + 0, 1211, 1211, 1211, 1211, 1211, 1211, 1218, 1221, 1216, + 1220, 1747, 1217, 1213, 1213, 1213, 1213, 1213, 1213, 1245, + 1245, 1245, 1245, 1245, 1245, 1214, 1214, 1214, 1214, 1214, + 1214, 1227, 1233, 1748, 1749, 1233, 1218, 0, 0, 1220, + 1747, 1216, 1216, 1216, 1216, 1216, 1216, 0, 1217, 1217, + 1217, 1217, 1217, 1217, 1219, 1219, 1219, 1219, 1219, 1219, + 1227, 0, 1748, 1749, 1218, 1218, 1218, 1218, 1218, 1218, + 0, 1220, 1220, 1220, 1220, 1220, 1220, 1234, 0, 0, + + 1234, 1221, 1221, 1221, 1221, 1221, 1221, 1235, 1750, 0, + 1235, 1775, 1227, 1227, 1227, 1227, 1227, 1227, 1238, 1248, + 1671, 1238, 1671, 1234, 0, 1233, 1233, 1233, 1233, 1233, + 1233, 1777, 1671, 1778, 1235, 1236, 1779, 1750, 1236, 1780, + 1775, 1239, 0, 0, 1239, 0, 0, 1240, 1781, 1782, + 1240, 0, 1234, 1238, 0, 0, 0, 1239, 1236, 1240, + 1777, 1671, 1778, 1235, 1241, 1779, 1246, 1241, 1780, 0, + 1234, 1234, 1234, 1234, 1234, 1234, 1241, 1781, 1782, 0, + 1235, 1235, 1235, 1235, 1235, 1235, 1239, 1236, 1240, 0, + 0, 1238, 1238, 1238, 1238, 1238, 1238, 0, 1249, 1248, + + 1248, 1248, 1248, 1248, 1248, 1241, 0, 1783, 1236, 1236, + 1236, 1236, 1236, 1236, 1239, 1239, 1239, 1239, 1239, 1239, + 1240, 1240, 1240, 1240, 1240, 1240, 1242, 0, 0, 1242, + 0, 0, 1243, 0, 0, 1243, 1783, 1241, 1241, 1241, + 1241, 1241, 1241, 1244, 0, 1242, 1244, 1251, 1243, 1246, + 1246, 1246, 1246, 1246, 1246, 1244, 1247, 1247, 1247, 1247, + 1247, 1247, 1247, 1247, 1247, 1250, 1250, 1250, 1250, 1250, + 1250, 1250, 1250, 1250, 1242, 0, 0, 1243, 1249, 1249, + 1249, 1249, 1249, 1249, 1244, 1251, 1251, 1251, 1251, 1251, + 1251, 1253, 0, 1252, 1784, 1785, 1786, 1254, 1787, 1242, + + 1242, 1242, 1242, 1242, 1242, 1243, 1243, 1243, 1243, 1243, + 1243, 0, 0, 0, 0, 0, 1244, 1244, 1244, 1244, + 1244, 1244, 1252, 1784, 1785, 1786, 0, 1787, 1253, 1253, + 1253, 1253, 1253, 1253, 1254, 1254, 1254, 1254, 1254, 1254, + 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 0, + 0, 0, 0, 0, 1252, 1252, 1252, 1252, 1252, 1252, + 1280, 1280, 1292, 1289, 1280, 1280, 0, 1291, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 0, 1280, 1280, + 1280, 1280, 1280, 1282, 1282, 1282, 1282, 1282, 1282, 1282, + 1282, 1282, 1289, 1290, 1290, 1290, 1291, 0, 1290, 0, + + 1292, 1292, 1292, 1292, 1292, 1292, 1290, 0, 0, 1280, + 0, 1280, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, + 1302, 0, 0, 0, 0, 1289, 1289, 1289, 1289, 1289, + 1289, 1293, 1291, 1291, 1291, 1291, 1291, 1291, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1281, 1281, 0, 1307, 1281, 1281, + 1293, 0, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + 1281, 1308, 1281, 1281, 1281, 1281, 1281, 1788, 1789, 1790, + 1290, 1290, 1290, 1290, 1290, 1290, 1307, 1310, 1310, 1310, + 1310, 1310, 1310, 0, 1293, 1293, 1293, 1293, 1293, 1293, + + 0, 0, 0, 1281, 0, 1281, 1788, 1789, 1790, 1308, + 1308, 1308, 1308, 1308, 1308, 0, 0, 0, 0, 1307, + 1307, 1307, 1307, 1307, 1307, 1309, 1434, 1434, 1434, 1434, + 1434, 1434, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1300, 1300, + 0, 0, 1300, 1300, 1309, 1795, 1300, 1300, 1300, 1300, + 1300, 1300, 1300, 1300, 1300, 0, 1300, 1300, 1300, 1300, + 1300, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, + 1348, 1348, 1348, 1798, 1795, 1544, 1544, 1544, 1309, 1309, + 1309, 1309, 1309, 1309, 1348, 1821, 1838, 1300, 0, 1300, + + 1544, 0, 0, 1326, 1815, 1326, 1815, 0, 1819, 0, + 1819, 1327, 1798, 0, 0, 1326, 1815, 0, 0, 1327, + 1819, 0, 1351, 0, 1821, 1838, 1300, 1300, 1300, 1300, + 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, + 1300, 1300, 1301, 1301, 1326, 1815, 1301, 1301, 1327, 1819, + 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 0, + 1301, 1301, 1301, 1301, 1301, 0, 1435, 1348, 1348, 1348, + 1348, 1348, 1348, 1839, 1544, 0, 1326, 1326, 1326, 1326, + 1326, 1326, 1847, 1848, 1327, 1327, 1327, 1327, 1327, 1327, + 1432, 1301, 0, 1301, 1328, 1351, 1351, 1351, 1351, 1351, + + 1351, 1347, 1839, 1347, 1435, 1435, 1435, 1435, 1435, 1435, + 1328, 1847, 1848, 1347, 1853, 1352, 1388, 1388, 1388, 0, + 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, + 1301, 1301, 1301, 1301, 1301, 1301, 1312, 1312, 0, 1328, + 1312, 1312, 1347, 1853, 1312, 1312, 1312, 1312, 1312, 1312, + 1312, 1312, 1312, 1388, 1312, 1312, 1312, 1312, 1312, 0, + 0, 1432, 1432, 1432, 1432, 1432, 1432, 1328, 1328, 1328, + 1328, 1328, 1328, 0, 1347, 1347, 1347, 1347, 1347, 1347, + 1857, 1355, 1388, 1858, 1859, 1312, 0, 1312, 1352, 1352, + 1352, 1352, 1352, 1352, 0, 0, 0, 0, 0, 1349, + + 1479, 1479, 1479, 0, 1479, 1388, 0, 0, 1355, 1857, + 1357, 0, 1858, 1859, 1312, 1312, 1312, 1312, 1312, 1312, + 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, + 1313, 1313, 1349, 0, 1313, 1313, 1357, 1355, 1313, 1313, + 1313, 1313, 1313, 1313, 1313, 1313, 1313, 0, 1313, 1313, + 1313, 1313, 1313, 1350, 1355, 1355, 1355, 1355, 1355, 1355, + 0, 1349, 1350, 1353, 1864, 1357, 0, 1866, 0, 1358, + 0, 0, 1349, 1349, 1349, 1349, 1349, 1349, 1868, 1313, + 0, 1313, 1354, 1357, 1357, 1357, 1357, 1357, 1357, 1479, + 0, 1350, 0, 1864, 1356, 1353, 1866, 1513, 1513, 1513, + + 1361, 0, 0, 1354, 1356, 0, 0, 1868, 1313, 1313, + 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, + 1313, 1313, 1313, 1313, 1353, 1361, 1350, 1350, 1350, 1350, + 1350, 1350, 1354, 1356, 1513, 1867, 1353, 1353, 1353, 1353, + 1353, 1353, 1358, 1358, 1358, 1358, 1358, 1358, 0, 1359, + 0, 1869, 1870, 1867, 1361, 1354, 1354, 1354, 1354, 1354, + 1354, 1359, 1360, 1513, 1867, 1871, 1872, 1356, 1356, 1356, + 1356, 1356, 1356, 1361, 1361, 1361, 1361, 1361, 1361, 1362, + 1869, 1870, 1867, 0, 1360, 1874, 1513, 1363, 1875, 0, + 1359, 1362, 1876, 0, 1871, 1872, 1364, 0, 0, 1363, + + 0, 1877, 0, 1365, 1873, 1878, 0, 0, 0, 1368, + 0, 0, 1364, 1360, 1874, 1873, 1879, 1875, 1368, 1366, + 1362, 1876, 1359, 1359, 1359, 1359, 1359, 1359, 1363, 1365, + 1877, 1369, 0, 1873, 1878, 1360, 1360, 1360, 1360, 1360, + 1360, 1364, 0, 1367, 1873, 1879, 1366, 1368, 0, 1370, + 0, 0, 1362, 1362, 1362, 1362, 1362, 1362, 1365, 1367, + 1363, 1363, 1363, 1363, 1363, 1363, 1369, 1371, 0, 1364, + 1364, 1364, 1364, 1364, 1364, 1366, 1365, 1365, 1365, 1365, + 1365, 1365, 1368, 1368, 1368, 1368, 1368, 1368, 1367, 1372, + 0, 0, 1366, 1366, 1366, 1366, 1366, 1366, 1374, 0, + + 1880, 1881, 1371, 1372, 1369, 1369, 1369, 1369, 1369, 1369, + 1374, 1375, 0, 0, 0, 0, 1367, 1367, 1367, 1367, + 1367, 1367, 1370, 1370, 1370, 1370, 1370, 1370, 1373, 1880, + 1881, 0, 1372, 0, 1376, 0, 1560, 1560, 1560, 1374, + 1371, 1371, 1371, 1371, 1371, 1371, 1555, 1555, 1555, 0, + 1882, 1373, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1376, 1372, 1372, 1372, 1372, 1372, 1372, 1380, 1555, + 1560, 1374, 1374, 1374, 1374, 1374, 1374, 0, 1379, 1882, + 1373, 0, 0, 0, 1375, 1375, 1375, 1375, 1375, 1375, + 1376, 1377, 1377, 1377, 1379, 1381, 0, 1883, 1555, 1560, + + 0, 1373, 1373, 1373, 1373, 1373, 1373, 1376, 1376, 1376, + 1376, 1376, 1376, 0, 0, 1382, 1382, 1382, 1383, 1377, + 1381, 1885, 0, 1379, 0, 1560, 1883, 0, 1377, 1382, + 1382, 1886, 1887, 1567, 1383, 1555, 1384, 1567, 1567, 0, + 0, 1380, 1380, 1380, 1380, 1380, 1380, 1386, 1377, 1381, + 1885, 1379, 1379, 1379, 1379, 1379, 1379, 1377, 1384, 1385, + 1886, 1887, 1567, 1383, 0, 0, 1567, 1567, 1381, 1381, + 1381, 1381, 1381, 1381, 1387, 1391, 1391, 1391, 0, 1884, + 1377, 1392, 0, 0, 0, 0, 1385, 1384, 1888, 1391, + 1912, 1383, 1383, 1383, 1383, 1383, 1383, 1393, 1915, 0, + + 1884, 1387, 1382, 1382, 1382, 1382, 1382, 1382, 1884, 1384, + 1384, 1384, 1384, 1384, 1384, 1385, 1415, 1888, 0, 1912, + 1386, 1386, 1386, 1386, 1386, 1386, 0, 1915, 1390, 1884, + 1387, 0, 1385, 1385, 1385, 1385, 1385, 1385, 1389, 1389, + 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1387, 1387, 1387, + 1387, 1387, 1387, 1390, 1392, 1392, 1392, 1392, 1392, 1392, + 1394, 0, 1391, 1391, 1391, 1391, 1391, 1391, 1395, 1916, + 1393, 1393, 1393, 1393, 1393, 1393, 0, 1396, 1920, 1923, + 1395, 0, 1390, 1397, 1397, 1397, 1394, 1396, 1398, 1415, + 1415, 1415, 1415, 1415, 1415, 0, 0, 1397, 1916, 1924, + + 1398, 1390, 1390, 1390, 1390, 1390, 1390, 1920, 1923, 1395, + 1399, 0, 0, 0, 0, 1394, 1396, 0, 1399, 1400, + 1450, 1450, 1450, 1450, 1450, 1450, 1401, 1925, 1924, 1398, + 1926, 0, 0, 1394, 1394, 1394, 1394, 1394, 1394, 1930, + 1400, 1395, 1395, 1395, 1395, 1395, 1395, 1399, 1401, 1402, + 1396, 1396, 1396, 1396, 1396, 1396, 1925, 0, 0, 1926, + 1449, 1398, 1398, 1398, 1398, 1398, 1398, 1417, 1930, 1400, + 1397, 1397, 1397, 1397, 1397, 1397, 1402, 1401, 2014, 2014, + 2014, 0, 0, 1399, 1399, 1399, 1399, 1399, 1399, 1449, + 0, 0, 1400, 1400, 1400, 1400, 1400, 1400, 0, 1401, + + 1401, 1401, 1401, 1401, 1401, 1402, 1411, 1411, 1411, 1411, + 1411, 1411, 1411, 1411, 1411, 1449, 1449, 1449, 1449, 1449, + 1449, 1934, 1402, 1402, 1402, 1402, 1402, 1402, 1412, 1412, + 1412, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, + 1417, 1417, 1417, 1417, 1417, 1417, 1414, 1437, 1956, 0, + 1934, 1412, 1412, 1412, 1412, 1412, 1412, 1419, 1412, 1973, + 1412, 1414, 1412, 1418, 1974, 1412, 1979, 2014, 1412, 1412, + 1416, 0, 1412, 1982, 1418, 1983, 1437, 1956, 1420, 0, + 1412, 1412, 1412, 1412, 1412, 1412, 1420, 1412, 1973, 1412, + 1414, 1412, 1421, 1974, 1412, 1979, 1416, 1412, 1412, 1422, + + 1421, 1412, 1982, 1418, 1983, 1426, 1437, 1437, 1437, 1437, + 1437, 1437, 1684, 1684, 1684, 1420, 1423, 1412, 0, 1414, + 1414, 1414, 1414, 1414, 1414, 1416, 0, 1684, 1423, 1421, + 1419, 1419, 1419, 1419, 1419, 1419, 1418, 1418, 1418, 1418, + 1418, 1418, 0, 1416, 1416, 1416, 1416, 1416, 1416, 0, + 0, 1420, 1420, 1420, 1420, 1420, 1420, 1423, 0, 1424, + 0, 0, 0, 0, 0, 1421, 1421, 1421, 1421, 1421, + 1421, 1424, 1422, 1422, 1422, 1422, 1422, 1422, 1426, 1426, + 1426, 1426, 1426, 1426, 1425, 1951, 1954, 1951, 1954, 1423, + 1423, 1423, 1423, 1423, 1423, 1425, 1427, 1951, 1954, 0, + + 1424, 1684, 1428, 1486, 0, 0, 0, 0, 1430, 0, + 1987, 1428, 0, 0, 0, 0, 0, 1429, 1989, 1990, + 1991, 1996, 1427, 1997, 1425, 1998, 1951, 1954, 1441, 0, + 0, 0, 1424, 1424, 1424, 1424, 1424, 1424, 1429, 1987, + 1428, 1486, 1486, 1486, 1486, 1486, 1486, 1989, 1990, 1991, + 1996, 1427, 1997, 0, 1998, 0, 0, 1425, 1425, 1425, + 1425, 1425, 1425, 1441, 0, 0, 0, 1429, 1433, 1427, + 1427, 1427, 1427, 1427, 1427, 1428, 1428, 1428, 1428, 1428, + 1428, 1430, 1430, 1430, 1430, 1430, 1430, 1436, 1439, 1999, + 1429, 1429, 1429, 1429, 1429, 1429, 1440, 1433, 0, 0, + + 2000, 1441, 1441, 1441, 1441, 1441, 1441, 2001, 2002, 1442, + 2004, 2005, 1440, 2006, 2007, 1439, 1436, 1443, 1999, 0, + 1433, 1433, 1433, 1433, 1433, 1433, 0, 1442, 1443, 2000, + 2008, 0, 1444, 0, 0, 0, 2001, 2002, 1446, 2004, + 2005, 1440, 2006, 2007, 1439, 0, 0, 2009, 1445, 2010, + 1436, 1436, 1436, 1436, 1436, 1436, 1442, 1443, 1498, 2008, + 1446, 1439, 1439, 1439, 1439, 1439, 1439, 1444, 1448, 1440, + 1440, 1440, 1440, 1440, 1440, 1445, 2009, 1447, 2010, 0, + 0, 0, 1442, 1442, 1442, 1442, 1442, 1442, 1447, 1446, + 1443, 1443, 1443, 1443, 1443, 1443, 1498, 1498, 1498, 1498, + + 1498, 1498, 2011, 1448, 1445, 1444, 1444, 1444, 1444, 1444, + 1444, 1446, 1446, 1446, 1446, 1446, 1446, 1447, 1517, 1491, + 2012, 1445, 1445, 1445, 1445, 1445, 1445, 0, 1493, 2013, + 0, 2011, 0, 0, 1487, 1487, 1487, 0, 0, 1487, + 1492, 1448, 1448, 1448, 1448, 1448, 1448, 1487, 1491, 2012, + 1447, 1447, 1447, 1447, 1447, 1447, 1499, 1493, 2013, 1487, + 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1492, + 0, 0, 0, 1491, 1491, 1491, 1491, 1491, 1491, 1493, + 1493, 1493, 1493, 1493, 1493, 1499, 0, 0, 1487, 0, + 2015, 1517, 1517, 1517, 1517, 1517, 1517, 1492, 1492, 1492, + + 1492, 1492, 1492, 1514, 1514, 1514, 1514, 1514, 1514, 1514, + 1514, 1514, 0, 1499, 1499, 1499, 1499, 1499, 1499, 2015, + 0, 0, 0, 1487, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1500, 1504, + 2016, 1504, 0, 2018, 2019, 0, 0, 1505, 0, 2020, + 2021, 1504, 0, 1506, 0, 0, 0, 0, 0, 1512, + 0, 1512, 0, 0, 0, 1515, 1505, 1500, 0, 2016, + 2022, 1512, 2018, 2019, 1519, 1506, 2023, 1515, 2020, 2021, + 1504, 1604, 1604, 1604, 1604, 1604, 1604, 1522, 0, 1500, + 1500, 1500, 1500, 1500, 1500, 1505, 1694, 1694, 1694, 2022, + 1512, 0, 0, 0, 1506, 2023, 1515, 0, 2122, 2122, + 2122, 1694, 1504, 1504, 1504, 1504, 1504, 1504, 1516, 0, + + 1505, 1505, 1505, 1505, 1505, 1505, 1506, 1506, 1506, 1506, + 1506, 1506, 1512, 1512, 1512, 1512, 1512, 1512, 1515, 1515, + 1515, 1515, 1515, 1515, 1518, 2024, 1516, 1519, 1519, 1519, + 1519, 1519, 1519, 1520, 2039, 0, 0, 0, 2040, 1521, + 1522, 1522, 1522, 1522, 1522, 1522, 1523, 1526, 1526, 1526, + 2041, 1518, 1524, 2043, 2024, 1516, 1523, 2044, 2045, 2046, + 1520, 1526, 1526, 2039, 1524, 1694, 1521, 2040, 0, 0, + 1528, 1516, 1516, 1516, 1516, 1516, 1516, 2122, 0, 2041, + 1518, 1534, 2043, 0, 0, 1523, 2044, 2045, 2046, 1520, + 0, 0, 1525, 1524, 0, 1521, 0, 1518, 1518, 1518, + + 1518, 1518, 1518, 1525, 0, 0, 1520, 1520, 1520, 1520, + 1520, 1520, 1521, 1521, 1521, 1521, 1521, 1521, 1536, 1523, + 1523, 1523, 1523, 1523, 1523, 1524, 1524, 1524, 1524, 1524, + 1524, 2078, 1525, 1527, 1526, 1526, 1526, 1526, 1526, 1526, + 1529, 0, 1527, 1528, 1528, 1528, 1528, 1528, 1528, 2084, + 2091, 1530, 1529, 2093, 1534, 1534, 1534, 1534, 1534, 1534, + 2078, 2073, 0, 2073, 0, 1525, 1525, 1525, 1525, 1525, + 1525, 1527, 1530, 2073, 0, 1531, 0, 0, 2084, 2091, + 0, 1529, 2093, 1531, 1537, 1537, 1537, 0, 1755, 1755, + 1755, 1536, 1536, 1536, 1536, 1536, 1536, 0, 1537, 1537, + + 0, 1530, 2073, 1755, 2094, 1532, 1527, 1527, 1527, 1527, + 1527, 1527, 1531, 1529, 1529, 1529, 1529, 1529, 1529, 1533, + 0, 0, 0, 0, 1530, 1530, 1530, 1530, 1530, 1530, + 1532, 1535, 0, 2094, 0, 0, 0, 1542, 0, 0, + 1533, 1607, 1607, 1607, 1607, 1607, 1607, 0, 1531, 1531, + 1531, 1531, 1531, 1531, 1543, 0, 1535, 2099, 1542, 1532, + 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1533, + 1543, 1537, 1537, 1537, 1537, 1537, 1537, 1755, 1532, 1532, + 1532, 1532, 1532, 1532, 1549, 1535, 2099, 1542, 0, 2047, + 2047, 2047, 1533, 1533, 1533, 1533, 1533, 1533, 1547, 1543, + + 0, 0, 0, 2047, 1535, 1535, 1535, 1535, 1535, 1535, + 1542, 1542, 1542, 1542, 1542, 1542, 1546, 1546, 1546, 1546, + 1546, 1546, 1546, 1546, 1546, 1547, 1554, 1543, 1543, 1543, + 1543, 1543, 1543, 1548, 2102, 2107, 0, 2108, 1554, 1550, + 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 0, + 1557, 2109, 1548, 2110, 1547, 1550, 1558, 1549, 1549, 1549, + 1549, 1549, 1549, 2102, 2107, 1557, 2108, 1554, 2113, 2115, + 0, 1547, 1547, 1547, 1547, 1547, 1547, 1562, 2047, 0, + 2109, 1548, 2110, 0, 1550, 1556, 1556, 1556, 1556, 1556, + 1556, 1556, 1556, 1556, 1557, 0, 0, 2113, 2115, 1554, + + 1554, 1554, 1554, 1554, 1554, 1592, 1548, 1548, 1548, 1548, + 1548, 1548, 1550, 1550, 1550, 1550, 1550, 1550, 0, 2116, + 2117, 0, 0, 1557, 1557, 1557, 1557, 1557, 1557, 1558, + 1558, 1558, 1558, 1558, 1558, 1559, 1561, 1561, 1561, 1561, + 1561, 1561, 1561, 1561, 1561, 0, 1563, 1559, 2116, 2117, + 1562, 1562, 1562, 1562, 1562, 1562, 1563, 1564, 0, 0, + 1566, 1566, 1566, 0, 0, 2076, 2118, 2076, 1565, 1564, + 2119, 2120, 2121, 2124, 1566, 1566, 1559, 2076, 1592, 1592, + 1592, 1592, 1592, 1592, 1593, 1563, 1590, 1590, 1590, 1590, + 1590, 1590, 1590, 1590, 1590, 2118, 1565, 1594, 1564, 2119, + + 2120, 2121, 2124, 0, 1591, 0, 2076, 1594, 1559, 1559, + 1559, 1559, 1559, 1559, 1596, 0, 0, 0, 0, 1563, + 1563, 1563, 1563, 1563, 1563, 1565, 1591, 1595, 0, 0, + 1564, 1564, 1564, 1564, 1564, 1564, 1594, 1599, 2125, 2126, + 2127, 1565, 1565, 1565, 1565, 1565, 1565, 1566, 1566, 1566, + 1566, 1566, 1566, 1598, 1595, 1591, 0, 1593, 1593, 1593, + 1593, 1593, 1593, 1603, 2128, 1598, 0, 2125, 2126, 2127, + 1594, 1594, 1594, 1594, 1594, 1594, 1600, 1591, 1591, 1591, + 1591, 1591, 1591, 1595, 1597, 1597, 1597, 1596, 1596, 1596, + 1596, 1596, 1596, 2128, 1598, 1600, 1605, 0, 1597, 1597, + + 1595, 1595, 1595, 1595, 1595, 1595, 0, 0, 0, 0, + 1599, 1599, 1599, 1599, 1599, 1599, 0, 0, 1601, 0, + 0, 0, 0, 0, 1600, 1605, 1598, 1598, 1598, 1598, + 1598, 1598, 1601, 1606, 1603, 1603, 1603, 1603, 1603, 1603, + 2129, 2130, 1605, 1605, 1605, 1605, 1605, 1605, 1612, 1600, + 1600, 1600, 1600, 1600, 1600, 0, 1608, 0, 0, 0, + 0, 1601, 1606, 1850, 1850, 1850, 0, 1609, 1608, 2129, + 2130, 1597, 1597, 1597, 1597, 1597, 1597, 1609, 1850, 2131, + 2132, 2133, 1610, 2136, 1606, 1606, 1606, 1606, 1606, 1606, + 2137, 1601, 1601, 1601, 1601, 1601, 1601, 1608, 1610, 1615, + + 0, 0, 0, 0, 0, 1611, 1609, 1615, 2131, 2132, + 2133, 0, 2136, 1614, 0, 0, 0, 1611, 0, 2137, + 2138, 1612, 1612, 1612, 1612, 1612, 1612, 1610, 1616, 1608, + 1608, 1608, 1608, 1608, 1608, 0, 1615, 2139, 2141, 0, + 1609, 1609, 1609, 1609, 1609, 1609, 1611, 1613, 1614, 2138, + 0, 0, 1850, 1617, 0, 1610, 1610, 1610, 1610, 1610, + 1610, 0, 0, 1613, 1640, 0, 2139, 2141, 1613, 1617, + 0, 1618, 1615, 1615, 1615, 1615, 1615, 1615, 1611, 1611, + 1611, 1611, 1611, 1611, 0, 0, 1614, 1614, 1614, 1614, + 1614, 1614, 1613, 1640, 1641, 1641, 1641, 1613, 1617, 1641, + + 1618, 1616, 1616, 1616, 1616, 1616, 1616, 1641, 0, 0, + 0, 0, 1640, 1640, 1640, 1640, 1640, 1640, 0, 1641, + 1613, 1613, 1613, 1613, 1613, 1613, 1617, 1617, 1617, 1617, + 1617, 1617, 1618, 1618, 1618, 1618, 1618, 1618, 1644, 1644, + 1644, 0, 0, 1644, 1645, 1645, 1645, 1659, 1641, 1645, + 2142, 1644, 2143, 1648, 1648, 1648, 2144, 1645, 1648, 2148, + 0, 2158, 2161, 1644, 2162, 2163, 1648, 2164, 2169, 1645, + 1658, 1658, 1658, 1658, 1658, 1658, 1659, 2190, 1648, 2142, + 0, 2143, 0, 1641, 0, 2144, 0, 0, 2148, 1660, + 2158, 2161, 1644, 2162, 2163, 0, 2164, 2169, 1645, 1659, + + 1659, 1659, 1659, 1659, 1659, 0, 2190, 1648, 1657, 1657, + 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1664, 1660, 0, + 0, 1662, 2195, 1663, 1763, 2197, 2198, 1644, 2202, 1668, + 0, 2203, 0, 1645, 1660, 1660, 1660, 1660, 1660, 1660, + 1669, 0, 1648, 1650, 1650, 1650, 1664, 2182, 1650, 2182, + 1662, 2195, 1663, 1763, 2197, 2198, 1650, 2202, 2206, 2182, + 2203, 1669, 1664, 1664, 1664, 1664, 1664, 1664, 1650, 1662, + 1662, 1662, 1662, 1662, 1662, 1663, 1663, 1663, 1663, 1663, + 1663, 1763, 1763, 1763, 1763, 1763, 1763, 2206, 2182, 1667, + 1669, 1667, 0, 0, 0, 0, 1672, 1650, 1672, 0, + + 0, 1667, 1668, 1668, 1668, 1668, 1668, 1668, 1672, 0, + 2221, 2221, 2221, 1669, 1669, 1669, 1669, 1669, 1669, 1676, + 0, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, + 1667, 1678, 1650, 1651, 1651, 1651, 0, 1672, 1651, 1910, + 1910, 1910, 1910, 1910, 1910, 0, 1651, 1675, 1675, 1675, + 1675, 1675, 1675, 1675, 1675, 1675, 2208, 2209, 1651, 0, + 2210, 2211, 1667, 1667, 1667, 1667, 1667, 1667, 1682, 1672, + 1672, 1672, 1672, 1672, 1672, 0, 1677, 0, 0, 2185, + 0, 2185, 1679, 0, 0, 2208, 2209, 1651, 1680, 2210, + 2211, 2185, 1676, 1676, 1676, 1676, 1676, 1676, 1679, 2221, + + 1680, 2214, 2216, 1677, 1678, 1678, 1678, 1678, 1678, 1678, + 1683, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, + 2185, 0, 1651, 1652, 1652, 1652, 0, 1679, 1652, 1680, + 2214, 2216, 1677, 0, 0, 0, 1652, 0, 0, 0, + 0, 1682, 1682, 1682, 1682, 1682, 1682, 1688, 1652, 1677, + 1677, 1677, 1677, 1677, 1677, 1679, 1679, 1679, 1679, 1679, + 1679, 1680, 1680, 1680, 1680, 1680, 1680, 2068, 2068, 2068, + 2068, 2068, 2068, 1681, 2222, 2222, 2222, 1652, 0, 1689, + 0, 1681, 0, 1683, 1683, 1683, 1683, 1683, 1683, 1686, + 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 0, 1687, + + 0, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, + 1681, 1687, 1652, 1653, 1653, 1653, 2217, 0, 1653, 0, + 1688, 1688, 1688, 1688, 1688, 1688, 1653, 1696, 1696, 1696, + 1696, 1696, 1696, 1696, 1696, 1696, 1691, 0, 1653, 1774, + 1687, 2227, 2227, 2227, 1693, 2217, 1681, 1681, 1681, 1681, + 1681, 1681, 1689, 1689, 1689, 1689, 1689, 1689, 1691, 2218, + 1693, 1690, 0, 2222, 1977, 1977, 1977, 1653, 1774, 0, + 1692, 1690, 1687, 1687, 1687, 1687, 1687, 1687, 1692, 1977, + 1774, 1774, 1774, 1774, 1774, 1774, 2219, 1691, 2218, 1693, + 0, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, + + 1690, 1700, 1653, 1654, 1654, 1654, 0, 1692, 1654, 1691, + 1691, 1691, 1691, 1691, 1691, 2219, 1654, 1693, 1693, 1693, + 1693, 1693, 1693, 2220, 0, 2187, 0, 1700, 1654, 0, + 2227, 2167, 2167, 2167, 1690, 1690, 1690, 1690, 1690, 1690, + 2187, 2225, 0, 1692, 1692, 1692, 1692, 1692, 1692, 1701, + 0, 0, 2220, 1977, 2187, 1705, 1700, 1654, 1704, 1704, + 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1706, 2229, 2187, + 2225, 1701, 2167, 2231, 1700, 1700, 1700, 1700, 1700, 1700, + 1710, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, + 2232, 1714, 1654, 1655, 1655, 1655, 0, 2229, 1655, 0, + + 1701, 2167, 2231, 0, 0, 0, 1655, 0, 0, 0, + 2234, 0, 1707, 0, 0, 0, 0, 2235, 1655, 2232, + 2167, 0, 1701, 1701, 1701, 1701, 1701, 1701, 1705, 1705, + 1705, 1705, 1705, 1705, 1707, 1715, 1715, 1715, 1720, 2234, + 1706, 1706, 1706, 1706, 1706, 1706, 2235, 1655, 0, 1715, + 1715, 0, 0, 1710, 1710, 1710, 1710, 1710, 1710, 0, + 0, 0, 1719, 1707, 1714, 1714, 1714, 1714, 1714, 1714, + 0, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, + 1719, 1758, 1655, 0, 0, 1707, 1707, 1707, 1707, 1707, + 1707, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, + + 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1719, + 1721, 1720, 1720, 1720, 1720, 1720, 1720, 0, 0, 0, + 0, 2236, 1715, 1715, 1715, 1715, 1715, 1715, 1722, 1722, + 1722, 1721, 0, 2238, 1752, 1719, 1719, 1719, 1719, 1719, + 1719, 0, 0, 1722, 0, 2228, 2228, 2228, 1753, 1722, + 2236, 2239, 2241, 1722, 1758, 1758, 1758, 1758, 1758, 1758, + 1721, 1752, 2238, 2243, 1754, 1722, 1724, 1724, 1724, 1724, + 1724, 1724, 1724, 1724, 1724, 1753, 1754, 1759, 0, 0, + 2239, 2241, 1722, 1721, 1721, 1721, 1721, 1721, 1721, 1759, + 1752, 0, 2243, 1760, 1722, 1757, 1757, 1757, 1757, 1757, + + 1757, 1757, 1757, 1757, 1753, 1754, 1762, 1752, 1752, 1752, + 1752, 1752, 1752, 0, 0, 0, 0, 1722, 1759, 1760, + 1765, 1753, 1753, 1753, 1753, 1753, 1753, 1766, 2082, 2082, + 2082, 1764, 2242, 1767, 2228, 2242, 2244, 1754, 1754, 1754, + 1754, 1754, 1754, 2082, 1767, 1765, 2245, 2248, 1760, 0, + 1759, 1759, 1759, 1759, 1759, 1759, 0, 1768, 0, 0, + 1764, 2242, 1766, 2249, 2242, 2244, 1760, 1760, 1760, 1760, + 1760, 1760, 0, 1767, 1765, 2245, 2248, 1762, 1762, 1762, + 1762, 1762, 1762, 1764, 1764, 1764, 1764, 1764, 1764, 1768, + 0, 1770, 2249, 1765, 1765, 1765, 1765, 1765, 1765, 1770, + + 1766, 1766, 1766, 1766, 1766, 1766, 1767, 1767, 1767, 1767, + 1767, 1767, 1769, 0, 2089, 2089, 2089, 2082, 1768, 1791, + 0, 2250, 0, 1769, 0, 0, 0, 0, 1770, 2089, + 1768, 1768, 1768, 1768, 1768, 1768, 1771, 0, 0, 0, + 0, 0, 1772, 0, 0, 0, 0, 1771, 1791, 1809, + 2250, 1773, 1769, 1772, 2071, 2071, 2071, 2071, 2071, 2071, + 0, 0, 1773, 0, 1770, 1770, 1770, 1770, 1770, 1770, + 1791, 1791, 1791, 1791, 1791, 1791, 1771, 2252, 1809, 1792, + 1792, 1792, 1772, 0, 1792, 1769, 1769, 1769, 1769, 1769, + 1769, 1773, 1792, 1845, 1845, 1845, 1809, 1809, 1809, 1809, + + 1809, 1809, 0, 2089, 1792, 2253, 2252, 0, 0, 1771, + 1771, 1771, 1771, 1771, 1771, 1772, 1772, 1772, 1772, 1772, + 1772, 0, 1845, 0, 1773, 1773, 1773, 1773, 1773, 1773, + 1793, 1793, 1793, 1792, 2253, 1793, 1794, 1794, 1794, 0, + 1810, 1794, 2257, 1793, 0, 1797, 1797, 1797, 0, 1794, + 1797, 1845, 1807, 1807, 1807, 1793, 1811, 1807, 1797, 2265, + 2266, 1794, 2268, 0, 0, 1807, 0, 0, 1792, 1810, + 1797, 2257, 1793, 1804, 1804, 1804, 1813, 1807, 1804, 0, + 0, 0, 1845, 0, 1793, 1811, 1804, 0, 2265, 2266, + 1794, 2268, 1810, 1810, 1810, 1810, 1810, 1810, 1804, 1797, + + 1817, 1793, 2097, 2097, 2097, 1813, 1807, 1811, 1811, 1811, + 1811, 1811, 1811, 0, 1794, 0, 1812, 2097, 2269, 1793, + 2271, 2274, 2230, 2230, 2230, 1794, 0, 1804, 1813, 1813, + 1813, 1813, 1813, 1813, 1797, 1799, 1799, 1799, 0, 0, + 1799, 1807, 2166, 2166, 2166, 1812, 0, 2269, 1799, 2271, + 2274, 1804, 1804, 0, 0, 1804, 2166, 1804, 1804, 1804, + 1799, 1898, 1804, 1812, 1812, 1812, 1812, 1812, 1812, 1816, + 2285, 1816, 0, 1817, 1817, 1817, 1817, 1817, 1817, 0, + 0, 1816, 1820, 2246, 1820, 0, 0, 0, 1823, 1799, + 0, 2097, 0, 2246, 1820, 0, 0, 0, 0, 2285, + + 1823, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, + 1816, 2230, 2246, 1799, 1799, 1799, 1799, 1799, 1799, 1799, + 1799, 1799, 2246, 1820, 1799, 1800, 1800, 1800, 0, 1823, + 1800, 2166, 1898, 1898, 1898, 1898, 1898, 1898, 1800, 0, + 1927, 0, 1816, 1816, 1816, 1816, 1816, 1816, 1824, 2286, + 1800, 0, 2288, 2291, 0, 1820, 1820, 1820, 1820, 1820, + 1820, 1823, 1823, 1823, 1823, 1823, 1823, 0, 1825, 1927, + 1824, 2292, 0, 0, 1826, 2240, 2240, 2240, 2286, 1800, + 1830, 2288, 2291, 1927, 1927, 1927, 1927, 1927, 1927, 1825, + 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1824, + + 2292, 1826, 1832, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1800, 0, 1831, 1800, 1801, 1801, 1801, 1825, 0, + 1801, 1824, 1824, 1824, 1824, 1824, 1824, 0, 1801, 0, + 1826, 1831, 1832, 2170, 2170, 2170, 2170, 2170, 2170, 1855, + 1801, 1825, 1825, 1825, 1825, 1825, 1825, 1826, 1826, 1826, + 1826, 1826, 1826, 1830, 1830, 1830, 1830, 1830, 1830, 0, + 1831, 1832, 1833, 0, 2240, 0, 2111, 2111, 2111, 1801, + 1834, 0, 0, 0, 2293, 1832, 1832, 1832, 1832, 1832, + 1832, 2111, 1833, 0, 0, 0, 1831, 1831, 1831, 1831, + 1831, 1831, 1834, 1801, 1801, 1801, 1801, 1801, 1801, 1801, + + 1801, 1801, 1841, 2293, 1801, 1802, 1802, 1802, 0, 0, + 1802, 1833, 1855, 1855, 1855, 1855, 1855, 1855, 1802, 0, + 2300, 1834, 0, 2303, 2304, 2307, 0, 1841, 0, 1840, + 1802, 0, 2296, 2296, 2296, 1833, 1833, 1833, 1833, 1833, + 1833, 1840, 2308, 1834, 1834, 1834, 1834, 1834, 1834, 2300, + 0, 1846, 2303, 2304, 2307, 2111, 1841, 1889, 0, 1802, + 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 2309, + 1840, 2308, 1846, 0, 0, 1841, 1841, 1841, 1841, 1841, + 1841, 0, 1856, 1802, 1802, 1802, 1802, 1802, 1802, 1802, + 1802, 1802, 1891, 1900, 1802, 1803, 1803, 1803, 2309, 0, + + 1803, 1846, 1840, 1840, 1840, 1840, 1840, 1840, 1803, 1856, + 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 2310, + 1803, 2296, 1900, 0, 1846, 1846, 1846, 1846, 1846, 1846, + 1889, 1889, 1889, 1889, 1889, 1889, 0, 0, 1856, 1896, + 1900, 1900, 1900, 1900, 1900, 1900, 1890, 0, 2310, 1803, + 0, 2280, 2283, 2280, 2283, 1856, 1856, 1856, 1856, 1856, + 1856, 0, 1890, 2280, 2283, 1891, 1891, 1891, 1891, 1891, + 1891, 1895, 0, 1803, 1803, 1803, 1803, 1803, 1803, 1803, + 1803, 1803, 2312, 0, 1803, 1805, 1805, 1805, 0, 0, + 1805, 1890, 2280, 2283, 0, 0, 2317, 1895, 1805, 1894, + + 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 0, 0, + 1805, 2312, 1896, 1896, 1896, 1896, 1896, 1896, 1901, 1890, + 1890, 1890, 1890, 1890, 1890, 2317, 1895, 0, 1899, 0, + 2319, 1964, 1964, 1964, 1902, 0, 2146, 2146, 2146, 1805, + 1903, 2188, 2188, 2188, 1895, 1895, 1895, 1895, 1895, 1895, + 1902, 2146, 0, 1901, 0, 0, 2188, 1899, 1904, 2319, + 1964, 2327, 0, 1805, 1805, 1805, 1805, 1805, 1805, 1805, + 1805, 1805, 1905, 0, 1805, 1806, 1806, 1806, 0, 1902, + 1806, 1899, 1899, 1899, 1899, 1899, 1899, 0, 1806, 1964, + 2327, 1901, 1901, 1901, 1901, 1901, 1901, 2329, 2330, 0, + + 1806, 0, 1906, 0, 0, 0, 0, 1902, 1902, 1902, + 1902, 1902, 1902, 1903, 1903, 1903, 1903, 1903, 1903, 1908, + 1964, 0, 1906, 1946, 0, 2146, 2329, 2330, 1907, 1806, + 2188, 1904, 1904, 1904, 1904, 1904, 1904, 1907, 1909, 2179, + 2179, 2179, 2179, 2179, 2179, 1905, 1905, 1905, 1905, 1905, + 1905, 1906, 1946, 1806, 1806, 1806, 1806, 1806, 1806, 1806, + 1806, 1806, 2334, 0, 1806, 0, 1907, 0, 0, 1946, + 1946, 1946, 1946, 1946, 1946, 1906, 1906, 1906, 1906, 1906, + 1906, 2297, 2297, 2297, 0, 1928, 1928, 1928, 0, 0, + 1928, 2334, 1908, 1908, 1908, 1908, 1908, 1908, 1928, 0, + + 0, 1907, 1907, 1907, 1907, 1907, 1907, 1928, 0, 0, + 1928, 1909, 1909, 1909, 1909, 1909, 1909, 1929, 1929, 1929, + 0, 0, 1929, 0, 1931, 1931, 1931, 0, 1945, 1931, + 1929, 0, 0, 1932, 1932, 1932, 1928, 1931, 1932, 1928, + 2335, 0, 1929, 1933, 1933, 1933, 1932, 2336, 1933, 1931, + 1938, 1938, 1938, 2337, 2338, 1938, 1933, 1945, 1932, 2339, + 1939, 1939, 1939, 1938, 0, 1939, 0, 2340, 1933, 2335, + 2297, 1929, 2341, 1939, 1928, 1938, 2336, 0, 1931, 1972, + 1972, 1972, 2337, 2338, 0, 1939, 0, 1932, 2339, 1945, + 1945, 1945, 1945, 1945, 1945, 1929, 2340, 1933, 1948, 0, + + 2342, 2341, 2344, 0, 1938, 0, 1929, 2345, 1972, 0, + 0, 0, 2346, 1931, 1939, 1940, 1940, 1940, 0, 2347, + 1940, 1933, 1932, 0, 0, 0, 0, 1948, 1940, 2342, + 0, 2344, 1933, 1937, 1937, 1937, 2345, 1972, 1937, 1938, + 1940, 2346, 1941, 1941, 1941, 1947, 1937, 1941, 2347, 1939, + 2348, 1949, 1942, 1942, 1942, 1941, 2351, 1942, 1937, 1948, + 1948, 1948, 1948, 1948, 1948, 1942, 0, 1941, 1972, 1940, + 1943, 1943, 1943, 0, 1947, 1943, 2358, 1942, 1957, 2348, + 1949, 0, 0, 1943, 0, 2351, 0, 1937, 1947, 1947, + 1947, 1947, 1947, 1947, 1942, 1943, 1941, 1949, 1949, 1949, + + 1949, 1949, 1949, 2359, 1940, 2358, 1942, 2033, 1952, 2361, + 1952, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, + 1952, 0, 1937, 1942, 1943, 1955, 0, 1955, 0, 2364, + 0, 1941, 2359, 1978, 1978, 1978, 2033, 1955, 2361, 1958, + 0, 1942, 0, 0, 0, 2374, 0, 2375, 1943, 1952, + 1959, 1957, 1957, 1957, 1957, 1957, 1957, 1965, 2364, 1943, + 1958, 0, 1978, 1960, 2379, 2380, 1955, 2387, 2033, 2033, + 2033, 2033, 2033, 2033, 2374, 1960, 2375, 1959, 1967, 2388, + 2389, 1952, 1952, 1952, 1952, 1952, 1952, 2032, 0, 1958, + 1967, 1978, 1966, 2379, 2380, 0, 2387, 0, 1955, 1955, + + 1955, 1955, 1955, 1955, 1960, 1976, 1959, 0, 2388, 2389, + 0, 1981, 1958, 1958, 1958, 1958, 1958, 1958, 1966, 1967, + 1968, 1976, 1978, 1959, 1959, 1959, 1959, 1959, 1959, 0, + 1965, 1965, 1965, 1965, 1965, 1965, 1960, 1960, 1960, 1960, + 1960, 1960, 0, 2390, 2395, 1968, 1975, 1966, 0, 0, + 1976, 1967, 1967, 1967, 1967, 1967, 1967, 1988, 2032, 2032, + 2032, 2032, 2032, 2032, 0, 1966, 1966, 1966, 1966, 1966, + 1966, 1975, 2390, 2395, 1968, 0, 0, 2025, 1976, 1976, + 1976, 1976, 1976, 1976, 1981, 1981, 1981, 1981, 1981, 1981, + 0, 0, 0, 1968, 1968, 1968, 1968, 1968, 1968, 2025, + + 1975, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, + 1995, 1995, 1995, 2029, 2029, 2029, 2030, 2034, 0, 1975, + 1975, 1975, 1975, 1975, 1975, 0, 0, 0, 2025, 0, + 1988, 1988, 1988, 1988, 1988, 1988, 0, 0, 2399, 1995, + 2035, 2402, 2029, 2403, 2405, 0, 2034, 2036, 0, 0, + 2025, 2025, 2025, 2025, 2025, 2025, 2049, 2037, 2036, 2313, + 2313, 2313, 0, 0, 0, 2038, 2035, 2399, 1995, 2037, + 2402, 2029, 2403, 2405, 2034, 2034, 2034, 2034, 2034, 2034, + 2406, 2408, 2193, 2193, 2193, 2049, 0, 2036, 0, 2030, + 2030, 2030, 2030, 2030, 2030, 2035, 0, 2193, 2037, 1995, + + 2038, 0, 2029, 2049, 2049, 2049, 2049, 2049, 2049, 2406, + 2408, 0, 0, 2035, 2035, 2035, 2035, 2035, 2035, 0, + 2036, 2036, 2036, 2036, 2036, 2036, 2315, 2315, 2315, 2411, + 2037, 2037, 2037, 2037, 2037, 2037, 0, 0, 2038, 2038, + 2038, 2038, 2038, 2038, 2050, 2050, 2050, 2410, 2313, 2050, + 2052, 2052, 2052, 0, 2412, 2052, 2410, 2050, 2411, 2053, + 2053, 2053, 0, 2052, 2053, 2054, 2054, 2054, 0, 2050, + 2054, 2193, 2053, 2413, 2414, 2052, 2410, 2050, 2054, 0, + 2055, 2055, 2055, 2412, 2053, 2055, 2056, 2056, 2056, 0, + 2054, 2056, 0, 2055, 0, 2057, 2057, 2057, 2050, 2056, + + 2057, 2416, 2413, 2414, 2052, 2055, 2050, 2417, 2057, 2419, + 0, 2056, 0, 2053, 2420, 2315, 2058, 2058, 2058, 2054, + 2057, 2058, 2060, 2060, 2060, 0, 2422, 2060, 2056, 2058, + 2416, 0, 2423, 2050, 2055, 2060, 2417, 0, 2419, 2052, + 2056, 2058, 0, 2420, 2369, 2424, 2369, 2060, 2053, 2057, + 0, 2204, 2204, 2204, 2054, 2422, 2369, 2056, 2061, 2061, + 2061, 2423, 0, 2061, 0, 0, 2204, 0, 2425, 2055, + 2058, 2061, 2426, 2057, 2424, 2056, 2060, 2062, 2062, 2062, + 0, 0, 2062, 2061, 2057, 2369, 2372, 0, 2372, 0, + 2062, 2063, 2063, 2063, 2058, 0, 2063, 2425, 2372, 2079, + + 0, 2426, 2062, 2067, 2063, 2058, 2437, 0, 2064, 2064, + 2064, 2060, 2061, 2064, 2418, 2418, 2063, 2065, 2065, 2065, + 0, 2064, 2065, 0, 2066, 2066, 2066, 2372, 0, 2066, + 2065, 2062, 2067, 2064, 2069, 2437, 2061, 2066, 2438, 2065, + 2204, 2070, 2065, 2418, 2418, 2063, 2074, 2061, 2074, 2066, + 0, 2067, 2067, 2067, 2067, 2067, 2067, 2080, 2074, 2083, + 2083, 2083, 2064, 2069, 0, 2081, 2062, 2438, 2065, 2063, + 2070, 2065, 2079, 2079, 2079, 2079, 2079, 2079, 2066, 2086, + 2063, 2069, 2069, 2069, 2069, 2069, 2069, 2074, 2083, 2070, + 2070, 2070, 2070, 2070, 2070, 0, 2077, 2064, 2077, 2212, + + 2212, 2212, 2066, 2087, 0, 0, 2065, 0, 2077, 0, + 0, 0, 0, 2066, 2212, 0, 2439, 2083, 2440, 2074, + 2074, 2074, 2074, 2074, 2074, 0, 0, 2318, 2318, 2318, + 2080, 2080, 2080, 2080, 2080, 2080, 2095, 2077, 2081, 2081, + 2081, 2081, 2081, 2081, 2088, 2439, 2441, 2440, 2083, 2255, + 2255, 2255, 2086, 2086, 2086, 2086, 2086, 2086, 2450, 2096, + 2088, 0, 2451, 2095, 2255, 2090, 2090, 2090, 0, 2077, + 2077, 2077, 2077, 2077, 2077, 2441, 2087, 2087, 2087, 2087, + 2087, 2087, 2376, 2376, 2376, 0, 2096, 2450, 2212, 2088, + 2151, 2451, 2095, 0, 2090, 2106, 2106, 2106, 2112, 2112, + + 2112, 0, 2134, 2134, 2134, 2378, 2378, 2378, 0, 2095, + 2095, 2095, 2095, 2095, 2095, 2096, 2318, 2088, 2088, 2088, + 2088, 2088, 2088, 2090, 2106, 0, 2134, 2112, 2456, 2134, + 2153, 0, 2096, 2096, 2096, 2096, 2096, 2096, 2255, 2145, + 2382, 2382, 2382, 2134, 2457, 0, 2147, 2147, 2147, 0, + 2391, 2391, 2391, 2106, 2090, 2134, 2112, 2456, 2134, 2153, + 2145, 2151, 2151, 2151, 2151, 2151, 2151, 2460, 2463, 0, + 0, 2376, 2134, 2457, 2154, 2147, 2464, 2153, 2153, 2153, + 2153, 2153, 2153, 2155, 2106, 0, 0, 2112, 0, 2145, + 2152, 2134, 2140, 2156, 2378, 0, 2460, 2463, 2140, 2157, + + 0, 2154, 2140, 2140, 2147, 2464, 0, 2140, 2140, 2140, + 0, 2140, 2145, 2145, 2145, 2145, 2145, 2145, 0, 2152, + 0, 2140, 2270, 2270, 2270, 2157, 2465, 2140, 0, 2382, + 2154, 2140, 2140, 2468, 0, 2147, 2140, 2140, 2140, 2391, + 2140, 2152, 2152, 2152, 2152, 2152, 2152, 2154, 2154, 2154, + 2154, 2154, 2154, 2472, 2157, 2465, 2155, 2155, 2155, 2155, + 2155, 2155, 2468, 2270, 0, 0, 2156, 2156, 2156, 2156, + 2156, 2156, 2157, 2157, 2157, 2157, 2157, 2157, 2171, 2171, + 2171, 2473, 2472, 2171, 2172, 2172, 2172, 2476, 0, 2172, + 0, 2171, 2270, 2173, 2173, 2173, 0, 2172, 2173, 2174, + + 2174, 2174, 0, 2171, 2174, 2478, 2173, 0, 0, 2172, + 2473, 2270, 2174, 2479, 2480, 2173, 2476, 2183, 2173, 2183, + 2175, 2175, 2175, 2481, 2174, 2175, 2176, 2176, 2176, 2183, + 0, 2176, 2171, 2175, 2478, 2177, 2177, 2177, 2172, 2176, + 2177, 0, 2479, 2480, 2173, 2175, 0, 2173, 2177, 2482, + 0, 2176, 2481, 2174, 2484, 0, 2485, 2486, 2183, 2186, + 2177, 2186, 0, 0, 0, 0, 2199, 2171, 2177, 0, + 2178, 2186, 0, 2172, 2175, 2192, 2487, 2174, 2482, 2180, + 2176, 2488, 2173, 2484, 2254, 2485, 2486, 0, 2174, 2177, + 2183, 2183, 2183, 2183, 2183, 2183, 0, 2177, 2175, 2178, + + 2186, 2199, 2192, 0, 2176, 2487, 2200, 0, 2180, 2175, + 2488, 0, 0, 0, 0, 2176, 2178, 2178, 2178, 2178, + 2178, 2178, 0, 2260, 2177, 2180, 2180, 2180, 2180, 2180, + 2180, 2192, 2186, 2186, 2186, 2186, 2186, 2186, 2200, 2199, + 2199, 2199, 2199, 2199, 2199, 2205, 2205, 2205, 2192, 2192, + 2192, 2192, 2192, 2192, 0, 0, 2247, 2254, 2254, 2254, + 2254, 2254, 2254, 2261, 2247, 2263, 0, 2200, 0, 0, + 0, 2247, 2262, 2263, 2205, 2264, 2298, 2298, 2298, 2200, + 2200, 2200, 2200, 2200, 2200, 2247, 2277, 2264, 2489, 0, + 0, 2298, 2261, 2247, 2260, 2260, 2260, 2260, 2260, 2260, + + 2247, 2262, 2263, 2205, 0, 2396, 2396, 2396, 2261, 2261, + 2261, 2261, 2261, 2261, 0, 0, 2264, 2489, 2262, 2262, + 2262, 2262, 2262, 2262, 2277, 2277, 2277, 2277, 2277, 2277, + 0, 2275, 2275, 2275, 2205, 2278, 2275, 2490, 2263, 2263, + 2263, 2263, 2263, 2263, 2275, 2400, 2400, 2400, 2264, 2264, + 2264, 2264, 2264, 2264, 2354, 2289, 2275, 2276, 2276, 2276, + 2491, 0, 2276, 2492, 2275, 2298, 2490, 2281, 0, 2281, + 2276, 0, 0, 2278, 2278, 2278, 2278, 2278, 2278, 2281, + 0, 2494, 2276, 2354, 2284, 2275, 2284, 2289, 0, 2491, + 2294, 0, 2492, 2275, 2396, 0, 2284, 2295, 2495, 0, + + 2354, 2354, 2354, 2354, 2354, 2354, 2294, 0, 2281, 2353, + 2494, 2276, 2393, 2393, 2393, 0, 2289, 2320, 2320, 2320, + 2275, 0, 2430, 2430, 2430, 2284, 2393, 2495, 2289, 2289, + 2289, 2289, 2289, 2289, 2400, 2294, 2332, 2332, 2332, 0, + 2281, 2281, 2281, 2281, 2281, 2281, 2276, 2325, 2325, 2325, + 2320, 0, 2322, 2322, 2322, 0, 0, 2284, 2284, 2284, + 2284, 2284, 2284, 2294, 2294, 2294, 2294, 2294, 2294, 2355, + 2295, 2295, 2295, 2295, 2295, 2295, 2332, 0, 2322, 2320, + 2353, 2353, 2353, 2353, 2353, 2353, 2356, 0, 2325, 2365, + 2365, 2365, 2322, 2357, 2365, 2366, 0, 2496, 2355, 0, + + 2497, 2393, 2365, 0, 0, 2332, 2320, 2322, 2370, 0, + 2370, 2430, 0, 2356, 2365, 2367, 2377, 2325, 2357, 2499, + 2370, 2322, 2507, 0, 2366, 2332, 2496, 0, 2432, 2497, + 2355, 2355, 2355, 2355, 2355, 2355, 2325, 0, 2373, 0, + 2373, 2322, 2356, 2365, 2367, 0, 0, 2357, 2499, 2370, + 2373, 2507, 2366, 2366, 2366, 2366, 2366, 2366, 0, 2356, + 2356, 2356, 2356, 2356, 2356, 0, 2357, 2357, 2357, 2357, + 2357, 2357, 2367, 2367, 2367, 2367, 2367, 2367, 2365, 2373, + 0, 2370, 2370, 2370, 2370, 2370, 2370, 2381, 2434, 2377, + 2377, 2377, 2377, 2377, 2377, 2384, 2384, 2384, 2381, 2432, + + 2432, 2432, 2432, 2432, 2432, 2433, 2433, 2433, 2433, 2433, + 2433, 2373, 2373, 2373, 2373, 2373, 2373, 2434, 2435, 0, + 0, 2508, 2510, 2442, 2436, 2520, 2521, 2381, 2384, 2452, + 2452, 2452, 2454, 2454, 2454, 0, 2445, 0, 2445, 0, + 2434, 2434, 2434, 2434, 2434, 2434, 2435, 2443, 2445, 2458, + 2508, 2510, 2442, 2436, 2520, 2521, 0, 2384, 0, 0, + 2381, 2381, 2381, 2381, 2381, 2381, 2446, 2448, 2446, 2448, + 2462, 2462, 2462, 0, 2524, 2435, 2443, 2445, 2446, 2448, + 0, 0, 2436, 0, 2384, 2442, 2442, 2442, 2442, 2442, + 2442, 2435, 2435, 2435, 2435, 2435, 2435, 2436, 2436, 2436, + + 2436, 2436, 2436, 2524, 2449, 0, 2449, 2446, 2448, 2443, + 2443, 2443, 2443, 2443, 2443, 0, 2449, 2503, 2452, 0, + 0, 2454, 2458, 2458, 2458, 2458, 2458, 2458, 2466, 2466, + 2466, 2504, 2469, 2469, 2469, 2470, 2470, 2470, 2525, 2446, + 2446, 2446, 2446, 2446, 2446, 2449, 2469, 2474, 2474, 2474, + 2500, 2500, 2500, 0, 2527, 2527, 2527, 2505, 0, 2462, + 2504, 2512, 2512, 2512, 2512, 2512, 2512, 2525, 0, 0, + 0, 2470, 2506, 2515, 2526, 2515, 2470, 2449, 2449, 2449, + 2449, 2449, 2449, 2505, 2506, 2515, 2531, 2474, 2503, 2503, + 2503, 2503, 2503, 2503, 2504, 2504, 2504, 2504, 2504, 2504, + + 2470, 0, 0, 2526, 0, 2470, 2513, 2513, 2513, 2513, + 2513, 2513, 2505, 2506, 2515, 2531, 2474, 2466, 2534, 2534, + 2534, 2469, 2533, 0, 2470, 2516, 2518, 2516, 2518, 2535, + 2505, 2505, 2505, 2505, 2505, 2505, 2474, 2516, 2518, 2500, + 2519, 2536, 2519, 2527, 2539, 2506, 2506, 2506, 2506, 2506, + 2506, 2533, 2519, 2540, 2534, 2541, 2543, 2544, 2535, 2534, + 2545, 2546, 2547, 2548, 2549, 2551, 2516, 2518, 2552, 2565, + 2536, 0, 0, 2539, 0, 2553, 2554, 2555, 2567, 2556, + 2557, 2519, 2540, 2534, 2541, 2543, 2544, 0, 2534, 2545, + 2546, 2547, 2548, 2549, 2551, 2558, 2559, 2552, 2516, 2516, + + 2516, 2516, 2516, 2516, 2553, 2554, 2555, 2534, 2556, 2557, + 2561, 0, 2568, 2519, 2519, 2519, 2519, 2519, 2519, 2566, + 2570, 2571, 0, 0, 2558, 2559, 2573, 0, 2573, 2578, + 2596, 2596, 2596, 0, 2574, 0, 2574, 2568, 2573, 2561, + 2565, 2565, 2565, 2565, 2565, 2565, 2574, 2579, 2566, 2570, + 2571, 2567, 2567, 2567, 2567, 2567, 2567, 2576, 2578, 2576, + 2566, 2566, 2566, 2566, 2566, 2566, 2568, 2573, 2580, 2576, + 2581, 2582, 2577, 2584, 2577, 2574, 2579, 2587, 2614, 2614, + 2614, 2614, 2614, 2614, 2577, 2568, 2568, 2568, 2568, 2568, + 2568, 2588, 2592, 2593, 2594, 2595, 2598, 2580, 2576, 2581, + + 2582, 2599, 2584, 2600, 2601, 2603, 2587, 2574, 2574, 2574, + 2574, 2574, 2574, 2577, 2604, 2606, 2613, 0, 0, 2596, + 2588, 2592, 2593, 2594, 2595, 2598, 2608, 2610, 2611, 2615, + 2599, 2617, 2600, 2601, 2603, 2625, 2626, 2629, 0, 2619, + 2620, 2619, 2620, 2604, 2606, 2577, 2577, 2577, 2577, 2577, + 2577, 2619, 2620, 2633, 2634, 2608, 2610, 2611, 0, 2622, + 2617, 2622, 0, 0, 2625, 2626, 2629, 2623, 2635, 2623, + 2636, 2622, 2637, 2639, 2639, 2639, 2641, 2641, 2641, 2623, + 2619, 2620, 2633, 2634, 2670, 2670, 2670, 2613, 2613, 2613, + 2613, 2613, 2613, 2638, 2640, 2643, 2644, 2635, 2646, 2636, + + 2622, 2637, 2615, 2615, 2615, 2615, 2615, 2615, 2623, 2647, + 2648, 0, 0, 2620, 2620, 2620, 2620, 2620, 2620, 2650, + 2651, 2662, 2638, 2640, 2643, 2644, 2664, 2646, 2654, 2654, + 2654, 2654, 2654, 2654, 2657, 2658, 2657, 2658, 2647, 2648, + 2623, 2623, 2623, 2623, 2623, 2623, 2657, 2658, 2650, 2651, + 2662, 2660, 2661, 2660, 2661, 2664, 2666, 2667, 2668, 2669, + 2674, 2678, 2639, 2660, 2661, 2641, 2672, 2672, 2672, 2677, + 2677, 2677, 2681, 2670, 2684, 2657, 2658, 0, 0, 2686, + 0, 2686, 0, 0, 0, 2666, 2667, 2668, 2669, 2674, + 2678, 2686, 2660, 2661, 2687, 2689, 2687, 2689, 0, 0, + + 0, 2681, 2690, 2684, 2690, 2692, 2687, 2689, 2658, 2658, + 2658, 2658, 2658, 2658, 2690, 2693, 2694, 2695, 2696, 2697, + 2686, 2699, 2702, 2703, 2704, 2661, 2661, 2661, 2661, 2661, + 2661, 2710, 0, 2712, 2692, 2687, 2689, 2700, 2700, 2700, + 0, 0, 0, 2690, 2693, 2694, 2695, 2696, 2697, 0, + 2699, 2702, 2703, 2704, 2706, 2672, 2706, 2713, 2677, 0, + 2710, 2707, 2712, 2707, 2700, 0, 2706, 2687, 2687, 2687, + 2687, 2687, 2687, 2707, 2714, 2690, 2690, 2690, 2690, 2690, + 2690, 2715, 2709, 2716, 2709, 2717, 2713, 2719, 2711, 2711, + 2711, 2721, 2729, 2700, 2709, 2706, 2711, 0, 2732, 2723, + + 2733, 2723, 2707, 2714, 2734, 2725, 2725, 2725, 0, 0, + 2715, 2723, 2716, 2725, 2717, 2736, 2719, 2737, 2742, 2743, + 2721, 2729, 2744, 2709, 2745, 2746, 2700, 2732, 2749, 2733, + 2747, 2747, 2747, 2734, 2707, 2707, 2707, 2707, 2707, 2707, + 2723, 2751, 2752, 2753, 2736, 2758, 2737, 2742, 2743, 2759, + 0, 2744, 2760, 2745, 2746, 2761, 2764, 2749, 2755, 2755, + 2755, 2756, 2756, 2756, 2762, 2762, 2762, 0, 2766, 2768, + 2751, 2752, 2753, 0, 2758, 2769, 2771, 2711, 2759, 2711, + 2773, 2760, 2775, 2776, 2761, 2764, 2767, 2767, 2767, 2774, + 2774, 2774, 2777, 2778, 2725, 2779, 2725, 2766, 2768, 2780, + + 2782, 2783, 2756, 2784, 2769, 2771, 2785, 2785, 2785, 2773, + 0, 2775, 2776, 0, 0, 0, 0, 0, 0, 2747, + 0, 2777, 2778, 0, 2779, 0, 0, 0, 2780, 2782, + 2783, 2756, 2784, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2755, 0, 0, + 2756, 0, 0, 2762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2767, 0, 0, 2774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2588, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2595, 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, - 2597, 2597, 2597, 2597, 2597, 2598, 2598, 2598, 2598, 2598, - 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2599, 2599, - 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, - - 2599, 2600, 2600, 2600, 2600, 2600, 2600, 2600, 2600, 2600, - 2600, 2600, 2600, 2600, 2601, 2601, 2601, 2601, 2601, 2601, - 2601, 2601, 2601, 2601, 2601, 2601, 2601, 2602, 2602, 2602, - 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, - 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, - 2603, 2603, 2603, 2604, 2604, 2604, 2604, 2604, 2604, 2604, - 2604, 2604, 2604, 2604, 2604, 2604, 2605, 2605, 2605, 2605, - 2605, 2605, 2605, 2605, 2605, 2605, 2605, 2605, 2605, 2606, - 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, - 2606, 2606, 2607, 2607, 2607, 2607, 2607, 2607, 2607, 2607, - - 2607, 2607, 2607, 2607, 2607, 2608, 2608, 2608, 2608, 2608, - 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2609, 2609, - 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, - 2609, 2610, 2610, 2610, 2610, 2610, 2610, 2610, 2610, 2610, - 2610, 2610, 2610, 2610, 2611, 2611, 2611, 2611, 2611, 2611, - 2611, 2611, 2611, 2611, 2611, 2611, 2611, 2612, 2612, 2612, - 2612, 2612, 2612, 2612, 2612, 2612, 2612, 2612, 2612, 2612, - 2613, 2613, 2613, 2614, 2614, 0, 2614, 2614, 2614, 2614, - 2614, 2614, 2614, 2614, 2614, 2614, 2615, 2615, 2616, 2616, - 2616, 2617, 2617, 0, 0, 0, 0, 0, 0, 2617, - - 2618, 2618, 2619, 2619, 0, 2619, 2619, 0, 2619, 2619, - 2619, 2620, 2620, 2620, 2621, 2621, 2622, 2622, 2622, 2623, - 2623, 0, 0, 0, 0, 0, 0, 2623, 2624, 0, - 0, 2624, 2625, 0, 0, 2625, 2626, 2626, 2626, 2626, - 2626, 2626, 0, 2626, 2626, 2626, 2626, 0, 2626, 2627, - 2627, 2627, 2627, 2627, 2627, 2627, 2627, 2627, 2627, 2627, - 2627, 2627, 2628, 2628, 2628, 2628, 2628, 2628, 0, 2628, - 2628, 2628, 2628, 0, 2628, 2629, 2629, 2629, 2629, 2629, - 2629, 2629, 2629, 2629, 2629, 2629, 2629, 2629, 2630, 2630, - 2630, 2630, 2630, 2630, 2630, 2630, 2630, 2630, 2630, 2630, - - 2630, 2631, 2631, 2631, 2631, 2631, 2631, 2631, 2631, 2631, - 2631, 2631, 2631, 2632, 2632, 2632, 2632, 2632, 2632, 2632, - 2632, 2632, 2632, 2632, 2632, 2633, 2633, 0, 2633, 2633, - 2633, 2633, 2633, 2633, 2633, 2633, 2633, 2633, 2634, 2634, - 2635, 2635, 0, 2635, 2635, 2635, 2635, 2635, 2635, 2635, - 2635, 2635, 2635, 2636, 2636, 0, 2636, 2636, 2636, 2636, - 2636, 2636, 2636, 2636, 2636, 2636, 2637, 2637, 2638, 2638, - 2639, 2639, 0, 2639, 2639, 2639, 2639, 2639, 2639, 2639, - 2639, 2639, 2639, 2640, 2640, 2641, 2641, 0, 2641, 2641, - 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2642, 2642, - - 0, 2642, 2642, 2642, 2642, 2642, 2642, 2642, 2642, 2642, - 2642, 2643, 2643, 2643, 2644, 2644, 0, 2644, 2644, 2644, - 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2645, 2645, 0, - 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, - 2646, 2646, 2647, 2647, 2647, 2648, 2648, 0, 0, 0, - 0, 0, 0, 2648, 2649, 2649, 2650, 2650, 0, 2650, - 2650, 0, 2650, 2650, 2650, 2651, 2651, 2651, 2652, 2652, - 2653, 2653, 2653, 2654, 2654, 0, 0, 0, 0, 0, - 0, 2654, 2655, 0, 0, 2655, 2656, 0, 0, 2656, - 2657, 2657, 2657, 2657, 2657, 2657, 0, 2657, 2657, 2657, - - 2657, 0, 2657, 2658, 2658, 0, 2658, 2658, 2658, 2658, - 2658, 2658, 2658, 2658, 2658, 2658, 2659, 2659, 2659, 2659, - 2659, 2659, 0, 2659, 2659, 2659, 2659, 0, 2659, 2660, - 2660, 0, 2660, 2660, 2660, 2660, 2660, 2660, 2660, 2660, - 2660, 2660, 2661, 2661, 0, 2661, 2661, 2661, 2661, 2661, - 2661, 2661, 2661, 2661, 2661, 2662, 2662, 2662, 2662, 2662, - 2662, 2662, 2662, 2662, 2662, 2662, 2662, 2663, 2663, 2663, - 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2664, - 2664, 0, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, - 2664, 2664, 2665, 2665, 0, 2665, 2665, 2665, 2665, 2665, - - 2665, 2665, 2665, 2665, 2665, 2666, 2666, 2667, 2667, 0, - 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, - 2668, 2668, 0, 2668, 2668, 2668, 2668, 2668, 2668, 2668, - 2668, 2668, 2668, 2669, 2669, 0, 2669, 2669, 2669, 2669, - 2669, 2669, 2669, 2669, 2669, 2669, 2670, 2670, 2671, 2671, - 2672, 2672, 0, 2672, 2672, 2672, 2672, 2672, 2672, 2672, - 2672, 2672, 2672, 2673, 2673, 0, 2673, 2673, 2673, 2673, - 2673, 2673, 2673, 2673, 2673, 2673, 2674, 2674, 2675, 2675, - 0, 2675, 2675, 2675, 2675, 2675, 2675, 2675, 2675, 2675, - 2675, 2676, 2676, 0, 2676, 2676, 2676, 2676, 2676, 2676, - - 2676, 2676, 2676, 2676, 2677, 2677, 0, 2677, 2677, 2677, - 2677, 2677, 2677, 2677, 2677, 2677, 2677, 2678, 2678, 2678, - 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, - 2679, 2679, 2680, 2680, 2681, 2681, 0, 0, 0, 2681, - 2682, 2682, 2683, 0, 0, 2683, 2684, 0, 0, 2684, - 2685, 2685, 0, 2685, 2685, 2685, 2685, 2685, 2685, 2685, - 2685, 2685, 2685, 2686, 2686, 0, 2686, 2686, 2686, 2686, - 2686, 2686, 2686, 2686, 2686, 2686, 2687, 2687, 0, 2687, - 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2688, - 2688, 0, 2688, 2688, 2688, 2688, 2688, 2688, 2688, 2688, - - 2688, 2688, 2689, 2689, 2689, 2689, 2689, 2689, 2689, 2689, - 2689, 2689, 2689, 2689, 2689, 2690, 2690, 2691, 2691, 2691, - 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, - 2692, 2692, 0, 2692, 2692, 2692, 2692, 2692, 2692, 2692, - 2692, 2692, 2692, 2693, 2693, 2693, 2693, 2693, 2693, 2693, - 2693, 2693, 2693, 2693, 2693, 2693, 2694, 2694, 2695, 2695, - 2696, 2696, 0, 2696, 2696, 2696, 2696, 2696, 2696, 2696, - 2696, 2696, 2696, 2697, 2697, 2697, 2697, 2697, 2697, 2697, - 2697, 2697, 2697, 2697, 2697, 2697, 2698, 2698, 2699, 2699, - 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, - - 2699, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, - 2700, 2700, 2700, 2700, 2701, 2701, 2701, 2702, 2702, 0, - 2702, 2702, 2702, 2702, 2702, 2702, 2702, 2702, 2702, 2702, - 2703, 2703, 0, 2703, 2703, 2703, 2703, 2703, 2703, 2703, - 2703, 2703, 2703, 2704, 2704, 2704, 2705, 2705, 0, 2705, - 2705, 2705, 2705, 2705, 2705, 2705, 2705, 2705, 2705, 2706, - 2706, 2707, 2707, 0, 0, 0, 0, 0, 0, 2707, - 2708, 2708, 2709, 2709, 0, 0, 0, 2709, 2709, 2710, - 2710, 2710, 2711, 2711, 2711, 2712, 2712, 2713, 2713, 0, - 0, 0, 0, 0, 0, 2713, 2714, 0, 0, 2714, - - 2715, 0, 0, 2715, 2716, 2716, 2716, 2716, 2716, 2716, - 2716, 2716, 2716, 2716, 2716, 2716, 2716, 2717, 2717, 2717, - 2717, 2717, 2717, 2717, 2717, 2717, 2717, 2717, 2717, 2717, - 2718, 2718, 2718, 2718, 2718, 2718, 2718, 2718, 2718, 2718, - 2718, 2718, 2718, 2719, 2719, 0, 2719, 2719, 2719, 2719, - 2719, 2719, 2719, 2719, 2719, 2719, 2720, 2720, 0, 2720, - 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2721, - 2721, 0, 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, - 2721, 2721, 2722, 2722, 2723, 2723, 0, 2723, 2723, 2723, - 2723, 2723, 2723, 2723, 2723, 2723, 2723, 2724, 2724, 0, - - 2724, 2724, 2724, 2724, 2724, 2724, 2724, 2724, 2724, 2724, - 2725, 2725, 0, 2725, 2725, 2725, 2725, 2725, 2725, 2725, - 2725, 2725, 2725, 2726, 2726, 0, 2726, 2726, 2726, 2726, - 2726, 2726, 2726, 2726, 2726, 2726, 2727, 2727, 2728, 2728, - 2729, 2729, 0, 2729, 2729, 2729, 2729, 2729, 2729, 2729, - 2729, 2729, 2729, 2730, 2730, 0, 2730, 2730, 2730, 2730, - 2730, 2730, 2730, 2730, 2730, 2730, 2731, 2731, 0, 2731, - 2731, 2731, 2731, 2731, 2731, 2731, 2731, 2731, 2731, 2732, - 2732, 2733, 2733, 0, 2733, 2733, 2733, 2733, 2733, 2733, - 2733, 2733, 2733, 2733, 2734, 2734, 0, 2734, 2734, 2734, - - 2734, 2734, 2734, 2734, 2734, 2734, 2734, 2735, 2735, 0, - 2735, 2735, 2735, 2735, 2735, 2735, 2735, 2735, 2735, 2735, - 2736, 2736, 0, 2736, 2736, 2737, 2737, 2738, 2738, 0, - 0, 0, 2738, 2739, 2739, 2740, 0, 0, 2740, 2741, - 0, 0, 2741, 2742, 2742, 0, 2742, 2742, 2742, 2742, - 2742, 2742, 2742, 2742, 2742, 2742, 2743, 2743, 0, 2743, - 2743, 2743, 2743, 2743, 2743, 2743, 2743, 2743, 2743, 2744, - 2744, 0, 2744, 2744, 2744, 2744, 2744, 2744, 2744, 2744, - 2744, 2744, 2745, 2745, 0, 2745, 2745, 2745, 2745, 2745, - 2745, 2745, 2745, 2745, 2745, 2746, 2746, 2747, 2747, 0, - - 2747, 2747, 2747, 2747, 2747, 2747, 2747, 2747, 2747, 2747, - 2748, 2748, 0, 2748, 2748, 2748, 2748, 2748, 2748, 2748, - 2748, 2748, 2748, 2749, 2749, 2750, 2750, 2750, 2750, 2750, - 2750, 2750, 2750, 2750, 2750, 2750, 2750, 2750, 2751, 2751, - 2751, 2751, 2751, 2751, 2751, 2751, 2751, 2751, 2751, 2751, - 2751, 2752, 2752, 2752, 2752, 2752, 2752, 2752, 2752, 2752, - 2752, 2752, 2752, 2752, 2753, 2753, 2753, 2753, 2753, 2753, - 2753, 2753, 2753, 2753, 2753, 2753, 2753, 2754, 2754, 2754, - 2754, 2754, 2754, 2754, 2754, 2754, 2754, 2754, 2754, 2754, - 2755, 2755, 2755, 2755, 2755, 2755, 2755, 2755, 2755, 2755, - - 2755, 2755, 2755, 2756, 2756, 2756, 2756, 2756, 2756, 2756, - 2756, 2756, 2756, 2756, 2756, 2756, 2757, 2757, 2757, 2757, - 2757, 2757, 2757, 2757, 2757, 2757, 2757, 2757, 2757, 2758, - 2758, 2758, 2758, 2758, 2758, 2758, 2758, 2758, 2758, 2758, - 2758, 2758, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596 + 0, 0, 0, 0, 0, 2785, 2787, 2787, 2787, 2787, + + 2787, 2787, 2787, 2787, 2787, 2787, 2787, 2787, 2788, 2788, + 2788, 2788, 2788, 2788, 2788, 2788, 2788, 2788, 2788, 2788, + 2789, 2789, 2789, 2789, 2789, 2789, 2789, 2789, 2789, 2789, + 2789, 2789, 2790, 2790, 2790, 2790, 2790, 2790, 2790, 2790, + 2790, 2790, 2790, 2790, 2791, 2791, 2791, 2791, 2791, 2791, + 2791, 2791, 2791, 2791, 2791, 2791, 2792, 2792, 2792, 2792, + 2792, 2792, 2792, 2792, 2792, 2792, 2792, 2792, 2793, 2793, + 2793, 2793, 2793, 2793, 2793, 2793, 2793, 2793, 2793, 2793, + 2794, 2794, 2794, 2794, 2794, 2794, 2794, 2794, 2794, 2794, + 2794, 2794, 2795, 2795, 2795, 2795, 2795, 2795, 2795, 2795, + + 2795, 2795, 2795, 2795, 2796, 2796, 2796, 2796, 2796, 2796, + 2796, 2796, 2796, 2796, 2796, 2796, 2797, 2797, 2797, 2797, + 2797, 2797, 2797, 2797, 2797, 2797, 2797, 2797, 2798, 2798, + 2798, 2798, 2798, 2798, 2798, 2798, 2798, 2798, 2798, 2798, + 2799, 2799, 2799, 2799, 2799, 2799, 2799, 2799, 2799, 2799, + 2799, 2799, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800, + 2800, 2800, 2800, 2800, 2801, 2801, 2801, 2801, 2801, 2801, + 2801, 2801, 2801, 2801, 2801, 2801, 2802, 2802, 2802, 2802, + 2802, 2802, 2802, 2802, 2802, 2802, 2802, 2802, 2803, 2803, + 2803, 2804, 2804, 0, 2804, 2804, 2804, 2804, 2804, 2804, + + 2804, 2804, 2804, 2805, 2805, 2806, 2806, 2806, 2807, 2807, + 0, 0, 0, 0, 0, 2807, 2808, 2808, 2809, 2809, + 0, 2809, 2809, 0, 2809, 2809, 2810, 2810, 2810, 2811, + 2811, 2812, 2812, 2812, 2813, 2813, 0, 0, 0, 0, + 0, 2813, 2814, 0, 2814, 2815, 0, 2815, 2816, 2816, + 2816, 2816, 2816, 2816, 0, 2816, 2816, 2816, 0, 2816, + 2817, 2817, 2817, 2817, 2817, 2817, 2817, 2817, 2817, 2817, + 2817, 2817, 2818, 2818, 2818, 2818, 2818, 2818, 0, 2818, + 2818, 2818, 0, 2818, 2819, 2819, 2819, 2819, 2819, 2819, + 2819, 2819, 2819, 2819, 2819, 2819, 2820, 2820, 2820, 2820, + + 2820, 2820, 2820, 2820, 2820, 2820, 2820, 2820, 2821, 2821, + 2821, 2821, 2821, 2821, 2821, 2821, 2821, 2821, 2821, 2822, + 2822, 2822, 2822, 2822, 2822, 2822, 2822, 2822, 2822, 2822, + 2823, 2823, 0, 2823, 2823, 2823, 2823, 2823, 2823, 2823, + 2823, 2823, 2824, 2824, 2825, 2825, 0, 2825, 2825, 2825, + 2825, 2825, 2825, 2825, 2825, 2825, 2826, 2826, 0, 2826, + 2826, 2826, 2826, 2826, 2826, 2826, 2826, 2826, 2827, 2827, + 2828, 2828, 2829, 2829, 0, 2829, 2829, 2829, 2829, 2829, + 2829, 2829, 2829, 2829, 2830, 2830, 2831, 2831, 0, 2831, + 2831, 2831, 2831, 2831, 2831, 2831, 2831, 2831, 2832, 2832, + + 0, 2832, 2832, 2832, 2832, 2832, 2832, 2832, 2832, 2832, + 2833, 2833, 2833, 2834, 2834, 0, 2834, 2834, 2834, 2834, + 2834, 2834, 2834, 2834, 2834, 2835, 2835, 0, 2835, 2835, + 2835, 2835, 2835, 2835, 2835, 2835, 2835, 2836, 2836, 2837, + 2837, 2837, 2838, 2838, 0, 0, 0, 0, 0, 2838, + 2839, 2839, 2840, 2840, 0, 2840, 2840, 0, 2840, 2840, + 2841, 2841, 2841, 2842, 2842, 2843, 2843, 2843, 2844, 2844, + 0, 0, 0, 0, 0, 2844, 2845, 0, 2845, 2846, + 0, 2846, 2847, 2847, 2847, 2847, 2847, 2847, 0, 2847, + 2847, 2847, 0, 2847, 2848, 2848, 0, 2848, 2848, 2848, + + 2848, 2848, 2848, 2848, 2848, 2848, 2849, 2849, 2849, 2849, + 2849, 2849, 0, 2849, 2849, 2849, 0, 2849, 2850, 2850, + 0, 2850, 2850, 2850, 2850, 2850, 2850, 2850, 2850, 2850, + 2851, 2851, 0, 2851, 2851, 2851, 2851, 2851, 2851, 2851, + 2851, 2851, 2852, 2852, 2852, 2852, 2852, 2852, 2852, 2852, + 2852, 2852, 2852, 2853, 2853, 2853, 2853, 2853, 2853, 2853, + 2853, 2853, 2853, 2853, 2854, 2854, 0, 2854, 2854, 2854, + 2854, 2854, 2854, 2854, 2854, 2854, 2855, 2855, 0, 2855, + 2855, 2855, 2855, 2855, 2855, 2855, 2855, 2855, 2856, 2856, + 2857, 2857, 0, 2857, 2857, 2857, 2857, 2857, 2857, 2857, + + 2857, 2857, 2858, 2858, 0, 2858, 2858, 2858, 2858, 2858, + 2858, 2858, 2858, 2858, 2859, 2859, 0, 2859, 2859, 2859, + 2859, 2859, 2859, 2859, 2859, 2859, 2860, 2860, 2861, 2861, + 2862, 2862, 0, 2862, 2862, 2862, 2862, 2862, 2862, 2862, + 2862, 2862, 2863, 2863, 0, 2863, 2863, 2863, 2863, 2863, + 2863, 2863, 2863, 2863, 2864, 2864, 2865, 2865, 0, 2865, + 2865, 2865, 2865, 2865, 2865, 2865, 2865, 2865, 2866, 2866, + 0, 2866, 2866, 2866, 2866, 2866, 2866, 2866, 2866, 2866, + 2867, 2867, 0, 2867, 2867, 2867, 2867, 2867, 2867, 2867, + 2867, 2867, 2868, 2868, 2868, 2868, 2868, 2868, 2868, 2868, + + 2868, 2868, 2868, 2868, 2869, 2869, 0, 0, 2869, 2870, + 2870, 2871, 2871, 0, 0, 2871, 2872, 2872, 2873, 0, + 2873, 2874, 0, 2874, 2875, 2875, 0, 2875, 2875, 2875, + 2875, 2875, 2875, 2875, 2875, 2875, 2876, 2876, 0, 2876, + 2876, 2876, 2876, 2876, 2876, 2876, 2876, 2876, 2877, 2877, + 0, 2877, 2877, 2877, 2877, 2877, 2877, 2877, 2877, 2877, + 2878, 2878, 0, 2878, 2878, 2878, 2878, 2878, 2878, 2878, + 2878, 2878, 2879, 2879, 2879, 2879, 2879, 2879, 2879, 2879, + 2879, 2879, 2879, 2879, 2880, 2880, 2881, 2881, 2881, 2881, + 2881, 2881, 2881, 2881, 2881, 2881, 2881, 2881, 2882, 2882, + + 0, 2882, 2882, 2882, 2882, 2882, 2882, 2882, 2882, 2882, + 2883, 2883, 2883, 2883, 2883, 2883, 2883, 2883, 2883, 2883, + 2883, 2883, 2884, 2884, 2885, 2885, 2886, 2886, 0, 2886, + 2886, 2886, 2886, 2886, 2886, 2886, 2886, 2886, 2887, 2887, + 2887, 2887, 2887, 2887, 2887, 2887, 2887, 2887, 2887, 2887, + 2888, 2888, 0, 0, 2888, 2889, 2889, 2889, 2889, 2889, + 2889, 2889, 2889, 2889, 2889, 2889, 2889, 2890, 2890, 2890, + 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2891, + 2891, 2891, 2892, 2892, 0, 2892, 2892, 2892, 2892, 2892, + 2892, 2892, 2892, 2892, 2893, 2893, 0, 2893, 2893, 2893, + + 2893, 2893, 2893, 2893, 2893, 2893, 2894, 2894, 2894, 2895, + 2895, 0, 2895, 2895, 2895, 2895, 2895, 2895, 2895, 2895, + 2895, 2896, 2896, 0, 0, 2896, 2897, 2897, 0, 0, + 0, 0, 0, 2897, 2898, 2898, 2899, 2899, 0, 0, + 2899, 2899, 2900, 2900, 2900, 2901, 2901, 2901, 2902, 2902, + 2903, 2903, 0, 0, 0, 0, 0, 2903, 2904, 0, + 2904, 2905, 0, 2905, 2906, 2906, 2906, 2906, 2906, 2906, + 2906, 2906, 2906, 2906, 2906, 2906, 2907, 2907, 2907, 2907, + 2907, 2907, 2907, 2907, 2907, 2907, 2907, 2907, 2908, 2908, + 2908, 2908, 2908, 2908, 2908, 2908, 2908, 2908, 2908, 2908, + + 2909, 2909, 0, 2909, 2909, 2909, 2909, 2909, 2909, 2909, + 2909, 2909, 2910, 2910, 0, 2910, 2910, 2910, 2910, 2910, + 2910, 2910, 2910, 2910, 2911, 2911, 0, 2911, 2911, 2911, + 2911, 2911, 2911, 2911, 2911, 2911, 2912, 2912, 2913, 2913, + 0, 2913, 2913, 2913, 2913, 2913, 2913, 2913, 2913, 2913, + 2914, 2914, 0, 2914, 2914, 2914, 2914, 2914, 2914, 2914, + 2914, 2914, 2915, 2915, 0, 2915, 2915, 2915, 2915, 2915, + 2915, 2915, 2915, 2915, 2916, 2916, 0, 2916, 2916, 2916, + 2916, 2916, 2916, 2916, 2916, 2916, 2917, 2917, 2918, 2918, + 2919, 2919, 0, 2919, 2919, 2919, 2919, 2919, 2919, 2919, + + 2919, 2919, 2920, 2920, 0, 2920, 2920, 2920, 2920, 2920, + 2920, 2920, 2920, 2920, 2921, 2921, 0, 2921, 2921, 2921, + 2921, 2921, 2921, 2921, 2921, 2921, 2922, 2922, 0, 0, + 2922, 2923, 2923, 0, 2923, 2923, 2923, 2923, 2923, 2923, + 2923, 2923, 2923, 2924, 2924, 0, 2924, 2924, 2924, 2924, + 2924, 2924, 2924, 2924, 2924, 2925, 2925, 0, 2925, 2925, + 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2926, 2926, 0, + 0, 2926, 2927, 2927, 2928, 2928, 0, 0, 2928, 2929, + 2929, 2930, 0, 2930, 2931, 0, 2931, 2932, 2932, 0, + 2932, 2932, 2932, 2932, 2932, 2932, 2932, 2932, 2932, 2933, + + 2933, 0, 2933, 2933, 2933, 2933, 2933, 2933, 2933, 2933, + 2933, 2934, 2934, 0, 2934, 2934, 2934, 2934, 2934, 2934, + 2934, 2934, 2934, 2935, 2935, 0, 2935, 2935, 2935, 2935, + 2935, 2935, 2935, 2935, 2935, 2936, 2936, 2937, 2937, 0, + 2937, 2937, 2937, 2937, 2937, 2937, 2937, 2937, 2937, 2938, + 2938, 0, 2938, 2938, 2938, 2938, 2938, 2938, 2938, 2938, + 2938, 2939, 2939, 2940, 2940, 2940, 2940, 2940, 2940, 2940, + 2940, 2940, 2940, 2940, 2940, 2941, 2941, 2941, 2941, 2941, + 2941, 2941, 2941, 2941, 2941, 2941, 2941, 2942, 2942, 2942, + 2942, 2942, 2942, 2942, 2942, 2942, 2942, 2942, 2942, 2943, + + 2943, 2943, 2943, 2943, 2943, 2943, 2943, 2943, 2943, 2943, + 2943, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, + 2944, 2944, 2944, 2945, 2945, 2945, 2945, 2945, 2945, 2945, + 2945, 2945, 2945, 2945, 2945, 2946, 2946, 2946, 2946, 2946, + 2946, 2946, 2946, 2946, 2946, 2946, 2946, 2947, 2947, 2947, + 2947, 2947, 2947, 2947, 2947, 2947, 2947, 2947, 2947, 2948, + 2948, 2948, 2948, 2948, 2948, 2948, 2948, 2948, 2948, 2948, + 2948, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786 } ; /* The intent behind this definition is that it'll catch @@ -5447,10 +5603,13 @@ do {\ + -#line 5455 "ob_proxy_parser_utf8_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +/* binlog relate SQL */ +#line 5614 "ob_proxy_parser_utf8_lex.c" #define INITIAL 0 #define hint 1 @@ -5477,9 +5636,10 @@ do {\ #define prepare 22 #define insert_all_expr 23 #define set_expr 24 -#define show_topology 25 -#define show_tables 26 -#define proxy_icmd_state 27 +#define show_elastic_id 25 +#define show_topology 26 +#define show_tables 27 +#define proxy_icmd_state 28 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -5721,11 +5881,11 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 388 "ob_proxy_parser_utf8.l" +#line 400 "ob_proxy_parser_utf8.l" /* basic dml stmt: */ -#line 5731 "ob_proxy_parser_utf8_lex.c" +#line 5891 "ob_proxy_parser_utf8_lex.c" yylval = yylval_param; @@ -5782,13 +5942,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2597 ) + if ( yy_current_state >= 2787 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 17443 ); + while ( yy_base[yy_current_state] != 17872 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -5814,86 +5974,86 @@ YY_DECL case 1: YY_RULE_SETUP -#line 391 "ob_proxy_parser_utf8.l" +#line 403 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_SELECT); PUSH_STATE(in_expr); return SELECT; } YY_BREAK case 2: YY_RULE_SETUP -#line 392 "ob_proxy_parser_utf8.l" +#line 404 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_DELETE); PUSH_STATE_IF_NOT_ICMD(in_expr); return DELETE; } YY_BREAK case 3: YY_RULE_SETUP -#line 393 "ob_proxy_parser_utf8.l" +#line 405 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_INSERT); return INSERT; } YY_BREAK case 4: YY_RULE_SETUP -#line 394 "ob_proxy_parser_utf8.l" +#line 406 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_UPDATE); return UPDATE; } YY_BREAK case 5: YY_RULE_SETUP -#line 395 "ob_proxy_parser_utf8.l" +#line 407 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_REPLACE); return REPLACE; } YY_BREAK case 6: YY_RULE_SETUP -#line 396 "ob_proxy_parser_utf8.l" +#line 408 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_MERGE); return MERGE; } YY_BREAK case 7: YY_RULE_SETUP -#line 397 "ob_proxy_parser_utf8.l" +#line 409 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW; } YY_BREAK case 8: YY_RULE_SETUP -#line 398 "ob_proxy_parser_utf8.l" +#line 410 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(XA); } YY_BREAK /* if begin is for starting transaction, will set has_anonymous_block = false in yacc */ case 9: YY_RULE_SETUP -#line 400 "ob_proxy_parser_utf8.l" +#line 412 "ob_proxy_parser_utf8.l" { SET_HAS_ANONYMOUS_BLOCK(); RETURN_NON_RESERVED_KEYWORD(BEGI); } YY_BREAK case 10: YY_RULE_SETUP -#line 401 "ob_proxy_parser_utf8.l" +#line 413 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(START); } YY_BREAK case 11: YY_RULE_SETUP -#line 402 "ob_proxy_parser_utf8.l" +#line 414 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_COMMIT); RETURN_IGNORED_WORD(); } YY_BREAK case 12: YY_RULE_SETUP -#line 403 "ob_proxy_parser_utf8.l" +#line 415 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_ROLLBACK); RETURN_IGNORED_WORD(); } YY_BREAK case 13: YY_RULE_SETUP -#line 404 "ob_proxy_parser_utf8.l" +#line 416 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET); PUSH_STATE_IF_NOT_ICMD(set_expr); return SET; } YY_BREAK case 14: YY_RULE_SETUP -#line 405 "ob_proxy_parser_utf8.l" +#line 417 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_CALL); return CALL; } YY_BREAK case 15: YY_RULE_SETUP -#line 406 "ob_proxy_parser_utf8.l" +#line 418 "ob_proxy_parser_utf8.l" { SET_HAS_ANONYMOUS_BLOCK(); PUSH_STATE(in_anonymous_block); } YY_BREAK case 16: YY_RULE_SETUP -#line 407 "ob_proxy_parser_utf8.l" +#line 419 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = ob_proxy_parser_utf8_yyget_extra(yyscanner); if (OB_NOTNULL(p)) { - if (OBPROXY_T_INSERT == p->cur_stmt_type_) + if (OBPROXY_T_INSERT == p->cur_stmt_type_) PUSH_STATE(insert_all_expr); } return WHEN; } @@ -5901,338 +6061,338 @@ YY_RULE_SETUP /* basic ddl stmt */ case 17: YY_RULE_SETUP -#line 415 "ob_proxy_parser_utf8.l" +#line 427 "ob_proxy_parser_utf8.l" { return CREATE; } YY_BREAK case 18: YY_RULE_SETUP -#line 416 "ob_proxy_parser_utf8.l" +#line 428 "ob_proxy_parser_utf8.l" { return DROP; } YY_BREAK case 19: YY_RULE_SETUP -#line 417 "ob_proxy_parser_utf8.l" +#line 429 "ob_proxy_parser_utf8.l" { return ALTER; } YY_BREAK case 20: YY_RULE_SETUP -#line 418 "ob_proxy_parser_utf8.l" +#line 430 "ob_proxy_parser_utf8.l" { return TRUNCATE; } YY_BREAK case 21: YY_RULE_SETUP -#line 419 "ob_proxy_parser_utf8.l" +#line 431 "ob_proxy_parser_utf8.l" { return RENAME; } YY_BREAK case 22: YY_RULE_SETUP -#line 420 "ob_proxy_parser_utf8.l" +#line 432 "ob_proxy_parser_utf8.l" { return INDEX; } YY_BREAK case 23: YY_RULE_SETUP -#line 421 "ob_proxy_parser_utf8.l" +#line 433 "ob_proxy_parser_utf8.l" { return TABLE; } YY_BREAK case 24: YY_RULE_SETUP -#line 422 "ob_proxy_parser_utf8.l" +#line 434 "ob_proxy_parser_utf8.l" { return STATUS; } YY_BREAK case 25: YY_RULE_SETUP -#line 423 "ob_proxy_parser_utf8.l" +#line 435 "ob_proxy_parser_utf8.l" { return FROM; } YY_BREAK case 26: YY_RULE_SETUP -#line 424 "ob_proxy_parser_utf8.l" +#line 436 "ob_proxy_parser_utf8.l" { return UNIQUE; } YY_BREAK /* ps stmt */ case 27: YY_RULE_SETUP -#line 427 "ob_proxy_parser_utf8.l" +#line 439 "ob_proxy_parser_utf8.l" { return USING; } YY_BREAK case 28: YY_RULE_SETUP -#line 428 "ob_proxy_parser_utf8.l" +#line 440 "ob_proxy_parser_utf8.l" { PUSH_STATE(prepare); return PREPARE; } YY_BREAK case 29: YY_RULE_SETUP -#line 429 "ob_proxy_parser_utf8.l" +#line 441 "ob_proxy_parser_utf8.l" { return EXECUTE; } YY_BREAK case 30: YY_RULE_SETUP -#line 430 "ob_proxy_parser_utf8.l" -{ return DEALLOCATE; } +#line 442 "ob_proxy_parser_utf8.l" +{ return DEALLOCATE; } YY_BREAK /* oracle ddl stmt */ case 31: YY_RULE_SETUP -#line 434 "ob_proxy_parser_utf8.l" +#line 446 "ob_proxy_parser_utf8.l" { return GRANT; } YY_BREAK case 32: YY_RULE_SETUP -#line 435 "ob_proxy_parser_utf8.l" +#line 447 "ob_proxy_parser_utf8.l" { return REVOKE; } YY_BREAK case 33: YY_RULE_SETUP -#line 436 "ob_proxy_parser_utf8.l" +#line 448 "ob_proxy_parser_utf8.l" { return ANALYZE; } YY_BREAK case 34: YY_RULE_SETUP -#line 437 "ob_proxy_parser_utf8.l" +#line 449 "ob_proxy_parser_utf8.l" { return PURGE; } YY_BREAK case 35: YY_RULE_SETUP -#line 438 "ob_proxy_parser_utf8.l" +#line 450 "ob_proxy_parser_utf8.l" { return COMMENT; } YY_BREAK case 36: YY_RULE_SETUP -#line 439 "ob_proxy_parser_utf8.l" +#line 451 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(FLASHBACK); } YY_BREAK case 37: YY_RULE_SETUP -#line 440 "ob_proxy_parser_utf8.l" +#line 452 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(AUDIT); } YY_BREAK case 38: YY_RULE_SETUP -#line 441 "ob_proxy_parser_utf8.l" +#line 453 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NOAUDIT); } YY_BREAK case 39: YY_RULE_SETUP -#line 443 "ob_proxy_parser_utf8.l" +#line 455 "ob_proxy_parser_utf8.l" { return GROUP;} YY_BREAK case 40: YY_RULE_SETUP -#line 444 "ob_proxy_parser_utf8.l" +#line 456 "ob_proxy_parser_utf8.l" { return HAVING;} YY_BREAK case 41: YY_RULE_SETUP -#line 445 "ob_proxy_parser_utf8.l" +#line 457 "ob_proxy_parser_utf8.l" { return ORDER;} YY_BREAK case 42: YY_RULE_SETUP -#line 446 "ob_proxy_parser_utf8.l" +#line 458 "ob_proxy_parser_utf8.l" { return FOR;} YY_BREAK case 43: YY_RULE_SETUP -#line 447 "ob_proxy_parser_utf8.l" +#line 459 "ob_proxy_parser_utf8.l" { return UNION;} YY_BREAK case 44: YY_RULE_SETUP -#line 448 "ob_proxy_parser_utf8.l" +#line 460 "ob_proxy_parser_utf8.l" { return AS; } YY_BREAK case 45: YY_RULE_SETUP -#line 449 "ob_proxy_parser_utf8.l" +#line 461 "ob_proxy_parser_utf8.l" { return WHERE; } YY_BREAK case 46: YY_RULE_SETUP -#line 450 "ob_proxy_parser_utf8.l" +#line 462 "ob_proxy_parser_utf8.l" { return VALUES; } YY_BREAK case 47: YY_RULE_SETUP -#line 451 "ob_proxy_parser_utf8.l" +#line 463 "ob_proxy_parser_utf8.l" { return VALUES; } YY_BREAK case 48: YY_RULE_SETUP -#line 452 "ob_proxy_parser_utf8.l" +#line 464 "ob_proxy_parser_utf8.l" { SET_HAS_EXPLAIN(); return EXPLAIN; } YY_BREAK case 49: YY_RULE_SETUP -#line 453 "ob_proxy_parser_utf8.l" +#line 465 "ob_proxy_parser_utf8.l" { SET_HAS_EXPLAIN(); return DESC; } YY_BREAK case 50: YY_RULE_SETUP -#line 454 "ob_proxy_parser_utf8.l" +#line 466 "ob_proxy_parser_utf8.l" { SET_HAS_EXPLAIN(); return DESCRIBE; } YY_BREAK /*change from non_reserved to reserved according https://dev.mysql.com/doc/refman/5.6/en/keywords.html*/ case 51: YY_RULE_SETUP -#line 456 "ob_proxy_parser_utf8.l" +#line 468 "ob_proxy_parser_utf8.l" { return READ; } YY_BREAK case 52: YY_RULE_SETUP -#line 457 "ob_proxy_parser_utf8.l" +#line 469 "ob_proxy_parser_utf8.l" { return WITH; } YY_BREAK case 53: YY_RULE_SETUP -#line 458 "ob_proxy_parser_utf8.l" +#line 470 "ob_proxy_parser_utf8.l" { return USE; } YY_BREAK case 54: YY_RULE_SETUP -#line 459 "ob_proxy_parser_utf8.l" +#line 471 "ob_proxy_parser_utf8.l" { return LIMIT; } YY_BREAK case 55: YY_RULE_SETUP -#line 460 "ob_proxy_parser_utf8.l" +#line 472 "ob_proxy_parser_utf8.l" { return ALL; } YY_BREAK case 56: YY_RULE_SETUP -#line 461 "ob_proxy_parser_utf8.l" +#line 473 "ob_proxy_parser_utf8.l" { return LIKE; } YY_BREAK case 57: YY_RULE_SETUP -#line 462 "ob_proxy_parser_utf8.l" +#line 474 "ob_proxy_parser_utf8.l" { return PARTITION; } YY_BREAK case 58: YY_RULE_SETUP -#line 463 "ob_proxy_parser_utf8.l" +#line 475 "ob_proxy_parser_utf8.l" { return BINARY; } YY_BREAK case 59: YY_RULE_SETUP -#line 464 "ob_proxy_parser_utf8.l" -{ return GROUP_NAME; } +#line 476 "ob_proxy_parser_utf8.l" +{ RETURN_NON_RESERVED_KEYWORD(GROUP_NAME); } YY_BREAK /* to make bison easy, do not return these reserved keyword in non strict mode */ case 60: YY_RULE_SETUP -#line 467 "ob_proxy_parser_utf8.l" +#line 479 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 61: YY_RULE_SETUP -#line 468 "ob_proxy_parser_utf8.l" +#line 480 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 62: YY_RULE_SETUP -#line 469 "ob_proxy_parser_utf8.l" +#line 481 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 63: YY_RULE_SETUP -#line 470 "ob_proxy_parser_utf8.l" +#line 482 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 64: YY_RULE_SETUP -#line 471 "ob_proxy_parser_utf8.l" +#line 483 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK /* no reserved keyword , don't forget to add these keyword in .y */ /*refer: https://dev.mysql.com/doc/refman/5.6/en/keywords.html*/ case 65: YY_RULE_SETUP -#line 475 "ob_proxy_parser_utf8.l" +#line 487 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(QUICK); } YY_BREAK case 66: YY_RULE_SETUP -#line 476 "ob_proxy_parser_utf8.l" +#line 488 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(COUNT); } YY_BREAK case 67: YY_RULE_SETUP -#line 477 "ob_proxy_parser_utf8.l" +#line 489 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(WARNINGS); } YY_BREAK case 68: YY_RULE_SETUP -#line 478 "ob_proxy_parser_utf8.l" +#line 490 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(ERRORS); } YY_BREAK case 69: YY_RULE_SETUP -#line 479 "ob_proxy_parser_utf8.l" +#line 491 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(TRACE); } YY_BREAK case 70: YY_RULE_SETUP -#line 480 "ob_proxy_parser_utf8.l" +#line 492 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(TRANSACTION); } YY_BREAK case 71: YY_RULE_SETUP -#line 482 "ob_proxy_parser_utf8.l" +#line 494 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(ONLY); } YY_BREAK case 72: YY_RULE_SETUP -#line 484 "ob_proxy_parser_utf8.l" +#line 496 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(CONSISTENT); } YY_BREAK case 73: YY_RULE_SETUP -#line 485 "ob_proxy_parser_utf8.l" +#line 497 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(SNAPSHOT); } YY_BREAK case 74: YY_RULE_SETUP -#line 487 "ob_proxy_parser_utf8.l" +#line 499 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(HELP); } YY_BREAK /*set names*/ case 75: /* rule 75 can match eol */ YY_RULE_SETUP -#line 491 "ob_proxy_parser_utf8.l" +#line 503 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_NAMES); return SET_NAMES; } YY_BREAK /*set charset*/ case 76: /* rule 76 can match eol */ YY_RULE_SETUP -#line 493 "ob_proxy_parser_utf8.l" +#line 505 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_CHARSET); return SET_CHARSET; } YY_BREAK /*set passwd*/ case 77: /* rule 77 can match eol */ YY_RULE_SETUP -#line 495 "ob_proxy_parser_utf8.l" +#line 507 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_PASSWORD); return SET_PASSWORD; } YY_BREAK /*set default*/ case 78: /* rule 78 can match eol */ YY_RULE_SETUP -#line 497 "ob_proxy_parser_utf8.l" +#line 509 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_DEFAULT); return SET_DEFAULT; } YY_BREAK case 79: /* rule 79 can match eol */ YY_RULE_SETUP -#line 499 "ob_proxy_parser_utf8.l" +#line 511 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_OB_READ_CONSISTENCY); return SET_OB_READ_CONSISTENCY; } YY_BREAK case 80: /* rule 80 can match eol */ YY_RULE_SETUP -#line 500 "ob_proxy_parser_utf8.l" +#line 512 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_TX_READ_ONLY); return SET_TX_READ_ONLY; } YY_BREAK /*internal cmd*/ @@ -6240,453 +6400,459 @@ YY_RULE_SETUP case 81: /* rule 81 can match eol */ YY_RULE_SETUP -#line 504 "ob_proxy_parser_utf8.l" +#line 516 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_NET); return SHOW_PROXYNET; } YY_BREAK case 82: YY_RULE_SETUP -#line 505 "ob_proxy_parser_utf8.l" +#line 517 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(THREAD); } YY_BREAK case 83: YY_RULE_SETUP -#line 506 "ob_proxy_parser_utf8.l" +#line 518 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(CONNECTION); } YY_BREAK case 84: YY_RULE_SETUP -#line 508 "ob_proxy_parser_utf8.l" +#line 520 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(OFFSET); } YY_BREAK /*show session*/ case 85: /* rule 85 can match eol */ YY_RULE_SETUP -#line 511 "ob_proxy_parser_utf8.l" +#line 523 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_GLOBAL_SESSION); return SHOW_GLOBALSESSION; } YY_BREAK case 86: /* rule 86 can match eol */ YY_RULE_SETUP -#line 512 "ob_proxy_parser_utf8.l" +#line 524 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SESSION); return SHOW_PROXYSESSION; } YY_BREAK case 87: /* rule 87 can match eol */ YY_RULE_SETUP -#line 513 "ob_proxy_parser_utf8.l" +#line 525 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_PROCESSLIST); return SHOW_PROCESSLIST; } YY_BREAK case 88: YY_RULE_SETUP -#line 514 "ob_proxy_parser_utf8.l" +#line 526 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(ATTRIBUTE); } YY_BREAK case 89: YY_RULE_SETUP -#line 515 "ob_proxy_parser_utf8.l" +#line 527 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(VARIABLES); } YY_BREAK case 90: YY_RULE_SETUP -#line 517 "ob_proxy_parser_utf8.l" +#line 529 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(STAT); } YY_BREAK /*show config*/ case 91: /* rule 91 can match eol */ YY_RULE_SETUP -#line 520 "ob_proxy_parser_utf8.l" +#line 532 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CONFIG); PUSH_STATE(proxy_icmd_state); return SHOW_PROXYCONFIG; } YY_BREAK case 92: YY_RULE_SETUP -#line 522 "ob_proxy_parser_utf8.l" +#line 534 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(DIFF); } YY_BREAK case 93: YY_RULE_SETUP -#line 523 "ob_proxy_parser_utf8.l" +#line 535 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(USER); } YY_BREAK case 94: YY_RULE_SETUP -#line 524 "ob_proxy_parser_utf8.l" +#line 536 "ob_proxy_parser_utf8.l" { POP_STATE(); return LIKE; } YY_BREAK /*show sm*/ case 95: /* rule 95 can match eol */ YY_RULE_SETUP -#line 527 "ob_proxy_parser_utf8.l" +#line 539 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SM); return SHOW_PROXYSM; } YY_BREAK /*show cluster*/ case 96: /* rule 96 can match eol */ YY_RULE_SETUP -#line 530 "ob_proxy_parser_utf8.l" +#line 542 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CLUSTER); return SHOW_PROXYCLUSTER; } YY_BREAK /*show resource*/ case 97: /* rule 97 can match eol */ YY_RULE_SETUP -#line 533 "ob_proxy_parser_utf8.l" +#line 545 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_RESOURCE); return SHOW_PROXYRESOURCE; } YY_BREAK /*show congestion*/ case 98: /* rule 98 can match eol */ YY_RULE_SETUP -#line 536 "ob_proxy_parser_utf8.l" +#line 548 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CONGESTION); return SHOW_PROXYCONGESTION; } YY_BREAK /*show route*/ case 99: /* rule 99 can match eol */ YY_RULE_SETUP -#line 539 "ob_proxy_parser_utf8.l" +#line 551 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_ROUTE); return SHOW_PROXYROUTE; } YY_BREAK case 100: YY_RULE_SETUP -#line 541 "ob_proxy_parser_utf8.l" +#line 553 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(ROUTINE); } YY_BREAK /*show vip*/ case 101: /* rule 101 can match eol */ YY_RULE_SETUP -#line 544 "ob_proxy_parser_utf8.l" +#line 556 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_VIP); return SHOW_PROXYVIP; } YY_BREAK /*show memory*/ case 102: /* rule 102 can match eol */ YY_RULE_SETUP -#line 547 "ob_proxy_parser_utf8.l" +#line 559 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_MEMORY); return SHOW_PROXYMEMORY; } YY_BREAK case 103: YY_RULE_SETUP -#line 548 "ob_proxy_parser_utf8.l" +#line 560 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(OBJPOOL); } YY_BREAK /*show sqlaudit*/ case 104: /* rule 104 can match eol */ YY_RULE_SETUP -#line 551 "ob_proxy_parser_utf8.l" +#line 563 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SQLAUDIT); return SHOW_SQLAUDIT; } YY_BREAK /*show warnlog*/ case 105: /* rule 105 can match eol */ YY_RULE_SETUP -#line 554 "ob_proxy_parser_utf8.l" +#line 566 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_WARNLOG); return SHOW_WARNLOG; } YY_BREAK /*show stat*/ case 106: /* rule 106 can match eol */ YY_RULE_SETUP -#line 557 "ob_proxy_parser_utf8.l" +#line 569 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_STAT); return SHOW_PROXYSTAT; } YY_BREAK case 107: YY_RULE_SETUP -#line 558 "ob_proxy_parser_utf8.l" +#line 570 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(REFRESH); } YY_BREAK /*show trace*/ case 108: /* rule 108 can match eol */ YY_RULE_SETUP -#line 561 "ob_proxy_parser_utf8.l" +#line 573 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_TRACE); return SHOW_PROXYTRACE; } YY_BREAK /*show info*/ case 109: /* rule 109 can match eol */ YY_RULE_SETUP -#line 564 "ob_proxy_parser_utf8.l" +#line 576 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_INFO); return SHOW_PROXYINFO; } YY_BREAK case 110: YY_RULE_SETUP -#line 565 "ob_proxy_parser_utf8.l" +#line 577 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(UPGRADE); } YY_BREAK case 111: YY_RULE_SETUP -#line 566 "ob_proxy_parser_utf8.l" +#line 578 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(IDC); } YY_BREAK case 112: /* rule 112 can match eol */ YY_RULE_SETUP -#line 568 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_topology); return SHOW_TOPOLOGY; } +#line 580 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_elastic_id ); return SHOW_ELASTIC_ID; } YY_BREAK case 113: YY_RULE_SETUP -#line 569 "ob_proxy_parser_utf8.l" +#line 581 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } YY_BREAK case 114: YY_RULE_SETUP -#line 570 "ob_proxy_parser_utf8.l" +#line 582 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return WHERE; } YY_BREAK -case YY_STATE_EOF(show_topology): -#line 571 "ob_proxy_parser_utf8.l" +case YY_STATE_EOF(show_elastic_id): +#line 583 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK case 115: /* rule 115 can match eol */ YY_RULE_SETUP -#line 572 "ob_proxy_parser_utf8.l" +#line 584 "ob_proxy_parser_utf8.l" { } YY_BREAK case 116: YY_RULE_SETUP -#line 573 "ob_proxy_parser_utf8.l" +#line 585 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK case 117: YY_RULE_SETUP -#line 574 "ob_proxy_parser_utf8.l" +#line 586 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK case 118: /* rule 118 can match eol */ YY_RULE_SETUP -#line 576 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } +#line 588 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_TOPOLOGY; } YY_BREAK case 119: /* rule 119 can match eol */ YY_RULE_SETUP -#line 577 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } +#line 590 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } YY_BREAK case 120: /* rule 120 can match eol */ YY_RULE_SETUP -#line 579 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_TABLES; } +#line 591 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } YY_BREAK case 121: /* rule 121 can match eol */ YY_RULE_SETUP -#line 580 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_FULL_TABLES; } +#line 593 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_TABLES; } YY_BREAK case 122: +/* rule 122 can match eol */ YY_RULE_SETUP -#line 582 "ob_proxy_parser_utf8.l" -{ POP_STATE(); PUSH_STATE(INITIAL); return FROM; } +#line 594 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_FULL_TABLES; } YY_BREAK case 123: YY_RULE_SETUP -#line 583 "ob_proxy_parser_utf8.l" +#line 596 "ob_proxy_parser_utf8.l" +{ POP_STATE(); PUSH_STATE(INITIAL); return FROM; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 597 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return LIKE; } YY_BREAK case YY_STATE_EOF(show_tables): -#line 584 "ob_proxy_parser_utf8.l" +#line 598 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 124: -/* rule 124 can match eol */ -YY_RULE_SETUP -#line 585 "ob_proxy_parser_utf8.l" -{ } - YY_BREAK case 125: +/* rule 125 can match eol */ YY_RULE_SETUP -#line 586 "ob_proxy_parser_utf8.l" -{ POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } +#line 599 "ob_proxy_parser_utf8.l" +{ } YY_BREAK case 126: YY_RULE_SETUP -#line 587 "ob_proxy_parser_utf8.l" -{ return ERROR; } +#line 600 "ob_proxy_parser_utf8.l" +{ POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK case 127: -/* rule 127 can match eol */ YY_RULE_SETUP -#line 588 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_COLUMNS; } +#line 601 "ob_proxy_parser_utf8.l" +{ return ERROR; } YY_BREAK case 128: /* rule 128 can match eol */ YY_RULE_SETUP -#line 589 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_INDEX; } +#line 602 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_COLUMNS; } YY_BREAK case 129: /* rule 129 can match eol */ YY_RULE_SETUP -#line 591 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_CREATE_TABLE; } +#line 603 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_INDEX; } YY_BREAK case 130: /* rule 130 can match eol */ YY_RULE_SETUP -#line 592 "ob_proxy_parser_utf8.l" -{ SET_DML_STMT(OBPROXY_T_SELECT); return SELECT_DATABASE; } +#line 605 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_CREATE_TABLE; } YY_BREAK case 131: /* rule 131 can match eol */ YY_RULE_SETUP -#line 593 "ob_proxy_parser_utf8.l" -{ SET_DML_STMT(OBPROXY_T_SELECT_PROXY_VERSION); return SELECT_PROXY_VERSION; } +#line 606 "ob_proxy_parser_utf8.l" +{ SET_DML_STMT(OBPROXY_T_SELECT); return SELECT_DATABASE; } YY_BREAK -/*alter config*/ case 132: /* rule 132 can match eol */ YY_RULE_SETUP -#line 596 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_CONFIG); return ALTER_PROXYCONFIG; } +#line 607 "ob_proxy_parser_utf8.l" +{ SET_DML_STMT(OBPROXY_T_SELECT_PROXY_VERSION); return SELECT_PROXY_VERSION; } YY_BREAK -/*alter resource*/ +/*alter config*/ case 133: /* rule 133 can match eol */ YY_RULE_SETUP -#line 599 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_RESOURCE); return ALTER_PROXYRESOURCE; } +#line 610 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_CONFIG); return ALTER_PROXYCONFIG; } YY_BREAK -/*ping proxy*/ +/*alter resource*/ case 134: /* rule 134 can match eol */ YY_RULE_SETUP -#line 602 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_PING_PROXY); return PING_PROXY; } +#line 613 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_RESOURCE); return ALTER_PROXYRESOURCE; } YY_BREAK -/*kill*/ +/*ping proxy*/ case 135: /* rule 135 can match eol */ YY_RULE_SETUP -#line 605 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_SESSION); return KILL_PROXYSESSION; } +#line 616 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_PING_PROXY); return PING_PROXY; } YY_BREAK +/*kill*/ case 136: /* rule 136 can match eol */ YY_RULE_SETUP -#line 606 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_GLOBAL_SESSION); return KILL_GLOBALSESSION; } +#line 619 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_SESSION); return KILL_PROXYSESSION; } YY_BREAK case 137: +/* rule 137 can match eol */ YY_RULE_SETUP -#line 607 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_MYSQL); return KILL; } +#line 620 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_GLOBAL_SESSION); return KILL_GLOBALSESSION; } YY_BREAK case 138: YY_RULE_SETUP -#line 608 "ob_proxy_parser_utf8.l" -{ RETURN_NON_RESERVED_KEYWORD(QUERY); } +#line 621 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_MYSQL); return KILL; } YY_BREAK -/* obproxy_route_addr */ case 139: -/* rule 139 can match eol */ YY_RULE_SETUP -#line 611 "ob_proxy_parser_utf8.l" -{ return SELECT_OBPROXY_ROUTE_ADDR; } +#line 622 "ob_proxy_parser_utf8.l" +{ RETURN_NON_RESERVED_KEYWORD(QUERY); } YY_BREAK +/* obproxy_route_addr */ case 140: /* rule 140 can match eol */ YY_RULE_SETUP -#line 612 "ob_proxy_parser_utf8.l" +#line 625 "ob_proxy_parser_utf8.l" +{ return SELECT_OBPROXY_ROUTE_ADDR; } + YY_BREAK +case 141: +/* rule 141 can match eol */ +YY_RULE_SETUP +#line 626 "ob_proxy_parser_utf8.l" { return SET_OBPROXY_ROUTE_ADDR; } YY_BREAK /* identifer */ -case 141: +case 142: YY_RULE_SETUP -#line 615 "ob_proxy_parser_utf8.l" +#line 629 "ob_proxy_parser_utf8.l" { SET_FOUND_ROWS(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 142: +case 143: YY_RULE_SETUP -#line 616 "ob_proxy_parser_utf8.l" +#line 630 "ob_proxy_parser_utf8.l" { SET_ROW_COUNT(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 143: +case 144: YY_RULE_SETUP -#line 617 "ob_proxy_parser_utf8.l" +#line 631 "ob_proxy_parser_utf8.l" { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 144: +case 145: YY_RULE_SETUP -#line 618 "ob_proxy_parser_utf8.l" +#line 632 "ob_proxy_parser_utf8.l" { return ','; } YY_BREAK -case 145: +case 146: YY_RULE_SETUP -#line 619 "ob_proxy_parser_utf8.l" +#line 633 "ob_proxy_parser_utf8.l" { RETURN_INT_NUM(); } YY_BREAK -case 146: +case 147: YY_RULE_SETUP -#line 620 "ob_proxy_parser_utf8.l" +#line 634 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 147: +case 148: YY_RULE_SETUP -#line 621 "ob_proxy_parser_utf8.l" +#line 635 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_SINGLE); } YY_BREAK -case 148: +case 149: YY_RULE_SETUP -#line 622 "ob_proxy_parser_utf8.l" +#line 636 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_DOUBLE); } YY_BREAK -case 149: +case 150: YY_RULE_SETUP -#line 623 "ob_proxy_parser_utf8.l" +#line 637 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_BACK); } YY_BREAK -case 150: +case 151: YY_RULE_SETUP -#line 624 "ob_proxy_parser_utf8.l" +#line 638 "ob_proxy_parser_utf8.l" { RETURN_NUMBER_VAL(); } YY_BREAK -case 151: +case 152: YY_RULE_SETUP -#line 625 "ob_proxy_parser_utf8.l" +#line 639 "ob_proxy_parser_utf8.l" { return PLACE_HOLDER; } YY_BREAK -case 152: +case 153: YY_RULE_SETUP -#line 626 "ob_proxy_parser_utf8.l" +#line 640 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 153: +case 154: YY_RULE_SETUP -#line 627 "ob_proxy_parser_utf8.l" +#line 641 "ob_proxy_parser_utf8.l" { RETURN_WITH_CALL_CHECK(yytext[0]); } YY_BREAK -case 154: +case 155: YY_RULE_SETUP -#line 628 "ob_proxy_parser_utf8.l" +#line 642 "ob_proxy_parser_utf8.l" { RETURN_WITH_CALL_CHECK('('); } YY_BREAK -case 155: +case 156: YY_RULE_SETUP -#line 629 "ob_proxy_parser_utf8.l" +#line 643 "ob_proxy_parser_utf8.l" { RETURN_WITH_CALL_CHECK(')'); } YY_BREAK -case 156: -/* rule 156 can match eol */ +case 157: +/* rule 157 can match eol */ YY_RULE_SETUP -#line 630 "ob_proxy_parser_utf8.l" +#line 644 "ob_proxy_parser_utf8.l" { } YY_BREAK /* hint option */ -case 157: -/* rule 157 can match eol */ +case 158: +/* rule 158 can match eol */ YY_RULE_SETUP -#line 633 "ob_proxy_parser_utf8.l" +#line 647 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_expr); PUSH_STATE(hint); @@ -6694,20 +6860,20 @@ YY_RULE_SETUP return SELECT_HINT_BEGIN; } YY_BREAK -case 158: -/* rule 158 can match eol */ +case 159: +/* rule 159 can match eol */ YY_RULE_SETUP -#line 639 "ob_proxy_parser_utf8.l" +#line 653 "ob_proxy_parser_utf8.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_UPDATE); return UPDATE_HINT_BEGIN; } YY_BREAK -case 159: -/* rule 159 can match eol */ +case 160: +/* rule 160 can match eol */ YY_RULE_SETUP -#line 644 "ob_proxy_parser_utf8.l" +#line 658 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_expr); PUSH_STATE(hint); @@ -6715,95 +6881,125 @@ YY_RULE_SETUP return DELETE_HINT_BEGIN; } YY_BREAK -case 160: -/* rule 160 can match eol */ +case 161: +/* rule 161 can match eol */ YY_RULE_SETUP -#line 650 "ob_proxy_parser_utf8.l" +#line 664 "ob_proxy_parser_utf8.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_INSERT); return INSERT_HINT_BEGIN; } YY_BREAK -case 161: -/* rule 161 can match eol */ +case 162: +/* rule 162 can match eol */ YY_RULE_SETUP -#line 655 "ob_proxy_parser_utf8.l" +#line 669 "ob_proxy_parser_utf8.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_REPLACE); return REPLACE_HINT_BEGIN; } YY_BREAK -case 162: -/* rule 162 can match eol */ +case 163: +/* rule 163 can match eol */ YY_RULE_SETUP -#line 660 "ob_proxy_parser_utf8.l" +#line 674 "ob_proxy_parser_utf8.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_MERGE); return MERGE_HINT_BEGIN; } YY_BREAK -case 163: -/* rule 163 can match eol */ +case 164: +/* rule 164 can match eol */ YY_RULE_SETUP -#line 666 "ob_proxy_parser_utf8.l" -{ return AUTOCOMMIT_0; } +#line 680 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_MASTER_STATUS); return SHOW_MASTER_STATUS; } YY_BREAK -case 164: +case 165: +/* rule 165 can match eol */ +YY_RULE_SETUP +#line 681 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINARY_LOGS); return SHOW_BINARY_LOGS; } + YY_BREAK +case 166: +/* rule 166 can match eol */ +YY_RULE_SETUP +#line 682 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_EVENTS); return SHOW_BINLOG_EVENTS; } + YY_BREAK +case 167: +/* rule 167 can match eol */ +YY_RULE_SETUP +#line 683 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_PURGE_BINARY_LOGS); return PURGE_BINARY_LOGS; } + YY_BREAK +case 168: +/* rule 168 can match eol */ YY_RULE_SETUP -#line 667 "ob_proxy_parser_utf8.l" +#line 684 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_RESET_MASTER); return RESET_MASTER; } + YY_BREAK +case 169: +/* rule 169 can match eol */ +YY_RULE_SETUP +#line 685 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT); return SHOW_BINLOG_SERVER_FOR_TENANT; } + YY_BREAK +case 170: +YY_RULE_SETUP +#line 687 "ob_proxy_parser_utf8.l" { return GLOBAL; } YY_BREAK -case 165: +case 171: YY_RULE_SETUP -#line 668 "ob_proxy_parser_utf8.l" +#line 688 "ob_proxy_parser_utf8.l" { return SESSION; } YY_BREAK -case 166: +case 172: YY_RULE_SETUP -#line 669 "ob_proxy_parser_utf8.l" +#line 689 "ob_proxy_parser_utf8.l" { RETURN_INT_NUM(); } YY_BREAK -case 167: +case 173: YY_RULE_SETUP -#line 670 "ob_proxy_parser_utf8.l" +#line 690 "ob_proxy_parser_utf8.l" { return ','; } YY_BREAK -case 168: +case 174: YY_RULE_SETUP -#line 671 "ob_proxy_parser_utf8.l" +#line 691 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 169: +case 175: YY_RULE_SETUP -#line 672 "ob_proxy_parser_utf8.l" +#line 692 "ob_proxy_parser_utf8.l" { RETURN_NUMBER_VAL(); } YY_BREAK -case 170: -/* rule 170 can match eol */ +case 176: +/* rule 176 can match eol */ YY_RULE_SETUP -#line 673 "ob_proxy_parser_utf8.l" +#line 693 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 171: +case 177: YY_RULE_SETUP -#line 674 "ob_proxy_parser_utf8.l" +#line 694 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK case YY_STATE_EOF(set_expr): -#line 675 "ob_proxy_parser_utf8.l" +#line 695 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 172: +case 178: YY_RULE_SETUP -#line 676 "ob_proxy_parser_utf8.l" +#line 696 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK -case 173: +case 179: YY_RULE_SETUP -#line 678 "ob_proxy_parser_utf8.l" +#line 698 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6814,9 +7010,9 @@ YY_RULE_SETUP } } YY_BREAK -case 174: +case 180: YY_RULE_SETUP -#line 688 "ob_proxy_parser_utf8.l" +#line 708 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6827,9 +7023,9 @@ YY_RULE_SETUP } } YY_BREAK -case 175: +case 181: YY_RULE_SETUP -#line 698 "ob_proxy_parser_utf8.l" +#line 718 "ob_proxy_parser_utf8.l" { PUSH_STATE(bt); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6840,90 +7036,90 @@ YY_RULE_SETUP } } YY_BREAK -case 176: +case 182: YY_RULE_SETUP -#line 707 "ob_proxy_parser_utf8.l" +#line 727 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK -case 177: +case 183: YY_RULE_SETUP -#line 709 "ob_proxy_parser_utf8.l" +#line 729 "ob_proxy_parser_utf8.l" { POP_STATE(); RETURN_IGNORED_WORD(); } YY_BREAK -case 178: +case 184: YY_RULE_SETUP -#line 710 "ob_proxy_parser_utf8.l" +#line 730 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 179: +case 185: YY_RULE_SETUP -#line 712 "ob_proxy_parser_utf8.l" +#line 732 "ob_proxy_parser_utf8.l" { return '('; } YY_BREAK -case 180: +case 186: YY_RULE_SETUP -#line 713 "ob_proxy_parser_utf8.l" +#line 733 "ob_proxy_parser_utf8.l" { return ')'; } YY_BREAK -case 181: +case 187: YY_RULE_SETUP -#line 714 "ob_proxy_parser_utf8.l" +#line 734 "ob_proxy_parser_utf8.l" { return QUERY_TIMEOUT; } YY_BREAK -case 182: +case 188: YY_RULE_SETUP -#line 715 "ob_proxy_parser_utf8.l" +#line 735 "ob_proxy_parser_utf8.l" { RETURN_INT_NUM(); } YY_BREAK -case 183: +case 189: YY_RULE_SETUP -#line 716 "ob_proxy_parser_utf8.l" +#line 736 "ob_proxy_parser_utf8.l" { return READ_CONSISTENCY; } YY_BREAK -case 184: +case 190: YY_RULE_SETUP -#line 717 "ob_proxy_parser_utf8.l" +#line 737 "ob_proxy_parser_utf8.l" { return WEAK; } YY_BREAK -case 185: +case 191: YY_RULE_SETUP -#line 718 "ob_proxy_parser_utf8.l" +#line 738 "ob_proxy_parser_utf8.l" { return STRONG; } YY_BREAK -case 186: +case 192: YY_RULE_SETUP -#line 719 "ob_proxy_parser_utf8.l" +#line 739 "ob_proxy_parser_utf8.l" { return FROZEN; } YY_BREAK -case 187: +case 193: YY_RULE_SETUP -#line 720 "ob_proxy_parser_utf8.l" +#line 740 "ob_proxy_parser_utf8.l" { return INDEX; } YY_BREAK -case 188: +case 194: YY_RULE_SETUP -#line 721 "ob_proxy_parser_utf8.l" +#line 741 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 189: +case 195: YY_RULE_SETUP -#line 722 "ob_proxy_parser_utf8.l" +#line 742 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 190: +case 196: YY_RULE_SETUP -#line 723 "ob_proxy_parser_utf8.l" +#line 743 "ob_proxy_parser_utf8.l" { POP_STATE(); return HINT_END; } YY_BREAK -case 191: +case 197: YY_RULE_SETUP -#line 724 "ob_proxy_parser_utf8.l" +#line 744 "ob_proxy_parser_utf8.l" {} YY_BREAK /* comment */ -case 192: +case 198: YY_RULE_SETUP -#line 727 "ob_proxy_parser_utf8.l" +#line 747 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_c_comment); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6938,25 +7134,25 @@ YY_RULE_SETUP } } YY_BREAK -case 193: +case 199: YY_RULE_SETUP -#line 741 "ob_proxy_parser_utf8.l" +#line 761 "ob_proxy_parser_utf8.l" { POP_STATE(); } YY_BREAK -case 194: -/* rule 194 can match eol */ +case 200: +/* rule 200 can match eol */ YY_RULE_SETUP -#line 742 "ob_proxy_parser_utf8.l" +#line 762 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 195: +case 201: YY_RULE_SETUP -#line 743 "ob_proxy_parser_utf8.l" +#line 763 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 196: +case 202: YY_RULE_SETUP -#line 745 "ob_proxy_parser_utf8.l" +#line 765 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6967,15 +7163,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 197: +case 203: YY_RULE_SETUP -#line 755 "ob_proxy_parser_utf8.l" +#line 775 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_old_comment_expr); } YY_BREAK -case 198: -/* rule 198 can match eol */ +case 204: +/* rule 204 can match eol */ YY_RULE_SETUP -#line 756 "ob_proxy_parser_utf8.l" +#line 776 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_old_comment_expr); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6985,10 +7181,10 @@ YY_RULE_SETUP } } YY_BREAK -case 199: -/* rule 199 can match eol */ +case 205: +/* rule 205 can match eol */ YY_RULE_SETUP -#line 765 "ob_proxy_parser_utf8.l" +#line 785 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_old_comment_expr); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7000,9 +7196,9 @@ YY_RULE_SETUP } } YY_BREAK -case 200: +case 206: YY_RULE_SETUP -#line 776 "ob_proxy_parser_utf8.l" +#line 796 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7011,9 +7207,9 @@ YY_RULE_SETUP } } YY_BREAK -case 201: +case 207: YY_RULE_SETUP -#line 784 "ob_proxy_parser_utf8.l" +#line 804 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7024,29 +7220,29 @@ YY_RULE_SETUP } } YY_BREAK -case 202: +case 208: YY_RULE_SETUP -#line 794 "ob_proxy_parser_utf8.l" +#line 814 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 203: +case 209: YY_RULE_SETUP -#line 795 "ob_proxy_parser_utf8.l" +#line 815 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_SINGLE); } YY_BREAK -case 204: +case 210: YY_RULE_SETUP -#line 796 "ob_proxy_parser_utf8.l" +#line 816 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_DOUBLE); } YY_BREAK -case 205: +case 211: YY_RULE_SETUP -#line 797 "ob_proxy_parser_utf8.l" +#line 817 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_BACK); } YY_BREAK -case 206: +case 212: YY_RULE_SETUP -#line 798 "ob_proxy_parser_utf8.l" +#line 818 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7058,160 +7254,171 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 207: +case 213: YY_RULE_SETUP -#line 808 "ob_proxy_parser_utf8.l" +#line 828 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 208: +case 214: YY_RULE_SETUP -#line 810 "ob_proxy_parser_utf8.l" +#line 830 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(ODP_COMMENT); } YY_BREAK -case 209: -/* rule 209 can match eol */ +case 215: +/* rule 215 can match eol */ YY_RULE_SETUP -#line 811 "ob_proxy_parser_utf8.l" +#line 831 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(GROUP_ID); } YY_BREAK -case 210: -/* rule 210 can match eol */ +case 216: +/* rule 216 can match eol */ YY_RULE_SETUP -#line 812 "ob_proxy_parser_utf8.l" +#line 832 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TABLE_ID); } YY_BREAK -case 211: -/* rule 211 can match eol */ +case 217: +/* rule 217 can match eol */ YY_RULE_SETUP -#line 813 "ob_proxy_parser_utf8.l" +#line 833 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TABLE_NAME); } YY_BREAK -case 212: -/* rule 212 can match eol */ +case 218: +/* rule 218 can match eol */ YY_RULE_SETUP -#line 814 "ob_proxy_parser_utf8.l" +#line 834 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(ELASTIC_ID); } YY_BREAK -case 213: -/* rule 213 can match eol */ +case 219: +/* rule 219 can match eol */ YY_RULE_SETUP -#line 815 "ob_proxy_parser_utf8.l" +#line 835 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TESTLOAD); } YY_BREAK -case 214: -/* rule 214 can match eol */ +case 220: +/* rule 220 can match eol */ YY_RULE_SETUP -#line 816 "ob_proxy_parser_utf8.l" +#line 836 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(DISASTER_STATUS); } YY_BREAK -case 215: -/* rule 215 can match eol */ +case 221: +/* rule 221 can match eol */ YY_RULE_SETUP -#line 817 "ob_proxy_parser_utf8.l" +#line 837 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TNT_ID); } YY_BREAK -case 216: -/* rule 216 can match eol */ +case 222: +/* rule 222 can match eol */ YY_RULE_SETUP -#line 818 "ob_proxy_parser_utf8.l" +#line 838 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TRACE_ID); } YY_BREAK -case 217: -/* rule 217 can match eol */ +case 223: +/* rule 223 can match eol */ YY_RULE_SETUP -#line 819 "ob_proxy_parser_utf8.l" +#line 839 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT_NAME_OB_DOT(NAME_OB_DOT); } YY_BREAK -case 218: -/* rule 218 can match eol */ +case 224: +/* rule 224 can match eol */ YY_RULE_SETUP -#line 820 "ob_proxy_parser_utf8.l" +#line 840 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(RPC_ID); } YY_BREAK -case 219: +case 225: +/* rule 225 can match eol */ YY_RULE_SETUP -#line 822 "ob_proxy_parser_utf8.l" +#line 841 "ob_proxy_parser_utf8.l" +{ PUSH_STATE(in_odp_comment_expr); return TARGET_DB_SERVER; } + YY_BREAK +case 226: +YY_RULE_SETUP +#line 843 "ob_proxy_parser_utf8.l" { return GROUP_ID; } YY_BREAK -case 220: +case 227: YY_RULE_SETUP -#line 823 "ob_proxy_parser_utf8.l" +#line 844 "ob_proxy_parser_utf8.l" { return TABLE_ID; } YY_BREAK -case 221: +case 228: YY_RULE_SETUP -#line 824 "ob_proxy_parser_utf8.l" +#line 845 "ob_proxy_parser_utf8.l" { return TABLE_NAME; } YY_BREAK -case 222: +case 229: YY_RULE_SETUP -#line 825 "ob_proxy_parser_utf8.l" +#line 846 "ob_proxy_parser_utf8.l" { return ELASTIC_ID; } YY_BREAK -case 223: +case 230: YY_RULE_SETUP -#line 826 "ob_proxy_parser_utf8.l" +#line 847 "ob_proxy_parser_utf8.l" { return TESTLOAD; } YY_BREAK -case 224: +case 231: YY_RULE_SETUP -#line 827 "ob_proxy_parser_utf8.l" +#line 848 "ob_proxy_parser_utf8.l" { return DISASTER_STATUS; } YY_BREAK -case 225: +case 232: YY_RULE_SETUP -#line 828 "ob_proxy_parser_utf8.l" +#line 849 "ob_proxy_parser_utf8.l" { return TNT_ID; } YY_BREAK -case 226: +case 233: YY_RULE_SETUP -#line 829 "ob_proxy_parser_utf8.l" +#line 850 "ob_proxy_parser_utf8.l" { return TRACE_ID; } YY_BREAK -case 227: +case 234: YY_RULE_SETUP -#line 830 "ob_proxy_parser_utf8.l" +#line 851 "ob_proxy_parser_utf8.l" { return RPC_ID; } YY_BREAK -case 228: +case 235: YY_RULE_SETUP -#line 831 "ob_proxy_parser_utf8.l" +#line 852 "ob_proxy_parser_utf8.l" +{ return TARGET_DB_SERVER; } + YY_BREAK +case 236: +YY_RULE_SETUP +#line 853 "ob_proxy_parser_utf8.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 229: +case 237: YY_RULE_SETUP -#line 832 "ob_proxy_parser_utf8.l" +#line 854 "ob_proxy_parser_utf8.l" { return ','; } YY_BREAK -case 230: +case 238: YY_RULE_SETUP -#line 833 "ob_proxy_parser_utf8.l" +#line 855 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 231: +case 239: YY_RULE_SETUP -#line 834 "ob_proxy_parser_utf8.l" +#line 856 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_value_expr); return yytext[0]; } YY_BREAK -case 232: +case 240: YY_RULE_SETUP -#line 835 "ob_proxy_parser_utf8.l" +#line 857 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 233: -/* rule 233 can match eol */ +case 241: +/* rule 241 can match eol */ YY_RULE_SETUP -#line 836 "ob_proxy_parser_utf8.l" +#line 858 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 234: +case 242: YY_RULE_SETUP -#line 837 "ob_proxy_parser_utf8.l" +#line 859 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK -case 235: +case 243: YY_RULE_SETUP -#line 838 "ob_proxy_parser_utf8.l" +#line 860 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7223,22 +7430,22 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 236: +case 244: YY_RULE_SETUP -#line 849 "ob_proxy_parser_utf8.l" +#line 871 "ob_proxy_parser_utf8.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 237: +case 245: YY_RULE_SETUP -#line 850 "ob_proxy_parser_utf8.l" +#line 872 "ob_proxy_parser_utf8.l" { POP_STATE(); return ','; } YY_BREAK -case 238: +case 246: YY_RULE_SETUP -#line 854 "ob_proxy_parser_utf8.l" +#line 876 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7251,15 +7458,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 239: -/* rule 239 can match eol */ +case 247: +/* rule 247 can match eol */ YY_RULE_SETUP -#line 865 "ob_proxy_parser_utf8.l" +#line 887 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 240: +case 248: YY_RULE_SETUP -#line 866 "ob_proxy_parser_utf8.l" +#line 888 "ob_proxy_parser_utf8.l" { do { PUSH_STATE(in_odp_comment_value_expr_calc) @@ -7272,10 +7479,10 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 241: -/* rule 241 can match eol */ +case 249: +/* rule 249 can match eol */ YY_RULE_SETUP -#line 878 "ob_proxy_parser_utf8.l" +#line 900 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7288,9 +7495,9 @@ YY_RULE_SETUP } } YY_BREAK -case 242: +case 250: YY_RULE_SETUP -#line 890 "ob_proxy_parser_utf8.l" +#line 912 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7298,90 +7505,95 @@ YY_RULE_SETUP } } YY_BREAK -case 243: +case 251: YY_RULE_SETUP -#line 897 "ob_proxy_parser_utf8.l" +#line 919 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_dbp_comment_expr); RETURN_SHARD_COMMENT(DBP_COMMENT); } YY_BREAK -case 244: +case 252: YY_RULE_SETUP -#line 898 "ob_proxy_parser_utf8.l" +#line 920 "ob_proxy_parser_utf8.l" { return ROUTE_TAG; } YY_BREAK -case 245: +case 253: YY_RULE_SETUP -#line 899 "ob_proxy_parser_utf8.l" +#line 921 "ob_proxy_parser_utf8.l" { return SYS_TAG; } YY_BREAK -case 246: +case 254: YY_RULE_SETUP -#line 900 "ob_proxy_parser_utf8.l" +#line 922 "ob_proxy_parser_utf8.l" { return SCAN_ALL; } YY_BREAK -case 247: +case 255: YY_RULE_SETUP -#line 901 "ob_proxy_parser_utf8.l" +#line 923 "ob_proxy_parser_utf8.l" +{ return STICKY_SESSION; } + YY_BREAK +case 256: +YY_RULE_SETUP +#line 924 "ob_proxy_parser_utf8.l" { return SHARD_KEY; } YY_BREAK -case 248: +case 257: YY_RULE_SETUP -#line 902 "ob_proxy_parser_utf8.l" +#line 925 "ob_proxy_parser_utf8.l" { return TABLE_NAME;} YY_BREAK -case 249: +case 258: YY_RULE_SETUP -#line 903 "ob_proxy_parser_utf8.l" +#line 926 "ob_proxy_parser_utf8.l" { return PARALL; } YY_BREAK -case 250: +case 259: YY_RULE_SETUP -#line 904 "ob_proxy_parser_utf8.l" +#line 927 "ob_proxy_parser_utf8.l" { return GROUP_ID; } YY_BREAK -case 251: +case 260: YY_RULE_SETUP -#line 905 "ob_proxy_parser_utf8.l" +#line 928 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_dbp_comment_trace_expr); return TRACE; } YY_BREAK -case 252: +case 261: YY_RULE_SETUP -#line 906 "ob_proxy_parser_utf8.l" +#line 929 "ob_proxy_parser_utf8.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 253: +case 262: YY_RULE_SETUP -#line 907 "ob_proxy_parser_utf8.l" +#line 930 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 254: +case 263: YY_RULE_SETUP -#line 908 "ob_proxy_parser_utf8.l" +#line 931 "ob_proxy_parser_utf8.l" { return '('; } YY_BREAK -case 255: +case 264: YY_RULE_SETUP -#line 909 "ob_proxy_parser_utf8.l" +#line 932 "ob_proxy_parser_utf8.l" { return ')'; } YY_BREAK -case 256: +case 265: YY_RULE_SETUP -#line 910 "ob_proxy_parser_utf8.l" +#line 933 "ob_proxy_parser_utf8.l" { return ','; } YY_BREAK -case 257: -/* rule 257 can match eol */ +case 266: +/* rule 266 can match eol */ YY_RULE_SETUP -#line 911 "ob_proxy_parser_utf8.l" +#line 934 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 258: +case 267: YY_RULE_SETUP -#line 912 "ob_proxy_parser_utf8.l" +#line 935 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 259: +case 268: YY_RULE_SETUP -#line 914 "ob_proxy_parser_utf8.l" +#line 937 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7393,39 +7605,39 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 260: +case 269: YY_RULE_SETUP -#line 924 "ob_proxy_parser_utf8.l" +#line 947 "ob_proxy_parser_utf8.l" {return yytext[0];} YY_BREAK -case 261: +case 270: YY_RULE_SETUP -#line 925 "ob_proxy_parser_utf8.l" +#line 948 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_dbp_comment_trace_value_expr); return '('; } YY_BREAK -case 262: -/* rule 262 can match eol */ +case 271: +/* rule 271 can match eol */ YY_RULE_SETUP -#line 926 "ob_proxy_parser_utf8.l" +#line 949 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 263: +case 272: YY_RULE_SETUP -#line 928 "ob_proxy_parser_utf8.l" +#line 951 "ob_proxy_parser_utf8.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 264: +case 273: YY_RULE_SETUP -#line 929 "ob_proxy_parser_utf8.l" +#line 952 "ob_proxy_parser_utf8.l" { POP_STATE(); POP_STATE(); return ')'; } YY_BREAK -case 265: +case 274: YY_RULE_SETUP -#line 934 "ob_proxy_parser_utf8.l" +#line 957 "ob_proxy_parser_utf8.l" { do { PUSH_STATE(in_dbp_comment_trace_value_expr_calc) @@ -7439,9 +7651,9 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 266: +case 275: YY_RULE_SETUP -#line 946 "ob_proxy_parser_utf8.l" +#line 969 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7455,15 +7667,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 267: -/* rule 267 can match eol */ +case 276: +/* rule 276 can match eol */ YY_RULE_SETUP -#line 958 "ob_proxy_parser_utf8.l" +#line 981 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 268: +case 277: YY_RULE_SETUP -#line 959 "ob_proxy_parser_utf8.l" +#line 982 "ob_proxy_parser_utf8.l" { do { PUSH_STATE(in_dbp_comment_trace_value_expr_calc) @@ -7476,10 +7688,10 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 269: -/* rule 269 can match eol */ +case 278: +/* rule 278 can match eol */ YY_RULE_SETUP -#line 971 "ob_proxy_parser_utf8.l" +#line 994 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7492,9 +7704,9 @@ YY_RULE_SETUP } } YY_BREAK -case 270: +case 279: YY_RULE_SETUP -#line 983 "ob_proxy_parser_utf8.l" +#line 1006 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7503,9 +7715,9 @@ YY_RULE_SETUP } YY_BREAK /* quote */ -case 271: +case 280: YY_RULE_SETUP -#line 991 "ob_proxy_parser_utf8.l" +#line 1014 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7516,10 +7728,10 @@ YY_RULE_SETUP } } YY_BREAK -case 272: -/* rule 272 can match eol */ +case 281: +/* rule 281 can match eol */ YY_RULE_SETUP -#line 1001 "ob_proxy_parser_utf8.l" +#line 1024 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7527,9 +7739,9 @@ YY_RULE_SETUP } } YY_BREAK -case 273: +case 282: YY_RULE_SETUP -#line 1008 "ob_proxy_parser_utf8.l" +#line 1031 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7547,32 +7759,32 @@ YY_RULE_SETUP } } YY_BREAK -case 274: +case 283: YY_RULE_SETUP -#line 1025 "ob_proxy_parser_utf8.l" +#line 1048 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 275: -/* rule 275 can match eol */ +case 284: +/* rule 284 can match eol */ YY_RULE_SETUP -#line 1026 "ob_proxy_parser_utf8.l" +#line 1049 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 276: -/* rule 276 can match eol */ +case 285: +/* rule 285 can match eol */ YY_RULE_SETUP -#line 1027 "ob_proxy_parser_utf8.l" +#line 1050 "ob_proxy_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 1028 "ob_proxy_parser_utf8.l" +#line 1051 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK /* comment sq return name_str */ -case 277: -/* rule 277 can match eol */ +case 286: +/* rule 286 can match eol */ YY_RULE_SETUP -#line 1031 "ob_proxy_parser_utf8.l" +#line 1054 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7580,9 +7792,9 @@ YY_RULE_SETUP } } YY_BREAK -case 278: +case 287: YY_RULE_SETUP -#line 1038 "ob_proxy_parser_utf8.l" +#line 1061 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7594,31 +7806,31 @@ YY_RULE_SETUP } } YY_BREAK -case 279: +case 288: YY_RULE_SETUP -#line 1049 "ob_proxy_parser_utf8.l" +#line 1072 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 280: -/* rule 280 can match eol */ +case 289: +/* rule 289 can match eol */ YY_RULE_SETUP -#line 1050 "ob_proxy_parser_utf8.l" +#line 1073 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 281: -/* rule 281 can match eol */ +case 290: +/* rule 290 can match eol */ YY_RULE_SETUP -#line 1051 "ob_proxy_parser_utf8.l" +#line 1074 "ob_proxy_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(comment_sq): -#line 1052 "ob_proxy_parser_utf8.l" +#line 1075 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK /* dquote */ -case 282: +case 291: YY_RULE_SETUP -#line 1055 "ob_proxy_parser_utf8.l" +#line 1078 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7629,10 +7841,10 @@ YY_RULE_SETUP } } YY_BREAK -case 283: -/* rule 283 can match eol */ +case 292: +/* rule 292 can match eol */ YY_RULE_SETUP -#line 1065 "ob_proxy_parser_utf8.l" +#line 1088 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7640,9 +7852,9 @@ YY_RULE_SETUP } } YY_BREAK -case 284: +case 293: YY_RULE_SETUP -#line 1072 "ob_proxy_parser_utf8.l" +#line 1095 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7660,31 +7872,31 @@ YY_RULE_SETUP } } YY_BREAK -case 285: +case 294: YY_RULE_SETUP -#line 1089 "ob_proxy_parser_utf8.l" +#line 1112 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 286: -/* rule 286 can match eol */ +case 295: +/* rule 295 can match eol */ YY_RULE_SETUP -#line 1090 "ob_proxy_parser_utf8.l" +#line 1113 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 287: -/* rule 287 can match eol */ +case 296: +/* rule 296 can match eol */ YY_RULE_SETUP -#line 1091 "ob_proxy_parser_utf8.l" +#line 1114 "ob_proxy_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 1092 "ob_proxy_parser_utf8.l" +#line 1115 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK /* backtick */ -case 288: +case 297: YY_RULE_SETUP -#line 1096 "ob_proxy_parser_utf8.l" +#line 1119 "ob_proxy_parser_utf8.l" { PUSH_STATE(bt); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7695,9 +7907,9 @@ YY_RULE_SETUP } } YY_BREAK -case 289: +case 298: YY_RULE_SETUP -#line 1106 "ob_proxy_parser_utf8.l" +#line 1129 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -7705,10 +7917,10 @@ YY_RULE_SETUP } } YY_BREAK -case 290: -/* rule 290 can match eol */ +case 299: +/* rule 299 can match eol */ YY_RULE_SETUP -#line 1113 "ob_proxy_parser_utf8.l" +#line 1136 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -7717,9 +7929,9 @@ YY_RULE_SETUP } } YY_BREAK -case 291: +case 300: YY_RULE_SETUP -#line 1121 "ob_proxy_parser_utf8.l" +#line 1144 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7733,248 +7945,242 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 1133 "ob_proxy_parser_utf8.l" +#line 1156 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK -case 292: +case 301: YY_RULE_SETUP -#line 1137 "ob_proxy_parser_utf8.l" +#line 1160 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 293: -/* rule 293 can match eol */ +case 302: +/* rule 302 can match eol */ YY_RULE_SETUP -#line 1138 "ob_proxy_parser_utf8.l" +#line 1161 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 294: +case 303: YY_RULE_SETUP -#line 1139 "ob_proxy_parser_utf8.l" +#line 1162 "ob_proxy_parser_utf8.l" { POP_STATE(); RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(bt_in_expr): -#line 1140 "ob_proxy_parser_utf8.l" +#line 1163 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK /* some useful keyword */ -case 295: -/* rule 295 can match eol */ +case 304: +/* rule 304 can match eol */ YY_RULE_SETUP -#line 1143 "ob_proxy_parser_utf8.l" +#line 1166 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD_FOR_DUAL(); } YY_BREAK -case 296: +case 305: YY_RULE_SETUP -#line 1144 "ob_proxy_parser_utf8.l" +#line 1167 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } YY_BREAK -case 297: +case 306: YY_RULE_SETUP -#line 1145 "ob_proxy_parser_utf8.l" +#line 1168 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 298: +case 307: YY_RULE_SETUP -#line 1146 "ob_proxy_parser_utf8.l" +#line 1169 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); } YY_BREAK -case 299: +case 308: YY_RULE_SETUP -#line 1147 "ob_proxy_parser_utf8.l" +#line 1170 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); } YY_BREAK -case 300: +case 309: YY_RULE_SETUP -#line 1148 "ob_proxy_parser_utf8.l" +#line 1171 "ob_proxy_parser_utf8.l" { PUSH_STATE(bt_in_expr); } YY_BREAK -case 301: +case 310: YY_RULE_SETUP -#line 1149 "ob_proxy_parser_utf8.l" +#line 1172 "ob_proxy_parser_utf8.l" { SET_FOUND_ROWS(); RETURN_IGNORED_WORD(); } YY_BREAK -case 302: +case 311: YY_RULE_SETUP -#line 1150 "ob_proxy_parser_utf8.l" +#line 1173 "ob_proxy_parser_utf8.l" { SET_ROW_COUNT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 303: +case 312: YY_RULE_SETUP -#line 1151 "ob_proxy_parser_utf8.l" +#line 1174 "ob_proxy_parser_utf8.l" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } YY_BREAK -case 304: +case 313: YY_RULE_SETUP -#line 1152 "ob_proxy_parser_utf8.l" +#line 1175 "ob_proxy_parser_utf8.l" { SET_GLOBAL_SET_STMT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 305: -/* rule 305 can match eol */ +case 314: +/* rule 314 can match eol */ YY_RULE_SETUP -#line 1153 "ob_proxy_parser_utf8.l" +#line 1176 "ob_proxy_parser_utf8.l" { RETURN_COL_NAME(TX_READ_ONLY); } YY_BREAK -case 306: -/* rule 306 can match eol */ -YY_RULE_SETUP -#line 1154 "ob_proxy_parser_utf8.l" -{ return AUTOCOMMIT_0; } - YY_BREAK -case 307: +case 315: YY_RULE_SETUP -#line 1155 "ob_proxy_parser_utf8.l" +#line 1177 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(in_expr): -#line 1156 "ob_proxy_parser_utf8.l" +#line 1178 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 308: -/* rule 308 can match eol */ +case 316: +/* rule 316 can match eol */ YY_RULE_SETUP -#line 1157 "ob_proxy_parser_utf8.l" +#line 1179 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 309: +case 317: YY_RULE_SETUP -#line 1158 "ob_proxy_parser_utf8.l" +#line 1180 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK -case 310: +case 318: YY_RULE_SETUP -#line 1159 "ob_proxy_parser_utf8.l" +#line 1181 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 311: +case 319: YY_RULE_SETUP -#line 1161 "ob_proxy_parser_utf8.l" +#line 1183 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_expr); return SELECT; } YY_BREAK -case 312: +case 320: YY_RULE_SETUP -#line 1162 "ob_proxy_parser_utf8.l" +#line 1184 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 313: +case 321: YY_RULE_SETUP -#line 1163 "ob_proxy_parser_utf8.l" +#line 1185 "ob_proxy_parser_utf8.l" { POP_STATE(); return ')'; } YY_BREAK -case 314: +case 322: YY_RULE_SETUP -#line 1164 "ob_proxy_parser_utf8.l" +#line 1186 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); } YY_BREAK -case 315: +case 323: YY_RULE_SETUP -#line 1165 "ob_proxy_parser_utf8.l" +#line 1187 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); } YY_BREAK case YY_STATE_EOF(in_subquery): -#line 1166 "ob_proxy_parser_utf8.l" +#line 1188 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 316: -/* rule 316 can match eol */ +case 324: +/* rule 324 can match eol */ YY_RULE_SETUP -#line 1167 "ob_proxy_parser_utf8.l" +#line 1189 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 317: +case 325: YY_RULE_SETUP -#line 1168 "ob_proxy_parser_utf8.l" +#line 1190 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_no_select_query); RETURN_IGNORED_WORD(); } YY_BREAK -case 318: +case 326: YY_RULE_SETUP -#line 1170 "ob_proxy_parser_utf8.l" +#line 1192 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 319: +case 327: YY_RULE_SETUP -#line 1171 "ob_proxy_parser_utf8.l" +#line 1193 "ob_proxy_parser_utf8.l" { POP_STATE(); POP_STATE(); return ')'; } YY_BREAK -case 320: +case 328: YY_RULE_SETUP -#line 1172 "ob_proxy_parser_utf8.l" +#line 1194 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); } YY_BREAK -case 321: +case 329: YY_RULE_SETUP -#line 1173 "ob_proxy_parser_utf8.l" +#line 1195 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); } YY_BREAK -case 322: +case 330: YY_RULE_SETUP -#line 1174 "ob_proxy_parser_utf8.l" +#line 1196 "ob_proxy_parser_utf8.l" { SET_FOUND_ROWS(); RETURN_IGNORED_WORD(); } YY_BREAK -case 323: +case 331: YY_RULE_SETUP -#line 1175 "ob_proxy_parser_utf8.l" +#line 1197 "ob_proxy_parser_utf8.l" { SET_ROW_COUNT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 324: +case 332: YY_RULE_SETUP -#line 1176 "ob_proxy_parser_utf8.l" +#line 1198 "ob_proxy_parser_utf8.l" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } YY_BREAK -case 325: +case 333: YY_RULE_SETUP -#line 1177 "ob_proxy_parser_utf8.l" +#line 1199 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(in_no_select_query): -#line 1178 "ob_proxy_parser_utf8.l" +#line 1200 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 326: -/* rule 326 can match eol */ +case 334: +/* rule 334 can match eol */ YY_RULE_SETUP -#line 1179 "ob_proxy_parser_utf8.l" +#line 1201 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 327: +case 335: YY_RULE_SETUP -#line 1180 "ob_proxy_parser_utf8.l" +#line 1202 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 328: +case 336: YY_RULE_SETUP -#line 1182 "ob_proxy_parser_utf8.l" +#line 1204 "ob_proxy_parser_utf8.l" { return FROM; } YY_BREAK -case 329: +case 337: YY_RULE_SETUP -#line 1183 "ob_proxy_parser_utf8.l" +#line 1205 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 330: +case 338: YY_RULE_SETUP -#line 1184 "ob_proxy_parser_utf8.l" +#line 1206 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 331: +case 339: YY_RULE_SETUP -#line 1185 "ob_proxy_parser_utf8.l" +#line 1207 "ob_proxy_parser_utf8.l" { POP_STATE(); } YY_BREAK -case 332: +case 340: YY_RULE_SETUP -#line 1186 "ob_proxy_parser_utf8.l" +#line 1208 "ob_proxy_parser_utf8.l" { POP_STATE(); } YY_BREAK -case 333: +case 341: YY_RULE_SETUP -#line 1188 "ob_proxy_parser_utf8.l" -{ POP_STATE(); return BEGI;} +#line 1210 "ob_proxy_parser_utf8.l" +{ POP_STATE(); RETURN_NON_RESERVED_KEYWORD(BEGI);} YY_BREAK -case 334: +case 342: YY_RULE_SETUP -#line 1189 "ob_proxy_parser_utf8.l" +#line 1211 "ob_proxy_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(INITIAL): @@ -7993,21 +8199,22 @@ case YY_STATE_EOF(in_dbp_comment_trace_value_expr_calc): case YY_STATE_EOF(in_anonymous_block): case YY_STATE_EOF(prepare): case YY_STATE_EOF(insert_all_expr): +case YY_STATE_EOF(show_topology): case YY_STATE_EOF(proxy_icmd_state): -#line 1191 "ob_proxy_parser_utf8.l" +#line 1213 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 335: +case 343: YY_RULE_SETUP -#line 1192 "ob_proxy_parser_utf8.l" +#line 1214 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 336: +case 344: YY_RULE_SETUP -#line 1193 "ob_proxy_parser_utf8.l" +#line 1215 "ob_proxy_parser_utf8.l" ECHO; YY_BREAK -#line 8013 "ob_proxy_parser_utf8_lex.c" +#line 8220 "ob_proxy_parser_utf8_lex.c" case YY_END_OF_BUFFER: { @@ -8299,7 +8506,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2597 ) + if ( yy_current_state >= 2787 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -8328,11 +8535,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2597 ) + if ( yy_current_state >= 2787 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 2596); + yy_is_jam = (yy_current_state == 2786); return yy_is_jam ? 0 : yy_current_state; } @@ -9157,7 +9364,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 1193 "ob_proxy_parser_utf8.l" +#line 1215 "ob_proxy_parser_utf8.l" inline void *ob_proxy_parser_utf8_yyalloc(size_t bytes,void *yyscanner) @@ -9367,96 +9574,104 @@ extern int ob_proxy_parser_utf8_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h index 486cb751..4cb2afb9 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h @@ -244,9 +244,10 @@ void ob_proxy_parser_utf8_yyfree (void * ,yyscan_t yyscanner ); #define prepare 22 #define insert_all_expr 23 #define set_expr 24 -#define show_topology 25 -#define show_tables 26 -#define proxy_icmd_state 27 +#define show_elastic_id 25 +#define show_topology 26 +#define show_tables 27 +#define proxy_icmd_state 28 #endif @@ -364,9 +365,9 @@ extern int ob_proxy_parser_utf8_yylex \ #undef YY_DECL #endif -#line 1193 "ob_proxy_parser_utf8.l" +#line 1215 "ob_proxy_parser_utf8.l" -#line 371 "ob_proxy_parser_utf8_lex.h" +#line 372 "ob_proxy_parser_utf8_lex.h" #undef ob_proxy_parser_utf8_yyIN_HEADER #endif /* ob_proxy_parser_utf8_yyHEADER_H */ diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c index 48704e9f..0ae9f526 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c +++ b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c @@ -112,9 +112,6 @@ static inline void handle_stmt_end(ObProxyParseResult* result) case OBPROXY_T_SELECT_TX_RO: result->stmt_type_ = OBPROXY_T_SELECT; break; - case OBPROXY_T_SET_AC_0: - result->stmt_type_ = OBPROXY_T_OTHERS; - break; case OBPROXY_T_BEGIN: result->stmt_type_ = OBPROXY_T_OTHERS; break; @@ -133,7 +130,7 @@ static inline void handle_stmt_end(ObProxyParseResult* result) } } else { result->stmt_type_ = result->cur_stmt_type_; - } + } if (OBPROXY_T_TEXT_PS_PREPARE == result->text_ps_inner_stmt_type_) { ObProxyBasicStmtType tmp_type = result->cur_stmt_type_; @@ -459,96 +456,104 @@ extern int ob_proxy_parser_utf8_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif @@ -811,22 +816,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 322 +#define YYFINAL 314 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1614 +#define YYLAST 1384 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 182 +#define YYNTOKENS 190 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 137 +#define YYNNTS 138 /* YYNRULES -- Number of rules. */ -#define YYNRULES 442 +#define YYNRULES 435 /* YYNRULES -- Number of states. */ -#define YYNSTATES 713 +#define YYNSTATES 715 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 425 +#define YYMAXUTOK 433 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -837,16 +842,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 180, 2, 2, 2, 2, - 175, 176, 181, 2, 173, 2, 177, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 171, - 2, 174, 2, 2, 172, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 188, 2, 2, 2, 2, + 183, 184, 189, 2, 181, 2, 185, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 179, + 2, 182, 2, 2, 180, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 178, 2, 179, 2, 2, 2, 2, + 2, 2, 2, 186, 2, 187, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -876,7 +881,8 @@ static const yytype_uint8 yytranslate[] = 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170 + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178 }; #if YYDEBUG @@ -887,234 +893,231 @@ static const yytype_uint16 yyprhs[] = 0, 0, 3, 5, 7, 9, 12, 15, 18, 22, 24, 27, 31, 33, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, - 68, 70, 72, 74, 76, 78, 80, 82, 84, 88, - 91, 94, 97, 100, 103, 106, 108, 110, 113, 115, - 117, 119, 121, 122, 124, 126, 129, 131, 133, 135, - 137, 139, 141, 143, 145, 148, 153, 156, 158, 160, - 164, 167, 171, 174, 177, 181, 185, 187, 189, 191, - 193, 195, 197, 199, 201, 203, 206, 208, 210, 212, - 213, 216, 217, 219, 222, 228, 232, 234, 238, 241, - 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, - 265, 267, 269, 271, 273, 276, 279, 283, 289, 293, - 299, 300, 303, 304, 307, 311, 315, 321, 323, 325, - 329, 335, 343, 345, 349, 351, 353, 355, 357, 359, - 361, 367, 369, 373, 379, 380, 382, 386, 388, 390, - 392, 395, 399, 401, 403, 406, 408, 411, 415, 419, - 421, 423, 425, 426, 430, 432, 436, 440, 446, 449, - 452, 457, 460, 463, 467, 469, 474, 481, 486, 492, - 499, 504, 508, 510, 512, 514, 516, 519, 523, 529, - 536, 543, 550, 557, 564, 572, 579, 586, 593, 600, - 609, 618, 619, 622, 625, 628, 630, 634, 636, 641, - 646, 650, 657, 662, 667, 674, 678, 680, 684, 685, - 689, 693, 697, 701, 705, 709, 713, 717, 721, 725, - 731, 735, 736, 738, 739, 741, 743, 745, 747, 750, - 752, 755, 757, 760, 763, 767, 768, 770, 773, 775, - 778, 780, 783, 786, 787, 790, 795, 797, 802, 808, - 810, 815, 820, 826, 827, 829, 831, 833, 834, 836, - 840, 844, 847, 849, 851, 853, 855, 857, 859, 861, - 863, 865, 867, 869, 871, 873, 875, 877, 879, 881, - 883, 885, 887, 889, 891, 893, 894, 897, 902, 907, - 908, 911, 912, 915, 918, 920, 922, 926, 929, 933, - 938, 940, 943, 944, 947, 951, 954, 957, 960, 961, - 964, 968, 971, 975, 978, 982, 986, 991, 993, 996, - 999, 1003, 1006, 1009, 1010, 1012, 1014, 1017, 1020, 1024, - 1027, 1029, 1032, 1034, 1037, 1040, 1043, 1046, 1047, 1049, - 1053, 1059, 1062, 1066, 1069, 1070, 1072, 1075, 1078, 1081, - 1084, 1089, 1095, 1101, 1105, 1107, 1110, 1114, 1118, 1121, - 1124, 1128, 1132, 1133, 1136, 1138, 1142, 1146, 1150, 1151, - 1153, 1155, 1159, 1162, 1166, 1169, 1172, 1174, 1175, 1178, - 1183, 1186, 1188, 1192, 1195, 1200, 1204, 1210, 1212, 1214, - 1216, 1218, 1220, 1222, 1224, 1226, 1228, 1230, 1232, 1234, - 1236, 1238, 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, - 1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274, - 1276, 1278, 1280, 1282, 1284, 1286, 1288, 1290, 1292, 1294, - 1296, 1298, 1300 + 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, + 90, 93, 96, 99, 102, 105, 108, 110, 112, 115, + 117, 119, 121, 123, 124, 126, 128, 131, 133, 135, + 137, 139, 141, 143, 145, 147, 150, 155, 158, 160, + 162, 166, 169, 173, 176, 179, 183, 187, 189, 191, + 193, 195, 197, 199, 201, 203, 205, 208, 210, 212, + 214, 215, 218, 219, 221, 224, 230, 234, 236, 240, + 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, + 262, 264, 266, 268, 271, 274, 278, 284, 288, 294, + 295, 298, 299, 302, 306, 310, 316, 318, 320, 324, + 330, 338, 340, 344, 346, 350, 352, 354, 356, 358, + 360, 362, 368, 370, 374, 380, 381, 383, 387, 389, + 391, 393, 396, 400, 402, 404, 407, 409, 412, 416, + 420, 422, 424, 426, 427, 431, 433, 437, 441, 447, + 450, 453, 458, 461, 464, 468, 470, 475, 482, 487, + 493, 500, 505, 509, 511, 513, 515, 517, 520, 524, + 530, 537, 544, 551, 558, 565, 573, 580, 587, 594, + 601, 610, 619, 626, 627, 630, 633, 636, 638, 642, + 644, 649, 654, 658, 665, 669, 674, 679, 686, 690, + 692, 696, 697, 701, 705, 709, 713, 717, 721, 725, + 729, 733, 737, 741, 747, 751, 752, 754, 755, 757, + 759, 761, 763, 766, 768, 771, 773, 776, 779, 783, + 784, 786, 789, 791, 794, 796, 799, 802, 803, 806, + 811, 813, 818, 824, 826, 831, 836, 842, 843, 845, + 847, 849, 850, 852, 856, 860, 863, 865, 867, 869, + 871, 873, 875, 877, 879, 881, 883, 885, 887, 889, + 891, 893, 895, 897, 899, 901, 903, 905, 907, 909, + 911, 913, 915, 917, 919, 921, 922, 925, 930, 935, + 936, 939, 940, 943, 946, 948, 950, 954, 957, 961, + 966, 968, 971, 972, 975, 979, 982, 985, 988, 989, + 992, 996, 999, 1003, 1006, 1010, 1014, 1019, 1021, 1024, + 1027, 1031, 1034, 1037, 1038, 1040, 1042, 1045, 1048, 1052, + 1055, 1057, 1060, 1062, 1065, 1068, 1071, 1074, 1075, 1077, + 1081, 1087, 1090, 1094, 1097, 1098, 1100, 1103, 1106, 1109, + 1112, 1117, 1123, 1129, 1133, 1135, 1138, 1142, 1146, 1149, + 1152, 1156, 1160, 1161, 1164, 1166, 1170, 1174, 1178, 1179, + 1181, 1183, 1187, 1190, 1194, 1197, 1200, 1202, 1203, 1206, + 1211, 1214, 1216, 1220, 1223, 1228, 1232, 1238, 1240, 1242, + 1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258, 1260, 1262, + 1264, 1266, 1268, 1270, 1272, 1274, 1276, 1278, 1280, 1282, + 1284, 1286, 1288, 1290, 1292, 1294 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 183, 0, -1, 184, -1, 1, -1, 185, -1, 184, - 185, -1, 186, 50, -1, 186, 171, -1, 186, 171, - 50, -1, 171, -1, 171, 50, -1, 56, 186, 171, - -1, 187, -1, 246, 187, -1, 188, -1, 237, -1, - 242, -1, 238, -1, 239, -1, 240, -1, 189, -1, - 307, -1, 272, -1, 208, -1, 273, -1, 311, -1, - 312, -1, 220, -1, 221, -1, 222, -1, 223, -1, - 224, -1, 225, -1, 226, -1, 190, -1, 199, -1, - 241, -1, 313, -1, 260, 204, 203, -1, 201, 188, - -1, 201, 237, -1, 201, 239, -1, 201, 240, -1, - 201, 238, -1, 201, 241, -1, 191, -1, 200, -1, - 14, 192, -1, 15, -1, 16, -1, 17, -1, 18, - -1, -1, 19, -1, 64, -1, 21, 64, -1, 188, - -1, 237, -1, 238, -1, 240, -1, 239, -1, 313, - -1, 226, -1, 241, -1, 172, 85, -1, 194, 173, - 172, 85, -1, 172, 85, -1, 195, -1, 193, -1, - 29, 318, 27, -1, 30, 318, -1, 30, 318, 31, - -1, 197, 196, -1, 198, 194, -1, 15, 29, 318, - -1, 32, 29, 318, -1, 22, -1, 23, -1, 24, - -1, 25, -1, 53, -1, 26, -1, 54, -1, 55, - -1, 202, -1, 202, 85, -1, 86, -1, 87, -1, - 88, -1, -1, 27, 233, -1, -1, 230, -1, 5, - 80, -1, 5, 80, 204, 27, 233, -1, 5, 80, - 230, -1, 161, -1, 161, 71, 318, -1, 12, 81, - -1, 12, 81, 230, -1, 205, -1, 206, -1, 207, - -1, 218, -1, 219, -1, 209, -1, 217, -1, 216, - -1, 159, -1, 156, -1, 214, -1, 215, -1, 210, - -1, 211, -1, 160, 227, -1, 202, 227, -1, 162, - 27, 85, -1, 162, 27, 85, 27, 85, -1, 163, - 27, 85, -1, 163, 27, 85, 27, 85, -1, -1, - 133, 85, -1, -1, 27, 85, -1, 157, 213, 212, - -1, 158, 213, 212, -1, 11, 19, 20, 213, 212, - -1, 155, -1, 153, -1, 153, 27, 85, -1, 153, - 72, 154, 174, 85, -1, 153, 27, 85, 72, 154, - 174, 85, -1, 82, -1, 83, 174, 117, -1, 92, - -1, 93, -1, 94, -1, 95, -1, 96, -1, 97, - -1, 13, 227, 175, 228, 176, -1, 318, -1, 318, - 177, 318, -1, 318, 177, 318, 177, 318, -1, -1, - 229, -1, 228, 173, 229, -1, 85, -1, 117, -1, - 100, -1, 172, 85, -1, 172, 172, 85, -1, 49, - -1, 231, -1, 230, 231, -1, 232, -1, 175, 176, - -1, 175, 188, 176, -1, 175, 230, 176, -1, 315, - -1, 234, -1, 188, -1, -1, 175, 236, 176, -1, - 85, -1, 236, 173, 85, -1, 263, 316, 314, -1, - 263, 316, 314, 235, 234, -1, 265, 233, -1, 261, - 233, -1, 262, 271, 27, 233, -1, 266, 316, -1, - 12, 243, -1, 244, 173, 243, -1, 244, -1, 172, - 85, 174, 245, -1, 172, 172, 98, 85, 174, 245, - -1, 98, 85, 174, 245, -1, 172, 172, 85, 174, - 245, -1, 172, 172, 99, 85, 174, 245, -1, 99, - 85, 174, 245, -1, 85, 174, 245, -1, 85, -1, - 117, -1, 100, -1, 247, -1, 247, 246, -1, 40, - 248, 41, -1, 40, 105, 256, 255, 41, -1, 40, - 102, 174, 259, 255, 41, -1, 40, 113, 174, 259, - 255, 41, -1, 40, 101, 174, 259, 255, 41, -1, - 40, 103, 174, 259, 255, 41, -1, 40, 104, 174, - 259, 255, 41, -1, 40, 84, 85, 174, 258, 255, - 41, -1, 40, 108, 174, 257, 255, 41, -1, 40, - 109, 174, 257, 255, 41, -1, 40, 106, 174, 259, - 255, 41, -1, 40, 107, 174, 259, 255, 41, -1, - 40, 110, 111, 174, 178, 250, 179, 41, -1, 40, - 110, 112, 174, 178, 252, 179, 41, -1, -1, 248, - 249, -1, 42, 85, -1, 43, 85, -1, 85, -1, - 251, 173, 250, -1, 251, -1, 101, 175, 259, 176, - -1, 113, 175, 259, 176, -1, 114, 175, 176, -1, - 114, 175, 115, 174, 259, 176, -1, 116, 175, 253, - 176, -1, 68, 175, 257, 176, -1, 68, 175, 257, - 180, 257, 176, -1, 254, 173, 253, -1, 254, -1, - 85, 174, 259, -1, -1, 255, 173, 256, -1, 101, - 174, 259, -1, 102, 174, 259, -1, 113, 174, 259, - -1, 103, 174, 259, -1, 104, 174, 259, -1, 108, - 174, 257, -1, 109, 174, 257, -1, 106, 174, 259, - -1, 107, 174, 259, -1, 85, 177, 85, 174, 258, - -1, 85, 174, 258, -1, -1, 259, -1, -1, 259, - -1, 85, -1, 89, -1, 5, -1, 33, 267, -1, - 8, -1, 34, 267, -1, 6, -1, 35, 267, -1, - 7, 264, -1, 36, 267, 264, -1, -1, 128, -1, - 128, 52, -1, 9, -1, 37, 267, -1, 10, -1, - 38, 267, -1, 268, 39, -1, -1, 269, 268, -1, - 44, 175, 117, 176, -1, 117, -1, 45, 175, 270, - 176, -1, 64, 175, 85, 85, 176, -1, 85, -1, - 85, 175, 117, 176, -1, 85, 175, 85, 176, -1, - 85, 175, 85, 85, 176, -1, -1, 46, -1, 47, - -1, 48, -1, -1, 69, -1, 11, 306, 66, -1, - 11, 306, 67, -1, 11, 68, -1, 277, -1, 279, - -1, 280, -1, 283, -1, 281, -1, 285, -1, 286, - -1, 287, -1, 288, -1, 290, -1, 291, -1, 292, - -1, 293, -1, 294, -1, 296, -1, 297, -1, 299, - -1, 300, -1, 301, -1, 302, -1, 303, -1, 304, - -1, 305, -1, -1, 121, 117, -1, 121, 117, 173, - 117, -1, 121, 117, 122, 117, -1, -1, 133, 85, - -1, -1, 133, 85, -1, 118, 278, -1, 119, -1, - 120, -1, 120, 117, 274, -1, 130, 275, -1, 130, - 131, 275, -1, 130, 131, 132, 275, -1, 123, -1, - 125, 282, -1, -1, 126, 85, -1, 126, 133, 85, - -1, 126, 128, -1, 133, 85, -1, 124, 284, -1, - -1, 126, 275, -1, 126, 117, 275, -1, 129, 275, - -1, 129, 117, 275, -1, 127, 275, -1, 127, 117, - 275, -1, 127, 128, 275, -1, 127, 128, 117, 275, - -1, 134, -1, 134, 117, -1, 135, 275, -1, 135, - 152, 275, -1, 136, 275, -1, 137, 289, -1, -1, - 85, -1, 128, -1, 128, 85, -1, 138, 276, -1, - 138, 140, 276, -1, 138, 139, -1, 141, -1, 141, - 85, -1, 142, -1, 142, 143, -1, 144, 274, -1, - 144, 117, -1, 145, 295, -1, -1, 117, -1, 117, - 173, 117, -1, 117, 173, 117, 173, 85, -1, 146, - 275, -1, 146, 147, 275, -1, 148, 298, -1, -1, - 117, -1, 117, 117, -1, 149, 150, -1, 149, 151, - -1, 149, 152, -1, 164, 12, 85, 174, -1, 164, - 12, 85, 174, 85, -1, 164, 12, 85, 174, 117, - -1, 165, 6, 85, -1, 166, -1, 167, 117, -1, - 167, 117, 117, -1, 168, 85, 117, -1, 168, 85, - -1, 169, 117, -1, 169, 120, 117, -1, 169, 170, - 117, -1, -1, 70, 181, -1, 56, -1, 57, 58, - 308, -1, 65, 56, 85, -1, 65, 57, 85, -1, - -1, 309, -1, 310, -1, 309, 173, 310, -1, 59, - 60, -1, 61, 62, 63, -1, 90, 85, -1, 91, - 85, -1, 85, -1, -1, 139, 85, -1, 139, 175, - 85, 176, -1, 316, 314, -1, 318, -1, 318, 177, - 318, -1, 318, 318, -1, 318, 177, 318, 318, -1, - 318, 71, 318, -1, 318, 177, 318, 71, 318, -1, - 57, -1, 65, -1, 56, -1, 58, -1, 62, -1, - 67, -1, 66, -1, 70, -1, 69, -1, 68, -1, - 119, -1, 120, -1, 122, -1, 126, -1, 127, -1, - 129, -1, 131, -1, 132, -1, 143, -1, 147, -1, - 151, -1, 152, -1, 170, -1, 101, -1, 102, -1, - 103, -1, 104, -1, 154, -1, 105, -1, 106, -1, - 107, -1, 108, -1, 109, -1, 110, -1, 111, -1, - 112, -1, 113, -1, 115, -1, 114, -1, 116, -1, - 64, -1, 53, -1, 54, -1, 55, -1, 85, -1, - 317, -1 + 191, 0, -1, 192, -1, 1, -1, 193, -1, 192, + 193, -1, 194, 50, -1, 194, 179, -1, 194, 179, + 50, -1, 179, -1, 179, 50, -1, 56, 194, 179, + -1, 195, -1, 254, 195, -1, 196, -1, 245, -1, + 250, -1, 246, -1, 247, -1, 248, -1, 197, -1, + 316, -1, 280, -1, 215, -1, 281, -1, 320, -1, + 321, -1, 228, -1, 229, -1, 230, -1, 231, -1, + 232, -1, 233, -1, 234, -1, 198, -1, 207, -1, + 249, -1, 282, -1, 322, -1, 268, 212, 211, -1, + 209, 196, -1, 209, 245, -1, 209, 247, -1, 209, + 248, -1, 209, 246, -1, 209, 249, -1, 199, -1, + 208, -1, 14, 200, -1, 15, -1, 16, -1, 17, + -1, 18, -1, -1, 19, -1, 64, -1, 21, 64, + -1, 196, -1, 245, -1, 246, -1, 248, -1, 247, + -1, 322, -1, 234, -1, 249, -1, 180, 84, -1, + 202, 181, 180, 84, -1, 180, 84, -1, 203, -1, + 201, -1, 29, 327, 27, -1, 30, 327, -1, 30, + 327, 31, -1, 205, 204, -1, 206, 202, -1, 15, + 29, 327, -1, 32, 29, 327, -1, 22, -1, 23, + -1, 24, -1, 25, -1, 53, -1, 26, -1, 54, + -1, 55, -1, 210, -1, 210, 84, -1, 85, -1, + 86, -1, 87, -1, -1, 27, 241, -1, -1, 238, + -1, 5, 80, -1, 5, 80, 212, 27, 241, -1, + 5, 80, 238, -1, 163, -1, 163, 71, 327, -1, + 213, -1, 214, -1, 226, -1, 227, -1, 216, -1, + 224, -1, 225, -1, 223, -1, 161, -1, 158, -1, + 221, -1, 222, -1, 217, -1, 218, -1, 162, 235, + -1, 210, 327, -1, 164, 27, 84, -1, 164, 27, + 84, 27, 84, -1, 165, 27, 84, -1, 165, 27, + 84, 27, 84, -1, -1, 134, 84, -1, -1, 27, + 84, -1, 159, 220, 219, -1, 160, 220, 219, -1, + 11, 19, 20, 220, 219, -1, 157, -1, 154, -1, + 154, 27, 84, -1, 154, 72, 156, 182, 84, -1, + 154, 27, 84, 72, 156, 182, 84, -1, 155, -1, + 155, 27, 84, -1, 81, -1, 82, 182, 118, -1, + 91, -1, 92, -1, 93, -1, 94, -1, 95, -1, + 96, -1, 13, 235, 183, 236, 184, -1, 327, -1, + 327, 185, 327, -1, 327, 185, 327, 185, 327, -1, + -1, 237, -1, 236, 181, 237, -1, 84, -1, 118, + -1, 99, -1, 180, 84, -1, 180, 180, 84, -1, + 49, -1, 239, -1, 238, 239, -1, 240, -1, 183, + 184, -1, 183, 196, 184, -1, 183, 238, 184, -1, + 324, -1, 242, -1, 196, -1, -1, 183, 244, 184, + -1, 84, -1, 244, 181, 84, -1, 271, 325, 323, + -1, 271, 325, 323, 243, 242, -1, 273, 241, -1, + 269, 241, -1, 270, 279, 27, 241, -1, 274, 325, + -1, 12, 251, -1, 252, 181, 251, -1, 252, -1, + 180, 84, 182, 253, -1, 180, 180, 97, 84, 182, + 253, -1, 97, 84, 182, 253, -1, 180, 180, 84, + 182, 253, -1, 180, 180, 98, 84, 182, 253, -1, + 98, 84, 182, 253, -1, 84, 182, 253, -1, 84, + -1, 118, -1, 99, -1, 255, -1, 255, 254, -1, + 40, 256, 41, -1, 40, 104, 264, 263, 41, -1, + 40, 101, 182, 267, 263, 41, -1, 40, 113, 182, + 267, 263, 41, -1, 40, 100, 182, 267, 263, 41, + -1, 40, 102, 182, 267, 263, 41, -1, 40, 103, + 182, 267, 263, 41, -1, 40, 83, 84, 182, 266, + 263, 41, -1, 40, 107, 182, 265, 263, 41, -1, + 40, 108, 182, 265, 263, 41, -1, 40, 105, 182, + 267, 263, 41, -1, 40, 106, 182, 267, 263, 41, + -1, 40, 110, 111, 182, 186, 258, 187, 41, -1, + 40, 110, 112, 182, 186, 260, 187, 41, -1, 40, + 109, 182, 267, 263, 41, -1, -1, 256, 257, -1, + 42, 84, -1, 43, 84, -1, 84, -1, 259, 181, + 258, -1, 259, -1, 100, 183, 267, 184, -1, 113, + 183, 267, 184, -1, 114, 183, 184, -1, 114, 183, + 116, 182, 267, 184, -1, 115, 183, 184, -1, 117, + 183, 261, 184, -1, 68, 183, 265, 184, -1, 68, + 183, 265, 188, 265, 184, -1, 262, 181, 261, -1, + 262, -1, 84, 182, 267, -1, -1, 263, 181, 264, + -1, 100, 182, 267, -1, 101, 182, 267, -1, 113, + 182, 267, -1, 102, 182, 267, -1, 103, 182, 267, + -1, 107, 182, 265, -1, 108, 182, 265, -1, 105, + 182, 267, -1, 106, 182, 267, -1, 109, 182, 267, + -1, 84, 185, 84, 182, 266, -1, 84, 182, 266, + -1, -1, 267, -1, -1, 267, -1, 84, -1, 88, + -1, 5, -1, 33, 275, -1, 8, -1, 34, 275, + -1, 6, -1, 35, 275, -1, 7, 272, -1, 36, + 275, 272, -1, -1, 129, -1, 129, 52, -1, 9, + -1, 37, 275, -1, 10, -1, 38, 275, -1, 276, + 39, -1, -1, 277, 276, -1, 44, 183, 118, 184, + -1, 118, -1, 45, 183, 278, 184, -1, 64, 183, + 84, 84, 184, -1, 84, -1, 84, 183, 118, 184, + -1, 84, 183, 84, 184, -1, 84, 183, 84, 84, + 184, -1, -1, 46, -1, 47, -1, 48, -1, -1, + 69, -1, 11, 315, 66, -1, 11, 315, 67, -1, + 11, 68, -1, 286, -1, 288, -1, 289, -1, 292, + -1, 290, -1, 294, -1, 295, -1, 296, -1, 297, + -1, 299, -1, 300, -1, 301, -1, 302, -1, 303, + -1, 305, -1, 306, -1, 308, -1, 309, -1, 310, + -1, 311, -1, 312, -1, 313, -1, 314, -1, 173, + -1, 174, -1, 175, -1, 176, -1, 177, -1, 178, + -1, -1, 122, 118, -1, 122, 118, 181, 118, -1, + 122, 118, 123, 118, -1, -1, 134, 84, -1, -1, + 134, 84, -1, 119, 287, -1, 120, -1, 121, -1, + 121, 118, 283, -1, 131, 284, -1, 131, 132, 284, + -1, 131, 132, 133, 284, -1, 124, -1, 126, 291, + -1, -1, 127, 84, -1, 127, 134, 84, -1, 127, + 129, -1, 134, 84, -1, 125, 293, -1, -1, 127, + 284, -1, 127, 118, 284, -1, 130, 284, -1, 130, + 118, 284, -1, 128, 284, -1, 128, 118, 284, -1, + 128, 129, 284, -1, 128, 129, 118, 284, -1, 135, + -1, 135, 118, -1, 136, 284, -1, 136, 153, 284, + -1, 137, 284, -1, 138, 298, -1, -1, 84, -1, + 129, -1, 129, 84, -1, 139, 285, -1, 139, 141, + 285, -1, 139, 140, -1, 142, -1, 142, 84, -1, + 143, -1, 143, 144, -1, 145, 283, -1, 145, 118, + -1, 146, 304, -1, -1, 118, -1, 118, 181, 118, + -1, 118, 181, 118, 181, 84, -1, 147, 284, -1, + 147, 148, 284, -1, 149, 307, -1, -1, 118, -1, + 118, 118, -1, 150, 151, -1, 150, 152, -1, 150, + 153, -1, 166, 12, 84, 182, -1, 166, 12, 84, + 182, 84, -1, 166, 12, 84, 182, 118, -1, 167, + 6, 84, -1, 168, -1, 169, 118, -1, 169, 118, + 118, -1, 170, 84, 118, -1, 170, 84, -1, 171, + 118, -1, 171, 121, 118, -1, 171, 172, 118, -1, + -1, 70, 189, -1, 56, -1, 57, 58, 317, -1, + 65, 56, 84, -1, 65, 57, 84, -1, -1, 318, + -1, 319, -1, 318, 181, 319, -1, 59, 60, -1, + 61, 62, 63, -1, 89, 84, -1, 90, 84, -1, + 84, -1, -1, 140, 84, -1, 140, 183, 84, 184, + -1, 325, 323, -1, 327, -1, 327, 185, 327, -1, + 327, 327, -1, 327, 185, 327, 327, -1, 327, 71, + 327, -1, 327, 185, 327, 71, 327, -1, 57, -1, + 65, -1, 56, -1, 58, -1, 62, -1, 67, -1, + 66, -1, 70, -1, 69, -1, 68, -1, 120, -1, + 121, -1, 123, -1, 127, -1, 128, -1, 130, -1, + 132, -1, 133, -1, 144, -1, 148, -1, 152, -1, + 153, -1, 172, -1, 156, -1, 53, -1, 54, -1, + 55, -1, 84, -1, 326, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 336, 336, 337, 339, 340, 342, 343, 344, 345, - 346, 347, 349, 350, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 377, 379, - 380, 381, 382, 383, 384, 386, 387, 389, 390, 391, - 392, 393, 395, 396, 397, 398, 400, 401, 402, 403, - 404, 405, 406, 407, 409, 416, 424, 432, 433, 436, - 442, 447, 453, 456, 459, 464, 470, 471, 472, 473, - 474, 475, 476, 477, 479, 480, 482, 483, 484, 486, - 487, 489, 490, 492, 493, 494, 496, 497, 499, 500, - 502, 503, 504, 505, 506, 507, 509, 510, 511, 512, - 513, 514, 515, 516, 517, 518, 524, 529, 536, 541, - 548, 549, 551, 552, 554, 558, 563, 568, 570, 571, - 576, 581, 588, 591, 597, 598, 599, 600, 601, 602, - 605, 607, 611, 616, 624, 627, 632, 637, 642, 647, - 652, 657, 662, 670, 671, 673, 675, 676, 677, 679, - 680, 682, 684, 685, 687, 688, 690, 694, 695, 696, - 697, 698, 703, 705, 706, 708, 712, 716, 720, 724, - 728, 732, 736, 741, 746, 752, 753, 755, 756, 757, - 758, 759, 760, 761, 762, 768, 769, 770, 771, 772, - 773, 775, 776, 778, 779, 780, 782, 783, 785, 790, - 795, 796, 797, 799, 800, 802, 803, 805, 813, 814, - 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, - 831, 833, 834, 836, 837, 839, 840, 842, 843, 844, - 845, 846, 847, 848, 849, 851, 852, 853, 855, 856, - 857, 858, 859, 860, 861, 863, 864, 865, 866, 871, - 872, 873, 874, 876, 877, 878, 879, 881, 882, 885, - 886, 887, 890, 891, 892, 893, 894, 895, 896, 897, - 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, - 908, 909, 910, 911, 912, 917, 919, 923, 928, 936, - 937, 941, 942, 945, 947, 948, 949, 953, 954, 955, - 959, 961, 963, 964, 965, 966, 967, 970, 972, 973, - 974, 975, 976, 977, 978, 979, 980, 984, 985, 989, - 990, 995, 998, 1000, 1001, 1002, 1003, 1007, 1008, 1009, - 1013, 1014, 1018, 1019, 1023, 1024, 1027, 1029, 1030, 1031, - 1032, 1036, 1037, 1040, 1042, 1043, 1044, 1048, 1049, 1050, - 1054, 1055, 1056, 1060, 1064, 1068, 1069, 1073, 1074, 1078, - 1079, 1080, 1083, 1084, 1087, 1091, 1092, 1093, 1095, 1096, - 1098, 1099, 1102, 1103, 1106, 1112, 1115, 1117, 1118, 1119, - 1121, 1126, 1129, 1133, 1137, 1142, 1146, 1152, 1153, 1154, - 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, - 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, - 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, - 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, - 1195, 1197, 1198 + 0, 334, 334, 335, 337, 338, 340, 341, 342, 343, + 344, 345, 347, 348, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 376, + 378, 379, 380, 381, 382, 383, 385, 386, 388, 389, + 390, 391, 392, 394, 395, 396, 397, 399, 400, 401, + 402, 403, 404, 405, 406, 408, 415, 423, 431, 432, + 435, 441, 446, 452, 455, 458, 463, 469, 470, 471, + 472, 473, 474, 475, 476, 478, 479, 481, 482, 483, + 485, 486, 488, 489, 491, 492, 493, 495, 496, 498, + 499, 500, 501, 502, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 521, 526, 533, 538, 545, + 546, 548, 549, 551, 555, 560, 565, 567, 568, 573, + 578, 585, 586, 592, 595, 601, 602, 603, 604, 605, + 606, 609, 611, 615, 620, 628, 631, 636, 641, 646, + 651, 656, 661, 666, 674, 675, 677, 679, 680, 681, + 683, 684, 686, 688, 689, 691, 692, 694, 698, 699, + 700, 701, 702, 707, 709, 710, 712, 716, 720, 724, + 728, 732, 736, 740, 745, 750, 756, 757, 759, 760, + 761, 762, 763, 764, 765, 766, 772, 773, 774, 775, + 776, 777, 778, 779, 780, 782, 783, 784, 786, 787, + 789, 794, 799, 800, 801, 802, 804, 805, 807, 808, + 810, 818, 819, 821, 822, 823, 824, 825, 826, 827, + 828, 829, 830, 831, 837, 839, 840, 842, 843, 845, + 846, 848, 849, 850, 851, 852, 853, 854, 855, 857, + 858, 859, 861, 862, 863, 864, 865, 866, 867, 869, + 870, 871, 872, 877, 878, 879, 880, 882, 883, 884, + 885, 887, 888, 891, 892, 893, 896, 897, 898, 899, + 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, + 910, 911, 912, 913, 914, 915, 916, 917, 918, 920, + 921, 922, 923, 924, 925, 930, 932, 936, 941, 949, + 950, 954, 955, 958, 960, 961, 962, 966, 967, 968, + 972, 974, 976, 977, 978, 979, 980, 983, 985, 986, + 987, 988, 989, 990, 991, 992, 993, 997, 998, 1002, + 1003, 1008, 1011, 1013, 1014, 1015, 1016, 1020, 1021, 1022, + 1026, 1027, 1031, 1032, 1036, 1037, 1040, 1042, 1043, 1044, + 1045, 1049, 1050, 1053, 1055, 1056, 1057, 1061, 1062, 1063, + 1067, 1068, 1069, 1073, 1077, 1081, 1082, 1086, 1087, 1091, + 1092, 1093, 1096, 1097, 1100, 1104, 1105, 1106, 1108, 1109, + 1111, 1112, 1115, 1116, 1119, 1125, 1128, 1130, 1131, 1132, + 1134, 1139, 1142, 1146, 1150, 1155, 1159, 1165, 1166, 1167, + 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, + 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, + 1188, 1189, 1190, 1191, 1193, 1194 }; #endif @@ -1137,26 +1140,29 @@ static const char *const yytname[] = "ONLY", "WITH", "CONSISTENT", "SNAPSHOT", "INDEX", "XA", "WARNINGS", "ERRORS", "TRACE", "QUICK", "COUNT", "AS", "WHERE", "VALUES", "ORDER", "GROUP", "HAVING", "INTO", "UNION", "FOR", "TX_READ_ONLY", - "AUTOCOMMIT_0", "SELECT_OBPROXY_ROUTE_ADDR", "SET_OBPROXY_ROUTE_ADDR", - "NAME_OB_DOT", "NAME_OB", "EXPLAIN", "DESC", "DESCRIBE", "NAME_STR", - "USE", "HELP", "SET_NAMES", "SET_CHARSET", "SET_PASSWORD", "SET_DEFAULT", + "SELECT_OBPROXY_ROUTE_ADDR", "SET_OBPROXY_ROUTE_ADDR", "NAME_OB_DOT", + "NAME_OB", "EXPLAIN", "DESC", "DESCRIBE", "NAME_STR", "USE", "HELP", + "SET_NAMES", "SET_CHARSET", "SET_PASSWORD", "SET_DEFAULT", "SET_OB_READ_CONSISTENCY", "SET_TX_READ_ONLY", "GLOBAL", "SESSION", "NUMBER_VAL", "GROUP_ID", "TABLE_ID", "ELASTIC_ID", "TESTLOAD", "ODP_COMMENT", "TNT_ID", "DISASTER_STATUS", "TRACE_ID", "RPC_ID", - "DBP_COMMENT", "ROUTE_TAG", "SYS_TAG", "TABLE_NAME", "SCAN_ALL", - "PARALL", "SHARD_KEY", "INT_NUM", "SHOW_PROXYNET", "THREAD", - "CONNECTION", "LIMIT", "OFFSET", "SHOW_PROCESSLIST", "SHOW_PROXYSESSION", - "SHOW_GLOBALSESSION", "ATTRIBUTE", "VARIABLES", "ALL", "STAT", - "SHOW_PROXYCONFIG", "DIFF", "USER", "LIKE", "SHOW_PROXYSM", - "SHOW_PROXYCLUSTER", "SHOW_PROXYRESOURCE", "SHOW_PROXYCONGESTION", - "SHOW_PROXYROUTE", "PARTITION", "ROUTINE", "SHOW_PROXYVIP", - "SHOW_PROXYMEMORY", "OBJPOOL", "SHOW_SQLAUDIT", "SHOW_WARNLOG", - "SHOW_PROXYSTAT", "REFRESH", "SHOW_PROXYTRACE", "SHOW_PROXYINFO", - "BINARY", "UPGRADE", "IDC", "SHOW_TOPOLOGY", "GROUP_NAME", - "SHOW_DB_VERSION", "SHOW_DATABASES", "SHOW_TABLES", "SHOW_FULL_TABLES", - "SELECT_DATABASE", "SHOW_CREATE_TABLE", "SELECT_PROXY_VERSION", - "SHOW_COLUMNS", "SHOW_INDEX", "ALTER_PROXYCONFIG", "ALTER_PROXYRESOURCE", - "PING_PROXY", "KILL_PROXYSESSION", "KILL_GLOBALSESSION", "KILL", "QUERY", + "TARGET_DB_SERVER", "DBP_COMMENT", "ROUTE_TAG", "SYS_TAG", "TABLE_NAME", + "SCAN_ALL", "STICKY_SESSION", "PARALL", "SHARD_KEY", "INT_NUM", + "SHOW_PROXYNET", "THREAD", "CONNECTION", "LIMIT", "OFFSET", + "SHOW_PROCESSLIST", "SHOW_PROXYSESSION", "SHOW_GLOBALSESSION", + "ATTRIBUTE", "VARIABLES", "ALL", "STAT", "SHOW_PROXYCONFIG", "DIFF", + "USER", "LIKE", "SHOW_PROXYSM", "SHOW_PROXYCLUSTER", + "SHOW_PROXYRESOURCE", "SHOW_PROXYCONGESTION", "SHOW_PROXYROUTE", + "PARTITION", "ROUTINE", "SHOW_PROXYVIP", "SHOW_PROXYMEMORY", "OBJPOOL", + "SHOW_SQLAUDIT", "SHOW_WARNLOG", "SHOW_PROXYSTAT", "REFRESH", + "SHOW_PROXYTRACE", "SHOW_PROXYINFO", "BINARY", "UPGRADE", "IDC", + "SHOW_ELASTIC_ID", "SHOW_TOPOLOGY", "GROUP_NAME", "SHOW_DB_VERSION", + "SHOW_DATABASES", "SHOW_TABLES", "SHOW_FULL_TABLES", "SELECT_DATABASE", + "SHOW_CREATE_TABLE", "SELECT_PROXY_VERSION", "SHOW_COLUMNS", + "SHOW_INDEX", "ALTER_PROXYCONFIG", "ALTER_PROXYRESOURCE", "PING_PROXY", + "KILL_PROXYSESSION", "KILL_GLOBALSESSION", "KILL", "QUERY", + "SHOW_MASTER_STATUS", "SHOW_BINARY_LOGS", "SHOW_BINLOG_EVENTS", + "PURGE_BINARY_LOGS", "RESET_MASTER", "SHOW_BINLOG_SERVER_FOR_TENANT", "';'", "'@'", "','", "'='", "'('", "')'", "'.'", "'{'", "'}'", "'#'", "'*'", "$accept", "root", "sql_stmts", "sql_stmt", "comment_stmt", "stmt", "select_stmt", "explain_stmt", "ddl_stmt", "mysql_ddl_stmt", @@ -1165,10 +1171,10 @@ static const char *const yytname[] = "text_ps_prepare_stmt", "text_ps_execute_stmt", "text_ps_stmt", "oracle_ddl_stmt", "explain_or_desc_stmt", "explain_or_desc", "opt_from", "select_expr_list", "select_tx_read_only_stmt", - "select_proxy_version_stmt", "set_autocommit_0_stmt", "hooked_stmt", - "shard_special_stmt", "show_columns_stmt", "show_index_stmt", - "opt_show_like", "opt_show_from", "show_tables_stmt", - "show_table_status_stmt", "show_db_version_stmt", "show_es_id_stmt", + "select_proxy_version_stmt", "hooked_stmt", "shard_special_stmt", + "show_columns_stmt", "show_index_stmt", "opt_show_like", "opt_show_from", + "show_tables_stmt", "show_table_status_stmt", "show_db_version_stmt", + "show_es_id_stmt", "show_topology_stmt", "select_obproxy_route_addr_stmt", "set_obproxy_route_addr_stmt", "set_names_stmt", "set_charset_stmt", "set_password_stmt", "set_default_stmt", "set_ob_read_consistency_stmt", @@ -1185,8 +1191,8 @@ static const char *const yytname[] = "insert_with_opt_hint", "insert_all_when", "replace_with_opt_hint", "merge_with_opt_hint", "hint_list_with_end", "hint_list", "hint", "opt_read_consistency", "opt_quick", "show_stmt", "icmd_stmt", - "opt_limit", "opt_like", "opt_large_like", "show_proxynet", - "opt_show_net", "show_proxyconfig", "show_processlist", + "binlog_stmt", "opt_limit", "opt_like", "opt_large_like", + "show_proxynet", "opt_show_net", "show_proxyconfig", "show_processlist", "show_globalsession", "opt_show_global_session", "show_proxysession", "opt_show_session", "show_proxysm", "show_proxycluster", "show_proxyresource", "show_proxycongestion", "opt_show_congestion", @@ -1224,59 +1230,58 @@ static const yytype_uint16 yytoknum[] = 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 59, 64, 44, 61, 40, 41, 46, 123, 125, - 35, 42 + 425, 426, 427, 428, 429, 430, 431, 432, 433, 59, + 64, 44, 61, 40, 41, 46, 123, 125, 35, 42 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 182, 183, 183, 184, 184, 185, 185, 185, 185, - 185, 185, 186, 186, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 188, 189, - 189, 189, 189, 189, 189, 190, 190, 191, 191, 191, - 191, 191, 192, 192, 192, 192, 193, 193, 193, 193, - 193, 193, 193, 193, 194, 194, 195, 196, 196, 197, - 198, 198, 199, 199, 199, 199, 200, 200, 200, 200, - 200, 200, 200, 200, 201, 201, 202, 202, 202, 203, - 203, 204, 204, 205, 205, 205, 206, 206, 207, 207, - 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 210, 210, 211, 211, - 212, 212, 213, 213, 214, 214, 215, 216, 217, 217, - 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, - 229, 229, 229, 230, 230, 231, 232, 232, 232, 233, - 233, 234, 235, 235, 236, 236, 237, 237, 238, 239, - 240, 241, 242, 243, 243, 244, 244, 244, 244, 244, - 244, 244, 245, 245, 245, 246, 246, 247, 247, 247, - 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, - 247, 248, 248, 249, 249, 249, 250, 250, 251, 251, - 251, 251, 251, 252, 252, 253, 253, 254, 255, 255, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 257, 257, 258, 258, 259, 259, 260, 260, 261, - 261, 262, 262, 263, 263, 264, 264, 264, 265, 265, - 266, 266, 267, 268, 268, 269, 269, 269, 269, 269, - 269, 269, 269, 270, 270, 270, 270, 271, 271, 272, - 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 274, 274, 274, 274, 275, - 275, 276, 276, 277, 278, 278, 278, 279, 279, 279, - 280, 281, 282, 282, 282, 282, 282, 283, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 285, 285, 286, - 286, 287, 288, 289, 289, 289, 289, 290, 290, 290, - 291, 291, 292, 292, 293, 293, 294, 295, 295, 295, - 295, 296, 296, 297, 298, 298, 298, 299, 299, 299, - 300, 300, 300, 301, 302, 303, 303, 304, 304, 305, - 305, 305, 306, 306, 307, 307, 307, 307, 308, 308, - 309, 309, 310, 310, 311, 312, 313, 314, 314, 314, - 315, 316, 316, 316, 316, 316, 316, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 318, 318 + 0, 190, 191, 191, 192, 192, 193, 193, 193, 193, + 193, 193, 194, 194, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 196, + 197, 197, 197, 197, 197, 197, 198, 198, 199, 199, + 199, 199, 199, 200, 200, 200, 200, 201, 201, 201, + 201, 201, 201, 201, 201, 202, 202, 203, 204, 204, + 205, 206, 206, 207, 207, 207, 207, 208, 208, 208, + 208, 208, 208, 208, 208, 209, 209, 210, 210, 210, + 211, 211, 212, 212, 213, 213, 213, 214, 214, 215, + 215, 215, 215, 215, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 217, 217, 218, 218, 219, + 219, 220, 220, 221, 221, 222, 223, 224, 224, 224, + 224, 225, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 235, 235, 236, 236, 236, 237, 237, + 237, 237, 237, 237, 238, 238, 239, 240, 240, 240, + 241, 241, 242, 243, 243, 244, 244, 245, 245, 246, + 247, 248, 249, 250, 251, 251, 252, 252, 252, 252, + 252, 252, 252, 253, 253, 253, 254, 254, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 256, 256, 257, 257, 257, 258, 258, + 259, 259, 259, 259, 259, 259, 260, 260, 261, 261, + 262, 263, 263, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 265, 265, 266, 266, 267, + 267, 268, 268, 269, 269, 270, 270, 271, 271, 272, + 272, 272, 273, 273, 274, 274, 275, 276, 276, 277, + 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, + 278, 279, 279, 280, 280, 280, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, + 282, 282, 282, 282, 282, 283, 283, 283, 283, 284, + 284, 285, 285, 286, 287, 287, 287, 288, 288, 288, + 289, 290, 291, 291, 291, 291, 291, 292, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 294, 294, 295, + 295, 296, 297, 298, 298, 298, 298, 299, 299, 299, + 300, 300, 301, 301, 302, 302, 303, 304, 304, 304, + 304, 305, 305, 306, 307, 307, 307, 308, 308, 308, + 309, 309, 309, 310, 311, 312, 312, 313, 313, 314, + 314, 314, 315, 315, 316, 316, 316, 316, 317, 317, + 318, 318, 319, 319, 320, 321, 322, 323, 323, 323, + 324, 325, 325, 325, 325, 325, 325, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 327, 327 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -1285,31 +1290,32 @@ static const yytype_uint8 yyr2[] = 0, 2, 1, 1, 1, 2, 2, 2, 3, 1, 2, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, - 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, - 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 4, 2, 1, 1, 3, - 2, 3, 2, 2, 3, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, - 2, 0, 1, 2, 5, 3, 1, 3, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, + 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 4, 2, 1, 1, + 3, 2, 3, 2, 2, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 0, 2, 0, 1, 2, 5, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 3, 5, 3, 5, 0, + 2, 0, 2, 3, 3, 5, 1, 1, 3, 5, + 7, 1, 3, 1, 3, 1, 1, 1, 1, 1, + 1, 5, 1, 3, 5, 0, 1, 3, 1, 1, + 1, 2, 3, 1, 1, 2, 1, 2, 3, 3, + 1, 1, 1, 0, 3, 1, 3, 3, 5, 2, + 2, 4, 2, 2, 3, 1, 4, 6, 4, 5, + 6, 4, 3, 1, 1, 1, 1, 2, 3, 5, + 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, + 8, 8, 6, 0, 2, 2, 2, 1, 3, 1, + 4, 4, 3, 6, 3, 4, 4, 6, 3, 1, + 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 3, 0, 1, 0, 1, 1, + 1, 1, 2, 1, 2, 1, 2, 2, 3, 0, + 1, 2, 1, 2, 1, 2, 2, 0, 2, 4, + 1, 4, 5, 1, 4, 4, 5, 0, 1, 1, + 1, 0, 1, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 3, 5, 3, 5, - 0, 2, 0, 2, 3, 3, 5, 1, 1, 3, - 5, 7, 1, 3, 1, 1, 1, 1, 1, 1, - 5, 1, 3, 5, 0, 1, 3, 1, 1, 1, - 2, 3, 1, 1, 2, 1, 2, 3, 3, 1, - 1, 1, 0, 3, 1, 3, 3, 5, 2, 2, - 4, 2, 2, 3, 1, 4, 6, 4, 5, 6, - 4, 3, 1, 1, 1, 1, 2, 3, 5, 6, - 6, 6, 6, 6, 7, 6, 6, 6, 6, 8, - 8, 0, 2, 2, 2, 1, 3, 1, 4, 4, - 3, 6, 4, 4, 6, 3, 1, 3, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, - 3, 0, 1, 0, 1, 1, 1, 1, 2, 1, - 2, 1, 2, 2, 3, 0, 1, 2, 1, 2, - 1, 2, 2, 0, 2, 4, 1, 4, 5, 1, - 4, 4, 5, 0, 1, 1, 1, 0, 1, 3, - 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 4, 4, 0, 2, 0, 2, 2, 1, 1, 3, 2, 3, 4, @@ -1324,9 +1330,7 @@ static const yytype_uint8 yyr2[] = 2, 1, 3, 2, 4, 3, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 + 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -1334,532 +1338,486 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 3, 237, 241, 245, 239, 248, 250, 372, 0, - 0, 52, 48, 49, 50, 51, 76, 77, 78, 79, - 81, 0, 0, 0, 253, 253, 253, 253, 253, 253, - 201, 80, 82, 83, 374, 0, 0, 132, 0, 386, - 86, 87, 88, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 310, 318, 312, 299, 327, 299, 299, 333, - 301, 340, 342, 295, 347, 299, 354, 0, 128, 127, - 109, 122, 122, 108, 0, 96, 0, 0, 0, 0, - 364, 0, 0, 0, 9, 0, 2, 4, 0, 12, - 14, 20, 34, 45, 0, 0, 35, 46, 0, 84, - 100, 101, 102, 23, 105, 112, 113, 110, 111, 107, - 106, 103, 104, 27, 28, 29, 30, 31, 32, 33, - 15, 17, 18, 19, 36, 16, 0, 185, 91, 0, - 267, 0, 0, 0, 22, 24, 272, 273, 274, 276, - 275, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 21, - 25, 26, 37, 93, 246, 243, 0, 271, 0, 0, - 98, 0, 0, 0, 0, 172, 174, 438, 439, 440, - 399, 397, 400, 401, 437, 398, 403, 402, 406, 405, - 404, 441, 420, 421, 422, 423, 425, 426, 427, 428, - 429, 430, 431, 432, 433, 435, 434, 436, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, - 424, 419, 0, 442, 141, 53, 0, 54, 47, 0, - 0, 70, 0, 0, 0, 0, 259, 256, 238, 0, - 253, 240, 242, 245, 249, 251, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, - 0, 378, 0, 0, 0, 384, 385, 304, 305, 303, - 299, 299, 299, 317, 0, 0, 311, 299, 0, 307, - 328, 299, 329, 331, 334, 335, 332, 0, 339, 301, - 337, 341, 343, 345, 0, 344, 348, 346, 299, 351, - 355, 353, 357, 358, 359, 0, 0, 0, 120, 120, - 114, 0, 0, 0, 0, 0, 365, 368, 369, 0, - 0, 10, 1, 5, 6, 7, 237, 0, 56, 68, - 67, 72, 62, 57, 58, 60, 59, 63, 61, 0, - 73, 39, 40, 43, 41, 42, 44, 85, 115, 13, - 186, 0, 89, 92, 153, 155, 161, 169, 160, 159, - 387, 391, 268, 0, 387, 168, 171, 0, 95, 247, - 122, 373, 269, 270, 99, 0, 0, 0, 0, 0, - 0, 144, 0, 55, 74, 69, 71, 75, 0, 263, - 0, 0, 252, 254, 244, 0, 0, 0, 0, 0, + 0, 3, 241, 245, 249, 243, 252, 254, 382, 0, + 0, 53, 49, 50, 51, 52, 77, 78, 79, 80, + 82, 0, 0, 0, 257, 257, 257, 257, 257, 257, + 203, 81, 83, 84, 384, 0, 0, 133, 0, 396, + 87, 88, 89, 0, 0, 135, 136, 137, 138, 139, + 140, 0, 320, 328, 322, 309, 337, 309, 309, 343, + 311, 350, 352, 305, 357, 309, 364, 0, 127, 131, + 126, 108, 121, 121, 107, 0, 97, 0, 0, 0, + 0, 374, 0, 0, 0, 299, 300, 301, 302, 303, + 304, 9, 0, 2, 4, 0, 12, 14, 20, 34, + 46, 0, 0, 35, 47, 0, 85, 99, 100, 23, + 103, 111, 112, 109, 110, 106, 104, 105, 101, 102, + 27, 28, 29, 30, 31, 32, 33, 15, 17, 18, + 19, 36, 16, 0, 186, 92, 0, 271, 0, 0, + 0, 22, 24, 37, 276, 277, 278, 280, 279, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 21, 25, 26, + 38, 94, 250, 247, 0, 275, 0, 0, 0, 0, + 0, 0, 173, 175, 431, 432, 433, 409, 407, 410, + 411, 408, 413, 412, 416, 415, 414, 434, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 430, 429, 0, 435, 142, 54, 0, 55, 48, 0, + 0, 71, 0, 0, 0, 0, 263, 260, 242, 0, + 257, 244, 246, 249, 253, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 218, 0, 0, 231, 231, 0, 0, 0, 187, 0, - 0, 205, 202, 11, 0, 0, 375, 379, 380, 376, - 377, 133, 295, 299, 319, 299, 299, 323, 299, 321, - 313, 315, 0, 316, 299, 308, 300, 330, 336, 302, - 338, 296, 0, 352, 356, 129, 0, 123, 0, 124, - 125, 97, 116, 118, 0, 363, 366, 367, 370, 371, - 8, 66, 64, 0, 156, 0, 0, 0, 38, 154, - 0, 390, 0, 0, 393, 0, 162, 0, 120, 182, - 184, 183, 181, 0, 0, 0, 0, 0, 0, 173, - 152, 147, 149, 148, 0, 0, 145, 142, 0, 264, - 265, 266, 0, 0, 0, 0, 233, 235, 236, 218, - 218, 218, 218, 233, 0, 0, 0, 0, 0, 0, - 0, 231, 231, 0, 0, 218, 218, 218, 232, 218, - 0, 0, 218, 203, 204, 382, 0, 0, 306, 320, - 324, 299, 325, 322, 314, 309, 0, 0, 349, 0, - 0, 121, 0, 0, 360, 0, 157, 158, 90, 388, - 0, 395, 392, 170, 0, 0, 94, 126, 177, 180, - 175, 0, 0, 0, 150, 0, 0, 140, 0, 255, - 257, 0, 0, 261, 260, 218, 234, 0, 0, 0, - 0, 230, 0, 220, 221, 223, 224, 227, 228, 225, - 226, 222, 188, 0, 0, 0, 0, 0, 0, 0, - 0, 383, 381, 326, 298, 297, 0, 0, 130, 117, - 119, 361, 362, 65, 0, 0, 394, 164, 0, 167, - 178, 0, 0, 151, 146, 143, 258, 262, 0, 191, - 189, 192, 193, 233, 219, 197, 198, 195, 196, 0, - 0, 0, 0, 0, 207, 0, 0, 190, 350, 0, - 389, 396, 0, 163, 176, 179, 194, 229, 0, 0, - 0, 0, 0, 0, 231, 0, 131, 165, 0, 0, - 0, 210, 0, 0, 216, 199, 206, 0, 200, 208, - 209, 0, 0, 212, 0, 213, 231, 0, 217, 215, - 0, 211, 214 + 384, 0, 388, 0, 0, 0, 394, 395, 314, 315, + 313, 309, 309, 309, 327, 0, 0, 321, 309, 0, + 317, 338, 309, 339, 341, 344, 345, 342, 0, 349, + 311, 347, 351, 353, 355, 0, 354, 358, 356, 309, + 361, 365, 363, 367, 368, 369, 0, 0, 0, 0, + 119, 119, 113, 0, 0, 0, 0, 0, 375, 378, + 379, 0, 0, 10, 1, 5, 6, 7, 241, 0, + 57, 69, 68, 73, 63, 58, 59, 61, 60, 64, + 62, 0, 74, 40, 41, 44, 42, 43, 45, 86, + 114, 13, 187, 0, 90, 93, 154, 156, 162, 170, + 161, 160, 397, 401, 272, 0, 397, 169, 172, 0, + 96, 251, 121, 383, 273, 274, 0, 0, 0, 0, + 0, 0, 145, 0, 56, 75, 70, 72, 76, 0, + 267, 0, 0, 256, 258, 248, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 221, 0, 0, 235, 235, 0, 0, 0, + 0, 188, 0, 0, 207, 204, 11, 0, 0, 385, + 389, 390, 386, 387, 134, 305, 309, 329, 309, 309, + 333, 309, 331, 323, 325, 0, 326, 309, 318, 310, + 340, 346, 312, 348, 306, 0, 362, 366, 128, 0, + 132, 122, 0, 123, 124, 98, 115, 117, 0, 373, + 376, 377, 380, 381, 8, 67, 65, 0, 157, 0, + 0, 0, 39, 155, 0, 400, 0, 0, 403, 0, + 163, 0, 119, 183, 185, 184, 182, 0, 0, 0, + 0, 0, 0, 174, 153, 148, 150, 149, 0, 0, + 146, 143, 0, 268, 269, 270, 0, 0, 0, 0, + 237, 239, 240, 221, 221, 221, 221, 237, 0, 0, + 0, 0, 0, 0, 0, 235, 235, 0, 0, 0, + 221, 221, 221, 236, 221, 221, 0, 0, 221, 205, + 206, 392, 0, 0, 316, 330, 334, 309, 335, 332, + 324, 319, 0, 0, 359, 0, 0, 120, 0, 0, + 370, 0, 158, 159, 91, 398, 0, 405, 402, 171, + 0, 0, 95, 125, 178, 181, 176, 0, 0, 0, + 151, 0, 0, 141, 0, 259, 261, 0, 0, 265, + 264, 221, 238, 0, 0, 0, 0, 234, 0, 223, + 224, 226, 227, 230, 231, 228, 229, 232, 225, 189, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, + 391, 336, 308, 307, 0, 0, 129, 116, 118, 371, + 372, 66, 0, 0, 404, 165, 0, 168, 179, 0, + 0, 152, 147, 144, 262, 266, 0, 192, 190, 193, + 194, 237, 222, 198, 199, 196, 197, 202, 0, 0, + 0, 0, 0, 0, 209, 0, 0, 191, 360, 0, + 399, 406, 0, 164, 177, 180, 195, 233, 0, 0, + 0, 0, 0, 0, 0, 235, 0, 130, 166, 0, + 0, 0, 212, 214, 0, 0, 219, 200, 208, 0, + 201, 210, 211, 0, 0, 215, 0, 216, 235, 0, + 220, 218, 0, 213, 217 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 85, 86, 87, 88, 89, 356, 91, 92, 93, - 228, 329, 340, 330, 331, 94, 95, 96, 97, 98, - 99, 478, 352, 100, 101, 102, 103, 104, 105, 106, - 459, 308, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 222, 505, 506, 353, 354, - 355, 357, 358, 575, 638, 120, 121, 122, 123, 124, - 125, 175, 176, 492, 126, 127, 258, 422, 663, 664, - 666, 693, 694, 534, 410, 537, 595, 538, 128, 129, - 130, 131, 165, 132, 133, 238, 239, 240, 512, 363, - 134, 135, 295, 279, 290, 136, 269, 137, 138, 139, - 276, 140, 273, 141, 142, 143, 144, 286, 145, 146, - 147, 148, 149, 297, 150, 151, 301, 152, 153, 154, - 155, 156, 157, 158, 169, 159, 426, 427, 428, 160, - 161, 162, 481, 359, 360, 223, 361 + -1, 92, 93, 94, 95, 96, 348, 98, 99, 100, + 218, 321, 332, 322, 323, 101, 102, 103, 104, 105, + 106, 472, 344, 107, 108, 109, 110, 111, 112, 453, + 300, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 212, 499, 500, 345, 346, + 347, 349, 350, 571, 636, 127, 128, 129, 130, 131, + 132, 182, 183, 486, 133, 134, 249, 415, 663, 664, + 666, 695, 696, 529, 402, 532, 591, 533, 135, 136, + 137, 138, 173, 139, 140, 228, 229, 230, 506, 355, + 141, 142, 143, 286, 270, 281, 144, 260, 145, 146, + 147, 267, 148, 264, 149, 150, 151, 152, 277, 153, + 154, 155, 156, 157, 288, 158, 159, 292, 160, 161, + 162, 163, 164, 165, 166, 177, 167, 419, 420, 421, + 168, 169, 170, 475, 351, 352, 213, 353 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -485 +#define YYPACT_NINF -479 static const yytype_int16 yypact[] = { - 392, -485, 32, -485, 42, -485, -485, -485, 49, -12, - 1337, 63, 91, -485, -485, -485, -485, -485, -485, -485, - -485, 1337, 1337, 172, 31, 31, 31, 31, 31, 31, - 145, -485, -485, -485, 830, 151, 161, -485, 102, -485, - -485, -485, -485, 138, 210, -485, -485, -485, -485, -485, - -485, 124, -485, 105, -33, 169, 190, -45, 176, -5, - 57, 231, 174, 34, 203, 35, 204, 56, 50, -485, - -485, 291, 291, -485, 1337, 251, 296, 297, 313, 320, - -485, 211, 242, -65, 279, 330, 559, -485, 17, -485, - -485, -485, -485, -485, 23, 159, -485, -485, 230, 1444, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, 995, 292, 158, 680, - 265, 1337, 680, 1337, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -8, 283, -485, 316, -485, 156, 193, - 158, 164, 254, 255, -31, -485, 168, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, 167, -485, 166, -485, 280, -485, -485, 1337, - 318, 315, 1337, 175, 177, 178, 179, -485, -485, 308, - 31, -485, -485, 42, -485, -485, 272, 185, 186, 188, - 189, 171, 191, 192, 194, 195, 201, 196, 68, -485, - 202, 244, 276, 282, 232, -485, -485, -485, 247, -485, - 26, -36, 30, -485, -32, 286, -485, 150, 289, -485, - -485, 176, -485, -485, -485, 290, -485, 293, -485, 243, - -485, -485, -485, -485, 266, -485, 208, -485, 176, -485, - 267, -485, -485, -485, -485, 300, 233, 301, 256, 256, - -485, 1337, 305, 306, 307, 309, 278, 294, -485, 295, - 302, -485, -485, -485, -485, 346, -485, 328, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, 335, - 250, -485, -485, -485, -485, -485, -485, 12, -485, -485, - -485, 9, 404, 158, -485, -485, -485, -485, -485, -485, - 298, 1112, -485, 406, 298, -485, -485, 407, -4, -485, - 291, -485, -485, -485, 158, 33, 261, 262, 268, 106, - -20, 14, 1337, -485, -485, -485, -485, -485, 321, 223, - 354, -14, -485, -485, -485, 269, 39, 39, 39, 39, - -83, 270, 277, 281, 284, 285, 287, 288, 317, 319, - -485, 39, 39, 39, 39, 322, 323, 39, -485, 355, - 356, -485, -485, -485, 390, 391, -485, 303, -485, -485, - -485, -485, 331, 176, -485, 176, 60, -485, 176, -485, - -485, -485, 369, -485, 176, -485, -485, -485, -485, -485, - -485, -52, 339, -485, -485, 388, 324, -485, 378, -485, - -485, -485, 437, 438, 325, -485, -485, -485, -485, -485, - -485, -485, -485, 299, -485, 314, 139, 680, -485, -485, - -35, -485, 1337, 1337, -485, 680, -13, 680, 256, -485, - -485, -485, -485, 33, 33, 33, 326, 381, 382, -485, - -485, -485, -485, -485, -11, -27, -485, 304, 327, -485, - -485, -485, 329, 383, -50, 332, 39, -485, -485, -485, - -485, -485, -485, 39, 384, 39, 39, 39, 39, 39, - 39, 39, 39, 39, -17, -485, -485, -485, -485, -485, - 333, 334, -485, -485, -485, -485, 429, 244, -485, -485, - -485, 176, -485, -485, -485, -485, 353, 377, 336, 347, - 417, -485, 419, 421, -2, 422, -485, -485, -485, -485, - 428, -485, 1230, -485, 433, 80, -485, -485, -485, -485, - -485, 33, 340, 345, -485, 435, 14, -485, 1337, -485, - -485, 348, 349, -485, -485, -485, -485, -16, -7, -1, - 0, -485, 357, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, 171, 2, 3, 5, 6, 86, 453, - 7, -485, -485, -485, -485, -485, 447, 361, -485, -485, - -485, -485, -485, -485, 363, 1337, -485, -485, 123, -485, - -485, 33, 33, -485, -485, -485, -485, -485, 8, -485, - -485, -485, -485, 39, -485, -485, -485, -485, -485, 367, - 368, 371, 405, 344, 413, 412, 365, -485, -485, 494, - -485, -485, 505, -485, -485, -485, -485, -485, 39, 39, - -70, 513, 560, 86, 39, 561, -485, -485, 424, 427, - 430, -485, 431, 432, 434, -485, -485, 18, -485, -485, - -485, 39, 39, -485, 513, -485, 39, 441, -485, -485, - 442, -485, -485 + 418, -479, 36, -479, -62, -479, -479, -479, 47, -14, + 1104, 50, 68, -479, -479, -479, -479, -479, -479, -479, + -479, 1104, 1104, 116, 8, 8, 8, 8, 8, 8, + 300, -479, -479, -479, 770, 109, 51, -479, 29, -479, + -479, -479, -479, 137, 157, -479, -479, -479, -479, -479, + -479, 129, -479, 221, 54, 71, 210, -54, 124, -2, + -36, 182, 172, 92, 217, -15, 224, 148, 49, 297, + -479, -479, 319, 319, -479, 1104, 285, 328, 330, 348, + 355, -479, 254, 291, -40, -479, -479, -479, -479, -479, + -479, 327, 379, 595, -479, -8, -479, -479, -479, -479, + -479, 11, 200, -479, -479, 360, 1212, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, 944, 341, 201, 95, 316, 1104, 95, + 1104, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, 0, 334, -479, 367, -479, 199, 218, 208, 305, + 308, -11, -479, 230, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, 216, -479, 227, -479, 350, -479, -479, 1104, + 388, 385, 1104, 234, 235, 237, 238, -479, -479, 383, + 8, -479, -479, -62, -479, -479, 353, 256, 257, 263, + 264, 212, 267, 275, 277, 278, 279, 198, 280, 46, + -479, 286, 76, 380, 384, 345, -479, -479, -479, 351, + -479, -25, -44, 38, -479, -16, 386, -479, 207, 392, + -479, -479, 124, -479, -479, -479, 393, -479, 394, -479, + 346, -479, -479, -479, -479, 361, -479, 301, -479, 124, + -479, 363, -479, -479, -479, -479, 400, 329, 402, 403, + 354, 354, -479, 1104, 405, 406, 407, 409, 376, 377, + -479, 378, 397, -479, -479, -479, -479, 447, -479, 414, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, 417, 325, -479, -479, -479, -479, -479, -479, 13, + -479, -479, -479, 10, 489, 201, -479, -479, -479, -479, + -479, -479, 381, 206, -479, 490, 381, -479, -479, 491, + 3, -479, 319, -479, -479, -479, 120, 337, 338, 340, + 147, -14, 2, 1104, -479, -479, -479, -479, -479, 408, + 284, 439, -7, -479, -479, -479, 342, 136, 136, 136, + 136, -27, 343, 347, 349, 352, 356, 357, 358, 359, + 364, 365, -479, 136, 136, 136, 136, 136, 366, 368, + 136, -479, 443, 444, -479, -479, -479, 470, 471, -479, + 370, -479, -479, -479, -479, 410, 124, -479, 124, 41, + -479, 124, -479, -479, -479, 451, -479, 124, -479, -479, + -479, -479, -479, -479, -69, 427, -479, -479, 464, 387, + -479, -479, 468, -479, -479, -479, 532, 535, 389, -479, + -479, -479, -479, -479, -479, -479, -479, 390, -479, 382, + 169, 95, -479, -479, -29, -479, 1104, 1104, -479, 95, + -9, 95, 354, -479, -479, -479, -479, 120, 120, 120, + 416, 506, 515, -479, -479, -479, -479, -479, 7, 110, + -479, 429, 431, -479, -479, -479, 432, 538, -53, 442, + 136, -479, -479, -479, -479, -479, -479, 136, 550, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, -13, + -479, -479, -479, -479, -479, -479, 450, 452, -479, -479, + -479, -479, 574, 76, -479, -479, -479, 124, -479, -479, + -479, -479, 521, 522, 460, 486, 559, -479, 560, 561, + 26, 562, -479, -479, -479, -479, 563, -479, 1070, -479, + 569, 70, -479, -479, -479, -479, -479, 120, 472, 473, + -479, 572, 2, -479, 1104, -479, -479, 474, 475, -479, + -479, -479, -479, -5, -4, -3, -1, -479, 479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + 212, 9, 15, 17, 18, 19, 140, 589, 20, -479, + -479, -479, -479, -479, 578, 481, -479, -479, -479, -479, + -479, -479, 480, 1104, -479, -479, 111, -479, -479, 120, + 120, -479, -479, -479, -479, -479, 21, -479, -479, -479, + -479, 136, -479, -479, -479, -479, -479, -479, 482, 483, + 484, 485, 487, 488, 492, 495, 496, -479, -479, 585, + -479, -479, 587, -479, -479, -479, -479, -479, 136, 136, + -59, 508, 588, 633, 140, 136, 652, -479, -479, 510, + 511, 514, -479, -479, 516, 513, 518, -479, -479, 42, + -479, -479, -479, 136, 136, -479, 588, -479, 136, 517, + -479, -479, 519, -479, -479 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -485, -485, -485, 520, 575, 484, 4, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, 448, -485, -485, -485, -485, -485, -485, -485, - -296, -62, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, 525, 55, -485, 36, -148, -302, - -485, -129, 45, -485, -485, 126, 147, 163, 187, 200, - -485, 241, -485, -477, 496, -485, -485, -485, -57, -485, - -485, -77, -485, -309, 15, -387, -484, -391, -485, -485, - -485, -485, 386, -485, -485, 264, 393, -485, -485, -485, - -485, -485, 198, -56, 342, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, 85, -485, - -485, 540, 271, -485, 173, -485, -10 + -479, -479, -479, 607, 668, 571, 1, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, 534, -479, -479, -479, -479, -479, -479, -287, + -60, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, 605, 632, -479, 126, -146, -281, + -479, -134, 138, -479, -479, 128, 131, 141, 151, 164, + -479, 339, -479, -455, 577, -479, -479, -479, 28, -479, + -479, 12, -479, -227, 103, -402, -478, -381, -479, -479, + -479, -479, 494, -479, -479, 253, 493, -479, -479, -479, + -479, -479, -479, 290, -55, 436, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, 174, + -479, -479, 621, 369, -479, 97, -479, -10 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -442 +#define YYTABLE_NINF -435 static const yytype_int16 yytable[] = { - 224, 282, 283, 365, 90, 519, 520, 521, 522, 299, - 309, 230, 231, 460, 326, 368, 578, 579, 580, -91, - 535, 536, 374, -92, 612, 649, 542, 539, 326, 3, - 4, 5, 6, 7, 650, 592, 10, -166, 90, 601, - 651, 652, 24, 655, 656, 690, 657, 658, 667, 676, - 569, 479, 318, 440, 378, 319, 24, 25, 26, 27, - 28, 29, -441, 500, 224, 171, 479, 324, 166, 170, - 556, 514, 479, 171, 584, 233, 234, 305, 172, 173, - 284, 435, 225, 631, 226, 326, 172, 173, 278, 224, - 90, 523, 436, 274, 524, 235, 441, 278, 328, 501, - 275, 442, 341, 515, 640, 320, 691, 281, 39, 418, - 419, 420, 163, 24, 502, 632, 236, 167, 489, 168, - 229, 557, 306, 285, 517, 596, 593, 227, 518, 310, - 90, 503, 596, 490, 603, 604, 605, 606, 607, 608, - 570, 379, 611, 433, 609, 610, 586, 438, 237, 587, - 491, 293, 174, 421, 348, 294, 613, 613, -166, 278, - 174, 585, 574, 278, 674, 675, 613, 351, 278, 677, - 164, 351, 613, 613, 479, 613, 613, 551, 613, 613, - 613, 613, 298, -441, 351, 474, 504, 659, 325, -441, - 287, 496, 577, 278, 705, 327, 288, 289, 706, 660, - 661, 232, 662, 476, 497, 498, 302, 303, 304, 261, - 597, 598, 599, 600, 434, 437, 439, 262, 263, 384, - 333, 445, 387, 265, 342, 447, 614, 615, 616, 246, - 617, 270, 271, 620, 272, 326, 3, 4, 5, 6, - 7, 334, 453, 267, 268, 343, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 400, 335, 257, 372, - 373, 344, 596, 24, 25, 26, 27, 28, 29, 509, - 510, 511, 401, 402, 403, 404, 264, 405, 406, 407, - 408, 336, 444, 278, 409, 345, 648, 688, 689, 241, - 242, 243, 244, 245, 337, 266, 672, 697, 346, 673, - 277, 461, 278, 424, 364, 425, 366, 280, 488, 278, - 707, 708, 415, 416, 351, 567, 291, 292, 307, 710, - 296, 300, 311, 312, 313, 314, 315, 317, 316, 321, - 322, 339, 30, 351, 362, 369, 370, 371, 375, 376, - 377, 380, 381, 382, 383, 385, 386, 392, 568, 431, - 388, 484, 389, 390, 391, 475, 573, 395, 576, 396, - 397, 429, 398, 399, 432, 411, 412, 430, 413, 414, - 417, 443, 507, 423, 446, 448, 287, 549, 449, 550, - 552, 452, 553, 451, 454, 455, 457, 456, 555, 458, - 462, 463, 464, 1, 465, 466, 470, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 467, 468, 471, 16, 17, 18, 19, 20, 469, - 472, 21, 22, 473, 23, 24, 25, 26, 27, 28, - 29, 477, 30, 485, 487, 493, 494, 480, 508, 513, - 543, 544, 495, 516, 525, 31, 32, 33, 34, 35, - 545, 526, 294, 546, 554, 527, 558, 36, 528, 529, - 559, 530, 531, 561, 562, 563, 582, 583, 591, 602, - 624, 565, 571, 572, 37, 38, 547, 39, 40, 41, - 42, 588, 43, 44, 45, 46, 47, 48, 49, 50, - 566, 532, 621, 533, 625, 623, 540, 541, 560, 564, - 581, 627, 628, 589, 629, 590, 630, 633, 594, 626, - 51, 618, 619, 634, 641, 52, 53, 54, 637, 642, - 643, 665, 55, 682, 646, 647, 56, 57, 58, 59, - 60, 653, 668, 61, 62, 669, 63, 64, 65, 670, - 66, 67, 678, 679, 685, 68, 680, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 636, 84, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 645, 686, - 681, 16, 17, 18, 19, 20, 683, 684, 21, 22, - 687, 23, 24, 25, 26, 27, 28, 29, 692, 30, - 699, 695, 698, 700, 701, 702, 323, 704, 703, 260, - 349, 367, 31, 32, 33, 34, 35, 711, 712, 332, - 639, 499, 644, 350, 36, 671, 696, 709, 654, 394, - 548, 450, 622, 393, 338, 486, 0, 0, 0, 0, - 0, 37, 38, 0, 39, 40, 41, 42, 0, 43, - 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, - 0, 0, 52, 53, 54, 326, 0, 0, 0, 55, - 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, - 61, 62, 0, 63, 64, 65, 0, 66, 67, 0, - 0, 0, 68, 24, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 0, - 84, 0, 0, 177, 178, 179, 180, 181, 182, 0, - 0, 0, 183, 0, 184, 185, 186, 187, 188, 189, - 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 0, 0, 208, - 209, 0, 210, 0, 0, 0, 211, 212, 0, 213, - 0, 214, 215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 216, 0, 0, 0, 217, 0, 0, - 0, 218, 219, 0, 220, 2, 3, 4, 5, 6, + 214, 97, 273, 274, 534, 357, 513, 514, 515, 516, + 290, 220, 221, 301, 454, 318, 318, 3, 4, 5, + 6, 7, 530, 531, 10, 360, 535, -92, 609, 538, + -93, 588, 574, 575, 576, 97, 647, 648, 649, 597, + 650, -167, 316, 24, 24, 25, 26, 27, 28, 29, + 653, 494, 223, 224, 552, 565, 654, 691, 655, 656, + 657, 667, 676, -434, 473, 214, 174, 172, 433, 215, + 178, 216, 225, 369, 428, 318, 296, 508, 310, 473, + 269, 311, 275, 179, 180, 429, 495, 411, 412, 413, + 269, 580, 226, 426, 97, 39, 340, 219, 278, 272, + 318, 496, 320, 24, 279, 280, 333, 253, 254, 269, + 629, 509, 553, 434, 217, 175, 171, 176, 435, 269, + 497, 297, 638, 605, 606, 692, 227, 276, 24, 592, + 414, 589, 312, 289, 97, 417, 592, 418, 599, 600, + 601, 602, 603, 604, 630, 222, 607, 608, 184, 185, + 186, 187, 188, 189, 566, 517, 431, 190, 518, 547, + 191, 192, 193, 194, 195, 196, 181, 252, 610, 370, + -167, 317, 269, 677, 570, 269, 610, 610, 610, 197, + 610, 265, 498, 343, 674, 675, 343, 581, 266, 473, + 610, 319, -434, 343, 468, 573, 610, 470, 610, 610, + 610, 610, 610, 268, 483, 269, 427, 430, 432, 375, + 284, 255, 378, 438, 285, 198, 199, 440, 200, 484, + 511, 256, 201, 202, 512, 203, 707, 204, 205, 325, + 708, 490, 326, 334, 446, 356, 335, 358, 485, 206, + 658, 257, 327, 207, 491, 492, 336, 208, 209, 258, + 259, 210, 328, 659, 660, 661, 337, 662, 269, 184, + 185, 186, 187, 188, 189, 329, 282, 211, 190, 338, + 592, 191, 192, 193, 194, 195, 196, 476, 231, 232, + 233, 234, 235, 699, 364, 365, 593, 594, 595, 596, + 197, 582, 672, 455, 583, 673, 391, 689, 690, 293, + 294, 295, 482, 611, 612, 613, 712, 614, 615, 408, + 409, 618, 392, 393, 394, 395, 283, 396, 397, 398, + 399, 400, 709, 710, 298, 401, 198, 199, 271, 200, + 503, 504, 505, 201, 202, 287, 203, 564, 204, 205, + 437, 269, 291, 478, 469, 569, 299, 572, 261, 262, + 206, 263, 343, 563, 207, 304, 303, 305, 208, 209, + 306, 307, 210, 501, 646, 318, 3, 4, 5, 6, + 7, 545, 308, 546, 548, 309, 549, 313, 211, 314, + 331, 30, 551, 236, 343, 354, 361, 362, 363, 367, + 366, 477, 368, 24, 25, 26, 27, 28, 29, 372, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 371, 373, 248, 374, 376, 377, 379, 380, 1, + 381, 382, 383, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 386, 387, 388, + 16, 17, 18, 19, 20, 389, 390, 21, 22, 403, + 23, 24, 25, 26, 27, 28, 29, 404, 30, 405, + 406, 407, 410, 424, 422, 416, 567, 568, 423, 425, + 436, 31, 32, 33, 34, 35, 439, 441, 442, 444, + 278, 447, 445, 36, 448, 449, 450, 451, 452, 456, + 457, 458, 621, 459, 460, 461, 462, 464, 465, 37, + 38, 466, 39, 40, 41, 42, 467, 43, 44, 45, + 46, 47, 48, 49, 50, 463, 471, 479, 481, 487, + 488, 474, 489, 507, 510, 519, 502, 539, 540, 520, + 541, 521, 285, 542, 522, 550, 555, 51, 523, 524, + 525, 526, 52, 53, 54, 554, 527, 528, 536, 55, + 537, 543, 557, 56, 57, 58, 59, 60, 634, 558, + 61, 62, 559, 63, 64, 65, 562, 66, 67, 556, + 561, 560, 68, 69, 643, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 578, 85, 86, 87, 88, 89, 90, 91, 577, 579, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 584, 585, 586, 16, 17, 18, + 19, 20, 587, 671, 21, 22, 590, 23, 24, 25, + 26, 27, 28, 29, 598, 30, 616, 619, 617, 622, + 623, 624, 625, 626, 627, 628, 631, 632, 31, 32, + 33, 34, 35, 635, 639, 640, 641, 665, 644, 645, + 36, 651, 668, 669, 670, 678, 679, 680, 681, 687, + 682, 688, 694, 684, 697, 683, 37, 38, 685, 39, + 40, 41, 42, 686, 43, 44, 45, 46, 47, 48, + 49, 50, 693, 700, 701, 702, 703, 705, 704, 706, + 315, 713, 251, 714, 341, 359, 324, 302, 642, 637, + 493, 342, 698, 652, 51, 544, 443, 620, 711, 52, + 53, 54, 330, 384, 0, 480, 55, 385, 0, 0, + 56, 57, 58, 59, 60, 0, 0, 61, 62, 0, + 63, 64, 65, 0, 66, 67, 0, 0, 0, 68, + 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 0, 85, 86, + 87, 88, 89, 90, 91, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, - 221, 0, 16, 17, 18, 19, 20, 0, 0, 21, + 0, 0, 16, 17, 18, 19, 20, 0, 0, 21, 22, 0, 23, 24, 25, 26, 27, 28, 29, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 31, 32, 33, 259, 35, 0, 0, + 0, 0, 0, 31, 32, 33, 250, 35, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 37, 38, 0, 39, 40, 41, 42, 0, - 43, 44, 45, 46, 47, 48, 49, 50, 0, 0, + 0, 37, 38, 0, 39, 40, 41, 42, 0, 43, + 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, - 0, 0, 0, 52, 53, 54, 0, 0, 0, 0, - 55, 0, 0, 0, 56, 57, 58, 59, 60, 0, - 0, 61, 62, 0, 63, 64, 65, 0, 66, 67, - 0, 0, 0, 68, 0, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 16, 17, 18, - 19, 20, 0, 0, 21, 22, 0, 23, 24, 25, - 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, - 33, 259, 35, 0, 0, 0, 0, 0, 0, 0, - 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 37, 38, 0, - 39, 40, 41, 42, 0, 43, 44, 45, 46, 47, - 48, 49, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 0, 0, 0, 0, 52, 53, 54, 0, 0, 0, + 0, 55, 0, 0, 0, 56, 57, 58, 59, 60, + 0, 0, 61, 62, 0, 63, 64, 65, 0, 66, + 67, 0, 0, 0, 68, 69, 0, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 0, 85, 86, 87, 88, 89, 90, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 16, 17, 18, 19, + 20, 0, 0, 21, 22, 0, 23, 24, 25, 26, + 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, + 250, 35, 0, 0, 0, 0, 0, 0, 0, 36, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 37, 38, 0, 39, 40, + 41, 42, 0, 43, 44, 45, 46, 47, 48, 49, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 52, 53, 54, 0, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, 61, 62, 0, 63, - 64, 65, 0, 66, 67, 0, 0, 0, 68, 0, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 177, 178, 179, 180, 181, - 182, 0, 0, 0, 183, 0, 184, 185, 186, 187, - 188, 189, 190, 482, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 191, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, - 0, 208, 209, 0, 210, 0, 0, 0, 211, 212, - 0, 213, 0, 214, 215, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 216, 0, 0, 0, 217, - 0, 0, 0, 218, 219, 0, 220, 0, 0, 0, + 64, 65, 0, 66, 67, 0, 0, 0, 68, 69, + 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 0, 85, 86, 87, + 88, 89, 90, 184, 185, 186, 187, 188, 189, 0, + 0, 0, 190, 0, 0, 191, 192, 193, 194, 195, + 196, 633, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 197, 0, 0, 184, 185, 186, + 187, 188, 189, 0, 0, 0, 190, 0, 0, 191, + 192, 193, 194, 195, 196, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, + 198, 199, 0, 200, 0, 0, 0, 201, 202, 0, + 203, 0, 204, 205, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 206, 0, 0, 0, 207, 0, + 0, 0, 208, 209, 198, 199, 210, 200, 0, 0, + 0, 201, 202, 0, 203, 0, 204, 205, 0, 0, + 0, 0, 211, 0, 0, 0, 0, 0, 206, 0, + 0, 0, 207, 0, 0, 0, 208, 209, 0, 0, + 210, 0, 0, 0, 0, 184, 185, 186, 187, 188, + 189, 0, 0, 0, 190, 0, 211, 191, 192, 193, + 194, 195, 196, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 221, 177, 178, 179, 180, 181, 182, 483, - 0, 0, 183, 0, 184, 185, 186, 187, 188, 189, - 190, 635, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 0, 0, 208, - 209, 0, 210, 0, 0, 0, 211, 212, 0, 213, - 0, 214, 215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 216, 0, 0, 0, 217, 0, 0, - 0, 218, 219, 0, 220, 0, 0, 0, 0, 0, - 177, 178, 179, 180, 181, 182, 0, 0, 0, 183, - 221, 184, 185, 186, 187, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 0, 0, 208, 209, 0, 210, - 0, 0, 0, 211, 212, 0, 213, 0, 214, 215, + 0, 0, 198, 199, 0, 200, 0, 0, 0, 201, + 202, 0, 203, 0, 204, 205, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, + 207, 0, 0, 0, 208, 209, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 216, 0, 0, 0, 217, 0, 0, 0, 218, 219, - 0, 220, 0, 0, 0, 0, 0, 177, 178, 179, - 180, 181, 182, 0, 0, 0, 183, 221, 184, 185, - 186, 187, 188, 189, 190, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 347, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 0, 0, 208, 209, 0, 210, 0, 0, 0, - 211, 212, 0, 213, 0, 214, 215, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, - 0, 217, 0, 0, 0, 218, 219, 0, 220, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 221 + 0, 0, 0, 0, 211 }; static const yytype_int16 yycheck[] = { - 10, 57, 58, 132, 0, 396, 397, 398, 399, 65, - 72, 21, 22, 309, 5, 163, 493, 494, 495, 27, - 411, 412, 170, 27, 41, 41, 417, 414, 5, 6, - 7, 8, 9, 10, 41, 85, 13, 50, 34, 523, - 41, 41, 33, 41, 41, 115, 41, 41, 41, 41, - 85, 353, 117, 85, 85, 120, 33, 34, 35, 36, - 37, 38, 50, 49, 74, 85, 368, 50, 19, 81, - 122, 85, 374, 85, 85, 44, 45, 27, 98, 99, - 85, 117, 19, 85, 21, 5, 98, 99, 133, 99, - 86, 174, 128, 126, 177, 64, 128, 133, 94, 85, - 133, 133, 98, 117, 581, 170, 176, 152, 85, 41, - 42, 43, 80, 33, 100, 117, 85, 68, 85, 70, - 29, 173, 72, 128, 85, 516, 176, 64, 89, 74, - 126, 117, 523, 100, 525, 526, 527, 528, 529, 530, - 175, 172, 533, 117, 531, 532, 173, 117, 117, 176, - 117, 117, 172, 85, 99, 121, 173, 173, 171, 133, - 172, 172, 175, 133, 641, 642, 173, 175, 133, 653, - 128, 175, 173, 173, 476, 173, 173, 117, 173, 173, - 173, 173, 147, 171, 175, 176, 172, 101, 171, 177, - 133, 85, 488, 133, 176, 172, 139, 140, 180, 113, - 114, 29, 116, 351, 98, 99, 150, 151, 152, 58, - 519, 520, 521, 522, 270, 271, 272, 56, 57, 229, - 94, 277, 232, 85, 98, 281, 535, 536, 537, 84, - 539, 126, 127, 542, 129, 5, 6, 7, 8, 9, - 10, 94, 298, 119, 120, 98, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 85, 94, 113, 66, - 67, 98, 653, 33, 34, 35, 36, 37, 38, 46, - 47, 48, 101, 102, 103, 104, 174, 106, 107, 108, - 109, 94, 132, 133, 113, 98, 595, 678, 679, 25, - 26, 27, 28, 29, 94, 85, 173, 684, 98, 176, - 131, 311, 133, 59, 131, 61, 133, 117, 370, 133, - 701, 702, 111, 112, 175, 176, 85, 143, 27, 706, - 117, 117, 71, 27, 27, 12, 6, 85, 117, 50, - 0, 172, 40, 175, 69, 52, 20, 181, 174, 85, - 85, 173, 175, 177, 64, 27, 31, 39, 477, 117, - 175, 361, 175, 175, 175, 351, 485, 85, 487, 174, - 174, 85, 174, 174, 117, 174, 174, 85, 174, 174, - 174, 85, 382, 171, 85, 85, 133, 433, 85, 435, - 436, 173, 438, 117, 117, 85, 85, 154, 444, 133, - 85, 85, 85, 1, 85, 117, 50, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 117, 117, 85, 22, 23, 24, 25, 26, 117, - 85, 29, 30, 173, 32, 33, 34, 35, 36, 37, - 38, 27, 40, 27, 27, 174, 174, 139, 117, 85, - 85, 85, 174, 174, 174, 53, 54, 55, 56, 57, - 60, 174, 121, 62, 85, 174, 117, 65, 174, 174, - 72, 174, 174, 85, 27, 27, 85, 85, 85, 85, - 117, 172, 482, 483, 82, 83, 173, 85, 86, 87, - 88, 177, 90, 91, 92, 93, 94, 95, 96, 97, - 176, 174, 63, 174, 117, 551, 174, 174, 174, 174, - 174, 154, 85, 176, 85, 176, 85, 85, 176, 173, - 118, 178, 178, 85, 174, 123, 124, 125, 85, 174, - 85, 68, 130, 179, 176, 176, 134, 135, 136, 137, - 138, 174, 85, 141, 142, 174, 144, 145, 146, 176, - 148, 149, 175, 175, 179, 153, 175, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 572, 171, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 588, 85, - 175, 22, 23, 24, 25, 26, 173, 175, 29, 30, - 85, 32, 33, 34, 35, 36, 37, 38, 85, 40, - 176, 41, 41, 176, 174, 174, 86, 173, 176, 34, - 126, 163, 53, 54, 55, 56, 57, 176, 176, 94, - 575, 380, 586, 127, 65, 635, 683, 704, 613, 243, - 432, 289, 547, 240, 94, 364, -1, -1, -1, -1, - -1, 82, 83, -1, 85, 86, 87, 88, -1, 90, - 91, 92, 93, 94, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, - -1, -1, 123, 124, 125, 5, -1, -1, -1, 130, - -1, -1, -1, 134, 135, 136, 137, 138, -1, -1, - 141, 142, -1, 144, 145, 146, -1, 148, 149, -1, - -1, -1, 153, 33, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, -1, -1, 53, 54, 55, 56, 57, 58, -1, - -1, -1, 62, -1, 64, 65, 66, 67, 68, 69, - 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, -1, 119, - 120, -1, 122, -1, -1, -1, 126, 127, -1, 129, - -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 143, -1, -1, -1, 147, -1, -1, - -1, 151, 152, -1, 154, 5, 6, 7, 8, 9, + 10, 0, 57, 58, 406, 139, 387, 388, 389, 390, + 65, 21, 22, 73, 301, 5, 5, 6, 7, 8, + 9, 10, 403, 404, 13, 171, 407, 27, 41, 410, + 27, 84, 487, 488, 489, 34, 41, 41, 41, 517, + 41, 50, 50, 33, 33, 34, 35, 36, 37, 38, + 41, 49, 44, 45, 123, 84, 41, 116, 41, 41, + 41, 41, 41, 50, 345, 75, 19, 129, 84, 19, + 84, 21, 64, 84, 118, 5, 27, 84, 118, 360, + 134, 121, 84, 97, 98, 129, 84, 41, 42, 43, + 134, 84, 84, 118, 93, 84, 106, 29, 134, 153, + 5, 99, 101, 33, 140, 141, 105, 56, 57, 134, + 84, 118, 181, 129, 64, 68, 80, 70, 134, 134, + 118, 72, 577, 525, 526, 184, 118, 129, 33, 510, + 84, 184, 172, 148, 133, 59, 517, 61, 519, 520, + 521, 522, 523, 524, 118, 29, 527, 528, 53, 54, + 55, 56, 57, 58, 183, 182, 118, 62, 185, 118, + 65, 66, 67, 68, 69, 70, 180, 58, 181, 180, + 179, 179, 134, 651, 183, 134, 181, 181, 181, 84, + 181, 127, 180, 183, 639, 640, 183, 180, 134, 470, + 181, 180, 179, 183, 184, 482, 181, 343, 181, 181, + 181, 181, 181, 132, 84, 134, 261, 262, 263, 219, + 118, 182, 222, 268, 122, 120, 121, 272, 123, 99, + 84, 84, 127, 128, 88, 130, 184, 132, 133, 101, + 188, 84, 101, 105, 289, 138, 105, 140, 118, 144, + 100, 84, 101, 148, 97, 98, 105, 152, 153, 120, + 121, 156, 101, 113, 114, 115, 105, 117, 134, 53, + 54, 55, 56, 57, 58, 101, 84, 172, 62, 105, + 651, 65, 66, 67, 68, 69, 70, 71, 25, 26, + 27, 28, 29, 685, 66, 67, 513, 514, 515, 516, + 84, 181, 181, 303, 184, 184, 84, 678, 679, 151, + 152, 153, 362, 530, 531, 532, 708, 534, 535, 111, + 112, 538, 100, 101, 102, 103, 144, 105, 106, 107, + 108, 109, 703, 704, 27, 113, 120, 121, 118, 123, + 46, 47, 48, 127, 128, 118, 130, 471, 132, 133, + 133, 134, 118, 353, 343, 479, 27, 481, 127, 128, + 144, 130, 183, 184, 148, 27, 71, 27, 152, 153, + 12, 6, 156, 373, 591, 5, 6, 7, 8, 9, + 10, 426, 118, 428, 429, 84, 431, 50, 172, 0, + 180, 40, 437, 83, 183, 69, 52, 20, 189, 84, + 182, 185, 84, 33, 34, 35, 36, 37, 38, 183, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 181, 185, 113, 64, 27, 31, 183, 183, 1, + 183, 183, 39, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 84, 182, 182, + 22, 23, 24, 25, 26, 182, 182, 29, 30, 182, + 32, 33, 34, 35, 36, 37, 38, 182, 40, 182, + 182, 182, 182, 118, 84, 179, 476, 477, 84, 118, + 84, 53, 54, 55, 56, 57, 84, 84, 84, 118, + 134, 118, 181, 65, 84, 156, 84, 84, 134, 84, + 84, 84, 547, 84, 118, 118, 118, 50, 84, 81, + 82, 84, 84, 85, 86, 87, 181, 89, 90, 91, + 92, 93, 94, 95, 96, 118, 27, 27, 27, 182, + 182, 140, 182, 84, 182, 182, 118, 84, 84, 182, + 60, 182, 122, 62, 182, 84, 72, 119, 182, 182, + 182, 182, 124, 125, 126, 118, 182, 182, 182, 131, + 182, 181, 84, 135, 136, 137, 138, 139, 568, 27, + 142, 143, 27, 145, 146, 147, 184, 149, 150, 182, + 180, 182, 154, 155, 584, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 84, 173, 174, 175, 176, 177, 178, 179, 182, 84, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 185, 184, 184, 22, 23, 24, + 25, 26, 84, 633, 29, 30, 184, 32, 33, 34, + 35, 36, 37, 38, 84, 40, 186, 63, 186, 118, + 118, 181, 156, 84, 84, 84, 84, 84, 53, 54, + 55, 56, 57, 84, 182, 182, 84, 68, 184, 184, + 65, 182, 84, 182, 184, 183, 183, 183, 183, 84, + 183, 84, 84, 181, 41, 187, 81, 82, 183, 84, + 85, 86, 87, 187, 89, 90, 91, 92, 93, 94, + 95, 96, 184, 41, 184, 184, 182, 184, 182, 181, + 93, 184, 34, 184, 133, 171, 101, 75, 582, 571, + 371, 134, 684, 610, 119, 425, 280, 543, 706, 124, + 125, 126, 101, 230, -1, 356, 131, 233, -1, -1, + 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, + 145, 146, 147, -1, 149, 150, -1, -1, -1, 154, + 155, -1, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, -1, 173, 174, + 175, 176, 177, 178, 179, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, - 170, -1, 22, 23, 24, 25, 26, -1, -1, 29, + -1, -1, 22, 23, 24, 25, 26, -1, -1, 29, 30, -1, 32, 33, 34, 35, 36, 37, 38, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 82, 83, -1, 85, 86, 87, 88, -1, - 90, 91, 92, 93, 94, 95, 96, 97, -1, -1, + -1, 81, 82, -1, 84, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, 95, 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 118, -1, - -1, -1, -1, 123, 124, 125, -1, -1, -1, -1, - 130, -1, -1, -1, 134, 135, 136, 137, 138, -1, - -1, 141, 142, -1, 144, 145, 146, -1, 148, 149, - -1, -1, -1, 153, -1, 155, 156, 157, 158, 159, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 119, + -1, -1, -1, -1, 124, 125, 126, -1, -1, -1, + -1, 131, -1, -1, -1, 135, 136, 137, 138, 139, + -1, -1, 142, 143, -1, 145, 146, 147, -1, 149, + 150, -1, -1, -1, 154, 155, -1, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, -1, -1, -1, 22, 23, 24, - 25, 26, -1, -1, 29, 30, -1, 32, 33, 34, - 35, 36, 37, 38, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 53, 54, - 55, 56, 57, -1, -1, -1, -1, -1, -1, -1, - 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 82, 83, -1, - 85, 86, 87, 88, -1, 90, 91, 92, 93, 94, - 95, 96, 97, -1, -1, -1, -1, -1, -1, -1, + 170, 171, -1, 173, 174, 175, 176, 177, 178, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, -1, -1, -1, 22, 23, 24, 25, + 26, -1, -1, 29, 30, -1, 32, 33, 34, 35, + 36, 37, 38, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 53, 54, 55, + 56, 57, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 118, -1, -1, -1, -1, 123, 124, - 125, -1, -1, -1, -1, 130, -1, -1, -1, 134, - 135, 136, 137, 138, -1, -1, 141, 142, -1, 144, - 145, 146, -1, 148, 149, -1, -1, -1, 153, -1, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 53, 54, 55, 56, 57, - 58, -1, -1, -1, 62, -1, 64, 65, 66, 67, - 68, 69, 70, 71, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 85, -1, -1, + -1, -1, -1, -1, -1, 81, 82, -1, 84, 85, + 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, + 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - -1, 119, 120, -1, 122, -1, -1, -1, 126, 127, - -1, 129, -1, 131, 132, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 143, -1, -1, -1, 147, - -1, -1, -1, 151, 152, -1, 154, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 170, 53, 54, 55, 56, 57, 58, 177, - -1, -1, 62, -1, 64, 65, 66, 67, 68, 69, + -1, -1, -1, 119, -1, -1, -1, -1, 124, 125, + 126, -1, -1, -1, -1, 131, -1, -1, -1, 135, + 136, 137, 138, 139, -1, -1, 142, 143, -1, 145, + 146, 147, -1, 149, 150, -1, -1, -1, 154, 155, + -1, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, -1, 173, 174, 175, + 176, 177, 178, 53, 54, 55, 56, 57, 58, -1, + -1, -1, 62, -1, -1, 65, 66, 67, 68, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, -1, 119, - 120, -1, 122, -1, -1, -1, 126, 127, -1, 129, - -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 143, -1, -1, -1, 147, -1, -1, - -1, 151, 152, -1, 154, -1, -1, -1, -1, -1, - 53, 54, 55, 56, 57, 58, -1, -1, -1, 62, - 170, 64, 65, 66, 67, 68, 69, 70, -1, -1, + -1, -1, -1, -1, 84, -1, -1, 53, 54, 55, + 56, 57, 58, -1, -1, -1, 62, -1, -1, 65, + 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 84, -1, + 120, 121, -1, 123, -1, -1, -1, 127, 128, -1, + 130, -1, 132, 133, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 144, -1, -1, -1, 148, -1, + -1, -1, 152, 153, 120, 121, 156, 123, -1, -1, + -1, 127, 128, -1, 130, -1, 132, 133, -1, -1, + -1, -1, 172, -1, -1, -1, -1, -1, 144, -1, + -1, -1, 148, -1, -1, -1, 152, 153, -1, -1, + 156, -1, -1, -1, -1, 53, 54, 55, 56, 57, + 58, -1, -1, -1, 62, -1, 172, 65, 66, 67, + 68, 69, 70, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, -1, 119, 120, -1, 122, - -1, -1, -1, 126, 127, -1, 129, -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 143, -1, -1, -1, 147, -1, -1, -1, 151, 152, - -1, 154, -1, -1, -1, -1, -1, 53, 54, 55, - 56, 57, 58, -1, -1, -1, 62, 170, 64, 65, - 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, -1, 119, 120, -1, 122, -1, -1, -1, - 126, 127, -1, 129, -1, 131, 132, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 143, -1, -1, - -1, 147, -1, -1, -1, 151, 152, -1, 154, -1, + -1, -1, 120, 121, -1, 123, -1, -1, -1, 127, + 128, -1, 130, -1, 132, 133, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 144, -1, -1, -1, + 148, -1, -1, -1, 152, 153, -1, -1, 156, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 170 + -1, -1, -1, -1, 172 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1869,75 +1827,75 @@ static const yytype_uint16 yystos[] = 0, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 26, 29, 30, 32, 33, 34, 35, 36, 37, 38, - 40, 53, 54, 55, 56, 57, 65, 82, 83, 85, - 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, - 97, 118, 123, 124, 125, 130, 134, 135, 136, 137, - 138, 141, 142, 144, 145, 146, 148, 149, 153, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 171, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 197, 198, 199, 200, 201, 202, - 205, 206, 207, 208, 209, 210, 211, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 237, 238, 239, 240, 241, 242, 246, 247, 260, 261, - 262, 263, 265, 266, 272, 273, 277, 279, 280, 281, - 283, 285, 286, 287, 288, 290, 291, 292, 293, 294, - 296, 297, 299, 300, 301, 302, 303, 304, 305, 307, - 311, 312, 313, 80, 128, 264, 19, 68, 70, 306, - 81, 85, 98, 99, 172, 243, 244, 53, 54, 55, - 56, 57, 58, 62, 64, 65, 66, 67, 68, 69, - 70, 85, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 119, 120, - 122, 126, 127, 129, 131, 132, 143, 147, 151, 152, - 154, 170, 227, 317, 318, 19, 21, 64, 192, 29, - 318, 318, 29, 44, 45, 64, 85, 117, 267, 268, - 269, 267, 267, 267, 267, 267, 84, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 113, 248, 56, - 186, 58, 56, 57, 174, 85, 85, 119, 120, 278, - 126, 127, 129, 284, 126, 133, 282, 131, 133, 275, - 117, 152, 275, 275, 85, 128, 289, 133, 139, 140, - 276, 85, 143, 117, 121, 274, 117, 295, 147, 275, - 117, 298, 150, 151, 152, 27, 72, 27, 213, 213, - 227, 71, 27, 27, 12, 6, 117, 85, 117, 120, - 170, 50, 0, 185, 50, 171, 5, 172, 188, 193, - 195, 196, 226, 237, 238, 239, 240, 241, 313, 172, - 194, 188, 237, 238, 239, 240, 241, 85, 227, 187, - 246, 175, 204, 230, 231, 232, 188, 233, 234, 315, - 316, 318, 69, 271, 316, 233, 316, 204, 230, 52, - 20, 181, 66, 67, 230, 174, 85, 85, 85, 172, - 173, 175, 177, 64, 318, 27, 31, 318, 175, 175, - 175, 175, 39, 268, 264, 85, 174, 174, 174, 174, - 85, 101, 102, 103, 104, 106, 107, 108, 109, 113, - 256, 174, 174, 174, 174, 111, 112, 174, 41, 42, - 43, 85, 249, 171, 59, 61, 308, 309, 310, 85, - 85, 117, 117, 117, 275, 117, 128, 275, 117, 275, - 85, 128, 133, 85, 132, 275, 85, 275, 85, 85, - 276, 117, 173, 275, 117, 85, 154, 85, 133, 212, - 212, 318, 85, 85, 85, 85, 117, 117, 117, 117, - 50, 85, 85, 173, 176, 188, 230, 27, 203, 231, - 139, 314, 71, 177, 318, 27, 314, 27, 213, 85, - 100, 117, 245, 174, 174, 174, 85, 98, 99, 243, - 49, 85, 100, 117, 172, 228, 229, 318, 117, 46, - 47, 48, 270, 85, 85, 117, 174, 85, 89, 259, - 259, 259, 259, 174, 177, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 255, 259, 259, 257, 259, 257, - 174, 174, 259, 85, 85, 60, 62, 173, 274, 275, - 275, 117, 275, 275, 85, 275, 122, 173, 117, 72, - 174, 85, 27, 27, 174, 172, 176, 176, 233, 85, - 175, 318, 318, 233, 175, 235, 233, 212, 245, 245, - 245, 174, 85, 85, 85, 172, 173, 176, 177, 176, - 176, 85, 85, 176, 176, 258, 259, 255, 255, 255, - 255, 258, 85, 259, 259, 259, 259, 259, 259, 257, - 257, 259, 41, 173, 255, 255, 255, 255, 178, 178, - 255, 63, 310, 275, 117, 117, 173, 154, 85, 85, - 85, 85, 117, 85, 85, 71, 318, 85, 236, 234, - 245, 174, 174, 85, 229, 318, 176, 176, 255, 41, - 41, 41, 41, 174, 256, 41, 41, 41, 41, 101, - 113, 114, 116, 250, 251, 68, 252, 41, 85, 174, - 176, 318, 173, 176, 245, 245, 41, 258, 175, 175, - 175, 175, 179, 173, 175, 179, 85, 85, 259, 259, - 115, 176, 85, 253, 254, 41, 250, 257, 41, 176, - 176, 174, 174, 176, 173, 176, 180, 259, 259, 253, - 257, 176, 176 + 40, 53, 54, 55, 56, 57, 65, 81, 82, 84, + 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, + 96, 119, 124, 125, 126, 131, 135, 136, 137, 138, + 139, 142, 143, 145, 146, 147, 149, 150, 154, 155, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, + 178, 179, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 205, 206, 207, 208, 209, 210, 213, 214, 215, + 216, 217, 218, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 245, 246, 247, + 248, 249, 250, 254, 255, 268, 269, 270, 271, 273, + 274, 280, 281, 282, 286, 288, 289, 290, 292, 294, + 295, 296, 297, 299, 300, 301, 302, 303, 305, 306, + 308, 309, 310, 311, 312, 313, 314, 316, 320, 321, + 322, 80, 129, 272, 19, 68, 70, 315, 84, 97, + 98, 180, 251, 252, 53, 54, 55, 56, 57, 58, + 62, 65, 66, 67, 68, 69, 70, 84, 120, 121, + 123, 127, 128, 130, 132, 133, 144, 148, 152, 153, + 156, 172, 235, 326, 327, 19, 21, 64, 200, 29, + 327, 327, 29, 44, 45, 64, 84, 118, 275, 276, + 277, 275, 275, 275, 275, 275, 83, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 113, 256, + 56, 194, 58, 56, 57, 182, 84, 84, 120, 121, + 287, 127, 128, 130, 293, 127, 134, 291, 132, 134, + 284, 118, 153, 284, 284, 84, 129, 298, 134, 140, + 141, 285, 84, 144, 118, 122, 283, 118, 304, 148, + 284, 118, 307, 151, 152, 153, 27, 72, 27, 27, + 220, 220, 235, 71, 27, 27, 12, 6, 118, 84, + 118, 121, 172, 50, 0, 193, 50, 179, 5, 180, + 196, 201, 203, 204, 234, 245, 246, 247, 248, 249, + 322, 180, 202, 196, 245, 246, 247, 248, 249, 84, + 327, 195, 254, 183, 212, 238, 239, 240, 196, 241, + 242, 324, 325, 327, 69, 279, 325, 241, 325, 212, + 238, 52, 20, 189, 66, 67, 182, 84, 84, 84, + 180, 181, 183, 185, 64, 327, 27, 31, 327, 183, + 183, 183, 183, 39, 276, 272, 84, 182, 182, 182, + 182, 84, 100, 101, 102, 103, 105, 106, 107, 108, + 109, 113, 264, 182, 182, 182, 182, 182, 111, 112, + 182, 41, 42, 43, 84, 257, 179, 59, 61, 317, + 318, 319, 84, 84, 118, 118, 118, 284, 118, 129, + 284, 118, 284, 84, 129, 134, 84, 133, 284, 84, + 284, 84, 84, 285, 118, 181, 284, 118, 84, 156, + 84, 84, 134, 219, 219, 327, 84, 84, 84, 84, + 118, 118, 118, 118, 50, 84, 84, 181, 184, 196, + 238, 27, 211, 239, 140, 323, 71, 185, 327, 27, + 323, 27, 220, 84, 99, 118, 253, 182, 182, 182, + 84, 97, 98, 251, 49, 84, 99, 118, 180, 236, + 237, 327, 118, 46, 47, 48, 278, 84, 84, 118, + 182, 84, 88, 267, 267, 267, 267, 182, 185, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 263, + 267, 267, 265, 267, 265, 267, 182, 182, 267, 84, + 84, 60, 62, 181, 283, 284, 284, 118, 284, 284, + 84, 284, 123, 181, 118, 72, 182, 84, 27, 27, + 182, 180, 184, 184, 241, 84, 183, 327, 327, 241, + 183, 243, 241, 219, 253, 253, 253, 182, 84, 84, + 84, 180, 181, 184, 185, 184, 184, 84, 84, 184, + 184, 266, 267, 263, 263, 263, 263, 266, 84, 267, + 267, 267, 267, 267, 267, 265, 265, 267, 267, 41, + 181, 263, 263, 263, 263, 263, 186, 186, 263, 63, + 319, 284, 118, 118, 181, 156, 84, 84, 84, 84, + 118, 84, 84, 71, 327, 84, 244, 242, 253, 182, + 182, 84, 237, 327, 184, 184, 263, 41, 41, 41, + 41, 182, 264, 41, 41, 41, 41, 41, 100, 113, + 114, 115, 117, 258, 259, 68, 260, 41, 84, 182, + 184, 327, 181, 184, 253, 253, 41, 266, 183, 183, + 183, 183, 183, 187, 181, 183, 187, 84, 84, 267, + 267, 116, 184, 184, 84, 261, 262, 41, 258, 265, + 41, 184, 184, 182, 182, 184, 181, 184, 188, 267, + 267, 261, 265, 184, 184 }; #define yyerrok (yyerrstatus = 0) @@ -2945,42 +2903,42 @@ YYLTYPE yylloc; case 37: - { result->cur_stmt_type_ = OBPROXY_T_OTHERS; ;} + {;} break; - case 47: + case 38: - { result->cur_stmt_type_ = OBPROXY_T_CREATE; ;} + { result->cur_stmt_type_ = OBPROXY_T_OTHERS; ;} break; case 48: - { result->cur_stmt_type_ = OBPROXY_T_DROP; ;} + { result->cur_stmt_type_ = OBPROXY_T_CREATE; ;} break; case 49: - { result->cur_stmt_type_ = OBPROXY_T_ALTER; ;} + { result->cur_stmt_type_ = OBPROXY_T_DROP; ;} break; case 50: - { result->cur_stmt_type_ = OBPROXY_T_TRUNCATE; ;} + { result->cur_stmt_type_ = OBPROXY_T_ALTER; ;} break; case 51: - { result->cur_stmt_type_ = OBPROXY_T_RENAME; ;} + { result->cur_stmt_type_ = OBPROXY_T_TRUNCATE; ;} break; - case 53: + case 52: - { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_TABLE; ;} + { result->cur_stmt_type_ = OBPROXY_T_RENAME; ;} break; case 54: - { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_INDEX; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_TABLE; ;} break; case 55: @@ -2990,7 +2948,7 @@ YYLTYPE yylloc; case 56: - {;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_INDEX; ;} break; case 57: @@ -3030,6 +2988,11 @@ YYLTYPE yylloc; case 64: + {;} + break; + + case 65: + { ObProxyTextPsParseNode *node = NULL; malloc_parse_node(node); @@ -3038,7 +3001,7 @@ YYLTYPE yylloc; ;} break; - case 65: + case 66: { ObProxyTextPsParseNode *node = NULL; @@ -3048,7 +3011,7 @@ YYLTYPE yylloc; ;} break; - case 66: + case 67: { ObProxyTextPsParseNode *node = NULL; @@ -3058,7 +3021,7 @@ YYLTYPE yylloc; ;} break; - case 69: + case 70: { result->text_ps_inner_stmt_type_ = OBPROXY_T_TEXT_PS_PREPARE; @@ -3066,7 +3029,7 @@ YYLTYPE yylloc; ;} break; - case 70: + case 71: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_EXECUTE; @@ -3074,7 +3037,7 @@ YYLTYPE yylloc; ;} break; - case 71: + case 72: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_EXECUTE; @@ -3082,19 +3045,19 @@ YYLTYPE yylloc; ;} break; - case 72: + case 73: { ;} break; - case 73: + case 74: { ;} break; - case 74: + case 75: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_DROP; @@ -3102,7 +3065,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 76: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_DROP; @@ -3110,74 +3073,74 @@ YYLTYPE yylloc; ;} break; - case 76: + case 77: { result->cur_stmt_type_ = OBPROXY_T_GRANT; ;} break; - case 77: + case 78: { result->cur_stmt_type_ = OBPROXY_T_REVOKE; ;} break; - case 78: + case 79: { result->cur_stmt_type_ = OBPROXY_T_ANALYZE; ;} break; - case 79: + case 80: { result->cur_stmt_type_ = OBPROXY_T_PURGE; ;} break; - case 80: + case 81: { result->cur_stmt_type_ = OBPROXY_T_FLASHBACK; ;} break; - case 81: + case 82: { result->cur_stmt_type_ = OBPROXY_T_COMMENT; ;} break; - case 82: + case 83: { result->cur_stmt_type_ = OBPROXY_T_AUDIT; ;} break; - case 83: + case 84: { result->cur_stmt_type_ = OBPROXY_T_NOAUDIT; ;} break; - case 86: + case 87: {;} break; - case 87: + case 88: {;} break; - case 88: + case 89: {;} break; - case 93: + case 94: { result->cur_stmt_type_ = OBPROXY_T_SELECT_TX_RO; ;} break; - case 97: + case 98: { result->col_name_ = (yyvsp[(3) - (3)].str); ;} break; - case 98: + case 99: - { result->cur_stmt_type_ = OBPROXY_T_SET_AC_0; ;} + {;} break; case 100: @@ -3217,17 +3180,17 @@ YYLTYPE yylloc; case 107: - {;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; ;} break; case 108: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; ;} break; case 109: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; ;} + {;} break; case 110: @@ -3247,23 +3210,19 @@ YYLTYPE yylloc; case 113: - {;} - break; - - case 114: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_CREATE_TABLE; ;} break; - case 115: + case 114: { + result->table_info_.table_name_ = (yyvsp[(2) - (2)].str); result->cur_stmt_type_ = OBPROXY_T_DESC; result->sub_stmt_type_ = OBPROXY_T_SUB_DESC_TABLE; ;} break; - case 116: + case 115: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_COLUMNS; @@ -3271,7 +3230,7 @@ YYLTYPE yylloc; ;} break; - case 117: + case 116: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_COLUMNS; @@ -3280,7 +3239,7 @@ YYLTYPE yylloc; ;} break; - case 118: + case 117: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_INDEX; @@ -3288,7 +3247,7 @@ YYLTYPE yylloc; ;} break; - case 119: + case 118: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_INDEX; @@ -3297,98 +3256,106 @@ YYLTYPE yylloc; ;} break; - case 120: + case 119: {;} break; - case 121: + case 120: { result->table_info_.table_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 122: + case 121: {;} break; - case 123: + case 122: { result->table_info_.database_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 124: + case 123: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TABLES; ;} break; - case 125: + case 124: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_FULL_TABLES; ;} break; - case 126: + case 125: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TABLE_STATUS; ;} break; - case 127: + case 126: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DB_VERSION; ;} break; - case 128: + case 127: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 129: + case 128: { SET_ICMD_ONE_STRING((yyvsp[(3) - (3)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 130: + case 129: { SET_ICMD_SECOND_STRING((yyvsp[(5) - (5)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 131: + case 130: { SET_ICMD_ONE_STRING((yyvsp[(3) - (7)].str)); SET_ICMD_SECOND_STRING((yyvsp[(7) - (7)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; + case 131: + + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; ;} + break; + case 132: - { result->cur_stmt_type_ = OBPROXY_T_SELECT_ROUTE_ADDR; ;} + { + result->table_info_.table_name_ = (yyvsp[(3) - (3)].str); + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + ;} break; case 133: - { - result->cur_stmt_type_ = OBPROXY_T_SET_ROUTE_ADDR; - result->cmd_info_.integer_[0] = (yyvsp[(3) - (3)].num); - ;} + { result->cur_stmt_type_ = OBPROXY_T_SELECT_ROUTE_ADDR; ;} break; case 134: - {;} + { + result->cur_stmt_type_ = OBPROXY_T_SET_ROUTE_ADDR; + result->cmd_info_.integer_[0] = (yyvsp[(3) - (3)].num); + ;} break; case 135: @@ -3416,14 +3383,19 @@ YYLTYPE yylloc; {;} break; - case 141: + case 140: + + {;} + break; + + case 142: { result->table_info_.table_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 142: + case 143: { result->table_info_.package_name_ = (yyvsp[(1) - (3)].str); @@ -3431,7 +3403,7 @@ YYLTYPE yylloc; ;} break; - case 143: + case 144: { result->table_info_.database_name_ = (yyvsp[(1) - (5)].str); @@ -3440,14 +3412,14 @@ YYLTYPE yylloc; ;} break; - case 144: + case 145: { result->call_parse_info_.node_count_ = 0; ;} break; - case 145: + case 146: { result->call_parse_info_.node_count_ = 0; @@ -3455,14 +3427,14 @@ YYLTYPE yylloc; ;} break; - case 146: + case 147: { add_call_node(result->call_parse_info_, (yyvsp[(3) - (3)].node)); ;} break; - case 147: + case 148: { malloc_call_node((yyval.node), CALL_TOKEN_STR_VAL); @@ -3470,7 +3442,7 @@ YYLTYPE yylloc; ;} break; - case 148: + case 149: { malloc_call_node((yyval.node), CALL_TOKEN_INT_VAL); @@ -3478,7 +3450,7 @@ YYLTYPE yylloc; ;} break; - case 149: + case 150: { malloc_call_node((yyval.node), CALL_TOKEN_NUMBER_VAL); @@ -3486,7 +3458,7 @@ YYLTYPE yylloc; ;} break; - case 150: + case 151: { malloc_call_node((yyval.node), CALL_TOKEN_USER_VAR); @@ -3494,7 +3466,7 @@ YYLTYPE yylloc; ;} break; - case 151: + case 152: { malloc_call_node((yyval.node), CALL_TOKEN_SYS_VAR); @@ -3502,7 +3474,7 @@ YYLTYPE yylloc; ;} break; - case 152: + case 153: { result->placeholder_list_idx_++; @@ -3511,7 +3483,7 @@ YYLTYPE yylloc; ;} break; - case 166: + case 167: { handle_stmt_end(result); @@ -3519,7 +3491,7 @@ YYLTYPE yylloc; ;} break; - case 171: + case 172: { handle_stmt_end(result); @@ -3527,56 +3499,56 @@ YYLTYPE yylloc; ;} break; - case 175: + case 176: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_USER); ;} break; - case 176: + case 177: { add_set_var_node(result->set_parse_info_, (yyvsp[(6) - (6)].var_node), (yyvsp[(4) - (6)].str), SET_VAR_SYS); ;} break; - case 177: + case 178: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_SYS); ;} break; - case 178: + case 179: { add_set_var_node(result->set_parse_info_, (yyvsp[(5) - (5)].var_node), (yyvsp[(3) - (5)].str), SET_VAR_SYS); ;} break; - case 179: + case 180: { add_set_var_node(result->set_parse_info_, (yyvsp[(6) - (6)].var_node), (yyvsp[(4) - (6)].str), SET_VAR_SYS); ;} break; - case 180: + case 181: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_SYS); ;} break; - case 181: + case 182: { add_set_var_node(result->set_parse_info_, (yyvsp[(3) - (3)].var_node), (yyvsp[(1) - (3)].str), SET_VAR_SYS); ;} break; - case 182: + case 183: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_STR); @@ -3584,7 +3556,7 @@ YYLTYPE yylloc; ;} break; - case 183: + case 184: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_INT); @@ -3592,7 +3564,7 @@ YYLTYPE yylloc; ;} break; - case 184: + case 185: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_NUMBER); @@ -3600,42 +3572,42 @@ YYLTYPE yylloc; ;} break; - case 187: + case 188: {;} break; - case 188: + case 189: {;} break; - case 189: + case 190: { result->dbmesh_route_info_.tb_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 190: + case 191: { result->dbmesh_route_info_.table_name_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 191: + case 192: { result->dbmesh_route_info_.group_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 192: + case 193: { result->dbmesh_route_info_.es_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 193: + case 194: { result->dbmesh_route_info_.testload_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 194: + case 195: { malloc_shard_column_node((yyval.shard_node), (yyvsp[(2) - (7)].str), (yyvsp[(3) - (7)].str), DBMESH_TOKEN_STR_VAL); @@ -3644,52 +3616,57 @@ YYLTYPE yylloc; ;} break; - case 195: + case 196: { result->trace_id_ = (yyvsp[(4) - (6)].str); ;} break; - case 196: + case 197: { result->rpc_id_ = (yyvsp[(4) - (6)].str); ;} break; - case 197: + case 198: { result->dbmesh_route_info_.tnt_id_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 198: + case 199: { result->dbmesh_route_info_.disaster_status_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 199: + case 200: {;} break; - case 200: + case 201: {;} break; - case 201: + case 202: - {;} + { result->target_db_server_ = (yyvsp[(4) - (6)].str); ;} break; case 203: + {;} + break; + + case 205: + { result->has_simple_route_info_ = true; result->simple_route_info_.table_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 204: + case 206: { result->simple_route_info_.part_key_ = (yyvsp[(2) - (2)].str); ;} break; - case 208: + case 210: { result->dbp_route_info_.has_group_info_ = true; @@ -3697,7 +3674,7 @@ YYLTYPE yylloc; ;} break; - case 209: + case 211: { result->dbp_route_info_.has_group_info_ = true; @@ -3705,37 +3682,42 @@ YYLTYPE yylloc; ;} break; - case 210: + case 212: { result->dbp_route_info_.scan_all_ = true; ;} break; - case 211: + case 213: { result->dbp_route_info_.scan_all_ = true; ;} break; - case 212: + case 214: + + { result->dbp_route_info_.sticky_session_ = true; ;} + break; + + case 215: {result->dbp_route_info_.has_shard_key_ = true;;} break; - case 213: + case 216: { result->trace_id_ = (yyvsp[(3) - (4)].str); ;} break; - case 214: + case 217: { result->trace_id_ = (yyvsp[(3) - (6)].str); result->rpc_id_ = (yyvsp[(5) - (6)].str); ;} break; - case 215: + case 218: {;} break; - case 217: + case 220: { if (result->dbp_route_info_.shard_key_count_ < OBPROXY_MAX_DBP_SHARD_KEY_NUM) { @@ -3746,52 +3728,57 @@ YYLTYPE yylloc; ;} break; - case 220: + case 223: { result->dbmesh_route_info_.group_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 221: + case 224: { result->dbmesh_route_info_.tb_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 222: + case 225: { result->dbmesh_route_info_.table_name_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 223: + case 226: { result->dbmesh_route_info_.es_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 224: + case 227: { result->dbmesh_route_info_.testload_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 225: + case 228: { result->trace_id_ = (yyvsp[(3) - (3)].str); ;} break; - case 226: + case 229: { result->rpc_id_ = (yyvsp[(3) - (3)].str); ;} break; - case 227: + case 230: { result->dbmesh_route_info_.tnt_id_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 228: + case 231: { result->dbmesh_route_info_.disaster_status_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 229: + case 232: + + { result->target_db_server_ = (yyvsp[(3) - (3)].str); ;} + break; + + case 233: { malloc_shard_column_node((yyval.shard_node), (yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), DBMESH_TOKEN_STR_VAL); @@ -3800,32 +3787,32 @@ YYLTYPE yylloc; ;} break; - case 230: + case 234: {;} break; - case 231: + case 235: { (yyval.str).str_ = NULL; (yyval.str).str_len_ = 0; ;} break; - case 233: + case 237: { (yyval.str).str_ = NULL; (yyval.str).str_len_ = 0; ;} break; - case 255: + case 259: { result->query_timeout_ = (yyvsp[(3) - (4)].num); ;} break; - case 256: + case 260: {;} break; - case 258: + case 262: { add_hint_index(result->dbmesh_route_info_, (yyvsp[(3) - (5)].str)); @@ -3833,75 +3820,105 @@ YYLTYPE yylloc; ;} break; - case 259: + case 263: {;} break; - case 260: + case 264: {;} break; - case 261: + case 265: {;} break; - case 262: + case 266: {;} break; - case 263: + case 267: {;} break; - case 264: + case 268: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_WEAK); ;} break; - case 265: + case 269: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_STRONG); ;} break; - case 266: + case 270: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_FROZEN); ;} break; - case 269: + case 273: { result->cur_stmt_type_ = OBPROXY_T_SHOW_WARNINGS; ;} break; - case 270: + case 274: { result->cur_stmt_type_ = OBPROXY_T_SHOW_ERRORS; ;} break; - case 271: + case 275: { result->cur_stmt_type_ = OBPROXY_T_SHOW_TRACE; ;} break; - case 295: + case 299: + + {;} + break; + + case 300: + + {;} + break; + + case 301: + + {;} + break; + + case 302: + + {;} + break; + + case 303: + + {;} + break; + + case 304: + + {;} + break; + + case 305: { ;} break; - case 296: + case 306: { result->cmd_info_.integer_[2] = (yyvsp[(2) - (2)].num);/*row*/ ;} break; - case 297: + case 307: { result->cmd_info_.integer_[1] = (yyvsp[(2) - (4)].num);/*offset*/ @@ -3909,7 +3926,7 @@ YYLTYPE yylloc; ;} break; - case 298: + case 308: { result->cmd_info_.integer_[1] = (yyvsp[(4) - (4)].num);/*offset*/ @@ -3917,342 +3934,342 @@ YYLTYPE yylloc; ;} break; - case 299: + case 309: {;} break; - case 300: + case 310: { result->cmd_info_.string_[0] = (yyvsp[(2) - (2)].str);;} break; - case 301: + case 311: {;} break; - case 302: + case 312: { result->cmd_info_.string_[1] = (yyvsp[(2) - (2)].str);;} break; - case 304: + case 314: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_NET_THREAD); ;} break; - case 305: + case 315: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_NET_CONNECTION); ;} break; - case 306: + case 316: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_NET_CONNECTION, (yyvsp[(2) - (3)].num)); ;} break; - case 307: + case 317: {;} break; - case 308: + case 318: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONFIG_DIFF); ;} break; - case 309: + case 319: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONFIG_DIFF_USER); ;} break; - case 310: + case 320: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_LIST); ;} break; - case 312: + case 322: {SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_GLOBAL_SESSION_LIST);;} break; - case 313: + case 323: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_INFO, (yyvsp[(2) - (2)].str));;} break; - case 314: + case 324: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_LIKE, (yyvsp[(3) - (3)].str));;} break; - case 315: + case 325: {SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_INFO_ALL);;} break; - case 316: + case 326: {result->cmd_info_.string_[0] = (yyvsp[(2) - (2)].str);;} break; - case 318: + case 328: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_LIST_INTERNAL); ;} break; - case 319: + case 329: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_ATTRIBUTE); ;} break; - case 320: + case 330: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_ATTRIBUTE, (yyvsp[(2) - (3)].num)); ;} break; - case 321: + case 331: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_STAT); ;} break; - case 322: + case 332: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_STAT, (yyvsp[(2) - (3)].num)); ;} break; - case 323: + case 333: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_VARIABLES_LOCAL); ;} break; - case 324: + case 334: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_VARIABLES_LOCAL, (yyvsp[(2) - (3)].num)); ;} break; - case 325: + case 335: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_VARIABLES_ALL); ;} break; - case 326: + case 336: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_VARIABLES_ALL, (yyvsp[(3) - (4)].num)); ;} break; - case 327: + case 337: {;} break; - case 328: + case 338: { SET_ICMD_ONE_ID((yyvsp[(2) - (2)].num)); ;} break; - case 329: + case 339: {;} break; - case 330: + case 340: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_IDC); ;} break; - case 331: + case 341: {;} break; - case 333: + case 343: {;} break; - case 334: + case 344: { SET_ICMD_ONE_STRING((yyvsp[(1) - (1)].str)); ;} break; - case 335: + case 345: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONGEST_ALL);;} break; - case 336: + case 346: { SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_CONGEST_ALL, (yyvsp[(2) - (2)].str));;} break; - case 337: + case 347: {;} break; - case 338: + case 348: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_ROUTE_ROUTINE); ;} break; - case 339: + case 349: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_ROUTE_PARTITION); ;} break; - case 340: + case 350: {;} break; - case 341: + case 351: { SET_ICMD_ONE_STRING((yyvsp[(2) - (2)].str)); ;} break; - case 342: + case 352: {;} break; - case 343: + case 353: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_MEMORY_OBJPOOL); ;} break; - case 344: + case 354: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SQLAUDIT_AUDIT_ID); ;} break; - case 345: + case 355: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SQLAUDIT_SM_ID, (yyvsp[(2) - (2)].num)); ;} break; - case 347: + case 357: {;} break; - case 348: + case 358: { SET_ICMD_SECOND_ID((yyvsp[(1) - (1)].num)); ;} break; - case 349: + case 359: { SET_ICMD_TWO_ID((yyvsp[(3) - (3)].num), (yyvsp[(1) - (3)].num)); ;} break; - case 350: + case 360: { SET_ICMD_TWO_ID((yyvsp[(3) - (5)].num), (yyvsp[(1) - (5)].num)); SET_ICMD_ONE_STRING((yyvsp[(5) - (5)].str)); ;} break; - case 351: + case 361: {;} break; - case 352: + case 362: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_STAT_REFRESH); ;} break; - case 354: + case 364: {;} break; - case 355: + case 365: { SET_ICMD_ONE_ID((yyvsp[(1) - (1)].num)); ;} break; - case 356: + case 366: { SET_ICMD_SUB_AND_TWO_ID(OBPROXY_T_SUB_TRACE_LIMIT, (yyvsp[(1) - (2)].num),(yyvsp[(2) - (2)].num)); ;} break; - case 357: + case 367: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_BINARY); ;} break; - case 358: + case 368: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_UPGRADE); ;} break; - case 359: + case 369: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_IDC); ;} break; - case 360: + case 370: { SET_ICMD_ONE_STRING((yyvsp[(3) - (4)].str)); ;} break; - case 361: + case 371: { SET_ICMD_TWO_STRING((yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].str)); ;} break; - case 362: + case 372: { SET_ICMD_CONFIG_INT_VALUE((yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].num)); ;} break; - case 363: + case 373: { SET_ICMD_ONE_STRING((yyvsp[(3) - (3)].str)); ;} break; - case 364: + case 374: {;} break; - case 365: + case 375: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CS, (yyvsp[(2) - (2)].num)); ;} break; - case 366: + case 376: { SET_ICMD_SUB_AND_TWO_ID(OBPROXY_T_SUB_KILL_SS, (yyvsp[(2) - (3)].num), (yyvsp[(3) - (3)].num)); ;} break; - case 367: + case 377: {SET_ICMD_TYPE_STRING_INT_VALUE(OBPROXY_T_SUB_KILL_GLOBAL_SS_ID, (yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].num));;} break; - case 368: + case 378: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_KILL_GLOBAL_SS_DBKEY, (yyvsp[(2) - (2)].str));;} break; - case 369: + case 379: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CONNECTION, (yyvsp[(2) - (2)].num)); ;} break; - case 370: + case 380: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CONNECTION, (yyvsp[(3) - (3)].num)); ;} break; - case 371: + case 381: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_QUERY, (yyvsp[(3) - (3)].num)); ;} break; - case 374: + case 384: { result->has_anonymous_block_ = false ; @@ -4260,22 +4277,22 @@ YYLTYPE yylloc; ;} break; - case 375: + case 385: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 376: + case 386: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 377: + case 387: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 384: + case 394: { result->cur_stmt_type_ = OBPROXY_T_USE_DB; @@ -4283,27 +4300,27 @@ YYLTYPE yylloc; ;} break; - case 385: + case 395: { result->cur_stmt_type_ = OBPROXY_T_HELP; ;} break; - case 387: + case 397: {;} break; - case 388: + case 398: { result->part_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 389: + case 399: { result->part_name_ = (yyvsp[(3) - (4)].str); ;} break; - case 390: + case 400: { handle_stmt_end(result); @@ -4311,14 +4328,14 @@ YYLTYPE yylloc; ;} break; - case 391: + case 401: { result->table_info_.table_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 392: + case 402: { result->table_info_.database_name_ = (yyvsp[(1) - (3)].str); @@ -4326,7 +4343,7 @@ YYLTYPE yylloc; ;} break; - case 393: + case 403: { UPDATE_ALIAS_NAME((yyvsp[(2) - (2)].str)); @@ -4334,7 +4351,7 @@ YYLTYPE yylloc; ;} break; - case 394: + case 404: { UPDATE_ALIAS_NAME((yyvsp[(4) - (4)].str)); @@ -4343,7 +4360,7 @@ YYLTYPE yylloc; ;} break; - case 395: + case 405: { UPDATE_ALIAS_NAME((yyvsp[(3) - (3)].str)); @@ -4351,7 +4368,7 @@ YYLTYPE yylloc; ;} break; - case 396: + case 406: { UPDATE_ALIAS_NAME((yyvsp[(5) - (5)].str)); diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h index 7ce9c0f2..16705243 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h @@ -134,96 +134,104 @@ extern int ob_proxy_parser_utf8_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif diff --git a/src/obproxy/optimizer/ob_sharding_select_log_plan.cpp b/src/obproxy/optimizer/ob_sharding_select_log_plan.cpp index b5c667c0..3c3a654b 100644 --- a/src/obproxy/optimizer/ob_sharding_select_log_plan.cpp +++ b/src/obproxy/optimizer/ob_sharding_select_log_plan.cpp @@ -155,7 +155,7 @@ int ObShardingSelectLogPlan::do_handle_avg_expr(ObProxyExprAvg *agg_expr, T *&ex MEMCPY(buf, sql_string.ptr(), sql_string.length()); expr->set_expr_name(buf, sql_string.length()); if (OB_FAIL(handle_derived(expr))) { - LOG_WARN("fail to handle derived", K(ret)); + LOG_WARN("fail to handle derived", K(ret)); } } } @@ -490,8 +490,8 @@ int ObShardingSelectLogPlan::handle_derived(ObProxyExpr *expr, bool column_first ObProxyExprType expr_type = expr->get_expr_type(); if (OB_PROXY_EXPR_TYPE_COLUMN == expr_type || OB_PROXY_EXPR_TYPE_SHARDING_CONST == expr_type || expr->is_func_expr()) { - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &select_expr_array = select_stmt->select_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &select_expr_array = dml_stmt->select_exprs_; // Priority is given to finding derived columns, all derived columns have aliases and can be uniquely located if (bret && do_need_derived(derived_exprs_, expr, column_first, bret)) { @@ -572,8 +572,8 @@ int ObShardingSelectLogPlan::analyze_group_by_clause() { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; for (int64_t i = 0; OB_SUCC(ret) && i < group_by_exprs.count(); i++) { ObProxyGroupItem *group_item = dynamic_cast(group_by_exprs.at(i)); @@ -596,8 +596,8 @@ int ObShardingSelectLogPlan::analyze_order_by_clause() { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; for (int64_t i = 0; OB_SUCC(ret) && i < order_by_exprs.count(); i++) { ObProxyOrderItem *order_item = dynamic_cast(order_by_exprs.at(i)); @@ -619,8 +619,8 @@ int ObShardingSelectLogPlan::analyze_order_by_clause() int ObShardingSelectLogPlan::analyze_select_clause() { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &select_expr_array = select_stmt->select_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &select_expr_array = dml_stmt->select_exprs_; for (int64_t i = 0; OB_SUCC(ret) && i < select_expr_array.count(); i++) { ObProxyExpr *select_expr = select_expr_array.at(i); @@ -636,9 +636,9 @@ int ObShardingSelectLogPlan::append_derived_order_by(bool &is_same_group_and_ord { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; if (!group_by_exprs.empty() && order_by_exprs.empty()) { is_same_group_and_order = true; @@ -680,28 +680,28 @@ int ObShardingSelectLogPlan::append_derived_order_by(bool &is_same_group_and_ord int ObShardingSelectLogPlan::rewrite_sql(ObSqlString &new_sql) { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); ObString sql = client_request_.get_sql(); if (derived_columns_.empty() && derived_orders_.empty() - && (select_stmt->limit_size_ == -1 || select_stmt->limit_size_ == 0)) { + && (dml_stmt->limit_size_ == -1 || dml_stmt->limit_size_ == 0)) { new_sql.append(sql); } else { const char *sql_ptr = sql.ptr(); int64_t sql_len = sql.length(); if (derived_columns_.empty() && derived_orders_.empty()) { - int64_t limit_position = select_stmt->limit_token_off_; + int64_t limit_position = dml_stmt->limit_token_off_; new_sql.append(sql_ptr, limit_position); new_sql.append("LIMIT "); - if (select_stmt->limit_size_ == 0) { - new_sql.append_fmt("%d", select_stmt->limit_size_); + if (dml_stmt->limit_size_ == 0) { + new_sql.append_fmt("%d", dml_stmt->limit_size_); } else { - new_sql.append_fmt("%d", select_stmt->limit_offset_ + select_stmt->limit_size_); + new_sql.append_fmt("%d", dml_stmt->limit_offset_ + dml_stmt->limit_size_); } } else { - int64_t from_position = select_stmt->get_from_token_off(); - int64_t limit_position = select_stmt->limit_token_off_; + int64_t from_position = dml_stmt->get_from_token_off(); + int64_t limit_position = dml_stmt->limit_token_off_; new_sql.append(sql_ptr, from_position); if (!derived_columns_.empty()) { @@ -747,10 +747,10 @@ int ObShardingSelectLogPlan::rewrite_sql(ObSqlString &new_sql) if (limit_position > 0) { new_sql.append("LIMIT "); - if (select_stmt->limit_size_ == 0) { - new_sql.append_fmt("%d", select_stmt->limit_size_); + if (dml_stmt->limit_size_ == 0) { + new_sql.append_fmt("%d", dml_stmt->limit_size_); } else { - new_sql.append_fmt("%d", select_stmt->limit_offset_ + select_stmt->limit_size_); + new_sql.append_fmt("%d", dml_stmt->limit_offset_ + dml_stmt->limit_size_); } } } @@ -764,8 +764,8 @@ int ObShardingSelectLogPlan::add_agg_operator(bool need_set_limit) { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; T *agg_operator = NULL; ObProxyAggInput *agg_input = NULL; @@ -779,8 +779,8 @@ int ObShardingSelectLogPlan::add_agg_operator(bool need_set_limit) LOG_WARN("set child failed", K(ret)); } else { if (need_set_limit) { - agg_input->set_limit_offset(select_stmt->limit_offset_); - agg_input->set_limit_size(select_stmt->limit_size_); + agg_input->set_limit_offset(dml_stmt->limit_offset_); + agg_input->set_limit_size(dml_stmt->limit_size_); is_set_limit_ = true; } plan_root_ = agg_operator; @@ -816,8 +816,8 @@ int ObShardingSelectLogPlan::add_sort_operator(bool need_set_limit) { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; T *sort_operator = NULL; ObProxySortInput *sort_input = NULL; @@ -829,8 +829,8 @@ int ObShardingSelectLogPlan::add_sort_operator(bool need_set_limit) LOG_WARN("set child failed", K(ret)); } else { if (need_set_limit) { - sort_input->set_limit_offset(select_stmt->limit_offset_); - sort_input->set_limit_size(select_stmt->limit_size_); + sort_input->set_limit_offset(dml_stmt->limit_offset_); + sort_input->set_limit_size(dml_stmt->limit_size_); is_set_limit_ = true; } plan_root_ = sort_operator; @@ -865,9 +865,9 @@ int ObShardingSelectLogPlan::add_agg_and_sort_operator(bool is_same_group_and_or { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; if (!group_by_exprs.empty() || !agg_exprs_.empty()) { if (!is_same_group_and_order) { @@ -908,7 +908,7 @@ int ObShardingSelectLogPlan::add_table_scan_operator(ObIArray(client_request_.get_parse_result().get_proxy_stmt()); + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); ObProxyTableScanOp *table_scan_op = NULL; ObProxyTableScanInput *table_scan_input = NULL; char *buf = NULL; @@ -920,7 +920,7 @@ int ObShardingSelectLogPlan::add_table_scan_operator(ObIArrayset_db_key_names(shard_connector_array))) { LOG_WARN("fail to set db key name", K(ret)); } else if (OB_FAIL(table_scan_input->set_shard_props(shard_prop_array))) { @@ -931,9 +931,9 @@ int ObShardingSelectLogPlan::add_table_scan_operator(ObIArrayset_agg_exprs(agg_exprs_))) { LOG_WARN("fail to set agg expr", K(ret)); - } else if (OB_FAIL(table_scan_input->set_group_exprs(select_stmt->group_by_exprs_))) { + } else if (OB_FAIL(table_scan_input->set_group_exprs(dml_stmt->group_by_exprs_))) { LOG_WARN("fail to set group exprs", K(ret)); - } else if (OB_FAIL(table_scan_input->set_order_exprs(select_stmt->order_by_exprs_))) { + } else if (OB_FAIL(table_scan_input->set_order_exprs(dml_stmt->order_by_exprs_))) { LOG_WARN("fail to set order exprs", K(ret)); } else { table_scan_input->set_request_sql(request_sql); @@ -948,7 +948,7 @@ int ObShardingSelectLogPlan::add_table_scan_operator(ObIArray(client_request_.get_parse_result().get_proxy_stmt()); + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); ObProxyProOp *op = NULL; ObProxyProInput *input = NULL; @@ -959,8 +959,8 @@ int ObShardingSelectLogPlan::add_projection_operator() input->set_calc_exprs(calc_exprs_); input->set_derived_column_count(derived_column_count_); if (!is_set_limit_) { - input->set_limit_offset(select_stmt->limit_offset_); - input->set_limit_size(select_stmt->limit_size_); + input->set_limit_offset(dml_stmt->limit_offset_); + input->set_limit_size(dml_stmt->limit_size_); is_set_limit_ = true; } if (OB_FAIL(op->set_child(0, plan_root_))) { @@ -977,9 +977,9 @@ int ObShardingSelectLogPlan::compare_group_and_order(bool &is_same_group_and_ord { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; if (!group_by_exprs.empty() && !order_by_exprs.empty() && group_by_exprs.count() == order_by_exprs.count()) { diff --git a/src/obproxy/packet/ob_mysql_packet_reader.cpp b/src/obproxy/packet/ob_mysql_packet_reader.cpp index d4800d9a..d28ba1ba 100644 --- a/src/obproxy/packet/ob_mysql_packet_reader.cpp +++ b/src/obproxy/packet/ob_mysql_packet_reader.cpp @@ -12,7 +12,6 @@ #define USING_LOG_PREFIX PROXY #include "packet/ob_mysql_packet_reader.h" -#include "rpc/obmysql/ob_mysql_util.h" #include "rpc/obmysql/packet/ompk_ok.h" using namespace oceanbase::common; @@ -111,20 +110,20 @@ inline int ObMysqlPacketReader::get_buf(ObIOBufferReader &buf_reader, const int6 return ret; } -inline int ObMysqlPacketReader::get_content_len_and_seq(ObIOBufferReader &buf_reader, - const int64_t offset, int64_t &content_len, uint8_t &seq) +int ObMysqlPacketReader::is_eof_packet(ObIOBufferReader &buf_reader, const int64_t offset, bool &is_eof) { int ret = OB_SUCCESS; char *pbuf = NULL; - if (OB_FAIL(get_buf(buf_reader, OB_MYSQL_NET_HEADER_LENGTH, offset, pbuf))) { + is_eof = false; + if (OB_FAIL(get_buf(buf_reader, proxy::MYSQL_NET_META_LENGTH, offset, pbuf))) { LOG_WARN("fail to get header buf", K(ret)); } else if (OB_ISNULL(pbuf)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("pbuf is null, which is unexpected", K(pbuf), K(ret)); } else { - content_len = static_cast(uint3korr(pbuf)); - seq = static_cast(uint1korr(pbuf + 3)); - } + int64_t eof = static_cast(uint1korr(pbuf + 4)); + is_eof = (proxy::MYSQL_EOF_PACKET_TYPE == eof); + } return ret; } @@ -191,12 +190,18 @@ int ObMysqlPacketReader::get_ok_packet_server_status(ObIOBufferReader &buf_reade int ObMysqlPacketReader::get_packet(ObIOBufferReader &buf_reader, ObMySQLPacket &packet) +{ + return get_packet(buf_reader, 0, packet); +} + +int ObMysqlPacketReader::get_packet(ObIOBufferReader &buf_reader, + const int64_t offset, + ObMySQLPacket &packet) { int ret = OB_SUCCESS; char *content_buf = NULL; int64_t content_len = 0; uint8_t seq = 0; - int64_t offset = 0; if (OB_FAIL(get_content_len_and_seq(buf_reader, offset, content_len, seq))) { LOG_WARN("fail to get content length and seq", K(content_len), K(seq), K(offset), K(ret)); } else if (OB_FAIL(get_buf(buf_reader, content_len, offset + OB_MYSQL_NET_HEADER_LENGTH, content_buf))) { diff --git a/src/obproxy/packet/ob_mysql_packet_reader.h b/src/obproxy/packet/ob_mysql_packet_reader.h index 75dadab0..a95758e3 100644 --- a/src/obproxy/packet/ob_mysql_packet_reader.h +++ b/src/obproxy/packet/ob_mysql_packet_reader.h @@ -15,6 +15,8 @@ #include "utils/ob_proxy_lib.h" #include "iocore/eventsystem/ob_io_buffer.h" +#include "proxy/mysqllib/ob_mysql_common_define.h" +#include "rpc/obmysql/ob_mysql_util.h" namespace oceanbase { @@ -44,6 +46,8 @@ class ObMysqlPacketReader // === GET function will not comsume the packet int get_content_len_and_seq(event::ObIOBufferReader &buf_reader, const int64_t offset, int64_t &content_len, uint8_t &seq); + int is_eof_packet(event::ObIOBufferReader &buf_reader, const int64_t offset, bool &is_eof); + // DESC: get the next ok packet from MIOBuffer // NOTE: 1. get function will NOT consume buffer as packet may hold some string int mio_buf // 2. if mio_buf.consume or reader.reset is called, do NOT use the packet any more @@ -71,6 +75,9 @@ class ObMysqlPacketReader obmysql::OMPKOK &ok_pkt); int get_packet(event::ObIOBufferReader &buf_reader, obmysql::ObMySQLPacket &packet); + int get_packet(event::ObIOBufferReader &buf_reader, + const int64_t offset, + obmysql::ObMySQLPacket &packet); int get_ok_packet_server_status(event::ObIOBufferReader &buf_reader, obmysql::ObServerStatusFlags &server_status); // === READ function will comsume the packet @@ -134,6 +141,26 @@ inline int ObMysqlPacketReader::read_packet_str(event::ObIOBufferReader &buf_rea return ret; } +inline int ObMysqlPacketReader::get_content_len_and_seq(event::ObIOBufferReader &buf_reader, + const int64_t offset, + int64_t &content_len, + uint8_t &seq) +{ + int ret = OB_SUCCESS; + char *pbuf = NULL; + if (OB_FAIL(get_buf(buf_reader, OB_MYSQL_NET_HEADER_LENGTH, offset, pbuf))) { + PROXY_LOG(WARN, "fail to get header buf", K(ret)); + } else if (OB_ISNULL(pbuf)) { + ret = OB_ERR_UNEXPECTED; + PROXY_LOG(WARN, "pbuf is null, which is unexpected", K(pbuf), K(ret)); + } else { + content_len = static_cast(uint3korr(pbuf)); + seq = static_cast(uint1korr(pbuf + 3)); + } + + return ret; +} + } // end of namespace packet } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/packet/ob_mysql_packet_util.cpp b/src/obproxy/packet/ob_mysql_packet_util.cpp index 6fe455e8..74eb479c 100644 --- a/src/obproxy/packet/ob_mysql_packet_util.cpp +++ b/src/obproxy/packet/ob_mysql_packet_util.cpp @@ -72,14 +72,36 @@ int ObMysqlPacketUtil::encode_header(ObMIOBuffer &write_buf, return ret; } +int ObMysqlPacketUtil::encode_field_packet(ObMIOBuffer &write_buf, + uint8_t &seq, + ObMySQLField &field) { + int ret = OB_SUCCESS; + OMPKField field_packet(field); + field_packet.set_seq(seq++); + if (OB_FAIL(ObMysqlPacketWriter::write_field_packet(write_buf, field_packet))) { + LOG_WARN("fail to write field", K(field_packet), K(field), K(ret)); + --seq; + } + return ret; +} + int ObMysqlPacketUtil::encode_row_packet(ObMIOBuffer &write_buf, uint8_t &seq, const ObNewRow &row, ObIArray *fields) +{ + return encode_row_packet(write_buf, TEXT, seq, row, fields); +} + +int ObMysqlPacketUtil::encode_row_packet(ObMIOBuffer &write_buf, + MYSQL_PROTOCOL_TYPE protocol_type, + uint8_t &seq, + const ObNewRow &row, + ObIArray *fields) { int ret = OB_SUCCESS; - ObSMRow sm_row(TEXT, row, NULL, fields); + ObSMRow sm_row(protocol_type, row, NULL, fields); OMPKRow row_packet(sm_row); row_packet.set_seq(seq++); @@ -108,99 +130,6 @@ int ObMysqlPacketUtil::encode_eof_packet(ObMIOBuffer &write_buf, return ret; } -int ObMysqlPacketUtil::encode_executor_response_packet(ObMIOBuffer *write_buf, uint8_t &seq, - engine::ObProxyResultResp *result_resp) -{ - int ret = OB_SUCCESS; - - int64_t column_count = result_resp->get_column_count(); - ObSEArray *fields = NULL; - ObSEArray ob_fields; - - // header , cols , first eof - if (OB_SUCC(ret)) { - if (OB_FAIL(result_resp->get_fields(fields))) { - LOG_WARN("faild to push field", K(fields), K(ret)); - } else if (OB_ISNULL(fields)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fields should not be null", K(ret)); - } else if (OB_UNLIKELY(fields->count() != column_count)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fields count should equal column_count", K(column_count), "fileds count", fields->count(), K(ret)); - } else if (OB_FAIL(ObMysqlPacketUtil::encode_header(*write_buf, seq, *fields))) { - LOG_WARN("faild to encode header", K(fields), K(seq), K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < column_count; i++) { - ObMySQLField &mysql_field = fields->at(i); - ObField ob_field; - if (OB_FAIL(ObSMUtils::to_ob_field(mysql_field, ob_field))) { - LOG_WARN("faild to ob field", K(mysql_field), K(ret)); - } else if (OB_FAIL(ob_fields.push_back(ob_field))) { - LOG_WARN("faild to push ob field", K(ob_field), K(ret)); - } - } - } - } - - // rows - if (OB_SUCC(ret)) { - ObObj *objs = NULL; - int64_t buf_len = sizeof(ObObj) * column_count; - - if (OB_ISNULL(objs = static_cast(op_fixed_mem_alloc(buf_len)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("faild to alloc obj array", K(column_count), K(ret)); - } else { - ObNewRow row; - //ObSEArray *row_array; - ObSEArray *row_array; - while ((OB_SUCC(ret)) && (OB_SUCC(result_resp->next(row_array)))) { - if (OB_ISNULL(row_array)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("row_array should not be null", K(ret)); - } else if (OB_UNLIKELY(row_array->count() != column_count)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("row_array count should equal column_count", K(column_count), - "row_array count", row_array->count(), K(ret)); - } - - for (int64_t i = 0; OB_SUCC(ret) && i < column_count; i++) { - objs[i] = *(row_array->at(i)); - } - - if (OB_SUCC(ret)) { - row.cells_ = objs; - row.count_ = column_count; - if (OB_FAIL(ObMysqlPacketUtil::encode_row_packet(*write_buf, seq, row, &ob_fields))) { - LOG_WARN("faild to encode row", K(seq), K(row), K(ret)); - } else { - row.reset(); - row_array = NULL; - } - } - } - - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - } - } - - if (OB_NOT_NULL(objs)) { - op_fixed_mem_free(objs, buf_len); - objs = NULL; - } - } - - // second eof - if (OB_SUCC(ret)) { - if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*write_buf, seq))) { - LOG_WARN("faild to encode row", K(seq), K(ret)); - } - } - - return ret; -} - int ObMysqlPacketUtil::encode_err_packet(ObMIOBuffer &write_buf, uint8_t &seq, const int errcode, const char *msg_buf) { return encode_err_packet(write_buf, seq, errcode, ObString::make_string(msg_buf)); diff --git a/src/obproxy/packet/ob_mysql_packet_util.h b/src/obproxy/packet/ob_mysql_packet_util.h index f9cc349d..2073997e 100644 --- a/src/obproxy/packet/ob_mysql_packet_util.h +++ b/src/obproxy/packet/ob_mysql_packet_util.h @@ -47,13 +47,20 @@ class ObMysqlPacketUtil static int encode_header(event::ObMIOBuffer &write_buf, uint8_t &seq, common::ObIArray &fields, uint16_t status_flag = 0); - static int encode_row_packet(event::ObMIOBuffer &write_buf, uint8_t &seq, + static int encode_field_packet(event::ObMIOBuffer &write_buf, + uint8_t &seq, + obmysql::ObMySQLField &field); + static int encode_row_packet(event::ObMIOBuffer &write_buf, + uint8_t &seq, + const common::ObNewRow &row, + common::ObIArray *fields = NULL); + static int encode_row_packet(event::ObMIOBuffer &write_buf, + obmysql::MYSQL_PROTOCOL_TYPE protocol_type, + uint8_t &seq, const common::ObNewRow &row, common::ObIArray *fields = NULL); static int encode_eof_packet(event::ObMIOBuffer &write_buf, uint8_t &seq, uint16_t status_flag = 0); - static int encode_executor_response_packet(event::ObMIOBuffer *write_buf, uint8_t &seq, - engine::ObProxyResultResp *result_resp); static int encode_err_packet(event::ObMIOBuffer &write_buf, uint8_t &seq, const int errcode, const char *msg_buf); diff --git a/src/obproxy/packet/ob_proxy_packet_writer.cpp b/src/obproxy/packet/ob_proxy_packet_writer.cpp index f879d1b7..d5d1a108 100644 --- a/src/obproxy/packet/ob_proxy_packet_writer.cpp +++ b/src/obproxy/packet/ob_proxy_packet_writer.cpp @@ -35,18 +35,20 @@ namespace obproxy namespace packet { -int ObProxyPacketWriter::write_packet(event::ObMIOBuffer &write_buf, ObMysqlClientSession &client_session, +int ObProxyPacketWriter::write_packet(event::ObMIOBuffer &write_buf, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, obmysql::ObMySQLPacket &packet) { int ret = OB_SUCCESS; - ObProxyProtocol protocol = client_session.get_client_session_protocol(); - + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session.is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); if (OB_FAIL(ObMysqlOB20PacketWriter::write_packet(write_buf, packet, ob20_head_param))) { LOG_WARN("fail to write ob20 packet", K(ret)); } else { @@ -61,18 +63,20 @@ int ObProxyPacketWriter::write_packet(event::ObMIOBuffer &write_buf, ObMysqlClie return ret; } -int ObProxyPacketWriter::write_raw_packet(event::ObMIOBuffer &write_buf, ObMysqlClientSession &client_session, +int ObProxyPacketWriter::write_raw_packet(event::ObMIOBuffer &write_buf, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, ObString &pkt_str) { int ret = OB_SUCCESS; - ObProxyProtocol client_protocol = client_session.get_client_session_protocol(); - if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, - compressed_seq, compressed_seq, true, false, - client_session.is_client_support_new_extra_info()); + compressed_seq, compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); if (OB_FAIL(ObMysqlOB20PacketWriter::write_raw_packet(write_buf, pkt_str, ob20_head_param))) { LOG_WARN("fail to write raw packet in ob20 format", K(ret)); } else { @@ -87,19 +91,23 @@ int ObProxyPacketWriter::write_raw_packet(event::ObMIOBuffer &write_buf, ObMysql return ret; } -int ObProxyPacketWriter::write_kv_resultset(event::ObMIOBuffer &write_buf, ObMysqlClientSession &client_session, - uint8_t &seq, const obmysql::ObMySQLField &field, ObObj &field_value, +int ObProxyPacketWriter::write_kv_resultset(event::ObMIOBuffer &write_buf, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, + uint8_t &seq, + const obmysql::ObMySQLField &field, + ObObj &field_value, const uint16_t status_flag) { int ret = OB_SUCCESS; - ObProxyProtocol client_protocol = client_session.get_client_session_protocol(); - if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session.is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::encode_kv_resultset(write_buf, ob20_head_param, seq, field, field_value, status_flag))) { LOG_WARN("fail to encode kv resultset", K(ret)); @@ -114,19 +122,22 @@ int ObProxyPacketWriter::write_kv_resultset(event::ObMIOBuffer &write_buf, ObMys return ret; } -int ObProxyPacketWriter::write_ok_packet(event::ObMIOBuffer &write_buf, ObMysqlClientSession &client_session, - uint8_t &seq, const int64_t affected_rows, +int ObProxyPacketWriter::write_ok_packet(event::ObMIOBuffer &write_buf, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, + uint8_t &seq, + const int64_t affected_rows, const obmysql::ObMySQLCapabilityFlags &capability) { int ret = OB_SUCCESS; - ObProxyProtocol protocol = client_session.get_client_session_protocol(); if (protocol == ObProxyProtocol::PROTOCOL_OB20) { Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session.is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::encode_ok_packet(write_buf, ob20_head_param, seq, affected_rows, capability))) { LOG_WARN("fail to encode ok packet in ob20 format", K(ret)); } else { @@ -141,31 +152,6 @@ int ObProxyPacketWriter::write_ok_packet(event::ObMIOBuffer &write_buf, ObMysqlC return ret; } -int ObProxyPacketWriter::write_executor_resp_packet(event::ObMIOBuffer *write_buf, - ObMysqlClientSession *client_session, uint8_t &seq, - engine::ObProxyResultResp *result_resp) -{ - int ret = OB_SUCCESS; - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); - - if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { - Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; - uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); - Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); - if (OB_FAIL(ObProto20Utils::encode_executor_response_packet(write_buf, ob20_head_param, seq, result_resp))) { - LOG_WARN("fail to encode executor response ob20 packet", K(ret)); - } - } else { - if (OB_FAIL(ObMysqlPacketUtil::encode_executor_response_packet(write_buf, seq, result_resp))) { - LOG_WARN("fail to encode executor response packet", K(ret)); - } - } - - return ret; -} - int ObProxyPacketWriter::get_err_buf(int err_code, char *&buf) { int ret = OB_SUCCESS; @@ -195,19 +181,27 @@ int ObProxyPacketWriter::get_err_buf(int err_code, char *&buf) return ret; } -int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, const int err_code, const char *msg_buf) +// build error packet back to client +int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, + proxy::ObMysqlClientSession *client_session, + const ObProxyProtocol protocol, + uint8_t &seq, + const int err_code, + const char *msg_buf) { - return write_error_packet(write_buf, client_session, seq, err_code, common::ObString::make_string(msg_buf)); + return write_error_packet(write_buf, client_session, protocol, seq, err_code, common::ObString::make_string(msg_buf)); } -int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, const int err_code, const ObString &msg_buf) +int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, + proxy::ObMysqlClientSession *client_session, + const ObProxyProtocol protocol, + uint8_t &seq, + const int err_code, + const ObString &msg_buf) { int ret = OB_SUCCESS; - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); - if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { if (OB_ISNULL(client_session)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid client session ptr in ob20 mode", K(ret)); @@ -215,8 +209,9 @@ int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, proxy Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, - compressed_seq, compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::encode_err_packet(write_buf, ob20_head_param, seq, err_code, msg_buf))) { LOG_WARN("fail to encode err packet in ob20 format", K(ret)); } diff --git a/src/obproxy/packet/ob_proxy_packet_writer.h b/src/obproxy/packet/ob_proxy_packet_writer.h index 1fb184c8..4b58c4db 100644 --- a/src/obproxy/packet/ob_proxy_packet_writer.h +++ b/src/obproxy/packet/ob_proxy_packet_writer.h @@ -33,16 +33,18 @@ class ObProxyPacketWriter { // packet static int write_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, + const proxy::ObProxyProtocol protocol, obmysql::ObMySQLPacket &packet); - static int write_raw_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, + static int write_raw_packet(event::ObMIOBuffer &write_buf, + proxy::ObMysqlClientSession &client_session, + const proxy::ObProxyProtocol protocol, ObString &pkt_str); static int write_kv_resultset(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, - uint8_t &seq, const obmysql::ObMySQLField &field, ObObj &field_value, - const uint16_t status_flag); - static int write_ok_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, uint8_t &seq, - const int64_t affected_rows, const obmysql::ObMySQLCapabilityFlags &capability); - static int write_executor_resp_packet(event::ObMIOBuffer *write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, engine::ObProxyResultResp *result_resp); + const proxy::ObProxyProtocol protocol, uint8_t &seq, + const obmysql::ObMySQLField &field, ObObj &field_value, const uint16_t status_flag); + static int write_ok_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, + const proxy::ObProxyProtocol protocol, uint8_t &seq, const int64_t affected_rows, + const obmysql::ObMySQLCapabilityFlags &capability); // get thread err buffer static int get_err_buf(int err_code, char *&buf); @@ -74,9 +76,11 @@ class ObProxyPacketWriter { } static int write_error_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, const int err_code, const char *msg_buf); + const proxy::ObProxyProtocol protocol, uint8_t &seq, + const int err_code, const char *msg_buf); static int write_error_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, const int err_code, const ObString &msg_buf); + const proxy::ObProxyProtocol protocol, uint8_t &seq, const int err_code, + const ObString &msg_buf); }; diff --git a/src/obproxy/prometheus/ob_prometheus_processor.h b/src/obproxy/prometheus/ob_prometheus_processor.h index 106516a8..44525392 100644 --- a/src/obproxy/prometheus/ob_prometheus_processor.h +++ b/src/obproxy/prometheus/ob_prometheus_processor.h @@ -88,7 +88,7 @@ class ObPrometheusProcessor obutils::ObAsyncCommonTask *prometheus_sync_cont_; char version_[100]; - char proxy_ip_[common::OB_IP_STR_BUFF]; // ip primary key + char proxy_ip_[common::MAX_IP_ADDR_LENGTH]; // ip primary key common::ObVector default_constant_labels_; ObPrometheusFamilyHashTable family_hash_; diff --git a/src/obproxy/proxy/api/ob_api_internal.h b/src/obproxy/proxy/api/ob_api_internal.h index d309439f..a956efb1 100644 --- a/src/obproxy/proxy/api/ob_api_internal.h +++ b/src/obproxy/proxy/api/ob_api_internal.h @@ -93,6 +93,9 @@ class ObFeatureAPIHooks // Remove all hooks. void destroy(); + // Remove hooks indicated by id + void destroy(ID id); + // Add the hook cont to the front of the hooks for id. int prepend(ID id, ObContInternal *cont); @@ -120,7 +123,7 @@ class ObFeatureAPIHooks private: bool hooks_p_; // Flag for (not) empty container. - + // The array of hooks lists. ObAPIHooks hooks_[N]; }; @@ -203,6 +206,23 @@ inline void ObFeatureAPIHooks::destroy() hooks_p_ = false; } +template +inline void ObFeatureAPIHooks::destroy(ID id) +{ + if (is_valid(id)) { + hooks_[id].destroy(); + + bool has_hooks_or_not = false; + for (int i = 0; i < N; ++i) { + if (!hooks_[i].is_empty()) { + has_hooks_or_not = true; + break; + } + } + hooks_p_ = has_hooks_or_not; + } +} + template inline int ObFeatureAPIHooks::prepend(ID id, ObContInternal *cont) { diff --git a/src/obproxy/proxy/api/ob_mysql_sm_api.h b/src/obproxy/proxy/api/ob_mysql_sm_api.h index 8d70ed8e..4099ffea 100644 --- a/src/obproxy/proxy/api/ob_mysql_sm_api.h +++ b/src/obproxy/proxy/api/ob_mysql_sm_api.h @@ -116,6 +116,7 @@ class ObMysqlSMApi void txn_hook_append(const ObMysqlHookID id, ObContInternal *cont); void txn_hook_prepend(const ObMysqlHookID id, ObContInternal *cont); ObAPIHook *txn_hook_get(const ObMysqlHookID id); + void txn_destroy_hook(const ObMysqlHookID id); public: // Tunneling request to plugin @@ -180,6 +181,11 @@ inline ObAPIHook *ObMysqlSMApi::txn_hook_get(const ObMysqlHookID id) return api_hooks_.get(id); } +inline void ObMysqlSMApi::txn_destroy_hook(const ObMysqlHookID id) +{ + api_hooks_.destroy(id); +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/client/Makemodule.am b/src/obproxy/proxy/client/Makemodule.am index 33b73fdd..d62193b0 100644 --- a/src/obproxy/proxy/client/Makemodule.am +++ b/src/obproxy/proxy/client/Makemodule.am @@ -8,4 +8,6 @@ obproxy/proxy/client/ob_mysql_client_pool.cpp\ obproxy/proxy/client/ob_raw_mysql_client.h\ obproxy/proxy/client/ob_raw_mysql_client.cpp\ obproxy/proxy/client/ob_mysql_proxy.h\ -obproxy/proxy/client/ob_mysql_proxy.cpp +obproxy/proxy/client/ob_mysql_proxy.cpp\ +obproxy/proxy/client/ob_driver_client.h\ +obproxy/proxy/client/ob_driver_client.cpp diff --git a/src/obproxy/proxy/client/ob_client_utils.cpp b/src/obproxy/proxy/client/ob_client_utils.cpp index 20bf5365..cfc78c7b 100644 --- a/src/obproxy/proxy/client/ob_client_utils.cpp +++ b/src/obproxy/proxy/client/ob_client_utils.cpp @@ -17,7 +17,7 @@ #include "rpc/obmysql/packet/ompk_handshake_response.h" #include "packet/ob_mysql_packet_reader.h" #include "packet/ob_mysql_packet_writer.h" - +#include "omt/ob_proxy_config_table_processor.h" using namespace oceanbase::common; using namespace oceanbase::obmysql; @@ -25,6 +25,8 @@ using namespace oceanbase::obproxy; using namespace oceanbase::obproxy::proxy; using namespace oceanbase::obproxy::event; using namespace oceanbase::obproxy::packet; +using namespace oceanbase::obproxy::omt; +using namespace oceanbase::obproxy::obutils; namespace oceanbase { @@ -41,7 +43,10 @@ void ObMysqlRequestParam::reset() current_idc_name_.reset(); is_user_idc_name_set_ = false; need_print_trace_stat_ = false; - + target_addr_.reset(); + ob_client_flags_.flags_ = 0; + mysql_client_ = NULL; + is_detect_client_ = false; } void ObMysqlRequestParam::reset_sql() @@ -81,6 +86,9 @@ int ObMysqlRequestParam::deep_copy(const ObMysqlRequestParam &other) is_user_idc_name_set_ = other.is_user_idc_name_set_; need_print_trace_stat_ = other.need_print_trace_stat_; target_addr_ = other.target_addr_; + ob_client_flags_.flags_ = other.ob_client_flags_.flags_; + mysql_client_ = other.mysql_client_; + is_detect_client_ = other.is_detect_client_; if (other.is_user_idc_name_set_ && !other.current_idc_name_.empty()) { MEMCPY(current_idc_name_buf_, other.current_idc_name_.ptr(), other.current_idc_name_.length()); current_idc_name_.assign_ptr(current_idc_name_buf_, other.current_idc_name_.length()); @@ -265,15 +273,15 @@ int64_t ObMysqlResultHandler::to_string(char *buf, const int64_t buf_len) const return pos; } -//------------------------- ObClientReuqestInfo--------------------------------// -void ObClientReuqestInfo::reset() +//------------------------- ObClientRequestInfo --------------------------------// +void ObClientRequestInfo::reset() { reset_names(); need_skip_stage2_ = false; request_param_.reset(); } -void ObClientReuqestInfo::reset_names() +void ObClientRequestInfo::reset_names() { if ((NULL != name_) && (name_len_ > 0)) { op_fixed_mem_free(name_, name_len_); @@ -282,31 +290,35 @@ void ObClientReuqestInfo::reset_names() name_len_ = 0; user_name_.reset(); database_name_.reset(); + cluster_name_.reset(); password_.reset(); password0_.reset(); password1_.reset(); using_password_num_ = -1; + password_version_ = 0; } -void ObClientReuqestInfo::reset_sql() +void ObClientRequestInfo::reset_sql() { request_param_.reset(); } -int64_t ObClientReuqestInfo::to_string(char *buf, const int64_t buf_len) const +int64_t ObClientRequestInfo::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; J_OBJ_START(); J_KV(K_(user_name), K_(database_name), + K_(cluster_name), K_(request_param)); J_OBJ_END(); return pos; } -int ObClientReuqestInfo::set_names(const ObString &user_name, +int ObClientRequestInfo::set_names(const ObString &user_name, const ObString &password, const ObString &database_name, + const ObString &cluster_name, const ObString &password1) { int ret = OB_SUCCESS; @@ -315,13 +327,24 @@ int ObClientReuqestInfo::set_names(const ObString &user_name, LOG_WARN("user_name can not be NULL", K(user_name), K(ret)); } else { reset_names(); - int64_t total_len = user_name.length() + password.length() + password1.length() + database_name.length(); + int64_t total_len = user_name.length() + password.length() + password1.length() + + database_name.length() + cluster_name.length(); + if (user_name.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { + if (password.empty()) { + total_len += ENC_STRING_BUF_LEN - 2; + } + if (password1.empty()) { + total_len += ENC_STRING_BUF_LEN - 2; + } + } + if (OB_ISNULL(name_ = static_cast(op_fixed_mem_alloc(total_len)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate mem", "alloc size", total_len, K(ret)); } else { int64_t pos = 0; name_len_ = total_len; + memset(name_, 0, total_len); MEMCPY(name_, user_name.ptr(), user_name.length()); user_name_.assign_ptr(name_, user_name.length()); pos += user_name.length(); @@ -329,25 +352,41 @@ int ObClientReuqestInfo::set_names(const ObString &user_name, if (!password.empty()) { MEMCPY(name_ + pos, password.ptr(), password.length()); password_.assign_ptr(name_ + pos, password.length()); + using_password_num_ = 0; password0_ = password_; pos += password.length(); + } else if (user_name.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { + password0_.assign_ptr(name_ + pos, ENC_STRING_BUF_LEN - 2); + pos += ENC_STRING_BUF_LEN - 2; } if (!password1.empty()) { MEMCPY(name_ + pos, password1.ptr(), password1.length()); password1_.assign_ptr(name_ + pos, password1.length()); pos += password1.length(); + if (password_.empty()) { + password_ = password1_; + using_password_num_ = 1; + } + } else if (user_name.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { + password1_.assign_ptr(name_ + pos, ENC_STRING_BUF_LEN - 2); + pos+= ENC_STRING_BUF_LEN - 2; } - if (!password.empty() && !password1.empty()) { + if (user_name.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME) && password0_.empty() && password1_.empty()) { using_password_num_ = 0; } - if (!database_name.empty()) { MEMCPY(name_ + pos, database_name.ptr(), database_name.length()); database_name_.assign_ptr(name_ + pos, database_name.length()); pos += database_name.length(); } + + if (!cluster_name.empty()) { + MEMCPY(name_ + pos, cluster_name.ptr(), cluster_name.length()); + cluster_name_.assign_ptr(name_ + pos, cluster_name.length()); + pos += cluster_name.length(); + } if (pos != total_len) { ret = OB_ERR_UNEXPECTED; LOG_WARN("pos must be equal to total len", K(pos), K(total_len), K(ret)); @@ -358,7 +397,7 @@ int ObClientReuqestInfo::set_names(const ObString &user_name, return ret; } -int ObClientReuqestInfo::set_request_param(const ObMysqlRequestParam &request_param) +int ObClientRequestInfo::set_request_param(const ObMysqlRequestParam &request_param) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!request_param.is_valid())) { @@ -418,7 +457,7 @@ int ObClientUtils::get_scramble(ObIOBufferReader *response_reader, char *buf, int ObClientUtils::build_handshake_response_packet( ObClientMysqlResp *handshake, - ObClientReuqestInfo *info, + ObClientRequestInfo *info, ObMIOBuffer *handshake_resp_buf) { int ret = OB_SUCCESS; @@ -486,6 +525,45 @@ int ObClientUtils::build_handshake_response_packet( return ret; } +const ObString& ObClientRequestInfo::get_password() +{ + int ret = OB_SUCCESS; + uint64_t global_version = get_global_proxy_config_table_processor().get_config_version(); + if (!cluster_name_.empty() && password_version_ != global_version && user_name_.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { + ObConfigItem item; + ObVipAddr addr; + password_.reset(); + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name_, "", ObProxyTableInfo::OBSERVER_SYS_PASSWORD, item))) { + LOG_WARN("get observer_sys_password config failed", K_(cluster_name), K(ret)); + } else if (40 == strlen(item.str())) { + MEMCPY(password0_.ptr(), item.str(), strlen(item.str())); + password_ = password0_; + } else { + memset(password0_.ptr(), 0, password0_.length()); + } + + using_password_num_ = 0; + + if (OB_SUCC(ret)) { + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name_, "", ObProxyTableInfo::OBSERVER_SYS_PASSWORD1, item))) { + LOG_WARN("get observer_sys_password1 config failed", K_(cluster_name), K(ret)); + } else if (40 == strlen(item.str())) { + MEMCPY(password1_.ptr(), item.str(), strlen(item.str())); + } else { + memset(password1_.ptr(), 0, sizeof(password1_.length())); + } + } + if (OB_SUCC(ret)) { + password_version_ = global_version; + } + LOG_DEBUG("get new password success", K(password0_), K(password1_)); + } + + return password_; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/client/ob_client_utils.h b/src/obproxy/proxy/client/ob_client_utils.h index 6e94f66b..bd281ddb 100644 --- a/src/obproxy/proxy/client/ob_client_utils.h +++ b/src/obproxy/proxy/client/ob_client_utils.h @@ -16,6 +16,7 @@ #include "iocore/net/ob_net.h" #include "proxy/mysqllib/ob_mysql_transaction_analyzer.h" #include "proxy/mysqllib/ob_resultset_fetcher.h" +#include "utils/ob_proxy_table_define.h" namespace oceanbase { @@ -23,25 +24,50 @@ namespace obproxy { namespace proxy { +class ObMysqlClient; + +union ObClientFlags +{ + ObClientFlags() : flags_(0) {} + explicit ObClientFlags(uint32_t flag) : flags_(flag) {} + + bool is_skip_autocommit() const { return 1 == client_flags_.OB_CLIENT_SKIP_AUTOCOMMIT; } + bool is_send_request_direct() const { return 1 == client_flags_.OB_CLIENT_SEND_REQUEST_DIRECT; } + + uint32_t flags_; + struct ClinetFlags + { + uint32_t OB_CLIENT_SKIP_AUTOCOMMIT: 1; + uint32_t OB_CLIENT_SEND_REQUEST_DIRECT: 1; + uint32_t OB_CLIENT_FLAG_RESERVED_NOT_USE: 30; + } client_flags_; +}; + class ObMysqlRequestParam { public: ObMysqlRequestParam() : sql_(), is_deep_copy_(false), is_user_idc_name_set_(false), - need_print_trace_stat_(false), current_idc_name_(), target_addr_() {}; + need_print_trace_stat_(false), current_idc_name_(), + target_addr_(), ob_client_flags_(0), mysql_client_(NULL), + is_detect_client_(false) {}; explicit ObMysqlRequestParam(const char *sql) : sql_(sql), is_deep_copy_(false), is_user_idc_name_set_(false), - need_print_trace_stat_(false), current_idc_name_(), target_addr_() {}; + need_print_trace_stat_(false), current_idc_name_(), target_addr_(), + ob_client_flags_(0), mysql_client_(NULL), is_detect_client_(false) {}; ObMysqlRequestParam(const char *sql, const ObString &idc_name) : sql_(sql), is_deep_copy_(false), is_user_idc_name_set_(true), - need_print_trace_stat_(true), current_idc_name_(idc_name), target_addr_() {}; + need_print_trace_stat_(true), current_idc_name_(idc_name), target_addr_(), + ob_client_flags_(0), mysql_client_(NULL), is_detect_client_(false) {}; void reset(); void reset_sql(); void set_target_addr(const common::ObAddr addr) { target_addr_ = addr; } + void set_mysql_client(ObMysqlClient *mysql_client) { mysql_client_ = mysql_client; } + void set_is_detect_client(const bool is_detect_client) { is_detect_client_ = is_detect_client; } bool is_valid() const { return !sql_.empty(); } int deep_copy(const ObMysqlRequestParam &other); int deep_copy_sql(const common::ObString &sql); TO_STRING_KV(K_(sql), K_(is_deep_copy), K_(current_idc_name), K_(is_user_idc_name_set), - K_(need_print_trace_stat), K_(target_addr)); + K_(need_print_trace_stat), K_(target_addr), K(ob_client_flags_.flags_), K_(is_detect_client)); common::ObString sql_; bool is_deep_copy_; @@ -50,6 +76,11 @@ class ObMysqlRequestParam common::ObString current_idc_name_; char current_idc_name_buf_[OB_PROXY_MAX_IDC_NAME_LENGTH]; common::ObAddr target_addr_; + // using flags to affect client_vc acition + // bit 1: whether set autocommit + ObClientFlags ob_client_flags_; + ObMysqlClient* mysql_client_; + bool is_detect_client_; }; class ObClientMysqlResp @@ -153,15 +184,15 @@ inline int ObMysqlResultHandler::get_double(const char *col_name, double &double return (NULL == rs_fetcher_) ? (common::OB_INNER_STAT_ERROR) : (rs_fetcher_->get_double(col_name, double_val)); } -class ObClientReuqestInfo +class ObClientRequestInfo { public: - ObClientReuqestInfo() - : user_name_(), database_name_(), password_(), + ObClientRequestInfo() + : user_name_(), database_name_(), cluster_name_(), password_(), password0_(), password1_(), using_password_num_(-1), request_param_(), name_(NULL), name_len_(0), - need_skip_stage2_(false) {} - ~ObClientReuqestInfo() { reset(); } + need_skip_stage2_(false), password_version_(0) {} + ~ObClientRequestInfo() { reset(); } void reset(); void reset_names(); @@ -173,21 +204,28 @@ class ObClientReuqestInfo int set_names(const common::ObString &user_name, const common::ObString &password, const common::ObString &database_name, + const common::ObString &cluster_name, const common::ObString &password1 = ""); int set_request_param(const ObMysqlRequestParam &request_param); const common::ObString &get_user_name() const { return user_name_; } const common::ObString &get_database_name() const { return database_name_; } - const common::ObString &get_password() const { return password_; } + const common::ObString &get_password(); bool change_password() { bool bret = false; - if (using_password_num_ != -1) { + if (using_password_num_ != -1 && user_name_.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { using_password_num_ = (using_password_num_ + 1) % 2; if (using_password_num_ == 0) { password_ = password0_; + if ('\0' == *password0_.ptr()) { + password_.reset(); + } } else { password_ = password1_; + if ('\0' == *password1_.ptr()) { + password_.reset(); + } } bret = true; } @@ -202,6 +240,7 @@ class ObClientReuqestInfo private: common::ObString user_name_; common::ObString database_name_; + common::ObString cluster_name_; common::ObString password_; common::ObString password0_; common::ObString password1_; @@ -210,8 +249,9 @@ class ObClientReuqestInfo char *name_; int64_t name_len_; bool need_skip_stage2_; + int64_t password_version_; - DISALLOW_COPY_AND_ASSIGN(ObClientReuqestInfo); + DISALLOW_COPY_AND_ASSIGN(ObClientRequestInfo); }; class ObClientUtils @@ -227,7 +267,7 @@ class ObClientUtils const int64_t buf_len, int64_t ©_len); static int build_handshake_response_packet(ObClientMysqlResp *handshake, - ObClientReuqestInfo *info, + ObClientRequestInfo *info, event::ObMIOBuffer *handshake_resp_buf); }; diff --git a/src/obproxy/proxy/client/ob_client_vc.cpp b/src/obproxy/proxy/client/ob_client_vc.cpp index e5935a1f..8c80d7c3 100644 --- a/src/obproxy/proxy/client/ob_client_vc.cpp +++ b/src/obproxy/proxy/client/ob_client_vc.cpp @@ -18,9 +18,11 @@ #include "proxy/mysql/ob_mysql_client_session.h" #include "obutils/ob_resource_pool_processor.h" #include "proxy/mysql/ob_mysql_sm.h" +#include "utils/ob_proxy_table_define.h" using namespace oceanbase::common; using namespace oceanbase::obmysql; +using namespace oceanbase::obproxy; using namespace oceanbase::obproxy::event; using namespace oceanbase::obproxy::packet; using namespace oceanbase::obproxy::obutils; @@ -43,7 +45,7 @@ static int64_t const RESCHEDULE_GET_NETHANDLER_LOCK_INTERVAL = HRTIME_MSECONDS(1 ObClientVC::ObClientVC(ObMysqlClient &client_core) : ObNetVConnection(), magic_(CLIENT_MAGIC_ALIVE), disconnect_by_client_(false), - is_request_sent_(false), is_resp_received_(false), core_client_(&client_core), + is_request_sent_(false), core_client_(&client_core), pending_action_(NULL), read_state_(), write_state_(), addr_() { SET_HANDLER(&ObClientVC::main_handler); @@ -82,9 +84,8 @@ int ObClientVC::main_handler(int event, void *data) } case CLIENT_INFORM_MYSQL_CLIENT_TRANSFER_RESP_EVENT: { pending_action_ = NULL; - // notify ObMysqlClient to read mysql response - if (NULL != core_client_) { - core_client_->handle_event(VC_EVENT_READ_READY, &write_state_.vio_); + if (OB_FAIL(transfer_bytes())) { + LOG_ERROR("fail to transfer bytes", K(ret)); } break; } @@ -177,7 +178,6 @@ void ObClientVC::do_io_close(const int lerrno) } is_request_sent_ = false; - is_resp_received_ = false; if (NULL != core_client_ && !disconnect_by_client_) { core_client_->handle_event(CLIENT_VC_DISCONNECT_EVENT, NULL); @@ -195,21 +195,17 @@ void ObClientVC::reenable_re(ObVIO *vio) read_avail = reader->read_avail(); } _LOG_DEBUG("client_vc reenable_re %s, read_avail=%ld, reader=%p, thread=%p, " - "is_request_sent=%d, is_resp_received=%d", + "is_request_sent=%d", (ObVIO::WRITE == vio->op_) ? "Write" : "Read", read_avail, - reader, this_ethread(), is_request_sent_, is_resp_received_); + reader, this_ethread(), is_request_sent_); if (ObVIO::WRITE == vio->op_) { // write_vio - if (NULL != core_client_) { - if (read_avail > 0 && !is_resp_received_) { - int ret = OB_SUCCESS; - if (OB_ISNULL(pending_action_ = mutex_->thread_holding_->schedule_imm( - this, CLIENT_INFORM_MYSQL_CLIENT_TRANSFER_RESP_EVENT))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("fail to schedule imm", K(ret)); - } else { - is_resp_received_ = true; - } + if (NULL != core_client_ && NULL == pending_action_ && read_avail > 0) { + int ret = OB_SUCCESS; + if (OB_ISNULL(pending_action_ = mutex_->thread_holding_->schedule_imm( + this, CLIENT_INFORM_MYSQL_CLIENT_TRANSFER_RESP_EVENT))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("fail to schedule imm", K(ret)); } } } else if (ObVIO::READ == vio->op_) { // read_vio @@ -217,8 +213,7 @@ void ObClientVC::reenable_re(ObVIO *vio) if (!is_request_sent_) { if (addr_.is_valid()) { ObMysqlSM *sm = reinterpret_cast(read_state_.vio_.cont_); - sm->trans_state_.server_info_.set_addr(addr_.get_ipv4(), - static_cast(addr_.get_port())); + sm->trans_state_.server_info_.set_addr(net::ops_ip_sa_cast(addr_.get_sockaddr())); sm->trans_state_.force_retry_congested_ = true; sm->trans_state_.need_retry_ = false; } @@ -231,10 +226,59 @@ void ObClientVC::reenable_re(ObVIO *vio) } } +int ObClientVC::transfer_bytes() +{ + int ret = OB_SUCCESS; + + // Check the state of our write buffer as well as ntodo + ObVIO &vio = write_state_.vio_; + int64_t ntodo = vio.ntodo(); + ObIOBufferReader *reader = vio.get_reader(); + if (OB_ISNULL(reader)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get reader", K(ret)); + } else { + int64_t bytes_avail = reader->read_avail(); + int64_t act_on = MIN(bytes_avail, ntodo); + int64_t total_added = 0; + ObMIOBuffer *transfer_to = core_client_->get_client_buf(); + + if (act_on <= 0) { + ret = OB_INVALID_ARGUMENT; + _LOG_WARN("act on data can not <= 0, avail=%ld, ntodo=%ld, " + "act_on=%ld, ret=%d", bytes_avail, ntodo, act_on, ret); + } else if (OB_ISNULL(transfer_to)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("resp buffer can not be NULL", K(transfer_to), K(ret)); + } else if (OB_FAIL(transfer_to->write(reader, act_on, total_added, 0)) + || act_on != total_added) { + LOG_WARN("failed to transfer data from iobuffer reader to iobfer", + K(act_on), K(total_added), K(ret)); + } else if (OB_FAIL(reader->consume(total_added))) { + LOG_WARN("fail to consume", K(total_added), K(ret)); + } else { + vio.ndone_ += total_added; + LOG_DEBUG("transfer_bytes succ", "ndone", vio.ndone_, "nbytes", vio.nbytes_); + if (write_state_.vio_.ntodo() > 0) { + if (NULL != write_state_.vio_.cont_) { + write_state_.vio_.cont_->handle_event(VC_EVENT_WRITE_READY, &write_state_.vio_); + } + } else { + // notify ObMysqlClient to read mysql response + if (NULL != core_client_) { + core_client_->handle_event(VC_EVENT_READ_READY, &write_state_.vio_); + } + } + } + } + + return ret; +} + ObMysqlClient::ObMysqlClient() : ObContinuation(), magic_(CLIENT_MAGIC_ALIVE), reentrancy_count_(0), terminate_(false), is_inited_(false), in_use_(false), is_request_complete_(false), use_short_connection_(false), - client_vc_(NULL), pool_(NULL), + client_vc_(NULL), pool_(NULL), cr_(NULL), active_timeout_action_(NULL), common_mutex_(), action_(), active_timeout_ms_(0), next_action_(CLIENT_ACTION_UNDEFINED), request_buf_(NULL), request_reader_(NULL), mysql_resp_(NULL), info_(), is_session_pool_client_(false), @@ -248,6 +292,7 @@ int ObMysqlClient::init(ObMysqlClientPool *pool, const ObString &password, const ObString &database, const bool is_meta_mysql_client, + const ObString &cluster_name, const ObString &password1, ClientPoolOption* client_pool_option) { @@ -262,8 +307,8 @@ int ObMysqlClient::init(ObMysqlClientPool *pool, } else if (OB_ISNULL(mutex = new_proxy_mutex(CLIENT_VC_LOCK))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate mutex", K(ret)); - } else if (OB_FAIL(info_.set_names(user_name, password, database, password1))) { - LOG_WARN("fail to set names", K(user_name), K(password), K(database), K(ret)); + } else if (OB_FAIL(info_.set_names(user_name, password, database, cluster_name, password1))) { + LOG_WARN("fail to set names", K(user_name), K(password), K(database), K(cluster_name), K(ret)); } else { if (client_pool_option != NULL) { info_.set_need_skip_stage2(client_pool_option->need_skip_stage2_); @@ -282,6 +327,31 @@ int ObMysqlClient::init(ObMysqlClientPool *pool, return ret; } +int ObMysqlClient::init_detect_client(ObClusterResource *cr) +{ + int ret = OB_SUCCESS; + ObProxyMutex *mutex = NULL; + ObString password(get_global_proxy_config().observer_sys_password.str()); + if (OB_UNLIKELY(is_inited_ ||NULL == cr)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K_(is_inited), K(ret)); + } else if (OB_ISNULL(mutex = new_proxy_mutex(CLIENT_VC_LOCK))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate mutex", K(ret)); + } else if (OB_FAIL(info_.set_names(ObProxyTableInfo::DETECT_USERNAME_USER, password, "obproxy", "obproxy"))) { + LOG_WARN("fail to set names", K(ret)); + } else { + common_mutex_ = mutex; + mutex_ = common_mutex_; + next_action_ = CLIENT_ACTION_CONNECT; + cr->inc_ref(); + cr_ = cr; + is_inited_ = true; + use_short_connection_ = true; + } + return ret; +} + int ObMysqlClient::post_request( ObContinuation *cont, const ObMysqlRequestParam &request_param, @@ -378,7 +448,7 @@ int ObMysqlClient::post_request( mysql_resp_ = NULL; } action = NULL; - release(); + release(false); } return ret; @@ -439,12 +509,7 @@ int ObMysqlClient::main_handler(int event, void *data) } } - --reentrancy_count_; - if (OB_UNLIKELY(reentrancy_count_ < 0)) { - LOG_ERROR("invalid reentrancy_count", K_(reentrancy_count), K(this)); - } - - if (0 == reentrancy_count_) { + if (1 == reentrancy_count_) { // here common_mutex_ is free or held by this thread, so we can ensure lock it MUTEX_LOCK(lock, common_mutex_, this_ethread()); if (OB_SUCCESS == ret && need_connect_retry_ && CLIENT_ACTION_CONNECT == next_action_) { @@ -465,6 +530,11 @@ int ObMysqlClient::main_handler(int event, void *data) if (OB_SUCC(ret)) { do_post_request(); } + + --reentrancy_count_; + if (OB_UNLIKELY(reentrancy_count_ < 0)) { + LOG_ERROR("invalid reentrancy_count", K_(reentrancy_count), K(this)); + } } else { if (is_request_complete_) { if (OB_FAIL(handle_request_complete())) { @@ -475,9 +545,20 @@ int ObMysqlClient::main_handler(int event, void *data) if (terminate_) { kill_this(); he_ret = EVENT_DONE; + } else { + --reentrancy_count_; + if (OB_UNLIKELY(reentrancy_count_ < 0)) { + LOG_ERROR("invalid reentrancy_count", K_(reentrancy_count), K(this)); + } } } + } else { + --reentrancy_count_; + if (OB_UNLIKELY(reentrancy_count_ < 0)) { + LOG_ERROR("invalid reentrancy_count", K_(reentrancy_count), K(this)); + } } + return he_ret; } @@ -537,7 +618,7 @@ int ObMysqlClient::handle_request_complete() } } - release(); + release(true); if (need_callback) { cont->handle_event(CLIENT_TRANSPORT_MYSQL_RESP_EVENT, mysql_resp); } @@ -723,7 +804,9 @@ int ObMysqlClient::do_next_action(void *data) break; } case CLIENT_ACTION_READ_LOGIN_RESP: { - if (OB_FAIL(transfer_and_analyze_response(vio, OB_MYSQL_COM_LOGIN))) { + if (info_.get_request_param().is_detect_client_) { + is_request_complete_ = true; + } else if (OB_FAIL(transfer_and_analyze_response(vio, OB_MYSQL_COM_LOGIN))) { LOG_WARN("fail to transfer and analyze resposne", K(ret)); } else if (!mysql_resp_->is_resp_completed()) { ret = OB_ERR_UNEXPECTED; @@ -735,6 +818,12 @@ int ObMysqlClient::do_next_action(void *data) if (OB_FAIL(transport_mysql_resp())) { LOG_WARN("fail to transfrom mysql resp", K(ret)); } + } else if (info_.get_request_param().ob_client_flags_.is_skip_autocommit()) { + if (OB_FAIL(setup_read_normal_resp())) { + LOG_WARN("fail to setup read normal resp", K(ret)); + } else if (OB_FAIL(forward_mysql_request())) { + LOG_WARN("fail to schedule post request", K(ret)); + } } else { retry_times_ = 0; if (OB_FAIL(setup_read_autocommit_resp())) { @@ -797,61 +886,19 @@ int ObMysqlClient::do_next_action(void *data) int ObMysqlClient::transfer_and_analyze_response(ObVIO &vio, const obmysql::ObMySQLCmd cmd) { int ret = OB_SUCCESS; - // Check the state of our write buffer as well as ntodo - int64_t ntodo = vio.ntodo(); - ObIOBufferReader *reader = vio.get_reader(); - if (OB_ISNULL(reader)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fail to get reader", K(ret)); - } else { - int64_t bytes_avail = reader->read_avail(); - int64_t act_on = MIN(bytes_avail, ntodo); - int64_t added = 0; - ObMIOBuffer *transfer_to = mysql_resp_->get_resp_miobuf(); - if (act_on <= 0) { - ret = OB_INVALID_ARGUMENT; - _LOG_WARN("act on data can not <= 0, avail=%ld, ntodo=%ld, " - "act_on=%ld, ret=%d", bytes_avail, ntodo, act_on, ret); - } else if (OB_ISNULL(transfer_to)) { + if (vio.ndone_ == vio.nbytes_) { + LOG_DEBUG("transfer_and_analyze_response"); + if (OB_FAIL(mysql_resp_->analyze_resp(cmd))) { + LOG_WARN("fail to analyze_trans_response", K(ret)); + } else if (!mysql_resp_->is_resp_completed()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("resp buffer can not be NULL", K(transfer_to), K(ret)); - } else if (OB_FAIL(transfer_bytes(*transfer_to, *reader, act_on, added))) { - LOG_WARN("fail to transfer_bytes", K(ret)); - } else { - vio.ndone_ += added; - LOG_DEBUG("transfer_bytes succ", "ndone", vio.ndone_, "nbytes", vio.nbytes_); - if (vio.ndone_ == vio.nbytes_) { - LOG_DEBUG("transder_and_analyze_response", K(added)); - if (OB_FAIL(mysql_resp_->analyze_resp(cmd))) { - LOG_WARN("fail to analyze_trans_response", K(ret)); - } else if (!mysql_resp_->is_resp_completed()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("mysql response must be received completed here", K(ret)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ndone should be equal to nbytes", - K_(vio.ndone), K_(vio.nbytes), K(ret)); - } + LOG_WARN("mysql response must be received completed here", K(ret)); } - } - - return ret; -} - -int ObMysqlClient::transfer_bytes(ObMIOBuffer &transfer_to, - ObIOBufferReader &transfer_from, - const int64_t act_on, int64_t &total_added) -{ - int ret = OB_SUCCESS; - - if (OB_FAIL(transfer_to.write(&transfer_from, act_on, total_added, 0)) - || act_on != total_added) { - LOG_WARN("failed to transfer data from iobuffer reader to iobfer", - K(act_on), K(total_added), K(ret)); - } else if (OB_FAIL(transfer_from.consume(total_added))) { - LOG_WARN("fail to consume", K(total_added), K(ret)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ndone should be equal to nbytes", + K_(vio.ndone), K_(vio.nbytes), K(ret)); } return ret; @@ -864,7 +911,6 @@ int ObMysqlClient::forward_mysql_request() if (request_reader_->read_avail() > 0) { client_vc_->clear_request_sent(); - client_vc_->clear_resp_received(); client_vc_->reenable_read(); } @@ -1010,7 +1056,13 @@ int ObMysqlClient::do_new_connection_with_cr(ObMysqlClientSession *client_sessio { int ret = OB_SUCCESS; - ObClusterResource *cr = pool_->acquire_cluster_resource(); // inc ref + ObClusterResource *cr = NULL; + if (NULL != cr_) { + cr_->inc_ref(); + cr = cr_; + } else { + cr = pool_->acquire_cluster_resource(); // inc ref + } LOG_DEBUG("new connection", K(cr), KPC(cr)); if (OB_ISNULL(cr)) { ret = OB_ERR_UNEXPECTED; @@ -1039,6 +1091,10 @@ int ObMysqlClient::setup_read_handshake() } else { client_vc_->mutex_ = mutex_; client_session->set_proxy_mysql_client(); + if (info_.get_request_param().ob_client_flags_.is_send_request_direct()) { + client_session->set_can_send_request(); + client_session->is_need_update_dummy_entry_ = true; + } client_session->set_session_pool_client(is_session_pool_client_); if (is_session_pool_client_) { // client_session->set_is_dbmesh_user(false); @@ -1048,10 +1104,9 @@ int ObMysqlClient::setup_read_handshake() client_session->set_server_addr(server_addr_); client_session->set_first_dml_sql_got(); client_session->inner_request_param_ = &info_.get_request_param(); - client_vc_->clear_resp_received(); next_action_ = CLIENT_ACTION_READ_HANDSHAKE; - if (pool_->is_cluster_param()) { + if ((NULL != pool_ && pool_->is_cluster_param()) || NULL != cr_) { if (OB_FAIL(do_new_connection_with_cr(client_session))) { LOG_WARN("fail to new connection with cr", K(ret)); } @@ -1079,9 +1134,9 @@ int ObMysqlClient::setup_read_handshake() return ret; } -void ObMysqlClient::release() +void ObMysqlClient::release(bool is_need_check_reentry) { - if (OB_LIKELY(0 == reentrancy_count_) && OB_LIKELY(!terminate_)) { + if (OB_LIKELY(!is_need_check_reentry || 1 == reentrancy_count_) && OB_LIKELY(!terminate_)) { int ret = OB_SUCCESS; if (OB_FAIL(cancel_active_timeout())) { LOG_ERROR("fail to cancel timeout action," @@ -1089,9 +1144,11 @@ void ObMysqlClient::release() } else { // for defense, make sure client vc's mutex is common mutex when release to client pool; // Never free client vc in mysql client, it will be free by mysql_sm - if (NULL != client_vc_ && client_vc_->mutex_ != common_mutex_) { + if (!info_.get_request_param().is_detect_client_ && NULL != client_vc_ && client_vc_->mutex_ != common_mutex_) { client_vc_->handle_event(CLIENT_VC_SWAP_MUTEX_EVENT, common_mutex_.ptr_); - client_vc_->mutex_ = common_mutex_; + if (NULL != client_vc_) { + client_vc_->mutex_ = common_mutex_; + } } action_.set_continuation(NULL); action_.cancelled_ = false; @@ -1101,7 +1158,9 @@ void ObMysqlClient::release() in_use_ = false; is_request_complete_ = false; mutex_ = common_mutex_; // when idle, keep common_mutex_ - pool_->release_mysql_client(this); + if (NULL != pool_) { + pool_->release_mysql_client(this); + } } } } @@ -1130,6 +1189,11 @@ void ObMysqlClient::kill_this() pool_ = NULL; } + if (NULL != cr_) { + cr_->dec_ref(); + cr_ = NULL; + } + is_inited_ = false; in_use_ = false; use_short_connection_ = false; @@ -1156,7 +1220,7 @@ void ObMysqlClient::kill_this() int ObMysqlClient::alloc(ObMysqlClientPool *pool, ObMysqlClient *&client, const ObString &user_name, const ObString &password, - const ObString &database, const bool is_meta_mysql_client, + const ObString &database, const bool is_meta_mysql_client, const ObString &cluster_name, const ObString &password1, ClientPoolOption* client_pool_option) { int ret = OB_SUCCESS; @@ -1164,7 +1228,7 @@ int ObMysqlClient::alloc(ObMysqlClientPool *pool, ObMysqlClient *&client, if (OB_ISNULL(client = op_alloc(ObMysqlClient))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate ObMysqlClient", K(ret)); - } else if (OB_FAIL(client->init(pool, user_name, password, database, is_meta_mysql_client, password1, client_pool_option))) { + } else if (OB_FAIL(client->init(pool, user_name, password, database, is_meta_mysql_client, cluster_name, password1, client_pool_option))) { LOG_WARN("fail to init client", K(ret)); } if (OB_FAIL(ret) && (NULL != client)) { diff --git a/src/obproxy/proxy/client/ob_client_vc.h b/src/obproxy/proxy/client/ob_client_vc.h index 9ccf8c46..19560323 100644 --- a/src/obproxy/proxy/client/ob_client_vc.h +++ b/src/obproxy/proxy/client/ob_client_vc.h @@ -80,6 +80,7 @@ class ObClientVC : public net::ObNetVConnection virtual void reenable(event::ObVIO *vio) { reenable_re(vio); } virtual void reenable_re(event::ObVIO *vio); void reenable_read() { reenable_re(&read_state_.vio_); } + int transfer_bytes(); // Timeouts virtual int set_active_timeout(ObHRTime timeout_in) { UNUSED(timeout_in); return 0; } @@ -101,14 +102,12 @@ class ObClientVC : public net::ObNetVConnection virtual int apply_options() { return 0; } void clear_request_sent() { is_request_sent_ = false; } - void clear_resp_received() { is_resp_received_ = false; } void set_addr(const common::ObAddr &addr) { addr_ = addr; } private: uint32_t magic_; bool disconnect_by_client_; // dissconnect by received VC_EVENT_EOS, sent by ObMysqlClient bool is_request_sent_; // used to inform client session read request only once - bool is_resp_received_; // used to inform mysql client read resp onely once ObMysqlClient *core_client_; event::ObAction *pending_action_; @@ -142,6 +141,7 @@ class ObMysqlClient : public event::ObContinuation const common::ObString &password, const common::ObString &database, const bool is_meta_mysql_client, + const common::ObString &cluster_name = "", const common::ObString &password1 = "", ClientPoolOption* client_pool_option = NULL); @@ -150,9 +150,12 @@ class ObMysqlClient : public event::ObContinuation const common::ObString &password, const common::ObString &database, const bool is_meta_mysql_client, + const common::ObString &cluster_name = "", const common::ObString &password1 = "", ClientPoolOption* client_pool_option = NULL); + int init_detect_client(obutils::ObClusterResource *cr); + // must be used under the mutex_'s lock bool is_avail() const { return !in_use_; } @@ -167,6 +170,8 @@ class ObMysqlClient : public event::ObContinuation static const char *get_client_event_name(const int64_t event); event::ObProxyMutex *get_common_mutex() { return common_mutex_.ptr_; } + void kill_this(); + event::ObMIOBuffer *get_client_buf() { return mysql_resp_->get_resp_miobuf(); } private: static const char *get_client_action_name(const ObClientActionType type); @@ -174,8 +179,6 @@ class ObMysqlClient : public event::ObContinuation int do_post_request(); int do_next_action(void *data); int transfer_and_analyze_response(event::ObVIO &vio, const obmysql::ObMySQLCmd cmd); - int transfer_bytes(event::ObMIOBuffer &transfer_to, event::ObIOBufferReader &transfer_from, - const int64_t act_on, int64_t &added); int notify_transfer_completed(); @@ -187,7 +190,6 @@ class ObMysqlClient : public event::ObContinuation int setup_read_normal_resp(); bool is_in_auth() const; int transport_mysql_resp(); - void kill_this(); int handle_client_vc_disconnect(); int forward_mysql_request(); @@ -196,7 +198,7 @@ class ObMysqlClient : public event::ObContinuation int handle_active_timeout(); int handle_request_complete(); - void release(); + void release(bool is_need_check_reentry); public: SLINK(ObMysqlClient, link_); @@ -215,6 +217,8 @@ class ObMysqlClient : public event::ObContinuation bool use_short_connection_; ObClientVC *client_vc_; ObMysqlClientPool *pool_; + // in some situtaion, we can create obmysql client without ClientPool + obutils::ObClusterResource *cr_; event::ObAction *active_timeout_action_; common::ObPtr common_mutex_; @@ -227,7 +231,7 @@ class ObMysqlClient : public event::ObContinuation event::ObIOBufferReader *request_reader_; ObClientMysqlResp *mysql_resp_; - ObClientReuqestInfo info_; + ObClientRequestInfo info_; bool is_session_pool_client_; ObProxySchemaKey schema_key_; diff --git a/src/obproxy/proxy/client/ob_driver_client.cpp b/src/obproxy/proxy/client/ob_driver_client.cpp new file mode 100644 index 00000000..29d1711f --- /dev/null +++ b/src/obproxy/proxy/client/ob_driver_client.cpp @@ -0,0 +1,375 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + * + * ************************************************************* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "proxy/client/ob_driver_client.h" +#include "proxy/mysql/ob_mysql_client_session.h" +#include "iocore/eventsystem/ob_action.h" +#include "iocore/net/ob_socket_manager.h" + +using namespace oceanbase::common; +using namespace oceanbase::obproxy::event; +using namespace oceanbase::obproxy::net; + +#define SET_NONBLOCKING(fd) { \ + int tmp_ret = OB_SUCCESS; \ + int flags = fcntl(fd, F_GETFL); \ + int res = -1; \ + flags |= O_NONBLOCK; \ + if (OB_SUCCESS != (tmp_ret = ObSocketManager::fcntl(fd, F_SETFL, flags, res))) { \ + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to set nonblocking", K(tmp_ret), K(errno), K(strerror(errno))); \ + if (OB_SUCCESS == ret) { \ + ret = tmp_ret; \ + } \ + } \ +} + +#define SET_BLOCKING(fd) { \ + int tmp_ret = OB_SUCCESS; \ + int flags = fcntl(fd, F_GETFL); \ + int res = -1; \ + flags &= ~O_NONBLOCK; \ + if (OB_SUCCESS != (tmp_ret = ObSocketManager::fcntl(fd, F_SETFL, flags, res))) { \ + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to set blocking", K(ret), K(errno), K(strerror(errno))); \ + if (OB_SUCCESS == ret) { \ + ret = tmp_ret; \ + } \ + } \ +} + +namespace oceanbase +{ +namespace obproxy +{ +namespace proxy +{ + +ObDriverClient::ObDriverClient() : is_inited_(false), unix_fd_(-1), connect_timeout_(0), recv_timeout_(0), send_timeout_(0), cs_id_(-1) +{ +} + +ObDriverClient::~ObDriverClient() +{ + destroy(); +} + +void ObDriverClient::destroy() +{ + is_inited_ = false; + if (unix_fd_ != -1) { + close(unix_fd_); + unix_fd_ = -1; + } + connect_timeout_ = 0; + send_timeout_ = 0; + recv_timeout_ = 0; + cs_id_ = -1; +} + +int ObDriverClient::init() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client init twice", K(this), K(ret)); + } else if (OB_FAIL(ObSocketManager::socket(AF_UNIX, SOCK_STREAM, 0, unix_fd_))) { + OBPROXY_DRIVER_CLIENT_LOG(ERROR, "dirver client create socket failed", K(this), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "init driver client", K(this), K_(cs_id)); + is_inited_ = true; + } + return ret; +} + +int ObDriverClient::sync_connect() +{ + int ret = OB_SUCCESS; + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + memset(addr.sun_path, 0, sizeof(addr.sun_path)); + strncpy(addr.sun_path, get_global_layout().get_unix_domain_path(), sizeof(addr.sun_path) - 1); + if (OB_FAIL(ObSocketManager::connect(unix_fd_, (struct sockaddr*)&addr, sizeof(addr)))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client connect unix domain failed", K(this), K(errno), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "driver client connect success" , K(this)); + } + return ret; +} + +int ObDriverClient::sync_connect_with_timeout() +{ + int ret = OB_SUCCESS; + if (connect_timeout_ < 0) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "connect timeout value unexpected", K(connect_timeout_), K(ret)); + } else if (connect_timeout_ == 0) { + ret = sync_connect(); + } else { + int64_t timeout = connect_timeout_; + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + memset(addr.sun_path, 0, sizeof(addr.sun_path)); + strncpy(addr.sun_path, get_global_layout().get_unix_domain_path(), sizeof(addr.sun_path) - 1); + SET_NONBLOCKING(unix_fd_); + + int connect_rv = 0; + while (OB_SUCC(ret)) { + connect_rv = connect(unix_fd_, (struct sockaddr*)&addr, sizeof(addr)); + if (connect_rv < 0) { + int64_t prev_time = get_current_time(); + if (errno != EINPROGRESS && errno != EWOULDBLOCK && errno != EAGAIN) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "connect failed", K(ret)); + } else if (errno == EWOULDBLOCK || errno == EAGAIN) { + // The unix socket encounters the above socket sleep 1ms to prevent it from being called all the time. + // Refer to https://stackoverflow.com/questions/48222690/set-connect-timeout-on-unix-domain-socket + usleep(1000); + int64_t new_time = get_current_time(); + timeout -= (new_time - prev_time); + prev_time = new_time; + if (timeout <= 0) { + ret = OB_TIMEOUT; + OBPROXY_DRIVER_CLIENT_LOG(WARN ,"connect timeout", K_(connect_timeout), K(ret)); + } + } else if (errno == EINPROGRESS) { + while (OB_SUCC(ret)) { + struct pollfd pfd; + pfd.fd = unix_fd_; + pfd.events = POLLOUT; + connect_rv = poll(&pfd, 1, static_cast(timeout)); + if (connect_rv > 0) { + break; + } else if (connect_rv == 0) { + ret = OB_TIMEOUT; + OBPROXY_DRIVER_CLIENT_LOG(WARN ,"connect timeout", K_(connect_timeout), K(ret)); + } else { + if (errno != EINTR) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "poll failed", K(ret)); + } else { + int64_t new_time = get_current_time(); + timeout -= (new_time - prev_time); + prev_time = new_time; + if (timeout <= 0) { + ret = OB_TIMEOUT; + OBPROXY_DRIVER_CLIENT_LOG(WARN ,"connect timeout", K_(connect_timeout), K(ret)); + } + } + } + } + if (OB_SUCC(ret) && connect_rv > 0) { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "connect with timeout success", K_(connect_timeout), K(ret)); + break; + } + } + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "connect with timeout success", K_(connect_timeout), K(ret)); + break; + } + } + SET_BLOCKING(unix_fd_); + } + + return ret; +} + +int ObDriverClient::sync_recv_internal(char *buf, int64_t buf_len, int64_t &recv_len, int recv_flags) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == buf || 0 >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "buf is null or len is invalid", K(buf_len), K(this), K_(cs_id), K(ret)); + } else { + + do { + recv_len = recv(unix_fd_, buf, buf_len, recv_flags); + } while (recv_len == -1 && EINTR == errno); + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "sync_recv_internal recv finish", K(recv_len), K(errno)); + + if (EAGAIN == errno || EWOULDBLOCK == errno) { + // will call this func again, do nothing + } else if (-1 == recv_len) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "recv failed", K(ret), KP(buf), K(buf_len), K(recv_len), K(recv_flags)); + } else { + // success, do nothing + } + } + + return ret; +} + +int ObDriverClient::sync_wait_io_or_timeout(bool is_recv) +{ + int ret = OB_SUCCESS; + struct pollfd pfd; + int rv = 0; + int64_t timeout = 0; + int64_t prev_time = get_current_time(); + int64_t new_time = 0; + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = unix_fd_; + if (is_recv) { + timeout = recv_timeout_ <= 0 ? -1 : recv_timeout_; + pfd.events = POLLIN | POLLERR; + } else { + timeout = send_timeout_ <= 0 ? -1 : send_timeout_; + pfd.events = POLLOUT; + } + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "sync_wait_io_or_timeout call poll", K(is_recv), K(timeout)); + + do { + // Prevent continuous interruptions, resulting in waiting + if (timeout > 0) { + new_time = get_current_time(); + timeout -= new_time - prev_time; + if (timeout < 0) { + timeout = 0; + } + prev_time = new_time; + } + rv = poll(&pfd, 1, static_cast(timeout)); + } while (rv == -1 && errno == EINTR); + + if (rv < 0) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "poll error", K(ret)); + } else if (rv == 0) { + ret = OB_TIMEOUT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "poll timeout", K(timeout), K(ret)); + } else { + // recv >= 0 , do nothing + } + + return ret; +} + +int ObDriverClient::sync_recv_with_timeout(char *buf, int64_t buf_len, int64_t &recv_len) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == buf || 0 >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "buf is null or len is invalid", K(buf_len), K(this), K_(cs_id), K(ret)); + } else { + int recv_flags= MSG_DONTWAIT; + recv_len = -1; + + while (OB_SUCC(ret) && -1 == recv_len) { + if (OB_FAIL(sync_recv_internal(buf, buf_len, recv_len, recv_flags))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to call sync_recv_internal", K(buf_len), K(recv_len), K(ret)); + } else if (-1 == recv_len && OB_FAIL(sync_wait_io_or_timeout(true))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to call sync_wait_io_or_timeout", K(ret)); + } else { + // do nothing + } + } + + if (OB_FAIL(ret)) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client recv failed", K(this), K(recv_len), K(recv_flags), K_(cs_id), K_(unix_fd), K(ret)); + } + + } + + return ret; +} + +int ObDriverClient::sync_send_internal(const char *buf, int64_t buf_len, int64_t &send_len, int send_flags) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == buf || 0 >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "buf is null or len is invalid", K(buf_len), K(this), K_(cs_id), K(ret)); + } else { + + do { + send_len = send(unix_fd_, buf, buf_len, send_flags); + } while (send_len == -1 && EINTR == errno); + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "sync_send_internal send finish", K(send_len), K(errno)); + + if (EAGAIN == errno || EWOULDBLOCK == errno) { + // will call this func again, do nothing + } else if (-1 == send_len) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "send failed", K(ret), KP(buf), K(buf_len), K(send_len), K(send_flags)); + } else { + // success, do nothing + } + } + + return ret; +} + +int ObDriverClient::sync_send_with_timeout(const char *buf, int64_t buf_len, int64_t &send_len) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == buf || 0 >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "buf is null or len is invalid", K(buf_len), K(this), K_(cs_id), K(ret)); + } else { + int send_flags = MSG_DONTWAIT | MSG_NOSIGNAL; + send_len = -1; + + while (OB_SUCC(ret) && -1 == send_len) { + if (OB_FAIL(sync_send_internal(buf, buf_len, send_len, send_flags))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to call sync_send_internal", K(buf_len), K(send_len), K(ret)); + } else if (-1 == send_len && OB_FAIL(sync_wait_io_or_timeout(false))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to call sync_wait_io_or_timeout", K(ret)); + } else { + // do nothing + } + } + + if (OB_FAIL(ret)) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client send failed", K(this), K(send_len), K(send_flags), K_(cs_id), K_(unix_fd), K(ret)); + } + + } + + return ret; +} + +int64_t ObDriverClient::get_current_time() +{ + timeval tv; + gettimeofday(&tv, NULL); + int64_t current_time = tv.tv_sec * 1000 + tv.tv_usec / 1000; + return current_time; +} + +} // end of proxy +} // end of obproxy +} // end of oceanbase diff --git a/src/obproxy/proxy/client/ob_driver_client.h b/src/obproxy/proxy/client/ob_driver_client.h new file mode 100644 index 00000000..0e345c46 --- /dev/null +++ b/src/obproxy/proxy/client/ob_driver_client.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + * + * ************************************************************* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OB_DRIVER_CLIENT_H_ +#define OB_DRIVER_CLIENT_H_ + +#include "proxy/client/ob_client_utils.h" +#include "iocore/net/ob_net_vconnection.h" +#include "iocore/eventsystem/ob_ethread.h" + +namespace oceanbase +{ +namespace obproxy +{ +namespace proxy +{ + +class ObDriverClient +{ +public: + ObDriverClient(); + virtual ~ObDriverClient(); + int init(); + int sync_connect(); + int sync_connect_with_timeout(); + int sync_recv_with_timeout(char *buf, int64_t buf_len, int64_t &recv_len); + int sync_send_with_timeout(const char *buf, int64_t buf_len, int64_t &send_len); + inline void set_connect_timeout(const int64_t timeout) { connect_timeout_ = timeout; } + inline void set_cs_id(const int64_t cs_id) { cs_id_ = cs_id; } + void destroy(); + + int64_t get_connect_timeout() const { return connect_timeout_; } + int64_t get_recv_timeout() const { return recv_timeout_; } + void set_recv_timeout(const int64_t timeout) { recv_timeout_ = timeout; } + int64_t get_send_timeout() const { return send_timeout_; } + void set_send_timeout(const int64_t timeout) { send_timeout_ = timeout; } + +private: + inline int64_t get_current_time(); + int sync_recv_internal(char *buf, int64_t buf_len, int64_t &recv_len, int recv_flags); + int sync_send_internal(const char *buf, int64_t buf_len, int64_t &send_len, int send_flags); + int sync_wait_io_or_timeout(bool is_recv); + +private: + bool is_inited_; + int unix_fd_; + int64_t connect_timeout_; + int64_t recv_timeout_; + int64_t send_timeout_; + int64_t cs_id_; +private: +DISALLOW_COPY_AND_ASSIGN(ObDriverClient); +}; + +} // end of namespace proxy +} // end of namespace obproxy +} // end of namespace oceanbase + +#endif diff --git a/src/obproxy/proxy/client/ob_mysql_client_pool.cpp b/src/obproxy/proxy/client/ob_mysql_client_pool.cpp index 99ba5d7b..423b2904 100644 --- a/src/obproxy/proxy/client/ob_mysql_client_pool.cpp +++ b/src/obproxy/proxy/client/ob_mysql_client_pool.cpp @@ -158,6 +158,7 @@ int ObMysqlClientPool::init( const ObString &user_name, const ObString &password, const ObString &database, + const ObString &cluster_name, const ObString &password1, ClientPoolOption* client_pool_option) { @@ -175,7 +176,8 @@ int ObMysqlClientPool::init( ObMysqlClient *mysql_client = NULL; const int64_t mc_count = get_mysql_client_pool_count(is_meta_mysql_client); for (int64_t i = 0; (i < mc_count && OB_SUCC(ret)); ++i) { - if (OB_FAIL(ObMysqlClient::alloc(this, mysql_client, user_name, password, database, is_meta_mysql_client, password1, client_pool_option))) { + if (OB_FAIL(ObMysqlClient::alloc(this, mysql_client, user_name, password, database, is_meta_mysql_client, + cluster_name, password1, client_pool_option))) { LOG_WARN("fail to alloc mysql client", K(user_name), K(password), K(database), "idx", i, K(is_meta_mysql_client), K(ret)); } else if (OB_ISNULL(mysql_client)) { diff --git a/src/obproxy/proxy/client/ob_mysql_client_pool.h b/src/obproxy/proxy/client/ob_mysql_client_pool.h index 3e5e9b33..e02f2719 100644 --- a/src/obproxy/proxy/client/ob_mysql_client_pool.h +++ b/src/obproxy/proxy/client/ob_mysql_client_pool.h @@ -52,6 +52,7 @@ class ObMysqlClientPool : public common::ObSharedRefCount const common::ObString &user_name, const common::ObString &password, const common::ObString &database, + const common::ObString &cluster_name = "", const common::ObString &password1 = "", ClientPoolOption* client_pool_option = NULL); void destroy(); diff --git a/src/obproxy/proxy/client/ob_mysql_proxy.cpp b/src/obproxy/proxy/client/ob_mysql_proxy.cpp index 377a50a1..97b40250 100644 --- a/src/obproxy/proxy/client/ob_mysql_proxy.cpp +++ b/src/obproxy/proxy/client/ob_mysql_proxy.cpp @@ -173,7 +173,7 @@ int ObMysqlProxyCont::async_post_request(const ObMysqlRequestParam &request_para action = NULL; if (OB_UNLIKELY(!request_param.is_valid()) || OB_UNLIKELY(timeout_ms <= 0) - || OB_ISNULL(client_pool)) { + || (!request_param.is_detect_client_ && OB_ISNULL(client_pool))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input value", K(request_param), K(timeout_ms), K(ret)); } else if (OB_FAIL(request_param_.deep_copy(request_param))) { @@ -181,8 +181,10 @@ int ObMysqlProxyCont::async_post_request(const ObMysqlRequestParam &request_para } else { is_nonblock_ = true; timeout_ms_ = timeout_ms; - client_pool->inc_ref(); - client_pool_ = client_pool; + if (NULL != client_pool) { + client_pool->inc_ref(); + client_pool_ = client_pool; + } } if (OB_SUCC(ret)) { @@ -322,7 +324,13 @@ int ObMysqlProxyCont::do_post_request() if (OB_SUCC(ret)) { ret = OB_EAGAIN; if (NULL == mysql_client_) { - mysql_client_ = client_pool_->acquire_mysql_client(); + // For probing requests, in order to prevent competition for connection pool connections, + // use a separate mysql_client + if (NULL != request_param_.mysql_client_) { + mysql_client_ = request_param_.mysql_client_; + } else { + mysql_client_ = client_pool_->acquire_mysql_client(); + } } if (NULL != mysql_client_) { ObAction *action = NULL; @@ -463,6 +471,7 @@ int ObMysqlProxy::init(const int64_t timeout_ms, const ObString &user_name, const ObString &password, const ObString &database, + const ObString &cluster_name, const ObString &password1) { int ret = OB_SUCCESS; @@ -472,7 +481,7 @@ int ObMysqlProxy::init(const int64_t timeout_ms, } else if (OB_UNLIKELY(timeout_ms <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input value", K(timeout_ms), K(ret)); - } else if (OB_FAIL(raw_mysql_client_.init(user_name, password, database, password1))) { + } else if (OB_FAIL(raw_mysql_client_.init(user_name, password, database, cluster_name, password1))) { LOG_WARN("fail to init raw mysql client", K(ret)); } else { timeout_ms_ = timeout_ms; @@ -500,7 +509,7 @@ int ObMysqlProxy::rebuild_client_pool(ObShardConnector *shard_conn, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input value", K(user_name)); } else { - if (OB_FAIL(alloc_client_pool(is_meta_mysql_client, user_name, password, database, password1, client_pool_option))) { + if (OB_FAIL(alloc_client_pool(is_meta_mysql_client, user_name, password, database, "", password1, client_pool_option))) { LOG_WARN("fail to alloc client pool", K(is_meta_mysql_client), K(user_name), K(database), K(ret)); } else { client_pool_->set_shard_conn(shard_conn); @@ -539,7 +548,7 @@ int ObMysqlProxy::rebuild_client_pool(ObClusterResource *cluster_resource, } else { ObString full_username(full_user_name); if (OB_FAIL(alloc_client_pool(is_meta_mysql_client, full_username, - password, database, password1, client_pool_option))) { + password, database, cluster_name, password1, client_pool_option))) { LOG_WARN("fail to alloc client pool", K(user_name), K(database), K(ret)); } else { client_pool_->set_cluster_resource(cluster_resource); @@ -613,7 +622,7 @@ int ObMysqlProxy::async_execute(ObContinuation *cont, LOG_DEBUG("ObMysqlProxy::async_execute", K(cont), K(request_param), K(timeout_ms), K(ret)); ObMysqlProxyCont *mp_cont = NULL; ObMysqlClientPool *pool = NULL; - if (OB_ISNULL(pool = acquire_client_pool())) { + if (!request_param.is_detect_client_ && OB_ISNULL(pool = acquire_client_pool())) { ret = OB_ENTRY_NOT_EXIST; LOG_WARN("client pool is null", K(ret)); } else { @@ -825,6 +834,7 @@ int ObMysqlProxy::alloc_client_pool(const bool is_meta_mysql_client, const ObString &user_name, const ObString &password, const ObString &database, + const ObString &cluster_name, const ObString &password1, ClientPoolOption* client_pool_option) { @@ -839,7 +849,7 @@ int ObMysqlProxy::alloc_client_pool(const bool is_meta_mysql_client, } else if (FALSE_IT(client_pool->inc_ref())) { // will dec_ref in destroy() } else if (OB_FAIL(client_pool->init(is_meta_mysql_client, user_name, - password, database, password1, client_pool_option))) { + password, database, cluster_name, password1, client_pool_option))) { LOG_WARN("fail to init client pool", K(user_name), K(password), K(database), K(is_meta_mysql_client), K(ret)); } else { @@ -851,14 +861,14 @@ int ObMysqlProxy::alloc_client_pool(const bool is_meta_mysql_client, client_pool_ = client_pool; // update raw mysql client info - ObClientReuqestInfo &info = raw_mysql_client_.get_request_info(); + ObClientRequestInfo &info = raw_mysql_client_.get_request_info(); info.reset_names(); bool need_skip_stage2 = false; if (client_pool_option) { need_skip_stage2 = client_pool_option->need_skip_stage2_; } info.set_need_skip_stage2(need_skip_stage2); - if (OB_FAIL(info.set_names(user_name, password, database))) { + if (OB_FAIL(info.set_names(user_name, password, database, cluster_name))) { LOG_WARN("fail to set raw mysql client request info", K(ret)); } } diff --git a/src/obproxy/proxy/client/ob_mysql_proxy.h b/src/obproxy/proxy/client/ob_mysql_proxy.h index 1f1d8f5c..f671d55f 100644 --- a/src/obproxy/proxy/client/ob_mysql_proxy.h +++ b/src/obproxy/proxy/client/ob_mysql_proxy.h @@ -57,6 +57,7 @@ class ObMysqlProxy const common::ObString &user_name, const common::ObString &password, const common::ObString &database, + const common::ObString &cluster_name = "", const common::ObString &password1 = ""); bool is_inited() const { return is_inited_; } void destroy(); @@ -116,6 +117,7 @@ class ObMysqlProxy const common::ObString &user_name, const common::ObString &password, const common::ObString &database, + const common::ObString &cluster_name = "", const common::ObString &password1 = "", ClientPoolOption* client_pool_option = NULL); public: diff --git a/src/obproxy/proxy/client/ob_raw_mysql_client.cpp b/src/obproxy/proxy/client/ob_raw_mysql_client.cpp index 8bdbb589..08614b88 100644 --- a/src/obproxy/proxy/client/ob_raw_mysql_client.cpp +++ b/src/obproxy/proxy/client/ob_raw_mysql_client.cpp @@ -39,7 +39,7 @@ ObRawMysqlClientActor::ObRawMysqlClientActor() addr_(), request_buf_(NULL), request_reader_(NULL) {} -int ObRawMysqlClientActor::init(ObClientReuqestInfo &info) +int ObRawMysqlClientActor::init(ObClientRequestInfo &info) { int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { @@ -149,7 +149,7 @@ int ObRawMysqlClientActor::connect(const ObAddr &addr, const int64_t timeout_ms) options.f_blocking_ = true; // blocking read or send ObIpEndpoint ip; - ops_ip_copy(ip.sa_, addr.get_ipv4(), static_cast(addr.get_port())); + ip.assign(addr.get_sockaddr()); if (OB_FAIL(con_.open(options))) { LOG_WARN("fail to open connection", K(ret)); } else if (OB_FAIL(con_.connect(ip.sa_, options))) { @@ -401,6 +401,7 @@ int ObRawMysqlClientActor::read_response(const ObMySQLCmd cmd) int ObRawMysqlClient::init(const ObString &user_name, const ObString &password, const ObString &database, + const ObString &cluster_name, const ObString &password1) { int ret = OB_SUCCESS; @@ -412,7 +413,7 @@ int ObRawMysqlClient::init(const ObString &user_name, LOG_WARN("init twice", K_(is_inited), K(ret)); } else if (OB_FAIL(mutex_init(&mutex_))) { LOG_WARN("fail to init mutex", K(ret)); - } else if (OB_FAIL(info_.set_names(user_name, password, database, password1))) { + } else if (OB_FAIL(info_.set_names(user_name, password, database, cluster_name, password1))) { LOG_WARN("fail to set names", K(user_name), K(password), K(password1), K(database), K(ret)); int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = mutex_destroy(&mutex_))) { diff --git a/src/obproxy/proxy/client/ob_raw_mysql_client.h b/src/obproxy/proxy/client/ob_raw_mysql_client.h index 37ff9a54..f489aa10 100644 --- a/src/obproxy/proxy/client/ob_raw_mysql_client.h +++ b/src/obproxy/proxy/client/ob_raw_mysql_client.h @@ -33,7 +33,7 @@ class ObRawMysqlClientActor ObRawMysqlClientActor(); ~ObRawMysqlClientActor() { destroy(); } - int init(ObClientReuqestInfo &info); + int init(ObClientRequestInfo &info); int sync_raw_execute(const char *sql, const int64_t timeout_ms, ObClientMysqlResp *&resp); void reset() { destroy(); } bool is_avail() { return is_avail_; } @@ -51,7 +51,7 @@ class ObRawMysqlClientActor private: bool is_inited_; bool is_avail_; - ObClientReuqestInfo *info_; + ObClientRequestInfo *info_; ObClientMysqlResp *resp_; net::ObConnection con_; common::ObAddr addr_; @@ -82,13 +82,14 @@ class ObRawMysqlClient int init(const common::ObString &user_name, const common::ObString &password, const common::ObString &database, + const common::ObString &cluster_name, const common::ObString &password1 = ""); int sync_raw_execute(const char *sql, const int64_t timeout_ms, ObClientMysqlResp *&resp); int set_server_addr(const common::ObIArray &addrs); int set_target_server(const common::ObIArray &replicas); - ObClientReuqestInfo &get_request_info() { return info_; } + ObClientRequestInfo &get_request_info() { return info_; } int disconnect(); void destroy(); @@ -98,7 +99,7 @@ class ObRawMysqlClient private: static const int64_t DEFAULT_SERVER_ADDRS_COUNT = 3; bool is_inited_; - ObClientReuqestInfo info_; + ObClientRequestInfo info_; ObProxyReplicaLocation target_server_[DEFAULT_SERVER_ADDRS_COUNT]; ObRawMysqlClientActor actor_; ObMutex mutex_; diff --git a/src/obproxy/proxy/mysql/ob_mysql_client_session.cpp b/src/obproxy/proxy/mysql/ob_mysql_client_session.cpp index 9018da7b..aae717e1 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_client_session.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_client_session.cpp @@ -63,19 +63,21 @@ ObMutex g_debug_cs_list_mutex; #endif ObMysqlClientSession::ObMysqlClientSession() - : can_direct_ok_(false), is_proxy_mysql_client_(false), active_(false), test_server_addr_(), + : can_direct_ok_(false), is_proxy_mysql_client_(false), can_direct_send_request_(false), + active_(false), test_server_addr_(), vc_ready_killed_(false), is_waiting_trans_first_request_(false), is_need_send_trace_info_(true), is_already_send_trace_info_(false), - is_first_handle_request_(true), is_in_trans_for_close_request_(false), - is_need_return_last_bound_ss_(false), - need_delete_cluster_(false), is_first_dml_sql_got_(false), compressed_seq_(0), + is_first_handle_request_(true), is_in_trans_for_close_request_(false), is_last_request_in_trans_(false), + is_trans_internal_routing_(false), is_need_return_last_bound_ss_(false), need_delete_cluster_(false), + is_first_dml_sql_got_(false), is_proxy_enable_trans_internal_routing_(false), compressed_seq_(0), cluster_resource_(NULL), dummy_entry_(NULL), is_need_update_dummy_entry_(false), - dummy_ldc_(), dummy_entry_valid_time_ns_(0), server_state_version_(0), + dummy_ldc_(), dummy_entry_valid_time_ns_(0), server_state_version_(0), inner_request_param_(NULL), tcp_init_cwnd_set_(false), half_close_(false), conn_decrease_(false), conn_prometheus_decrease_(false), vip_connection_decrease_(false), magic_(MYSQL_CS_MAGIC_DEAD), create_thread_(NULL), is_local_connection_(false), client_vc_(NULL), in_list_stat_(LIST_INIT), current_tid_(-1), - cs_id_(0), proxy_sessid_(0), bound_ss_(NULL), cur_ss_(NULL), lii_ss_(NULL), last_bound_ss_(NULL), read_buffer_(NULL), + cs_id_(0), proxy_sessid_(0), bound_ss_(NULL), cur_ss_(NULL), lii_ss_(NULL), last_bound_ss_(NULL), + trans_coordinator_ss_addr_(), read_buffer_(NULL), buffer_reader_(NULL), mysql_sm_(NULL), read_state_(MCS_INIT), ka_vio_(NULL), server_ka_vio_(NULL), trace_stats_(NULL), select_plan_(NULL), ps_id_(0), cursor_id_(CURSOR_ID_START), using_ldg_(false) @@ -157,13 +159,17 @@ void ObMysqlClientSession::destroy() is_already_send_trace_info_ = false; is_first_handle_request_ = true; is_in_trans_for_close_request_ = false; + is_last_request_in_trans_ = false; + is_trans_internal_routing_ = false; is_need_return_last_bound_ss_ = false; is_first_dml_sql_got_ = false; + is_proxy_enable_trans_internal_routing_ = false; compressed_seq_ = 0; - + trans_coordinator_ss_addr_.reset(); schema_key_.reset(); ObProxyClientSession::cleanup(); create_thread_ = NULL; + using_ldg_ = false; op_reclaim_free(this); } @@ -369,17 +375,14 @@ int ObMysqlClientSession::new_connection( if (OB_FAIL(fetch_tenant_by_vip())) { PROXY_CS_LOG(WARN, "fail to fetch tenant by vip", K(ret)); ret = OB_SUCCESS; - } else { - session_info_.set_is_read_only_user(ct_info_.vip_tenant_.is_read_only()); - session_info_.set_is_request_follower_user(ct_info_.vip_tenant_.is_request_follower()); - session_info_.set_vip_addr_name(ct_info_.vip_tenant_.vip_addr_.addr_); + } else if (is_vip_lookup_success()) { ObString user_name; if (!get_global_white_list_table_processor().can_ip_pass( ct_info_.vip_tenant_.cluster_name_, ct_info_.vip_tenant_.tenant_name_, - user_name, client_addr.ip_.v4_, false)) { + user_name, client_vc_->get_real_client_addr())) { ret = OB_ERR_CAN_NOT_PASS_WHITELIST; PROXY_CS_LOG(DEBUG, "can not pass white_list", K(ct_info_.vip_tenant_.cluster_name_), - K(ct_info_.vip_tenant_.tenant_name_), K(client_addr), K(ret)); + K(ct_info_.vip_tenant_.tenant_name_), K(client_addr), K(ret)); } } } @@ -406,15 +409,30 @@ int ObMysqlClientSession::new_connection( int ObMysqlClientSession::fetch_tenant_by_vip() { int ret = OB_SUCCESS; - if (OB_FAIL(get_global_vip_tenant_processor().get_vip_tenant(ct_info_.vip_tenant_))) { - //if login succ latter, we will desc cache miss stat. - MYSQL_SSN_INCREMENT_DYN_STAT(VIP_TO_TENANT_CACHE_MISS); - ct_info_.lookup_success_ = false; - PROXY_CS_LOG(INFO, "fail to get_vip_tenant", "vip_tenant", ct_info_.vip_tenant_, K(ret)); - } else { - MYSQL_SSN_INCREMENT_DYN_STAT(VIP_TO_TENANT_CACHE_HIT); - ct_info_.lookup_success_ = true; - PROXY_CS_LOG(DEBUG, "succ to get_vip_tenant name", "vip_tenant", ct_info_.vip_tenant_); + ct_info_.lookup_success_ = false; + ObVipAddr addr = ct_info_.vip_tenant_.vip_addr_; + ObConfigItem tenant_item, cluster_item; + bool found = false; + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + addr, "", "", "proxy_tenant_name", tenant_item, "LEVEL_VIP", found))) { + PROXY_CS_LOG(WARN, "get proxy tenant name config failed", K(addr), K(ret)); + } + + if (OB_SUCC(ret) && found) { + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + addr, "", "", "rootservice_cluster_name", cluster_item, "LEVEL_VIP", found))) { + PROXY_CS_LOG(WARN, "get cluster name config failed", K(addr), K(ret)); + } + } + + if (OB_SUCC(ret) && found) { + if (OB_FAIL(ct_info_.vip_tenant_.set_tenant_cluster(tenant_item.str(), cluster_item.str()))) { + PROXY_CS_LOG(WARN, "set tenant and cluster name failed", K(tenant_item), K(cluster_item), K(ret)); + } else { + session_info_.set_vip_addr_name(addr.addr_); + ct_info_.lookup_success_ = true; + PROXY_CS_LOG(DEBUG, "succ to get conn info", "vip_tenant", ct_info_.vip_tenant_); + } } return ret; } @@ -422,13 +440,9 @@ int ObMysqlClientSession::fetch_tenant_by_vip() int ObMysqlClientSession::get_vip_addr() { int ret = OB_SUCCESS; - int32_t ip; - int32_t port; int64_t vid; - ip = ntohl(client_vc_->get_virtual_ip()); - port = static_cast(client_vc_->get_virtual_port()); vid = static_cast(client_vc_->get_virtual_vid()); - ct_info_.vip_tenant_.vip_addr_.set(ip, port, vid); + ct_info_.vip_tenant_.vip_addr_.set(client_vc_->get_virtual_addr(), vid); // TODO, get client ip, slb ip from kernal @@ -580,6 +594,7 @@ int ObMysqlClientSession::create_scramble() uint64_t ObMysqlClientSession::get_next_proxy_sessid() { + // TODO: Consider IPv6 support static uint64_t next_proxy_sessid = 1; const ObAddr &addr = get_global_hot_upgrade_info().local_addr_; int64_t ipv4 = static_cast(addr.get_ipv4()); @@ -800,6 +815,8 @@ int ObMysqlClientSession::state_server_keep_alive(int event, void *data) case VC_EVENT_READ_READY: case VC_EVENT_EOS: // The server session closed or something is amiss + case VC_EVENT_DETECT_SERVER_DEAD: + // find server dead case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: @@ -864,7 +881,8 @@ int ObMysqlClientSession::state_keep_alive(int event, void *data) // fallthrough case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: - case VC_EVENT_INACTIVITY_TIMEOUT: { + case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: { if (MCS_HALF_CLOSED == read_state_) { half_close_ = false; } @@ -1411,7 +1429,8 @@ bool ObMysqlClientSession::is_authorised_proxysys(const ObProxyLoginUserType typ int ret = OB_SUCCESS; //1.check ip - if (!get_global_proxy_config().skip_proxy_sys_private_check + if (RUN_MODE_PROXY == g_run_mode + && !get_global_proxy_config().skip_proxy_sys_private_check && !ops_is_ip_private(client_vc_->get_remote_addr()) && !ops_is_ip_loopback(client_vc_->get_remote_addr())) { char src_ip[INET6_ADDRSTRLEN]; @@ -1463,7 +1482,9 @@ bool ObMysqlClientSession::is_authorised_proxysys(const ObProxyLoginUserType typ bool ObMysqlClientSession::is_need_convert_vip_to_tname() { - return (get_global_proxy_config().need_convert_vip_to_tname && !this->is_proxy_mysql_client_ ); + return (get_global_proxy_config().need_convert_vip_to_tname + && !this->is_proxy_mysql_client_ + && RUN_MODE_PROXY == g_run_mode); } inline bool ObMysqlClientSession::need_close() const @@ -1614,7 +1635,7 @@ int ObMysqlClientSession::check_update_ldc() } else { need_ignore = true; } - PROXY_CS_LOG(ERROR, "fail to tryrdlock server_state_lock, ignore this update", + PROXY_CS_LOG(WARN, "fail to tryrdlock server_state_lock, ignore this update", K(err_no), "old_idc_name", dummy_ldc_.get_idc_name(), K(new_idc_name), diff --git a/src/obproxy/proxy/mysql/ob_mysql_client_session.h b/src/obproxy/proxy/mysql/ob_mysql_client_session.h index c3401c4b..d991d91f 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_client_session.h +++ b/src/obproxy/proxy/mysql/ob_mysql_client_session.h @@ -27,6 +27,7 @@ #include "optimizer/ob_sharding_select_log_plan.h" #include "optimizer/ob_proxy_optimizer_processor.h" #include "iocore/net/ob_unix_net_vconnection.h" +#include "ob_proxy_init.h" namespace oceanbase { @@ -107,10 +108,12 @@ class ObMysqlClientSession : public ObProxyClientSession inline ObMysqlServerSession *get_cur_server_session() const { return cur_ss_; } inline ObMysqlServerSession *get_lii_server_session() const { return lii_ss_; } inline ObMysqlServerSession *get_last_bound_server_session() const { return last_bound_ss_; } + inline net::ObIpEndpoint &get_trans_coordinator_ss_addr() { return trans_coordinator_ss_addr_; } inline void set_server_session(ObMysqlServerSession *ssession) { bound_ss_ = ssession; } inline void set_cur_server_session(ObMysqlServerSession *ssession) { cur_ss_ = ssession; } inline void set_lii_server_session(ObMysqlServerSession *ssession) { lii_ss_ = ssession; } inline void set_last_bound_server_session(ObMysqlServerSession *ssession) { last_bound_ss_ = ssession; } + inline void set_trans_coordinator_ss_addr(const sockaddr &addr) { trans_coordinator_ss_addr_.assign(addr); } bool is_hold_conn_id(const uint32_t conn_id); // Functions for manipulating api hooks @@ -133,13 +136,6 @@ class ObMysqlClientSession : public ObProxyClientSession //proxy inner mysql_client do need convert vip to tenant bool is_need_convert_vip_to_tname(); - // client protocol judgement - ObProxyProtocol get_client_session_protocol() const - { - return session_info_.is_client_support_ob20_protocol() ? - ObProxyProtocol::PROTOCOL_OB20 : ObProxyProtocol::PROTOCOL_NORMAL; - } - // client cap judgement bool is_client_support_full_link_trace() const { return session_info_.is_client_support_full_link_trace(); } bool is_client_support_new_extra_info() const { return session_info_.is_client_support_new_extra_info(); } @@ -236,6 +232,7 @@ class ObMysqlClientSession : public ObProxyClientSession void set_need_delete_cluster() { need_delete_cluster_ = true; } void set_proxy_mysql_client() { is_proxy_mysql_client_ = true; } + void set_can_send_request() { can_direct_send_request_ = true; } void set_session_pool_client(bool is_session_pool_client) { session_info_.is_session_pool_client_ = is_session_pool_client; } @@ -256,9 +253,14 @@ class ObMysqlClientSession : public ObProxyClientSession bool is_first_handle_request() const { return is_first_handle_request_; } void set_in_trans_for_close_request(bool is_in_trans_for_close_request) { is_in_trans_for_close_request_ = is_in_trans_for_close_request; } bool is_in_trans_for_close_request() const { return is_in_trans_for_close_request_; } + void set_last_request_in_trans(bool is_in_trans) { is_last_request_in_trans_ = is_in_trans; } + bool is_last_request_in_trans() { return is_last_request_in_trans_; } + void set_trans_internal_routing(bool is_internal_routing) { is_trans_internal_routing_ = is_internal_routing; } + bool is_trans_internal_routing() const { return is_trans_internal_routing_; } void set_need_return_last_bound_ss(bool is_need_return_last_bound_ss) { is_need_return_last_bound_ss_ = is_need_return_last_bound_ss; } bool is_need_return_last_bound_ss() const { return is_need_return_last_bound_ss_; } - + void set_proxy_enable_trans_internal_routing(bool is_enable_internal_route) { is_proxy_enable_trans_internal_routing_ = is_enable_internal_route; } + bool is_proxy_enable_trans_internal_routing() const { return is_proxy_enable_trans_internal_routing_; } bool enable_analyze_internal_cmd() const { return session_info_.enable_analyze_internal_cmd(); } bool is_metadb_user() const { return session_info_.is_metadb_user(); } bool is_proxysys_user() const { return session_info_.is_proxysys_user(); } @@ -332,6 +334,7 @@ class ObMysqlClientSession : public ObProxyClientSession bool can_direct_ok_; bool is_proxy_mysql_client_; // used for ObMysqlClient + bool can_direct_send_request_; // used for ObMysqlClient bool can_server_session_release_; //used for session release proxy::ObCommonAddr common_addr_; // session pool server_addr @@ -350,11 +353,13 @@ class ObMysqlClientSession : public ObProxyClientSession bool is_already_send_trace_info_; bool is_first_handle_request_; bool is_in_trans_for_close_request_; + bool is_last_request_in_trans_; + bool is_trans_internal_routing_; bool is_need_return_last_bound_ss_; bool need_delete_cluster_; bool is_first_dml_sql_got_;//default false, will route with merge status careless //it is true after user first dml sql arrived. - + bool is_proxy_enable_trans_internal_routing_; // from config, update each tranasction start uint8_t compressed_seq_; // seq management between client & proxy obutils::ObClusterResource *cluster_resource_; @@ -379,8 +384,6 @@ class ObMysqlClientSession : public ObProxyClientSession #endif private: - static const uint32_t LOCAL_IPV4_ADDR = 0x100007F; - enum ObClientReadState { MCS_INIT = 0, @@ -431,6 +434,9 @@ class ObMysqlClientSession : public ObProxyClientSession ObMysqlServerSession *lii_ss_; ObMysqlServerSession *last_bound_ss_; + // coordinator session address in transaction + net::ObIpEndpoint trans_coordinator_ss_addr_; + event::ObMIOBuffer *read_buffer_; event::ObIOBufferReader *buffer_reader_; @@ -459,11 +465,11 @@ class ObMysqlClientSession : public ObProxyClientSession inline void ObMysqlClientSession::set_local_connection() { - if (is_proxy_mysql_client_) { + if (is_proxy_mysql_client_ || RUN_MODE_CLIENT == g_run_mode) { is_local_connection_ = true; } else { if (OB_NOT_NULL(client_vc_)) { - is_local_connection_ = LOCAL_IPV4_ADDR == client_vc_->get_local_ip(); + is_local_connection_ = net::ops_is_ip_loopback(client_vc_->get_local_addr()); } } } @@ -481,13 +487,13 @@ inline uint32_t ObMysqlClientSession::get_next_ps_stmt_id() inline common::ObAddr ObMysqlClientSession::get_real_client_addr(net::ObNetVConnection *server_vc) { common::ObAddr ret_addr; - if (is_proxy_mysql_client_) { + if (is_proxy_mysql_client_ || RUN_MODE_CLIENT == g_run_mode) { if (OB_NOT_NULL(server_vc)) { - ret_addr.set_ipv4_addr(ntohl(server_vc->get_local_ip()), server_vc->get_local_port()); + ret_addr.set_sockaddr(server_vc->get_local_addr()); } } else { if (OB_NOT_NULL(client_vc_)) { - ret_addr.set_ipv4_addr(ntohl(client_vc_->get_real_client_ip()), client_vc_->get_real_client_port()); + ret_addr.set_sockaddr(client_vc_->get_real_client_addr()); } } PROXY_CS_LOG(DEBUG, "succ to get real client addr", K(ret_addr)); diff --git a/src/obproxy/proxy/mysql/ob_mysql_debug_names.cpp b/src/obproxy/proxy/mysql/ob_mysql_debug_names.cpp index 67c56fc6..2489e507 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_debug_names.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_debug_names.cpp @@ -68,6 +68,10 @@ const char *ObMysqlDebugNames::get_event_name(const int event) ret = "VC_EVENT_ACTIVE_TIMEOUT"; break; + case VC_EVENT_DETECT_SERVER_DEAD: + ret = "VC_EVENT_DETECT_SERVER_DEAD"; + break; + case EVENT_INTERVAL: ret = "VC_EVENT_INTERVAL"; break; diff --git a/src/obproxy/proxy/mysql/ob_mysql_global_session_manager.cpp b/src/obproxy/proxy/mysql/ob_mysql_global_session_manager.cpp index cc70732b..8216b465 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_global_session_manager.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_global_session_manager.cpp @@ -81,6 +81,7 @@ int ObMysqlServerSessionList::main_handler(int event, void *data) case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: net_vc = static_cast((static_cast(data))->vc_server_); break; @@ -1042,4 +1043,4 @@ ObMysqlContJobList& get_global_server_conn_job_list() } // end of namespace proxy } // end of namespace obproxy -} // end of namespace oceanbase \ No newline at end of file +} // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_mysql_proxy_port.cpp b/src/obproxy/proxy/mysql/ob_mysql_proxy_port.cpp index 3d602d94..24a794a0 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_proxy_port.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_proxy_port.cpp @@ -23,10 +23,16 @@ namespace obproxy { namespace proxy { -ObMysqlProxyPort &get_global_proxy_port() +ObMysqlProxyPort &get_global_proxy_ipv4_port() { - static ObMysqlProxyPort g_proxy_port; - return g_proxy_port; + static ObMysqlProxyPort g_proxy_ipv4_port; + return g_proxy_ipv4_port; +} + +ObMysqlProxyPort &get_global_proxy_ipv6_port() +{ + static ObMysqlProxyPort g_proxy_ipv6_port; + return g_proxy_ipv6_port; } void ObMysqlProxyPort::reset() diff --git a/src/obproxy/proxy/mysql/ob_mysql_proxy_port.h b/src/obproxy/proxy/mysql/ob_mysql_proxy_port.h index 45fb1afb..f94c93b9 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_proxy_port.h +++ b/src/obproxy/proxy/mysql/ob_mysql_proxy_port.h @@ -55,7 +55,8 @@ struct ObMysqlProxyPort net::ObIpAddr inbound_ip_; }; -ObMysqlProxyPort &get_global_proxy_port(); +ObMysqlProxyPort &get_global_proxy_ipv4_port(); +ObMysqlProxyPort &get_global_proxy_ipv6_port(); } // end of namespace proxy } // end of namespace obproxy diff --git a/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.cpp b/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.cpp index 80953a0b..59ab305f 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.cpp @@ -22,9 +22,11 @@ #include "iocore/eventsystem/ob_blocking_task.h" #include "iocore/eventsystem/ob_grpc_task.h" #include "iocore/eventsystem/ob_shard_watch_task.h" +#include "iocore/eventsystem/ob_shard_scan_all_task.h" #include "obutils/ob_congestion_manager.h" #include "obutils/ob_proxy_config.h" #include "dbconfig/ob_proxy_db_config_processor.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -41,7 +43,8 @@ namespace proxy { // global acceptor, ObMysqlProxyAccept -ObMysqlProxyAcceptor g_mysql_proxy_acceptor; +ObMysqlProxyAcceptor g_mysql_proxy_ipv4_acceptor; +ObMysqlProxyAcceptor g_mysql_proxy_ipv6_acceptor; // called from ob_api.cpp int ObMysqlProxyServerMain::make_net_accept_options( @@ -105,7 +108,7 @@ int ObMysqlProxyServerMain::init_mysql_proxy_server(const ObMysqlConfigParams &c // enable reclaim mysql sm op_reclaim_sparse_opt(ObMysqlSM, ObMysqlSM::instantiate_func, ENABLE_RECLAIM, 1); - if (OB_FAIL(init_mysql_proxy_port(config_params))) { + if (RUN_MODE_PROXY == g_run_mode && OB_FAIL(init_mysql_proxy_port(config_params))) { LOG_ERROR("fail to init mysql proxy port", K(ret)); } else if (OB_FAIL(init_mysql_stats())) { LOG_ERROR("fail to init_mysql_stats", K(ret)); @@ -119,11 +122,23 @@ int ObMysqlProxyServerMain::init_mysql_proxy_server(const ObMysqlConfigParams &c } #endif - if (OB_SUCC(ret)) { + int64_t ip_mode = config_params.ip_listen_mode_; + bool enable_ipv4 = (ip_mode == 1 || ip_mode == 3); + bool enable_ipv6 = (ip_mode == 2 || ip_mode == 3); + + if (OB_SUCC(ret) && enable_ipv4) { // do the configuration defined ports if (OB_FAIL(make_mysql_proxy_acceptor(config_params, - get_global_proxy_port(), - g_mysql_proxy_acceptor))) { + get_global_proxy_ipv4_port(), + g_mysql_proxy_ipv4_acceptor))) { + LOG_ERROR("fail to make mysql proxy acceptor", K(ret)); + } + } + + if (OB_SUCC(ret) && enable_ipv6) { + if (OB_FAIL(make_mysql_proxy_acceptor(config_params, + get_global_proxy_ipv6_port(), + g_mysql_proxy_ipv6_acceptor))) { LOG_ERROR("fail to make mysql proxy acceptor", K(ret)); } } @@ -133,15 +148,23 @@ int ObMysqlProxyServerMain::init_mysql_proxy_server(const ObMysqlConfigParams &c int ObMysqlProxyServerMain::start_mysql_proxy_acceptor() { int ret = OB_SUCCESS; - ObMysqlProxyPort &proxy_port = get_global_proxy_port(); + int64_t ip_mode = get_global_proxy_config().ip_listen_mode; + bool enable_ipv4 = (ip_mode == 1 || ip_mode == 3); + bool enable_ipv6 = (ip_mode == 2 || ip_mode == 3); // start accepting connections // although we make a good pretence here, I don't believe that ObNetProcessor::main_accept() // ever actually returns NULL. It would be useful to be able to detect errors // and spew them here though. - if (OB_ISNULL(g_net_processor.main_accept(*(g_mysql_proxy_acceptor.accept_), proxy_port.fd_, - g_mysql_proxy_acceptor.net_opt_))) { + if (enable_ipv4 && OB_ISNULL(g_net_processor.main_accept(*(g_mysql_proxy_ipv4_acceptor.accept_), + get_global_proxy_ipv4_port().fd_, + g_mysql_proxy_ipv4_acceptor.net_opt_))) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("fail to execute main accept", K(ret)); + LOG_ERROR("fail to execute ipv4 main accept", K(ret)); + } else if (enable_ipv6 && OB_ISNULL(g_net_processor.main_accept(*(g_mysql_proxy_ipv6_acceptor.accept_), + get_global_proxy_ipv6_port().fd_, + g_mysql_proxy_ipv6_acceptor.net_opt_))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("fail to execute ipv6 main accept", K(ret)); } return ret; @@ -161,6 +184,7 @@ int ObMysqlProxyServerMain::start_processor_threads(const ObMysqlConfigParams &c int ret = OB_SUCCESS; int64_t stack_size = config_params.stack_size_; int64_t event_threads = config_params.work_thread_num_; + int64_t shard_scan_threads = config_params.shard_scan_thread_num_; int64_t task_threads = config_params.task_thread_num_; bool enable_cpu_topology = config_params.enable_cpu_topology_; bool automatic_match_work_thread = config_params.automatic_match_work_thread_; @@ -188,6 +212,11 @@ int ObMysqlProxyServerMain::start_processor_threads(const ObMysqlConfigParams &c } else if (get_global_proxy_config().enable_sharding && OB_FAIL(g_shard_watch_task_processor.start(grpc_watch_threads, stack_size))) { LOG_ERROR("fail to start grpc parent task processor", K(stack_size), K(ret)); + } else if (get_global_proxy_config().enable_sharding + && OB_FAIL(g_shard_scan_all_task_processor.start(shard_scan_threads > 0 ? shard_scan_threads + : g_event_processor.thread_count_for_type_[ET_CALL] / 2, + stack_size))) { + LOG_ERROR("fail to start grpc parent task processor", K(stack_size), K(ret)); } else if (OB_FAIL(init_cs_map_for_thread())) { LOG_ERROR("fail to init cs_map for thread", K(ret)); } else if (OB_FAIL(init_table_map_for_thread())) { @@ -210,30 +239,60 @@ int ObMysqlProxyServerMain::start_processor_threads(const ObMysqlConfigParams &c return ret; } +int ObMysqlProxyServerMain::init_inherited_info(ObMysqlProxyPort &proxy_port, const int fd) +{ + int ret = OB_SUCCESS; + proxy_port.fd_ = fd; + struct sockaddr_storage sock_addr; + int64_t namelen = sizeof(sock_addr); + memset(&sock_addr, 0, namelen); + if (OB_FAIL(ObSocketManager::getsockname(proxy_port.fd_, (struct sockaddr*)(&sock_addr), &namelen))) { + LOG_ERROR("fail to get sock name", K(ret)); + } else { + // This step of conversion is mainly to obtain the port number, sockaddr_in and sockaddr_in6 port number positions are compatible + struct sockaddr_in *ain = (sockaddr_in *)&sock_addr; + proxy_port.inbound_ip_.assign(*(struct sockaddr*)(&sock_addr)); + proxy_port.port_ = static_cast((ntohs)(ain->sin_port)); + LOG_INFO("succ init mysql proxy port by inherited fd", K(proxy_port)); + } + return ret; +} + int ObMysqlProxyServerMain::init_mysql_proxy_port(const ObMysqlConfigParams &config_params) { int ret = OB_SUCCESS; - ObMysqlProxyPort &proxy_port = get_global_proxy_port(); + ObMysqlProxyPort &proxy_ipv4_port = get_global_proxy_ipv4_port(); + ObMysqlProxyPort &proxy_ipv6_port = get_global_proxy_ipv6_port(); const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); + int64_t ip_mode = config_params.ip_listen_mode_; + bool enable_ipv4 = (ip_mode == 1 || ip_mode == 3); + bool enable_ipv6 = (ip_mode == 2 || ip_mode == 3); // init from inherited fd if (info.is_inherited_) { - proxy_port.fd_ = info.fd_; - struct sockaddr sock_addr; - int64_t namelen = sizeof(sock_addr); - memset(&sock_addr, 0, namelen); - if (OB_FAIL(ObSocketManager::getsockname(proxy_port.fd_, &sock_addr , &namelen))) { - LOG_ERROR("fail to get sock name", K(ret), K(ret)); - } else { - struct sockaddr_in *ain = (sockaddr_in *)&sock_addr; - proxy_port.inbound_ip_.assign(sock_addr); - proxy_port.port_ = static_cast((ntohs)(ain->sin_port)); - LOG_INFO("succ init mysql proxy port by inherited fd", K(proxy_port)); + if (enable_ipv4) { + if (OB_FAIL(init_inherited_info(proxy_ipv4_port, info.ipv4_fd_))) { + LOG_WARN("fail to init inherited info", K(ret)); + } + } + + if (OB_SUCC(ret) && enable_ipv6) { + if (OB_FAIL(init_inherited_info(proxy_ipv6_port, info.ipv6_fd_))) { + LOG_WARN("fail to init inherited info", K(ret)); + } } } else { // init from config - proxy_port.port_ = static_cast(config_params.listen_port_); - proxy_port.inbound_ip_ = config_params.local_bound_ip_; - LOG_INFO("succ init mysql proxy port by config", K(proxy_port)); + if (enable_ipv4) { + proxy_ipv4_port.port_ = static_cast(config_params.listen_port_); + proxy_ipv4_port.inbound_ip_ = config_params.local_bound_ip_; + LOG_INFO("succ init mysql proxy ipv4 port by config", K(proxy_ipv4_port)); + } + + if (enable_ipv6) { + proxy_ipv6_port.port_ = static_cast(config_params.listen_port_); + proxy_ipv6_port.inbound_ip_ = config_params.local_bound_ipv6_ip_; + LOG_INFO("succ init mysql proxy ipv6 port by config", K(proxy_ipv6_port)); + } } return ret; } diff --git a/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.h b/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.h index 290d2127..01195d51 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.h +++ b/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.h @@ -70,6 +70,7 @@ class ObMysqlProxyServerMain static int start_processor_threads(const ObMysqlConfigParams &config_params); static int init_mysql_proxy_port(const ObMysqlConfigParams &config_params); + static int init_inherited_info(ObMysqlProxyPort &proxy_port, const int fd); }; } // end of namespace proxy diff --git a/src/obproxy/proxy/mysql/ob_mysql_server_session.cpp b/src/obproxy/proxy/mysql/ob_mysql_server_session.cpp index 051d571b..7409bb54 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_server_session.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_server_session.cpp @@ -15,6 +15,7 @@ #include "prometheus/ob_sql_prometheus.h" #include "proxy/mysql/ob_mysql_global_session_manager.h" #include "obutils/ob_proxy_config.h" +#include "utils/ob_proxy_table_define.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -142,7 +143,15 @@ void ObMysqlServerSession::do_io_shutdown(const ShutdownHowToType howto) void ObMysqlServerSession::do_io_close(const int alerrno) { - PROXY_SS_LOG(INFO, "server session do_io_close", K(*this), KP(server_vc_), KP(this)); + bool need_print = true; + if(NULL != client_session_ && + client_session_->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER) { + need_print = false; + } + + if (need_print) { + PROXY_SS_LOG(INFO, "server session do_io_close", K(*this), KP(server_vc_), KP(this)); + } if (MSS_ACTIVE == state_) { MYSQL_DECREMENT_DYN_STAT(CURRENT_SERVER_TRANSACTIONS); --server_trans_stat_; @@ -174,9 +183,14 @@ void ObMysqlServerSession::do_io_close(const int alerrno) if (this == client_session_->get_last_bound_server_session()) { client_session_->set_last_bound_server_session(NULL); } - PROXY_SS_LOG(INFO, "server session is closing", K_(ss_id), K_(server_sessid), K_(server_ip), - "cs_id", client_session_->get_cs_id(), - "proxy_sessid", client_session_->get_proxy_sessid()); + if (server_ip_ == client_session_->get_trans_coordinator_ss_addr()) { + client_session_->get_trans_coordinator_ss_addr().reset(); + } + if (need_print) { + PROXY_SS_LOG(INFO, "server session is closing", K_(ss_id), K_(server_sessid), K_(server_ip), + "cs_id", client_session_->get_cs_id(), + "proxy_sessid", client_session_->get_proxy_sessid()); + } } else { PROXY_SS_LOG(INFO, "server session has not bound to client session", K(*this)); } diff --git a/src/obproxy/proxy/mysql/ob_mysql_session_manager.cpp b/src/obproxy/proxy/mysql/ob_mysql_session_manager.cpp index 44f4bb27..01741a12 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_session_manager.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_session_manager.cpp @@ -187,6 +187,7 @@ int ObServerSessionPool::event_handler(int event, void *data) case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: net_vc = static_cast((static_cast(data))->vc_server_); break; diff --git a/src/obproxy/proxy/mysql/ob_mysql_sm.cpp b/src/obproxy/proxy/mysql/ob_mysql_sm.cpp index 560b37ca..3297af19 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_sm.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_sm.cpp @@ -68,12 +68,15 @@ #include "omt/ob_conn_table_processor.h" #include "omt/ob_ssl_config_table_processor.h" #include "iocore/net/ob_inet.h" +#include "iocore/eventsystem/ob_shard_scan_all_task.h" #include "prometheus/ob_thread_prometheus.h" +#include "ob_proxy_init.h" #include "common/obsm_utils.h" #include "proxy/mysqllib/ob_proxy_ob20_request.h" #include "proxy/mysqllib/ob_mysql_resp_analyzer.h" #include "obproxy/packet/ob_proxy_packet_writer.h" #include "obproxy/cmd/ob_internal_cmd_processor.h" +#include "engine/ob_proxy_operator_cont.h" using namespace oceanbase::share; using namespace oceanbase::common; @@ -198,7 +201,8 @@ ObMysqlSM::ObMysqlSM() need_renew_cluster_resource_(false), is_in_trans_(true), retry_acquire_server_session_count_(0), start_acquire_server_session_time_(0), skip_plugin_(false), add_detect_server_cnt_(false), enable_cloud_full_username_(false), - enable_client_ssl_(false), enable_server_ssl_(false), config_version_(0) + enable_client_ssl_(false), enable_server_ssl_(false), enable_read_write_split_(false), + enable_transaction_split_(false), enable_ob_protocol_v2_(false), config_version_(0), target_db_server_(NULL) { static bool scatter_inited = false; @@ -230,6 +234,10 @@ inline void ObMysqlSM::cleanup() sm_cluster_resource_->dec_ref(); sm_cluster_resource_ = NULL; } + if (OB_NOT_NULL(target_db_server_)) { + op_free(target_db_server_); + target_db_server_ = NULL; + } } inline void ObMysqlSM::destroy() @@ -478,29 +486,6 @@ inline int ObMysqlSM::setup_client_request_read() ret = OB_ERR_UNEXPECTED; LOG_WARN("client session failed to do_io_read", K_(sm_id), K(ret)); } else { - // consume the ob20 tail crc(4) in client buf reader while analyzed all the mysql packet in ob20 payload - ObClientSessionInfo &client_session_info = get_client_session()->get_session_info(); - - ObProxyProtocol client_proto = get_client_session_protocol(); - bool ob20_req_received_done = client_session_info.ob20_request_.ob20_request_received_done_; - int64_t ob20_req_remain_payload_len = client_session_info.ob20_request_.remain_payload_len_; - LOG_DEBUG("setup client req read", K(client_proto), K(ob20_req_received_done), K(ob20_req_remain_payload_len)); - - if (client_proto == ObProxyProtocol::PROTOCOL_OB20 - && ob20_req_received_done - && ob20_req_remain_payload_len == 0) { - client_session_info.ob20_request_.reset(); - LOG_DEBUG("setup client request read consume ob20 tail crc len 4"); - int64_t read_avail = client_buffer_reader_->read_avail(); - if (OB_LIKELY(read_avail >= OB20_PROTOCOL_TAILER_LENGTH)) { - if (OB_FAIL(client_buffer_reader_->consume(OB20_PROTOCOL_TAILER_LENGTH))) { - LOG_WARN("fail to consume the last crc buffer in client request buffer", K(ret)); - } - } else { - LOG_DEBUG("client buffer reader has consumed all, no need consume the tail 4 crc in buffer", K(read_avail)); - } - } - if (OB_SUCC(ret)) { int64_t read_avail = client_buffer_reader_->read_avail(); if (read_avail > 0 @@ -543,6 +528,9 @@ int ObMysqlSM::state_client_request_read(int event, void *data) milestones_.trans_start_ = get_based_hrtime(); } } + + // record the config of enable_transaction_internal_routing + client_session_->set_proxy_enable_trans_internal_routing(trans_state_.mysql_config_params_->enable_transaction_internal_routing_ && is_enable_ob_protocol_v2()); } if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { @@ -597,7 +585,8 @@ int ObMysqlSM::state_client_request_read(int event, void *data) } case VC_EVENT_ERROR: - case VC_EVENT_ACTIVE_TIMEOUT: { + case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: { LOG_WARN("ObMysqlSM::state_client_request_read", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id), "client_vc", client_session_ == NULL ? "NULL" : P(client_session_->get_netvc())); @@ -615,7 +604,8 @@ int ObMysqlSM::state_client_request_read(int event, void *data) } - if (OB_SUCC(ret) && !client_session_->is_proxy_mysql_client_) { + if (OB_SUCC(ret) && !client_session_->is_proxy_mysql_client_ + && RUN_MODE_PROXY == g_run_mode) { ObNetVConnection *vc = client_session_->get_netvc(); if (OB_UNLIKELY(NULL != vc && vc->options_.sockopt_flags_ != trans_state_.mysql_config_params_->client_sock_option_flag_out_)) { @@ -772,8 +762,8 @@ int ObMysqlSM::state_client_request_read(int event, void *data) set_client_wait_timeout(); // no request data to read, reset read trigger and avoid unnecessary reading - ObUnixNetVConnection* vc = static_cast(client_session_->get_netvc()); if (!client_session_->is_proxy_mysql_client_) { + ObUnixNetVConnection* vc = static_cast(client_session_->get_netvc()); if (!handling_ssl_request_) { vc->reset_read_trigger(); } @@ -908,6 +898,7 @@ int ObMysqlSM::state_handle_shard_ddl(int event, void *data) case VC_EVENT_EOS: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("handle shard ddl meet error, will disconnect", K_(sm_id), "event", ObMysqlDebugNames::get_event_name(event), K(ret)); ret = OB_CONNECT_ERROR; @@ -953,18 +944,20 @@ int ObMysqlSM::process_shard_ddl_result(ObShardDDLStatus *ddl_status) } if (OB_SUCC(ret)) { + ObProxyProtocol client_protocol = get_client_session_protocol(); ObMysqlClientSession *client_session = get_client_session(); + if (ddl_status->is_success()) { const ObMySQLCapabilityFlags &capability = client_session->get_session_info().get_orig_capability_flags(); - if (OB_FAIL(ObMysqlPacketUtil::encode_ok_packet(*buf, seq, 0, capability))) { - LOG_WARN("[ObMysqlSM::do_internal_request] fail to encode login response ok packet", + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, seq, 0, capability))) { + LOG_WARN("[ObMysqlSM::do_internal_request] fail to encode shard ddl ok packet", K_(sm_id), K(ret)); } } else { int64_t error_code = 0; if (OB_FAIL(get_int_value(ddl_status->get_error_code(), error_code))) { LOG_WARN("fail to get int error code", "errcode", ddl_status->get_error_code(), K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, seq, static_cast(-error_code), ddl_status->get_error_message()))) { LOG_WARN("fail to encode err pacekt buf", K(seq), "errmsg", ddl_status->get_error_message(), @@ -987,19 +980,17 @@ int ObMysqlSM::setup_handle_execute_plan() ObShardingSelectLogPlan* plan = NULL; ObProxyOperator* operator_root = NULL; + ObProxyOperatorCont *operator_cont = NULL; + ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; int64_t total_len = client_buffer_reader_->read_avail(); - if (total_len > trans_state_.trans_info_.client_request_.get_packet_meta().pkt_len_) { - total_len = trans_state_.trans_info_.client_request_.get_packet_meta().pkt_len_; + if (total_len > client_request.get_packet_meta().pkt_len_) { + total_len = client_request.get_packet_meta().pkt_len_; } - ObShardProp *shard_prop = client_session_->get_session_info().get_shard_prop(); - ObHRTime execute_timeout = 0; - if (OB_NOT_NULL(shard_prop)) { - execute_timeout = HRTIME_MSECONDS(shard_prop->get_socket_timeout()); - } else { - execute_timeout = client_session_->get_session_info().get_query_timeout(); - } + uint8_t seq = static_cast(client_request.get_packet_meta().pkt_seq_ + 1); + + ObHRTime execute_timeout = get_query_timeout(); // consume data in client buffer reader if (OB_FAIL(client_buffer_reader_->consume(total_len))) { @@ -1013,16 +1004,23 @@ int ObMysqlSM::setup_handle_execute_plan() } else if (OB_NOT_NULL(pending_action_)){ ret = OB_ERR_UNEXPECTED; LOG_WARN("pending_action must be NULL here", K_(pending_action), K_(sm_id), K(ret)); - } else if (OB_FAIL(operator_root->open(this, pending_action_, hrtime_to_msec(execute_timeout)))) { - LOG_WARN("fail to open operator", K_(sm_id), K(execute_timeout), K(ret)); - } else if (OB_FAIL(operator_root->get_next_row())) { - LOG_WARN("fail to get next row", K_(sm_id), K(ret)); - } else if (OB_ISNULL(pending_action_)) { - LOG_WARN("pending action should not be null", K_(sm_id), K(ret)); + } else if (OB_ISNULL(operator_cont = new(std::nothrow) ObProxyOperatorCont(this, &self_ethread()))) { + LOG_WARN("fail to alloc parallel execute cont", K(ret)); + } else if (OB_FAIL(operator_cont->init(operator_root, seq, hrtime_to_msec(execute_timeout)))) { + LOG_WARN("fail to init execute cont", K(ret)); + } else if (OB_ISNULL(g_shard_scan_all_task_processor.schedule_imm(operator_cont, ET_SHARD_SCAN_ALL))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to schedule parallel execute cont", K(ret)); } else { + pending_action_ = &operator_cont->get_action(); client_session_->set_inactivity_timeout(execute_timeout); } + if (OB_FAIL(ret) && OB_LIKELY(NULL != operator_cont)) { + operator_cont->destroy(); + operator_cont = NULL; + } + return ret; } @@ -1034,14 +1032,14 @@ int ObMysqlSM::state_handle_execute_plan(int event, void *data) ObShardingSelectLogPlan* plan = NULL; ObProxyOperator* operator_root = NULL; - pending_action_ = NULL; switch (event) { - case VC_EVENT_READ_COMPLETE: + case ASYNC_PROCESS_DONE_EVENT: + pending_action_ = NULL; if (OB_ISNULL(data)) { ret = OB_ERR_NULL_VALUE; LOG_WARN("data is NULL", K_(sm_id), K(ret)); - } else if (OB_FAIL(process_executor_result(reinterpret_cast(data)))) { + } else if (OB_FAIL(process_executor_result(reinterpret_cast(data)))) { LOG_WARN("fail to process executor result, will disconnect", K_(sm_id), K(ret)); } else { trans_state_.next_action_ = ObMysqlTransact::SM_ACTION_INTERNAL_NOOP; @@ -1051,6 +1049,7 @@ int ObMysqlSM::state_handle_execute_plan(int event, void *data) case VC_EVENT_EOS: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("handle execute plan meet error, will disconnect", K_(sm_id), "event", ObMysqlDebugNames::get_event_name(event), K(ret)); ret = OB_CONNECT_ERROR; @@ -1067,9 +1066,23 @@ int ObMysqlSM::state_handle_execute_plan(int event, void *data) } } + if (OB_NOT_NULL(pending_action_)) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = pending_action_->cancel())) { + LOG_WARN("failed to cancel pending action", K_(pending_action), K_(sm_id), K(tmp_ret)); + } + + if (OB_SUCC(ret)) { + ret = tmp_ret; + } + pending_action_ = NULL; + } + if (OB_ISNULL(plan = client_session_->get_sharding_select_log_plan())) { + ret = OB_ERR_UNEXPECTED; LOG_WARN("select log plan should not be null", K_(sm_id), K(ret)); } else if (OB_ISNULL(operator_root = plan->get_plan_root())) { + ret = OB_ERR_UNEXPECTED; LOG_WARN("operator should not be null", K_(sm_id), K(ret)); } else { operator_root->close(); @@ -1084,12 +1097,10 @@ int ObMysqlSM::state_handle_execute_plan(int event, void *data) return VC_EVENT_NONE; } -int ObMysqlSM::process_executor_result(ObProxyResultResp *result_resp) +int ObMysqlSM::process_executor_result(ObIOBufferReader *resp_reader) { int ret = OB_SUCCESS; - ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; - uint8_t seq = static_cast(client_request.get_packet_meta().pkt_seq_ + 1); ObMIOBuffer *buf = NULL; if (NULL != trans_state_.internal_buffer_) { @@ -1104,15 +1115,33 @@ int ObMysqlSM::process_executor_result(ObProxyResultResp *result_resp) if (OB_SUCC(ret)) { ObMysqlClientSession *client_session = get_client_session(); - if (result_resp->is_resultset_resp()) { - if (OB_FAIL(ObProxyPacketWriter::write_executor_resp_packet(buf, client_session, seq, result_resp))) { - LOG_WARN("fail to build shard scan resp", K(ret)); + ObProxyProtocol client_protocol = get_client_session_protocol(); + + if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; + uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); + Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); + if (OB_FAIL(ObProto20Utils::consume_and_compress_data(resp_reader, buf, + resp_reader->read_avail(), ob20_head_param))) { + LOG_WARN("fail to consume and compress data for executor response packet in ob20", K(ret)); + } else { + LOG_DEBUG("succ to executor response in ob20 packet"); } } else { - if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, seq, result_resp->get_err_code(), - result_resp->get_err_msg()))) { - LOG_WARN("fail to encode err pacekt buf", K(seq), "errmsg", result_resp->get_err_msg(), - "errcode", result_resp->get_err_code(), K(ret)); + int64_t data_size = resp_reader->read_avail(); + int64_t bytes_written = 0; + if (OB_FAIL(buf->remove_append(resp_reader, bytes_written))) { + LOG_ERROR("Error while remove_append to buf", "Attempted size", data_size, + "wrote size", bytes_written, K(ret)); + } else if (OB_UNLIKELY(bytes_written != data_size)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected result", "Attempted size", data_size, + "wrote size", bytes_written, K(ret)); + } else { + LOG_DEBUG("succ to write to client", "Attempted size", bytes_written); } } } @@ -1137,8 +1166,7 @@ int ObMysqlSM::handle_shard_request(bool &need_response_for_stmt, bool &need_wai ObDbConfigLogicDb *db_info = NULL; if (!session_info.is_sharding_user() - || parse_result.is_shard_special_cmd() - || ObProxyShardUtils::is_special_db(trans_state_)) { + || parse_result.is_shard_special_cmd()) { // do nothing } else { if (obmysql::OB_MYSQL_COM_FIELD_LIST == req_cmd) { @@ -1146,10 +1174,12 @@ int ObMysqlSM::handle_shard_request(bool &need_response_for_stmt, bool &need_wai LOG_WARN("com_field_list cmd is unsupported for sharding table", K(ret)); } else if (obmysql::OB_MYSQL_COM_QUERY != req_cmd) { //do nothing - } else if (parse_result.is_invalid_stmt() && parse_result.has_shard_comment()) { - ret = OB_ERR_PARSER_SYNTAX; - LOG_WARN("fail to parse shard sql with shard comment", - "sql", client_request.get_sql(), K(ret)); + } else if (ObProxyShardUtils::is_special_db(parse_result)) { + if (OB_FAIL(ObProxyShardUtils::handle_information_schema_request(*client_session_, + trans_state_, + *client_buffer_reader_))) { + LOG_WARN("fail to handle information schema request", K(ret)); + } } else { // get logic db and check auth if (OB_FAIL(ObProxyShardUtils::get_logic_db_info(trans_state_, @@ -1164,14 +1194,24 @@ int ObMysqlSM::handle_shard_request(bool &need_response_for_stmt, bool &need_wai LOG_WARN("fail to check shard request", K(ret)); } else if (parse_result.is_dual_request()) { //do nothing + } else if (parse_result.is_ddl_stmt()) { + const ObString runtime_env = get_global_proxy_config().runtime_env.str(); + if (0 == runtime_env.case_compare(OB_PROXY_DBP_RUNTIME_ENV)) { + if (OB_FAIL(ObProxyShardUtils::handle_ddl_request(this, *client_session_, trans_state_, *db_info, need_wait_callback))) { + LOG_WARN("fail to handle ddl request", K(ret)); + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("ddl stmt is unsupported for sharding table", K(ret)); + } } else if (db_info->is_single_shard_db_table()) { // sindle db table - if (OB_FAIL(ObProxyShardUtils::handle_single_shard_request(this, *client_session_, - trans_state_, *client_buffer_reader_, *db_info, need_wait_callback))) { + if (OB_FAIL(ObProxyShardUtils::handle_single_shard_request(*client_session_, + trans_state_, *client_buffer_reader_, *db_info))) { LOG_WARN("fail to handle single shard request", K(ret)); } - } else if (OB_FAIL(ObProxyShardUtils::handle_shard_request(this, *client_session_, - trans_state_, *client_buffer_reader_, *db_info, need_wait_callback))) { + } else if (OB_FAIL(ObProxyShardUtils::handle_shard_request(*client_session_, + trans_state_, *client_buffer_reader_, *db_info))) { LOG_WARN("fail to handle shard request", K(ret)); } } @@ -1726,14 +1766,18 @@ inline bool ObMysqlSM::check_connection_throttle() bool ObMysqlSM::can_pass_white_list() { bool can_pass = false; - ObStringKV string_kv; - ObClientSessionInfo &session_info = client_session_->get_session_info(); - ObHSRResult &hsr = session_info.get_login_req().get_hsr_result(); - ObUnixNetVConnection* unix_vc = static_cast(client_session_->get_netvc()); - if (OB_UNLIKELY(NULL == unix_vc)) { - LOG_WARN("invalid unix_vc"); - } else if (get_global_white_list_table_processor().can_ip_pass(hsr.cluster_name_, hsr.tenant_name_, hsr.user_name_, unix_vc->get_real_client_ip(), true)) { + if (RUN_MODE_CLIENT == g_run_mode) { can_pass = true; + } else { + ObStringKV string_kv; + ObClientSessionInfo &session_info = client_session_->get_session_info(); + ObHSRResult &hsr = session_info.get_login_req().get_hsr_result(); + ObUnixNetVConnection* unix_vc = static_cast(client_session_->get_netvc()); + if (OB_UNLIKELY(NULL == unix_vc)) { + LOG_WARN("invalid unix_vc"); + } else if (get_global_white_list_table_processor().can_ip_pass(hsr.cluster_name_, hsr.tenant_name_, hsr.user_name_, unix_vc->get_real_client_addr())) { + can_pass = true; + } } return can_pass; @@ -1783,16 +1827,22 @@ int ObMysqlSM::analyze_capacity_flag_from_client() } // whether client truely support ob2.0 or not - if (!session_info.is_client_support_ob20_protocol() - || !is_client_send_client_mode) { - // reset ob2.0 cap - uint64_t client_cap = session_info.get_client_ob_capability(); - client_cap &= ~(OB_CAP_OB_PROTOCOL_V2); - session_info.set_client_ob_capability(client_cap); + // whether proxy config flag set or not + if (OB_SUCC(ret)) { + uint64_t origin_client_cap = session_info.get_client_ob_capability(); + if (!session_info.is_client_support_ob20_protocol() + || !is_client_send_client_mode + || !get_global_proxy_config().enable_ob_protocol_v2_with_client) { + origin_client_cap &= ~(OB_CAP_OB_PROTOCOL_V2); + session_info.set_client_ob_capability(origin_client_cap); + } } - uint64_t last_client_cap = session_info.get_client_ob_capability(); - LOG_INFO("final client capability flag", K(last_client_cap)); + if (OB_SUCC(ret)) { + const uint64_t last_client_cap = session_info.get_client_ob_capability(); + const bool is_client_support_ob20 = session_info.is_client_support_ob20_protocol(); + LOG_INFO("final client capability flag in negotiation", K(last_client_cap), K(is_client_support_ob20)); + } return ret; } @@ -2002,7 +2052,12 @@ void ObMysqlSM::analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool i // 3. if BEGIN or START TRANSACTION, try to hold it if (OB_LIKELY(OB_MYSQL_COM_QUERY == req_cmd)) { MYSQL_INCREMENT_DYN_STAT(TOTAL_QUERY_COUNT); - if (OB_UNLIKELY(client_request.get_parse_result().need_hold_start_trans())) { + // Not set start trans sql + // 1. already in transaction + // 2. already hold xa start + if (OB_UNLIKELY(client_request.get_parse_result().need_hold_start_trans() + && trans_state_.is_trans_first_request_ + && !trans_state_.is_hold_xa_start_)) { if (OB_FAIL(session_info.set_start_trans_sql(client_request.get_sql()))) { LOG_WARN("fail to set start transaction sqld", K_(sm_id), K(ret)); } @@ -2027,7 +2082,7 @@ void ObMysqlSM::analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool i if (OB_FAIL(analyze_login_request(ctx, status))) { LOG_WARN("fail to analyze login request", K(ret)); } - } else if (OB_MYSQL_COM_CHANGE_USER == req_cmd || OB_MYSQL_COM_RESET_CONNECTION == req_cmd) { + } else if (OB_MYSQL_COM_RESET_CONNECTION == req_cmd) { if (session_info.is_sharding_user() || session_info.is_session_pool_client_) { if (OB_FAIL(encode_error_message(OB_NOT_SUPPORTED))) { LOG_WARN("fail to encode unsupport change user error message", K(ret)); @@ -2067,6 +2122,31 @@ void ObMysqlSM::analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool i } else if (OB_MYSQL_COM_STMT_PREPARE_EXECUTE == req_cmd) { if (OB_FAIL(analyze_ps_prepare_execute_request())) { LOG_WARN("fail to analyze ps prepare execute request", K(ret)); + // Not set start trans sql + // 1. already in transaction + // 2. already hold xa start + // 3. already hold begin + } else if (get_global_proxy_config().enable_xa_route + && client_request.get_parse_result().need_hold_xa_start() + && trans_state_.is_trans_first_request_ + && !trans_state_.is_hold_start_trans_ + && !trans_state_.is_hold_xa_start_) { + LOG_DEBUG("[ObMysqlSM::analyze_mysql_request] save xa start request packet"); + session_info.set_start_trans_sql(client_request.get_req_pkt()); + // save the xa start ps id, session_info.ps_id_ will be reset at ObMysqlSM::setup_cmd_complete() + session_info.set_xa_start_ps_id(session_info.get_client_ps_id()); + } + } else if (OB_MYSQL_COM_CHANGE_USER == req_cmd) { + if (OB_UNLIKELY(session_info.is_sharding_user() || client_session_->using_ldg())) { + if (OB_FAIL(encode_error_message(OB_NOT_SUPPORTED))) { + LOG_WARN("fail to encode unsupport change user error message", K(ret)); + } else { + LOG_WARN("sharding or ldg not support change user", K(session_info.is_sharding_user()), + KPC_(client_session), K(ret)); + } + status = ANALYZE_ERROR; + } else if (OB_FAIL(analyze_change_user_request())) { + LOG_WARN("fail to analyze change user request", K(ret)); } } else { // do nothing @@ -2106,6 +2186,129 @@ void ObMysqlSM::analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool i milestone_diff(milestones_.client_.analyze_request_begin_, milestones_.client_.analyze_request_end_); } +int ObMysqlSM::analyze_change_user_request() +{ + int ret = OB_SUCCESS; + ObClientSessionInfo& client_info = client_session_->get_session_info(); + // len represents the size of the entire OB_MYSQL_COM_CHANGE_USER message + int64_t len = trans_state_.trans_info_.client_request_.get_packet_meta().pkt_len_; + if (OB_UNLIKELY(len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid len", K(len), K(ret)); + } else { + ObVariableLenBuffer<128> user_buffer; + if (OB_FAIL(user_buffer.init(len))) { + LOG_WARN("fail to init user buffer", K(ret)); + } else { + char *start = const_cast(user_buffer.ptr()); + char *written_pos = client_buffer_reader_->copy(start, len, 0); + if (OB_UNLIKELY(written_pos != start + len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("write pos not expected", K(written_pos), K(start), K(len), K(ret)); + } else if (OB_FAIL(client_buffer_reader_->consume_all())) { + LOG_WARN("client_buffer_reader consume_all failed", K(ret)); + } else { + ObMIOBuffer *write_buffer = client_buffer_reader_->writer(); + // buf points to the username part of OB_MYSQL_COM_CHANGE_USER + char *buf = start + MYSQL_NET_META_LENGTH; + ObString username = ObString::make_string(buf); + int64_t name_len = strlen(buf); + ObHSRResult result; + int64_t written_len = 0; + ObString& tenant_name = client_info.get_login_req().get_hsr_result().tenant_name_; + ObString& cluster_name = client_info.get_login_req().get_hsr_result().cluster_name_; + if (OB_FAIL(ObProxyAuthParser::parse_full_user_name(username, tenant_name, cluster_name, result))) { + LOG_WARN("parse full user name failed", K(ret)); + } else if (OB_FAIL(write_buffer->write(start, MYSQL_NET_META_LENGTH, written_len))) { + LOG_WARN("fail to write header", K(ret)); + } else if (OB_UNLIKELY(MYSQL_NET_META_LENGTH != written_len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } + // write username + if (OB_SUCC(ret)) { + if (OB_FAIL(write_buffer->write(result.user_name_.ptr(), result.user_name_.length(), written_len))) { + LOG_WARN("fail to write username", K(ret)); + } else if (OB_UNLIKELY(result.user_name_.length() != written_len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } + } + // write tenant name + int64_t new_name_len = 0; + if (OB_SUCC(ret)) { + if (result.has_tenant_username_ && result.has_cluster_username_) { + if (OB_UNLIKELY(tenant_name != result.tenant_name_ || cluster_name != result.cluster_name_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("name not match", K(result), K(tenant_name), K(cluster_name), K(ret)); + } + } else if (result.has_tenant_username_ && !result.has_cluster_username_) { + if (OB_UNLIKELY(tenant_name != result.tenant_name_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("name not match", K(result), K(tenant_name), K(ret)); + } + } else if (!result.has_tenant_username_ && !result.has_cluster_username_) { + // do nothing + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("should not come here", K(result), K(ret)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(write_buffer->write("@", 1, written_len))) { + LOG_WARN("fail to write @", K(ret)); + } else if (1 != written_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } else if (OB_FAIL(write_buffer->write(tenant_name.ptr(), tenant_name.length(), written_len))) { + LOG_WARN("fail to write tenant_name", K(ret)); + } else if (tenant_name.length() != written_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } else { + new_name_len = tenant_name.length() + result.user_name_.length() + 1; + } + } + LOG_DEBUG("change user name", K(result), K(tenant_name)); + } + // Write the rest of the message + if (OB_SUCC(ret)) { + if (OB_FAIL(write_buffer->write("\0", 1, written_len))) { + LOG_WARN("fail to write string null", K(ret)); + } else if (1 != written_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } else if (OB_FAIL(write_buffer->write(buf + name_len + 1, len - MYSQL_NET_META_LENGTH - name_len - 1, written_len))) { + LOG_WARN("fail to write left buffer", K(ret)); + } else if (written_len != len - MYSQL_NET_META_LENGTH - name_len - 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } else if (get_client_session_protocol() == ObProxyProtocol::PROTOCOL_OB20) { + char crc_buf[4]; + memset(crc_buf, 0, sizeof(crc_buf)); + if (OB_FAIL(write_buffer->write(crc_buf, 4, written_len))) { + LOG_WARN("fail to write crc_buf", K(ret)); + } else if (4 != written_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } + } + } + // Re-modify the message length + if (OB_SUCC(ret)) { + uint32_t new_len = static_cast(len - MYSQL_NET_HEADER_LENGTH + new_name_len - name_len); + client_buffer_reader_->replace(reinterpret_cast(&new_len), 3, 0); + ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; + client_request.get_packet_meta().pkt_len_ = new_len + MYSQL_NET_HEADER_LENGTH; + if (OB_FAIL(client_request.add_request(client_buffer_reader_, trans_state_.mysql_config_params_->request_buffer_length_))) { + LOG_WARN("fail to add com request", K(ret)); + } + } + } + } + } + return ret; +} + int ObMysqlSM::analyze_login_request(ObRequestAnalyzeCtx &ctx, ObMysqlAnalyzeStatus &status) { int ret = OB_SUCCESS; @@ -2116,7 +2319,7 @@ int ObMysqlSM::analyze_login_request(ObRequestAnalyzeCtx &ctx, ObMysqlAnalyzeSta ObUnixNetVConnection* unix_vc = static_cast(client_session_->get_netvc()); if (NULL == unix_vc) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("client unix vc is null", K(ret)); + LOG_WARN("client entry vc is null", K(ret)); } else if (!client_session_->is_proxy_mysql_client_ && hsr.response_.is_ssl_request() && !unix_vc->ssl_connected()) { if (OB_FAIL(unix_vc->ssl_init(ObUnixNetVConnection::SSL_SERVER, client_session_->get_vip_cluster_name(), @@ -2204,11 +2407,7 @@ int ObMysqlSM::analyze_login_request(ObRequestAnalyzeCtx &ctx, ObMysqlAnalyzeSta if (!client_session_->is_proxy_mysql_client_) { net::ObIpEndpoint client_addr; - if (client_session_->is_need_convert_vip_to_tname()) { - net::ops_ip_copy(client_addr, client_session_->get_netvc()->get_real_client_addr()); - } else { - net::ops_ip_copy(client_addr, client_session_->get_netvc()->get_remote_addr()); - } + net::ops_ip_copy(client_addr, ops_ip_sa_cast(client_session_->get_real_client_addr().get_sockaddr())); LOG_INFO("client login audit", K(client_addr), K(hsr.cluster_name_), K(hsr.tenant_name_), K(hsr.user_name_), "status", ret == OB_SUCCESS && status != ANALYZE_ERROR ? "success" : "failed"); } @@ -2227,24 +2426,19 @@ int ObMysqlSM::do_analyze_ps_prepare_request(const ObString &ps_sql) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObPsEntry *ps_entry = NULL; + ObGlobalPsEntry *global_ps_entry = NULL; ObPsIdEntry *ps_id_entry = NULL; - bool is_new_ps_entry = false; - - ObBasePsEntryCache &ps_entry_cache = self_ethread().get_ps_entry_cache(); - ps_entry_cache.get_ps_entry(ps_sql, ps_entry); - - if (NULL == ps_entry) { - if (OB_FAIL(ObPsEntry::alloc_and_init_ps_entry(ps_sql, client_request.get_parse_result(), ps_entry))) { - LOG_WARN("fail to alloc and init ps entry", K(ret)); - } else if (OB_FAIL(ps_entry_cache.set_ps_entry(ps_entry))) { - LOG_WARN("fail to add ps entry to cache", K(ret)); - if (OB_LIKELY(NULL != ps_entry)) { - ps_entry->destroy(); - ps_entry = NULL; - } + if (get_global_proxy_config().enable_global_ps_cache) { + ObBasePsEntryGlobalCache& ps_entry_global_cache = get_global_ps_entry_cache(); + if (OB_FAIL(ps_entry_global_cache.acquire_or_create_ps_entry(ps_sql, client_request.get_parse_result(), global_ps_entry))) { + LOG_WARN("create ps entry failed", K(ps_sql), K(ret)); } else { - ps_entry->inc_ref(); - is_new_ps_entry = true; + ps_entry = global_ps_entry; + } + } else { + ObBasePsEntryThreadCache &ps_entry_thread_cache = self_ethread().get_ps_entry_cache(); + if (OB_FAIL(ps_entry_thread_cache.acquire_or_create_ps_entry(ps_sql, client_request.get_parse_result(), ps_entry))) { + LOG_WARN("create ps entry failed", K(ps_sql), K(ret)); } } @@ -2254,21 +2448,20 @@ int ObMysqlSM::do_analyze_ps_prepare_request(const ObString &ps_sql) LOG_WARN("fail to alloc ps id entry", K(ret)); } else if (OB_FAIL(session_info.add_ps_id_entry(ps_id_entry))) { LOG_WARN("fail to add ps id entry", KPC(ps_entry), K(ret)); - if (OB_LIKELY(NULL != ps_id_entry)) { - ps_id_entry->destroy(); - ps_id_entry = NULL; - } } else { // set current ps info session_info.set_ps_entry(ps_id_entry->ps_entry_); session_info.set_client_ps_id(ps_id_entry->ps_id_); session_info.set_ps_id_entry(ps_id_entry); } - } - - if (is_new_ps_entry) { - ps_entry->dec_ref(); - ps_entry = NULL; + if (OB_FAIL(ret)) { + if (OB_LIKELY(NULL != ps_id_entry)) { + ps_id_entry->destroy(); + ps_id_entry = NULL; + } else if (OB_LIKELY(NULL == ps_id_entry && NULL != ps_entry)) { + ps_entry->dec_ref(); + } + } } return ret; } @@ -2567,7 +2760,7 @@ int ObMysqlSM::analyze_text_ps_prepare_request(const ObRequestAnalyzeCtx &ctx) } int ObMysqlSM::do_parse_text_ps_prepare_sql(char*& text_ps_prepare_buf, - int64_t& text_ps_prepare_buf_len, + int64_t& text_ps_prepare_buf_len, ObString& text_ps_sql, const ObRequestAnalyzeCtx& ctx) { int ret = OB_SUCCESS; @@ -2579,8 +2772,8 @@ int ObMysqlSM::do_parse_text_ps_prepare_sql(char*& text_ps_prepare_buf, // This prepare statement needs to be parsed once ObProxyTextPsInfo prepare_info = client_request.get_parse_result().text_ps_info_; if (1 == prepare_info.param_count_) { - ObProxyTextPsParam ¶m = prepare_info.params_.at(0); - ObString user_name = param.str_value_.string_; + ObProxyTextPsParam* param = prepare_info.params_.at(0); + ObString user_name = param->str_value_.config_string_; ObObj user_value; if (OB_FAIL(cs_info.get_user_variable_value(user_name, user_value))) { LOG_WARN("get user variable failed", K(ret), K(user_name)); @@ -2635,7 +2828,7 @@ int ObMysqlSM::do_analyze_text_ps_prepare_request(const ObString& text_ps_sql) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObTextPsEntry *text_ps_entry = NULL; - bool is_new_text_ps_entry = false; + ObGlobalTextPsEntry *global_text_ps_entry = NULL; ObString text_ps_name = client_request.get_parse_result().get_text_ps_name(); ObTextPsNameEntry *text_ps_name_entry = session_info.get_text_ps_name_entry(text_ps_name); LOG_DEBUG("prepare text ps name", K(client_request.get_parse_result().get_text_ps_name())); @@ -2661,21 +2854,17 @@ int ObMysqlSM::do_analyze_text_ps_prepare_request(const ObString& text_ps_sql) } } - ObBasePsEntryCache& text_ps_entry_cache = self_ethread().get_text_ps_entry_cache(); - text_ps_entry_cache.get_text_ps_entry(text_ps_sql, text_ps_entry); - if (OB_SUCC(ret) && NULL == text_ps_entry) { - if (OB_FAIL(ObTextPsEntry::alloc_and_init_text_ps_entry( - text_ps_sql, client_request.get_parse_result(), text_ps_entry))) { - LOG_WARN("fail to alloc and init text ps entry", K(ret)); - } else if (OB_FAIL(text_ps_entry_cache.set_text_ps_entry(text_ps_entry))) { - LOG_WARN("fail to add text ps entry to cache", K(ret)); - if (OB_LIKELY(NULL != text_ps_entry)) { - text_ps_entry->destroy(); - text_ps_entry = NULL; - } + if (get_global_proxy_config().enable_global_ps_cache) { + ObBasePsEntryGlobalCache& text_ps_entry_global_cache = get_global_text_ps_entry_cache(); + if (OB_FAIL(text_ps_entry_global_cache.acquire_or_create_ps_entry(text_ps_sql, client_request.get_parse_result(), global_text_ps_entry))) { + LOG_WARN("create text ps entry failed", K(text_ps_sql), K(ret)); } else { - text_ps_entry->inc_ref(); - is_new_text_ps_entry = true; + text_ps_entry = global_text_ps_entry; + } + } else { + ObBasePsEntryThreadCache &text_ps_entry_thread_cache = self_ethread().get_text_ps_entry_cache(); + if (OB_FAIL(text_ps_entry_thread_cache.acquire_or_create_ps_entry(text_ps_sql, client_request.get_parse_result(), text_ps_entry))) { + LOG_WARN("create text ps entry failed", K(text_ps_sql), K(ret)); } } @@ -2685,25 +2874,21 @@ int ObMysqlSM::do_analyze_text_ps_prepare_request(const ObString& text_ps_sql) LOG_WARN("fail to alloc text ps name entry", K(ret)); } else if (OB_FAIL(session_info.add_text_ps_name_entry(text_ps_name_entry))) { LOG_WARN("fail to add text ps name entry", KPC(text_ps_name_entry), K(ret)); + } else { + text_ps_name_entry->version_ = client_session_->inc_and_get_ps_id(); + session_info.set_client_ps_id(text_ps_name_entry->version_); + session_info.set_text_ps_name_entry(text_ps_name_entry); + LOG_DEBUG("session info add text ps name", K(client_request.get_parse_result().get_text_ps_name())); + } + if (OB_FAIL(ret)) { if (OB_LIKELY(NULL != text_ps_name_entry)) { text_ps_name_entry->destroy(); text_ps_name_entry = NULL; + } else if (OB_LIKELY(NULL == text_ps_name_entry && NULL != text_ps_entry)) { + text_ps_entry->destroy(); } - } else { - text_ps_name_entry->version_ = client_session_->inc_and_get_ps_id(); } } - - if (OB_SUCC(ret)) { - session_info.set_client_ps_id(text_ps_name_entry->version_); - session_info.set_text_ps_name_entry(text_ps_name_entry); - LOG_DEBUG("session info add text ps name", K(client_request.get_parse_result().get_text_ps_name())); - } - - if (is_new_text_ps_entry) { - text_ps_entry->dec_ref(); - text_ps_entry = NULL; - } return ret; } @@ -2854,6 +3039,7 @@ int ObMysqlSM::state_watch_for_client_abort(int event, void *data) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: if (tunnel_.is_tunnel_active()) { // Check to see if the client is part of the tunnel. // If so forward the event to the tunnel. Otherwise, @@ -2883,6 +3069,16 @@ int ObMysqlSM::state_watch_for_client_abort(int event, void *data) milestones_.client_.client_end_ = get_based_hrtime(); set_client_abort(ObMysqlTransact::ABORTED, event); update_congestion_entry(event); + if (OB_MYSQL_COM_QUIT != trans_state_.trans_info_.client_request_.get_packet_meta().cmd_) { + if (NULL != trans_state_.congestion_entry_) { + trans_state_.congestion_entry_->set_client_feedback_failed_at(event::get_hrtime()); + if (trans_state_.congestion_entry_->client_feedback_congested_) { + if (NULL != sm_cluster_resource_) { + sm_cluster_resource_->alive_addr_set_.set_refactored(trans_state_.congestion_entry_->server_ip_); + } + } + } + } terminate_sm_ = true; break; @@ -3143,7 +3339,6 @@ int ObMysqlSM::state_observer_open(int event, void *data) trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_HANDSHAKE; } LOG_DEBUG("succ to establish server sesssion", K_(sm_id)); - handle_observer_open(); } } @@ -3228,6 +3423,7 @@ int ObMysqlSM::state_server_response_read(int event, void *data) // fall through case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("ObMysqlSM::state_server_response_read", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id)); // Error handling function @@ -3279,8 +3475,7 @@ int ObMysqlSM::state_server_response_read(int event, void *data) } bool need_receive_completed = false; - if (OB_UNLIKELY((NULL != client_session_ && client_session_->is_proxy_mysql_client_) - || ObMysqlTransact::SERVER_SEND_REQUEST != trans_state_.current_.send_action_)) { + if (ObMysqlTransact::SERVER_SEND_REQUEST != trans_state_.current_.send_action_) { need_receive_completed = true; } @@ -3441,7 +3636,8 @@ ObProxyProtocol ObMysqlSM::get_server_session_protocol() const if (NULL == server_session_ || (!server_session_->is_checksum_supported() && !server_session_->is_ob_protocol_v2_supported()) || ObMysqlTransact::SERVER_SEND_SAVED_LOGIN == trans_state_.current_.send_action_ || ObMysqlTransact::SERVER_SEND_LOGIN == trans_state_.current_.send_action_ - || ObMysqlTransact::SERVER_SEND_HANDSHAKE == trans_state_.current_.send_action_) { + || ObMysqlTransact::SERVER_SEND_HANDSHAKE == trans_state_.current_.send_action_ + || ObMysqlTransact::is_binlog_request(trans_state_)) { return ObProxyProtocol::PROTOCOL_NORMAL; } else if (server_session_->is_ob_protocol_v2_supported()) { return ObProxyProtocol::PROTOCOL_OB20; @@ -3613,7 +3809,9 @@ inline int ObMysqlSM::handle_first_compress_response_packet(ObMysqlAnalyzeStatus if (server_buffer_reader_->is_read_avail_more_than(MYSQL_COMPRESSED_HEALDER_LENGTH)) { ObMysqlCompressAnalyzer::AnalyzeMode mode; - if (!need_receive_completed || ObMysqlTransact::SERVER_SEND_REQUEST != trans_state_.current_.send_action_) { + if (ObMysqlTransact::SERVER_SEND_XA_START == trans_state_.current_.send_action_) { + mode = ObMysqlCompressAnalyzer::DECOMPRESS_MODE; + } else if (!need_receive_completed || ObMysqlTransact::SERVER_SEND_REQUEST != trans_state_.current_.send_action_) { mode = ObMysqlCompressAnalyzer::SIMPLE_MODE; } else { mode = ObMysqlCompressAnalyzer::DECOMPRESS_MODE; @@ -3838,6 +4036,7 @@ inline int ObMysqlSM::handle_first_normal_response_packet(ObMysqlAnalyzeStatus & bool is_autocommit_0 = false; if (OB_FAIL(client_session_->get_session_info().field_mgr_.get_common_sys_variable_value("autocommit", obj))) { LOG_DEBUG("fail to get autocommit val", K(ret)); + ret = OB_SUCCESS; } else if (obj.get_int() == 0) { LOG_DEBUG("autocommit is 0"); is_autocommit_0 = true; @@ -3845,7 +4044,8 @@ inline int ObMysqlSM::handle_first_normal_response_packet(ObMysqlAnalyzeStatus & if (OB_LIKELY(server_buffer_reader_->is_read_avail_more_than(MYSQL_NET_META_LENGTH))) { if (OB_UNLIKELY(!client_session_->get_session_info().is_oceanbase_server() - || trans_state_.mysql_config_params_->is_mysql_routing_mode())) { + || trans_state_.mysql_config_params_->is_mysql_routing_mode() + || ObMysqlTransact::is_binlog_request(trans_state_))) { LOG_DEBUG("handle_first_normal_response_packet", K(trans_state_.current_.state_), K(is_in_trans_), K(is_autocommit_0)); analyzer_.set_server_cmd(trans_state_.trans_info_.sql_cmd_, STANDARD_MYSQL_PROTOCOL_MODE, @@ -4016,18 +4216,11 @@ void ObMysqlSM::analyze_status_after_analyze_mysql_in_ob20_payload(ObMysqlAnalyz ObClientSessionInfo &client_session_info) { int64_t mysql_packet_len = trans_state_.trans_info_.client_request_.get_packet_len(); + int ret = OB_SUCCESS; if (OB_LIKELY(status == ANALYZE_DONE)) { - int ret = OB_SUCCESS; if (OB_UNLIKELY(mysql_packet_len == MYSQL_PACKET_MAX_LENGTH)) { status = ANALYZE_NOT_SUPPORT; LOG_WARN("do not support full mysql packet in ob2.0 payload now", K(status)); - } else if (OB_FAIL(analyze_ob20_remain_after_analyze_mysql_request_done(client_session_info))) { - if (ret == OB_NOT_SUPPORTED) { - status = ANALYZE_NOT_SUPPORT; - } else { - status = ANALYZE_ERROR; - LOG_WARN("fail to analyze ob20 remain after mysql req done", K(ret), K(status)); - } } } else if (OB_UNLIKELY(status == ANALYZE_CONT)) { status = ANALYZE_NOT_SUPPORT; @@ -4037,6 +4230,17 @@ void ObMysqlSM::analyze_status_after_analyze_mysql_in_ob20_payload(ObMysqlAnalyz } else { LOG_WARN("unexpected status after analyze mysql in ob20 payload", K(status)); } + + if (OB_FAIL(analyze_ob20_remain_after_analyze_mysql_request_done(client_session_info))) { + if (OB_LIKELY(status == ANALYZE_DONE)) { + if (ret == OB_NOT_SUPPORTED) { + status = ANALYZE_NOT_SUPPORT; + } else { + status = ANALYZE_ERROR; + LOG_WARN("fail to analyze ob20 remain after mysql req done", K(ret), K(status)); + } + } + } } int ObMysqlSM::analyze_ob20_remain_after_analyze_mysql_request_done(ObClientSessionInfo &client_session_info) @@ -4047,6 +4251,7 @@ int ObMysqlSM::analyze_ob20_remain_after_analyze_mysql_request_done(ObClientSess int64_t remain_payload_len = client_session_info.ob20_request_.remain_payload_len_; if (remain_payload_len < mysql_packet_len) { ret = OB_NOT_SUPPORTED; + client_session_info.ob20_request_.remain_payload_len_ = 0; LOG_WARN("unexpected situation after received total compress packet and total mysql packet", K(ret), K(remain_payload_len), K(mysql_packet_len)); } else { @@ -4340,6 +4545,7 @@ int ObMysqlSM::state_server_request_send(int event, void *data) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("ObMysqlSM::state_server_request_send", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id)); // if something unusual happened in sending request, also need to get request write time @@ -4885,9 +5091,10 @@ int ObMysqlSM::tunnel_handler_response_transfered(int event, void *data) ret = OB_INNER_STAT_ERROR; LOG_WARN("client_entry or server entry is null, disconnect", K_(client_entry), K(ret)); } else { - // only the first request in one transaction will need to update pl, + // only the first request in one transaction or internal routing transaction will need to update pl, // begin(start transaction), or set autocommit = 0 is not the first request; - if (trans_state_.is_trans_first_request_) { + if ((trans_state_.is_trans_first_request_ || client_session_->is_trans_internal_routing()) + && !ObMysqlTransact::is_binlog_request(trans_state_)) { ObMysqlTransact::handle_pl_update(trans_state_); } @@ -4967,6 +5174,7 @@ int ObMysqlSM::tunnel_handler_server(int event, ObMysqlTunnelProducer &p) switch (event) { case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: case VC_EVENT_ERROR: // fall through case VC_EVENT_EOS: @@ -4978,6 +5186,7 @@ int ObMysqlSM::tunnel_handler_server(int event, ObMysqlTunnelProducer &p) trans_state_.current_.state_ = ObMysqlTransact::ACTIVE_TIMEOUT; break; case VC_EVENT_ERROR: + case VC_EVENT_DETECT_SERVER_DEAD: trans_state_.current_.state_ = ObMysqlTransact::CONNECTION_ERROR; break; case VC_EVENT_EOS: @@ -5165,7 +5374,8 @@ void ObMysqlSM::print_mysql_complete_log(ObMysqlTunnelProducer *p) bool print_warn_log = false; bool print_info_log = false; if (OB_LIKELY(NULL != client_session_)) { - if (OB_UNLIKELY(result.is_error_resp() && client_session_->is_proxy_mysql_client_)) { + if (OB_UNLIKELY(result.is_error_resp() && client_session_->is_proxy_mysql_client_ + && client_session_->get_session_info().get_priv_info().user_name_ != ObProxyTableInfo::DETECT_USERNAME_USER)) { if (result.is_not_supported_error()) { print_info_log = true; } else { @@ -5269,8 +5479,7 @@ void ObMysqlSM::update_safe_read_snapshot() ObSafeSnapshotEntry *entry = NULL; bool is_need_force_sync = true; ObAddr last_addr; - last_addr.set_ipv4_addr(trans_state_.server_info_.addr_.get_ip4_host_order(), - static_cast(trans_state_.server_info_.addr_.get_port_host_order())); + last_addr.set_sockaddr(trans_state_.server_info_.addr_.sa_); if (result.is_partition_hit()) { entry = sm_cluster_resource_->safe_snapshot_mgr_.get(last_addr); @@ -5384,7 +5593,7 @@ int ObMysqlSM::trim_ok_packet(ObIOBufferReader &reader) if (OK_PACKET_ACTION_CONSUME == analyze_result.get_ok_packet_action_type()) { if (OB_FAIL(ObProxySessionInfoHandler::analyze_extra_ok_packet( reader, client_session->get_session_info(), - server_session->get_session_info(), need_handle_sysvar, analyze_result))) { + server_session->get_session_info(), need_handle_sysvar, analyze_result, trans_state_.trace_log_))) { LOG_WARN("fail to analyze extra ok packet", K_(sm_id), K(ret)); } } else if (OK_PACKET_ACTION_REWRITE == analyze_result.get_ok_packet_action_type()) { @@ -5399,6 +5608,7 @@ int ObMysqlSM::trim_ok_packet(ObIOBufferReader &reader) trans_state_.is_auth_request_, need_handle_sysvar, analyze_result, + trans_state_.trace_log_, is_save_to_common_sys))) { LOG_WARN("fail to analyze rewrite ok packet", K_(sm_id), K(ret)); } @@ -5417,10 +5627,14 @@ int ObMysqlSM::trim_ok_packet(ObIOBufferReader &reader) // handle other variables if (OB_SUCC(ret)) { + bool is_only_sync_trans_sess = trans_state_.trans_info_.server_response_.get_analyze_result().is_error_resp(); if (OB_FAIL(handle_saved_session_variables())) { LOG_WARN("fail to handle saved session varialbes", K(ret)); - } else if (OB_FAIL(ObProxySessionInfoHandler::save_changed_sess_info( - client_session->get_session_info(), server_session->get_session_info(), analyze_result.get_extra_info()))) { + } else if (OB_FAIL(ObProxySessionInfoHandler::save_changed_sess_info(client_session->get_session_info(), + server_session->get_session_info(), + analyze_result.get_extra_info(), + trans_state_.trace_log_, + is_only_sync_trans_sess))) { LOG_WARN("fail to save changed session info", K(ret)); } } @@ -5459,8 +5673,17 @@ int ObMysqlSM::tunnel_handler_client(int event, ObMysqlTunnelConsumer &c) case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_ERROR: - LOG_WARN("ObMysqlSM::tunnel_handler_client", "event", - ObMysqlDebugNames::get_event_name(event), K_(sm_id)); + case VC_EVENT_DETECT_SERVER_DEAD: { + // Probe user does not print disconnection log + bool is_detect_user = false; + if (NULL != client_session_ && client_session_->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER) { + is_detect_user = true; + } + + if (!is_detect_user) { + LOG_WARN("ObMysqlSM::tunnel_handler_client", "event", + ObMysqlDebugNames::get_event_name(event), K_(sm_id)); + } // The client died or aborted. Check to see // if we should setup a background fill set_client_abort(ObMysqlTransact::ABORTED, event); @@ -5482,7 +5705,7 @@ int ObMysqlSM::tunnel_handler_client(int event, ObMysqlTunnelConsumer &c) // session and client session close_connection = true; break; - + } case VC_EVENT_WRITE_COMPLETE: { c.write_success_ = true; trans_state_.client_info_.abort_ = ObMysqlTransact::DIDNOT_ABORT; @@ -5557,6 +5780,7 @@ int ObMysqlSM::tunnel_handler_request_transfer_client(int event, ObMysqlTunnelPr case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("ObMysqlSM::tunnel_handler_request_transfer_client", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id)); // Did not complete request transfer tunneling. Abort the @@ -5644,6 +5868,7 @@ int ObMysqlSM::tunnel_handler_request_transfer_server(int event, ObMysqlTunnelCo case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: { LOG_WARN("ObMysqlSM::tunnel_handler_request_transfer_server", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id)); @@ -5781,17 +6006,21 @@ void ObMysqlSM::do_congestion_control_lookup() // 2. cur congestion is avail(base servers has been added) // 3. need pl lookup // 4. not mysql route mode - // + // 5. need use coordinator session in transaction (included in 'need pl lookup') // Attention! when force_retry_congested_, also need do congestion lookup if (OB_UNLIKELY(enable_congestion && sm_cluster_resource_->is_congestion_avail() - && trans_state_.need_pl_lookup_ + && trans_state_.is_need_pl_lookup() && !trans_state_.mysql_config_params_->is_mysql_routing_mode() && !trans_state_.mysql_config_params_->is_mock_routing_mode())) { trans_state_.need_congestion_lookup_ = true; + LOG_DEBUG("need to do congestion lookup", + K(trans_state_.is_need_pl_lookup()), + K(trans_state_.pl_lookup_state_)); } else { LOG_DEBUG("no need do congestion lookup", K_(sm_id), K(enable_congestion), - K(sm_cluster_resource_->is_congestion_avail()), "need_pl_lookup", trans_state_.need_pl_lookup_, + K(sm_cluster_resource_->is_congestion_avail()), + "pl_lookup_state", ObMysqlTransact::get_pl_lookup_state_string(trans_state_.pl_lookup_state_), "force_retry_congestion", trans_state_.force_retry_congested_, "route_mode", trans_state_.mysql_config_params_->server_routing_mode_); trans_state_.need_congestion_lookup_ = false; @@ -5990,6 +6219,75 @@ void ObMysqlSM::do_partition_location_lookup() } } +void ObMysqlSM::do_binlog_location_lookup() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { + milestones_.bl_lookup_begin_ = get_based_hrtime(); + milestones_.bl_lookup_end_ = 0; + } + + LOG_DEBUG("do binlog location lookup"); + MYSQL_SM_SET_DEFAULT_HANDLER(&ObMysqlSM::state_binlog_location_lookup); + if (OB_UNLIKELY(NULL != pending_action_)) { + trans_state_.pll_info_.lookup_success_ = false; + LOG_ERROR("do_binlog_location_lookup, pending_action_ should be NULL", + K_(pending_action), K_(sm_id)); + call_transact_and_set_next_state(NULL); + } else if (trans_state_.server_info_.addr_.is_valid()) { + trans_state_.pll_info_.lookup_success_ = true; + call_transact_and_set_next_state(NULL); + } else { + const ObTableEntryName &name = trans_state_.pll_info_.te_name_; + ObAction *bl_lookup_action_handle = NULL; + bool find_entry = false; + // Obtained from the cache, no longer retrieved from the remote end + ObTableRefHashMap &table_map = self_ethread().get_table_map(); + ObTableEntry *tmp_entry = NULL; + ObTableEntryKey key(name, 0, 0); + tmp_entry = table_map.get(key); + if (OB_LIKELY(NULL != tmp_entry)) { + tmp_entry->renew_last_access_time(); + ObMysqlRouteResult result; + result.table_entry_ = tmp_entry; + result.is_table_entry_from_remote_ = false; + tmp_entry->set_need_force_flush(false); + find_entry = true; + LOG_DEBUG("ObMysqlRoute get table entry succ", KPC(tmp_entry)); + state_binlog_location_lookup(TABLE_ENTRY_EVENT_LOOKUP_DONE, &result); + } + + if (OB_UNLIKELY(!find_entry)) { + ObRouteParam param; + param.cont_ = this; + param.need_pl_route_ = false; + param.force_renew_ = trans_state_.pll_info_.is_force_renew(); + param.is_need_force_flush_ = trans_state_.pll_info_.is_need_force_flush(); + param.mysql_proxy_ = &sm_cluster_resource_->mysql_proxy_; + param.timeout_us_ = hrtime_to_usec(trans_state_.mysql_config_params_->short_async_task_timeout_); + param.name_.shallow_copy(name); + param.cr_version_ = 0; + param.cr_id_ = 0; + + LOG_DEBUG("Doing binlog location lookup", K_(sm_id), K(param)); + bl_lookup_action_handle = NULL; + ret = ObMysqlRoute::get_route_entry(param, sm_cluster_resource_, bl_lookup_action_handle); + } + + if (OB_SUCC(ret)) { + if (NULL == bl_lookup_action_handle) { + // do nothing + } else { + pending_action_ = bl_lookup_action_handle; + } + } else { + trans_state_.pll_info_.lookup_success_ = false; + LOG_WARN("fail to get binlog table entry", K_(sm_id), K(name), K(ret)); + call_transact_and_set_next_state(NULL); + } + } +} + void ObMysqlSM::do_server_addr_lookup() { ObProxyKillQueryInfo *query_info = trans_state_.trans_info_.client_request_.query_info_; @@ -5998,7 +6296,7 @@ void ObMysqlSM::do_server_addr_lookup() // call ObMysqlTransact::handle_server_addr_lookup() to handle fail / success call_transact_and_set_next_state(NULL); - } else if (!trans_state_.need_pl_lookup_) { + } else if (!trans_state_.is_need_pl_lookup()) { // need use last server session query_info->errcode_ = OB_NOT_SUPPORTED; LOG_WARN("[ObMysqlSM::do_server_addr_lookup] As we need use last server session, " @@ -6028,7 +6326,7 @@ void ObMysqlSM::do_server_addr_lookup() // call ObMysqlTransact::handle_server_addr_lookup() to handle fail / success call_transact_and_set_next_state(NULL); } - }//end of trans_state_.need_pl_lookup_ + }//end of is_need_pl_lookup } int ObMysqlSM::state_congestion_control_lookup(int event, void *data) @@ -6059,7 +6357,9 @@ void ObMysqlSM::set_detect_server_info(net::ObIpEndpoint target_addr, int cnt, i if (OB_LIKELY(target_addr.is_valid() && NULL != sm_cluster_resource_ && NULL != client_session_ - && !client_session_->is_proxy_mysql_client_)) { + && !client_session_->is_proxy_mysql_client_ + //Optimize the performance in closed scenes, 1 means accurate detection + && (1 == get_global_proxy_config().server_detect_mode || add_detect_server_cnt_))) { bool found = false; common::DRWLock &server_state_lock1 = sm_cluster_resource_->get_server_state_lock(0); common::DRWLock &server_state_lock2 = sm_cluster_resource_->get_server_state_lock(1); @@ -6069,8 +6369,7 @@ void ObMysqlSM::set_detect_server_info(net::ObIpEndpoint target_addr, int cnt, i sm_cluster_resource_->get_server_state_info(sm_cluster_resource_->server_state_version_); for (int i = 0; !found && i < server_state_info.count(); i++) { ObServerStateSimpleInfo &info = server_state_info.at(i); - ObIpEndpoint addr; - ops_ip_copy(addr.sa_, info.addr_.ip_.v4_, static_cast(info.addr_.port_)); + ObIpEndpoint addr(info.addr_.get_sockaddr()); if (addr == target_addr) { // add_detect_server_cnt_ prevents do_observer_open from failing before, and subtracts 1 from cnt if (cnt > 0 && 1 == get_global_proxy_config().server_detect_mode) { @@ -6131,7 +6430,7 @@ int ObMysqlSM::do_observer_open() if (OB_UNLIKELY(trans_state_.is_rerouted_)) { release_server_session(); } - + if (add_detect_server_cnt_) { set_detect_server_info(trans_state_.pre_server_info_.addr_, -1, 0); } @@ -6322,23 +6621,41 @@ inline int ObMysqlSM::do_oceanbase_internal_observer_open(ObMysqlServerSession * last_session = client_session_->get_server_session(); // if need_pl_lookup is false, we must use last server session - // allow no last server session when OB_MYSQL_COM_STMT_CLOSE/OB_MYSQL_COM_STMT_FETCH and need_pl_lookup_ = false + // allow no last server session when OB_MYSQL_COM_STMT_CLOSE/OB_MYSQL_COM_STMT_FETCH and NEED_PL_LOOKUP obmysql::ObMySQLCmd cmd = trans_state_.trans_info_.sql_cmd_; - if (!trans_state_.need_pl_lookup_ + bool is_text_ps_close = trans_state_.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt(); + if (!trans_state_.is_need_pl_lookup() && ((OB_MYSQL_COM_STMT_CLOSE != cmd && OB_MYSQL_COM_STMT_FETCH != cmd - && OB_MYSQL_COM_STMT_RESET != cmd) + && OB_MYSQL_COM_STMT_RESET != cmd + && OB_MYSQL_COM_STMT_GET_PIECE_DATA != cmd + && !is_text_ps_close) || !client_session_->is_need_return_last_bound_ss())) { - if (OB_ISNULL(last_session)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("last server session is NULL, disconnect", K_(sm_id), K(ret)); - } else if (OB_UNLIKELY(last_session->server_ip_ != trans_state_.server_info_.addr_)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("last server session ip is unexpected", - K_(last_session->server_ip), K_(trans_state_.server_info_.addr), K_(sm_id), K(ret)); - } else { + ObMysqlServerSession *target_session = NULL; + if (trans_state_.pl_lookup_state_ == ObMysqlTransact::USE_COORDINATOR_SESSION) { + if (OB_FAIL(client_session_->acquire_svr_session(trans_state_.server_info_.addr_.sa_, false, target_session))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("acquire coordinator session fail, disconnect", K_(sm_id), K(ret)); + } + LOG_DEBUG("use coordinator server session", K_(sm_id)); + } else if (trans_state_.pl_lookup_state_ == ObMysqlTransact::USE_LAST_SERVER_SESSION){ + target_session = last_session; LOG_DEBUG("use last server session", K_(sm_id)); - selected_session = last_session; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected pl lookup state", K(trans_state_.pl_lookup_state_)); + } + if (OB_SUCC(ret)) { + if (OB_ISNULL(target_session)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("target server session is NULL, disconnect", K_(sm_id), K(ret)); + } else if (OB_UNLIKELY(target_session->server_ip_ != trans_state_.server_info_.addr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("target session ip is unexpected", + K_(target_session->server_ip), K_(trans_state_.server_info_.addr), K_(sm_id), K(ret)); + } else { + selected_session = target_session; + } } } else { LOG_DEBUG("sql cmd", K(cmd), K(client_session_->is_session_pool_client())); @@ -6426,6 +6743,7 @@ inline int ObMysqlSM::do_internal_observer_open() int ret = OB_SUCCESS; ObMysqlServerSession *selected_session = NULL; ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; + bool is_in_trans = ObMysqlTransact::is_in_trans(trans_state_); if (OB_LIKELY(client_session_->get_session_info().is_oceanbase_server())) { if (OB_FAIL(do_oceanbase_internal_observer_open(selected_session))) { @@ -6478,20 +6796,36 @@ inline int ObMysqlSM::do_internal_observer_open() "client_session version", client_info.get_session_version(), "server version", server_info.get_session_var_version(), "cmd", cmd); + + trans_state_.trace_log_.log_it("[get_conn]", + "time", get_based_hrtime(), + "lookup", trans_state_.pl_lookup_state_, + "sql_cmd", trans_state_.trans_info_.sql_cmd_, + "stmt_type", trans_state_.trans_info_.client_request_.get_parse_result().get_stmt_type(), + "in_trans", is_in_trans, + "internal_route", get_client_session()->is_trans_internal_routing() && is_in_trans, + "svr", server_session_->server_ip_, + "sessid", server_session_->get_server_sessid()); + if (OB_UNLIKELY(OB_MYSQL_COM_STMT_CLOSE == cmd - || OB_MYSQL_COM_STMT_RESET == cmd)) { + || OB_MYSQL_COM_STMT_RESET == cmd + || ObMysqlTransact::is_binlog_request(trans_state_) + || client_session_->can_direct_send_request_)) { // no need sync var on OB_MYSQL_COM_STMT_CLOSE trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_REQUEST; } else if (OB_UNLIKELY(client_info.need_reset_database(server_info))) { trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_USE_DATABASE; - } else if (OB_UNLIKELY(client_info.need_reset_session_vars(server_info))) { + } else if (OB_UNLIKELY(client_info.is_server_support_session_var_sync() && + client_info.need_reset_user_session_vars(server_info))) { + trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_SESSION_USER_VARS; + } else if (OB_UNLIKELY(!(client_info.is_server_support_session_var_sync()) && + client_info.need_reset_session_vars(server_info))) { trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_SESSION_VARS; - } else if (OB_UNLIKELY(client_info.need_reset_last_insert_id(server_info))) { - // TODO: current version proxy parse can't judge last_insert_id exactly, - // so we do not judge, whether sql_reuslt has_last_insert_id here - trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_LAST_INSERT_ID; } else if (OB_UNLIKELY(trans_state_.is_hold_start_trans_)) { trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_START_TRANS; + } else if (OB_UNLIKELY(trans_state_.is_hold_xa_start_)) { + trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_XA_START; + LOG_DEBUG("[ObMysqlSM::do_internal_observer_open] set send action SERVER_SEND_XA_START to sync xa start"); } else if (OB_UNLIKELY(((OB_MYSQL_COM_STMT_EXECUTE == cmd) || (OB_MYSQL_COM_STMT_SEND_PIECE_DATA == cmd) || (OB_MYSQL_COM_STMT_SEND_LONG_DATA == cmd)) @@ -6507,6 +6841,16 @@ inline int ObMysqlSM::do_internal_observer_open() } else { if (OB_FAIL(connect_observer())) { LOG_WARN("failed to connection observer", K_(sm_id), K(ret)); + } else { + + trans_state_.trace_log_.log_it("[create_conn]", + "time", get_based_hrtime(), + "lookup", trans_state_.pl_lookup_state_, + "sql_cmd", trans_state_.trans_info_.sql_cmd_, + "stmt_type", trans_state_.trans_info_.client_request_.get_parse_result().get_stmt_type(), + "in_trans", is_in_trans, + "internal_route", get_client_session()->is_trans_internal_routing() && is_in_trans, + "svr", trans_state_.server_info_.addr_); } } } @@ -6577,6 +6921,7 @@ int ObMysqlSM::do_internal_request_for_sharding_init_db(ObMIOBuffer *buf) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); + ObProxyProtocol client_procotol = get_client_session_protocol(); // handle use db stmt or OB_MYSQL_COM_INIT_DB cmd when sharding LOG_DEBUG("sharding init db"); @@ -6606,9 +6951,11 @@ int ObMysqlSM::do_internal_request_for_sharding_init_db(ObMIOBuffer *buf) LOG_WARN("fail to save user login info", K_(sm_id), K(ret)); } else { // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); if (OB_FAIL(ObMysqlResponseBuilder::build_ok_resq_with_state_changed(*buf, client_request, *client_session, - is_in_trans))) { + client_procotol, is_in_trans))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build ok res", K_(sm_id), K(ret)); } } @@ -6623,12 +6970,13 @@ int ObMysqlSM::do_internal_request_for_sharding_show_db_version(ObMIOBuffer *buf ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6660,12 +7008,13 @@ int ObMysqlSM::do_internal_request_for_sharding_show_db(ObMIOBuffer *buf) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6688,12 +7037,13 @@ int ObMysqlSM::do_internal_request_for_sharding_show_table(ObMIOBuffer *buf) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6727,7 +7077,7 @@ int ObMysqlSM::do_internal_request_for_sharding_show_table_status(ObMIOBuffer *b ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); @@ -6738,8 +7088,9 @@ int ObMysqlSM::do_internal_request_for_sharding_show_table_status(ObMIOBuffer *b ObString logic_tenant_name; Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6761,28 +7112,29 @@ int ObMysqlSM::do_internal_request_for_sharding_show_table_status(ObMIOBuffer *b return ret; } -int ObMysqlSM::do_internal_request_for_sharding_show_topology(ObMIOBuffer *buf) +int ObMysqlSM::do_internal_request_for_sharding_show_elastic_id(ObMIOBuffer *buf) { int ret = OB_SUCCESS; ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); - // handle show topology when sharding + // handle show elastic id when sharding ObInternalCmdInfo &cmd_info = *client_request.cmd_info_; ObString logic_db_name = cmd_info.get_like_string(); ObString logic_tenant_name; ObString group_name = cmd_info.get_value_string(); - LOG_DEBUG("sharding show topology", K(logic_db_name), K(group_name)); + LOG_DEBUG("sharding show elastic id", K(logic_db_name), K(group_name)); if (logic_db_name.empty()) { if (OB_FAIL(client_info.get_logic_database_name(logic_db_name))) { LOG_WARN("fail to get_logic_db_name", K(ret)); @@ -6790,13 +7142,52 @@ int ObMysqlSM::do_internal_request_for_sharding_show_topology(ObMIOBuffer *buf) } if (OB_FAIL(ret)) { // do nothing - } if (OB_FAIL(client_info.get_logic_tenant_name(logic_tenant_name))) { + } else if (OB_FAIL(client_info.get_logic_tenant_name(logic_tenant_name))) { LOG_WARN("fail to get_logic_tenant_name", K(ret)); - } else if (OB_FAIL(ObShowTopologyHandler::show_topology_cmd_callback(buf, info, logic_tenant_name, - logic_db_name, group_name))) { - LOG_WARN("[ObMysqlSM::do_internal_request] fail to handle show topology", K_(sm_id), K(ret)); + } else if (OB_FAIL(ObShowTopologyHandler::show_elastic_id_cmd_callback(buf, info, + logic_tenant_name, logic_db_name, group_name))) { + LOG_WARN("[ObMysqlSM::do_internal_request] fail to handle show elastic id", K_(sm_id), K(ret)); } + return ret; +} + +int ObMysqlSM::do_internal_request_for_sharding_show_topology(ObMIOBuffer *buf) +{ + int ret = OB_SUCCESS; + + ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; + ObMysqlClientSession *client_session = get_client_session(); + ObClientSessionInfo &client_info = client_session->get_session_info(); + ObProxyProtocol client_protocol = get_client_session_protocol(); + Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; + uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); + Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_proxy_enable_trans_internal_routing()); + ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), + trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); + + // handle show topology when sharding + ObString logic_db_name; + ObString logic_tenant_name; + ObString logic_table_name = client_request.get_parse_result().get_table_name(); + LOG_DEBUG("sharding show topology", K(logic_db_name)); + if (logic_db_name.empty()) { + if (OB_FAIL(client_info.get_logic_database_name(logic_db_name))) { + LOG_WARN("fail to get_logic_db_name", K(ret)); + } + } + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(client_info.get_logic_tenant_name(logic_tenant_name))) { + LOG_WARN("fail to get_logic_tenant_name", K(ret)); + } else if (OB_FAIL(client_info.get_logic_database_name(logic_db_name))) { + } else if (OB_FAIL(ObShowTopologyHandler::show_topology_cmd_callback(buf, info, + logic_tenant_name, logic_db_name, logic_table_name))) { + LOG_WARN("[ObMysqlSM::do_internal_request] fail to handle show topology", K_(sm_id), K(ret)); + } return ret; } @@ -6807,12 +7198,13 @@ int ObMysqlSM::do_internal_request_for_sharding_select_db(ObMIOBuffer *buf) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6850,6 +7242,8 @@ void ObMysqlSM::do_internal_request() K_(sm_id), K(ret)); } else { buf = trans_state_.internal_buffer_; + ObProxyProtocol client_protocol = get_client_session_protocol(); + switch (trans_state_.trans_info_.sql_cmd_) { case OB_MYSQL_COM_HANDSHAKE: { OMPKHandshake handshake; @@ -6885,7 +7279,7 @@ void ObMysqlSM::do_internal_request() } } - if (FAILEDx(ObProxyPacketWriter::write_packet(*buf, *client_session_, handshake))) { + if (FAILEDx(ObProxyPacketWriter::write_packet(*buf, *client_session_, client_protocol, handshake))) { LOG_WARN("fail to build handshake packet", K_(sm_id), K(ret)); } else { ObMySQLCapabilityFlags capability(handshake.get_server_capability()); @@ -6905,7 +7299,8 @@ void ObMysqlSM::do_internal_request() ObMysqlAuthRequest &orig_auth_req = client_session_->get_session_info().get_login_req(); const ObMySQLCapabilityFlags &capability = client_session_->get_session_info().get_orig_capability_flags(); uint8_t pkt_seq = static_cast(orig_auth_req.get_packet_meta().pkt_seq_ + 1); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("fail to write ok packet", K(ret)); } } @@ -6915,7 +7310,8 @@ void ObMysqlSM::do_internal_request() LOG_DEBUG("proxy response OB_MYSQL_COM_PING ok packet", K_(sm_id), "cs_id", client_session_->get_cs_id()); uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_session_->get_session_info().get_orig_capability_flags(); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("fail to encode OB_MYSQL_COM_PING response ok packet", K(ret)); } break; @@ -6946,7 +7342,8 @@ void ObMysqlSM::do_internal_request() uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_info.get_orig_capability_flags(); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build OB_MYSQL_COM_STMT_RESET response ok packet", K_(sm_id), K(client_ps_id), K(ret)); } @@ -6970,17 +7367,28 @@ void ObMysqlSM::do_internal_request() case OB_MYSQL_COM_DELAYED_INSERT: case OB_MYSQL_COM_CHANGE_USER: case OB_MYSQL_COM_SHUTDOWN: + case OB_MYSQL_COM_STMT_PREPARE_EXECUTE: case OB_MYSQL_COM_DAEMON: { ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObClientSessionInfo &client_info = client_session_->get_session_info(); uint8_t next_seq = static_cast(client_request.get_packet_meta().pkt_seq_ + 1); // 1. hold_start_trans if (client_request.get_parse_result().need_hold_start_trans()) { + // hold begin reset hold xa start trans_state_.is_hold_start_trans_ = true; - if (OB_FAIL(ObMysqlResponseBuilder::build_start_trans_resp(*buf, client_request, *client_session_))) { + if (OB_FAIL(ObMysqlResponseBuilder::build_start_trans_resp(*buf, client_request, + *client_session_, client_protocol))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build start trans resp", K_(sm_id), K(ret)); } - + // hold_xa_start + } else if (client_request.get_parse_result().need_hold_xa_start()) { + LOG_DEBUG("[ObMysqlSM::do_internal_request] to build xa start resp"); + // hold xa start reset hold begin + trans_state_.is_hold_xa_start_ = true; + if (OB_FAIL(ObMysqlResponseBuilder::build_prepare_execute_xa_start_resp(*buf, client_request, + *client_session_, client_protocol))) { + LOG_WARN("[ObMysqlSM::do_internal_request] fail to build xa start resp", K_(sm_id), K(ret)); + } // 2. bad_route_request } else if (ObMysqlTransact::is_bad_route_request(trans_state_)) { trans_state_.mysql_errcode_ = OB_NOT_SUPPORTED; @@ -6992,6 +7400,7 @@ void ObMysqlSM::do_internal_request() } else { // throw away the former 'begin' or 'start transaction' trans_state_.is_hold_start_trans_ = false; + trans_state_.is_hold_xa_start_ = false; } // 3. not_supported @@ -7004,32 +7413,21 @@ void ObMysqlSM::do_internal_request() // 4. select_tx_ro } else if (client_request.get_parse_result().is_select_tx_ro()) { // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); if (OB_FAIL(ObMysqlResponseBuilder::build_select_tx_ro_resp(*buf, client_request, *client_session_, - is_in_trans))) { + client_protocol, is_in_trans))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build select @@tx_read_only", K_(sm_id), K(ret)); } - - // 5. set_autocommit_0 - } else if (client_request.get_parse_result().is_set_autocommit_0()) { - // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); - ObObj value; - value.set_int(0); - if (client_info.update_common_sys_variable("autocommit", value, true, false)) { - LOG_WARN("fail to update sys variable", K_(sm_id), K(ret)); - } else if (OB_FAIL(ObMysqlResponseBuilder::build_ok_resq_with_state_changed(*buf, client_request, - *client_session_, is_in_trans))) { - LOG_WARN("[ObMysqlSM::do_internal_request] fail to build set autocommit = 0", K_(sm_id), K(ret)); - } - // 6. ping_proxy } else if (client_request.get_parse_result().is_ping_proxy_cmd() && !client_request.get_parse_result().is_internal_error_cmd()) { if (OB_LIKELY(get_global_hot_upgrade_info().need_conn_accept_)) { uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_session_->get_session_info().get_orig_capability_flags(); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("fail to write ok packet", K(ret)); } } else { @@ -7044,7 +7442,8 @@ void ObMysqlSM::do_internal_request() // python mysql will send 'SET autocommit=0' after connected, proxysys need resp ok packet uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_session_->get_session_info().get_orig_capability_flags(); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("fail to build ok packet", K(ret)); } } else { @@ -7058,15 +7457,14 @@ void ObMysqlSM::do_internal_request() // 8. select route_addr } else if (client_request.get_parse_result().is_select_route_addr()) { ObMysqlServerSession *last_session = client_session_->get_server_session(); - int64_t addr = 0; if (NULL != last_session && NULL != last_session->get_netvc()) { - addr = ObMysqlTransact::build_addr_from_ip_port( - ntohl(last_session->get_netvc()->get_remote_ip()), - last_session->get_netvc()->get_remote_port()); // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); if (OB_FAIL(ObMysqlResponseBuilder::build_select_route_addr_resp(*buf, client_request, - *client_session_, is_in_trans, addr))) { + *client_session_, client_protocol, is_in_trans, + last_session->get_netvc()->get_remote_addr()))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build select @obproxy_route_addr", K_(sm_id), K(ret)); } } else { @@ -7081,9 +7479,11 @@ void ObMysqlSM::do_internal_request() } else if (client_request.get_parse_result().is_set_route_addr()) { client_info.set_obproxy_route_addr(client_request.get_parse_result().cmd_info_.integer_[0]); // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); if (OB_FAIL(ObMysqlResponseBuilder::build_set_route_addr_resp(*buf, client_request, *client_session_, - is_in_trans))) { + client_protocol, is_in_trans))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build set @obproxy_route_addr", K_(sm_id), K(ret)); } else { LOG_DEBUG("@obproxy_route_addr is set", K(client_info.get_obproxy_route_addr())); @@ -7145,6 +7545,11 @@ void ObMysqlSM::do_internal_request() if (OB_FAIL(do_internal_request_for_sharding_show_table_status(buf))) { LOG_WARN("fail to do internal request for sharding show db", K_(sm_id), K(ret)); } + } else if (client_session_->get_session_info().is_sharding_user() + && client_request.get_parse_result().is_show_elastic_id_stmt()) { + if (OB_FAIL(do_internal_request_for_sharding_show_elastic_id(buf))) { + LOG_WARN("fail to do internal request for sharding show db", K_(sm_id), K(ret)); + } } else if (client_session_->get_session_info().is_sharding_user() && client_request.get_parse_result().is_show_topology_stmt()) { if (OB_FAIL(do_internal_request_for_sharding_show_topology(buf))) { @@ -7158,9 +7563,11 @@ void ObMysqlSM::do_internal_request() // 13. select_proxy_version } else if (client_request.get_parse_result().is_select_proxy_version()) { // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); - if (OB_FAIL(ObMysqlResponseBuilder::build_select_proxy_version_resp(*buf, client_request, - *client_session_, is_in_trans))) { + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); + if (OB_FAIL(ObMysqlResponseBuilder::build_select_proxy_version_resp(*buf, client_request, *client_session_, + client_protocol, is_in_trans))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build select proxy_version", K_(sm_id), K(ret)); } // 14. drop prepare stmt @@ -7169,9 +7576,9 @@ void ObMysqlSM::do_internal_request() uint32_t client_ps_id = client_info.get_client_ps_id(); uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_info.get_orig_capability_flags(); - if (OB_FAIL(ObMysqlPacketUtil::encode_ok_packet(*buf, pkt_seq, 0, capability))) { - LOG_WARN("[ObMysqlSM::do_internal_request] fail to encode drop/deallocate prepare stmt response ok packet", - K_(sm_id), K(client_ps_id), K(ret)); + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { + LOG_WARN("fail to write ok packet", K(ret)); } else { client_info.delete_text_ps_name_entry(text_ps_name); client_info.remove_ps_id_addrs(client_ps_id); @@ -7195,9 +7602,10 @@ void ObMysqlSM::do_internal_request() Ob20ProtocolHeader &ob20_head = client_session_->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session_->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session_->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session_->is_client_support_new_extra_info()); - cmd_info.set_protocol(client_session_->get_client_session_protocol()); + compressed_seq, true, false, false, + client_session_->is_client_support_new_extra_info(), + client_session_->is_trans_internal_routing()); + cmd_info.set_protocol(get_client_session_protocol()); cmd_info.set_ob20_head_param(ob20_head_param); ObAction *cmd_handler = NULL; @@ -7270,6 +7678,7 @@ inline void ObMysqlSM::set_client_abort(const ObMysqlTransact::ObAbortStateType break; case VC_EVENT_ERROR: + case VC_EVENT_DETECT_SERVER_DEAD: trans_state_.client_info_.state_ = ObMysqlTransact::CONNECTION_ERROR; xflush_head = XFH_CONNECTION_ERROR; break; @@ -7310,7 +7719,7 @@ inline void ObMysqlSM::set_client_abort(const ObMysqlTransact::ObAbortStateType "request_cmd", get_mysql_cmd_str(trans_state_.trans_info_.client_request_.get_packet_meta().cmd_), "sql_cmd", get_mysql_cmd_str(trans_state_.trans_info_.sql_cmd_), "sql", trans_state_.trans_info_.get_print_sql()); - } else { + } else if (client_session_->get_session_info().get_priv_info().user_name_ != ObProxyTableInfo::DETECT_USERNAME_USER) { LOG_WARN("client will abort soon", K_(sm_id), K(cs_id), @@ -7515,9 +7924,10 @@ void ObMysqlSM::handle_observer_open() //fall through case ObMysqlTransact::SERVER_SEND_SESSION_VARS: //fall through - case ObMysqlTransact::SERVER_SEND_LAST_INSERT_ID: + case ObMysqlTransact::SERVER_SEND_SESSION_USER_VARS: //fall through case ObMysqlTransact::SERVER_SEND_START_TRANS: + case ObMysqlTransact::SERVER_SEND_XA_START: //fall through case ObMysqlTransact::SERVER_SEND_PREPARE: case ObMysqlTransact::SERVER_SEND_TEXT_PS_PREPARE: @@ -7654,7 +8064,8 @@ void ObMysqlSM::handle_server_setup_error(int event, void *data) : ObMysqlTransact::CONNECTION_CLOSED); break; } - case VC_EVENT_ERROR: { + case VC_EVENT_ERROR: + case VC_EVENT_DETECT_SERVER_DEAD: { trans_state_.current_.state_ = ObMysqlTransact::CONNECTION_ERROR; break; } @@ -7786,13 +8197,15 @@ int ObMysqlSM::setup_client_transfer(ObMysqlVCType to_vc_type) switch (to_vc_type) { case MYSQL_TRANSFORM_VC: MYSQL_SM_SET_DEFAULT_HANDLER(&ObMysqlSM::state_request_wait_for_transform_read); - if (OB_ISNULL(api_.request_transform_info_.entry_) - || api_.request_transform_info_.entry_->vc_ != api_.request_transform_info_.vc_) { + if (OB_ISNULL(api_.request_transform_info_.entry_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid internal state", KP_(api_.request_transform_info_.vc), K_(sm_id), K(ret)); + } else if (api_.request_transform_info_.entry_->vc_ != api_.request_transform_info_.vc_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid internal state", - K_(api_.request_transform_info_.entry), - K_(api_.request_transform_info_.entry_->vc), - K_(api_.request_transform_info_.vc), K_(sm_id), K(ret)); + KP_(api_.request_transform_info_.entry), + KP_(api_.request_transform_info_.entry_->vc), + KP_(api_.request_transform_info_.vc), K_(sm_id), K(ret)); } else if (OB_ISNULL(c = tunnel_.add_consumer(api_.request_transform_info_.entry_->vc_, client_entry_->vc_, &ObMysqlSM::tunnel_handler_transform_write, @@ -8015,7 +8428,8 @@ int ObMysqlSM::setup_server_request_send() server_entry_->write_buffer_ = (buf_start != client_buffer_reader_) ? buf_start->writer() : NULL; // set query_timeout to each request, ddl stmt will never timeout - if (OB_UNLIKELY(trans_state_.trans_info_.client_request_.get_parse_result().is_ddl_stmt())) { + if (OB_UNLIKELY(trans_state_.trans_info_.client_request_.get_parse_result().is_ddl_stmt() + || ObMysqlTransact::is_binlog_request(trans_state_))) { cancel_server_query_timeout(); // if PL/SQL: // 1. if in trans, use trx timeout @@ -8026,7 +8440,9 @@ int ObMysqlSM::setup_server_request_send() } else if (OB_UNLIKELY(trans_state_.trans_info_.client_request_.get_parse_result().is_call_stmt() || trans_state_.trans_info_.client_request_.get_parse_result().is_text_ps_call_stmt() || trans_state_.trans_info_.client_request_.get_parse_result().has_anonymous_block())) { - if (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)) { + if (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)) { set_server_trx_timeout(); } else { cancel_server_query_timeout(); @@ -8237,7 +8653,9 @@ int ObMysqlSM::setup_internal_transfer(MysqlSMHandler handler_arg) // if the internal request is not the first request and not proxysys, // it means that it is in trans (or hold trans), in this case we do NOT change the trans_state_ if (trans_state_.is_trans_first_request_) { - if (trans_state_.is_auth_request_ || trans_state_.is_hold_start_trans_) { + if (trans_state_.is_auth_request_ + || trans_state_.is_hold_start_trans_ + || trans_state_.is_hold_xa_start_) { trans_state_.current_.state_ = ObMysqlTransact::CMD_COMPLETE; } else { // proxysys && !OB_MYSQL_COM_LOGIN &&!OB_MYSQL_COM_HANDSHAKE will also enter here @@ -8349,6 +8767,11 @@ int ObMysqlSM::setup_server_transfer() if (is_resultset) { LOG_ERROR("compress protocol's never reach here", K(is_resultset)); } + } else if (get_global_proxy_config().enable_binlog_service + && (OB_MYSQL_COM_REGISTER_SLAVE == trans_state_.trans_info_.sql_cmd_ + || OB_MYSQL_COM_BINLOG_DUMP == trans_state_.trans_info_.sql_cmd_ + || OB_MYSQL_COM_BINLOG_DUMP_GTID == trans_state_.trans_info_.sql_cmd_)) { + analyzer = &analyzer_; } else { analyzer = is_resultset ? &analyzer_ : NULL; } @@ -8384,6 +8807,7 @@ int ObMysqlSM::setup_cmd_complete() reinterpret_cast(client_session_->get_last_bound_server_session()), K_(sm_id), K(ret)); } else { + ObMysqlTransact::record_trans_state(trans_state_, ObMysqlTransact::is_in_trans(trans_state_)); set_detect_server_info(trans_state_.server_info_.addr_, -1, ObTimeUtility::current_time()); if (OB_UNLIKELY(add_detect_server_cnt_)) { LOG_ERROR("setup_cmd_complete, add_detect_server_cnt_ should be false"); @@ -8458,32 +8882,63 @@ int ObMysqlSM::setup_cmd_complete() } } - // it's necessary to end full link trace resource after trans/resp finished - if (OB_FAIL(handle_resp_for_end_flt_trace(ObMysqlTransact::TRANSACTION_COMPLETE == trans_state_.current_.state_))) { - LOG_WARN("fail to handle resp for end flt trace", K(ret)); - } else { - cmd_size_stats_.reset(); - if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { - cmd_time_stats_.reset(); - } - trans_state_.reset(); - // reset ps info - if (NULL != server_session_) { - server_session_->get_session_info().reset_server_ps_id(); - } - if (NULL != client_session_) { - client_session_->get_session_info().reset_recv_client_ps_id(); - client_session_->get_session_info().reset_client_ps_id(); - client_session_->get_session_info().reset_ps_entry(); - client_session_->get_session_info().reset_client_cursor_id(); + // consume the ob20 tail crc(4) in client buf reader while analyzed all the mysql packet in ob20 payload + ObClientSessionInfo &client_session_info = get_client_session()->get_session_info(); + ObProxyProtocol client_proto = get_client_session_protocol(); + bool ob20_req_received_done = client_session_info.ob20_request_.ob20_request_received_done_; + int64_t ob20_req_remain_payload_len = client_session_info.ob20_request_.remain_payload_len_; + if (client_proto == ObProxyProtocol::PROTOCOL_OB20 + && ob20_req_received_done + && ob20_req_remain_payload_len == 0) { + client_session_info.ob20_request_.reset(); + int64_t read_avail = client_buffer_reader_->read_avail(); + LOG_DEBUG("before handle tail crc in setup cmd complete", K(read_avail)); + if (OB_LIKELY(read_avail >= OB20_PROTOCOL_TAILER_LENGTH)) { + if (OB_FAIL(client_buffer_reader_->consume(OB20_PROTOCOL_TAILER_LENGTH))) { + LOG_WARN("fail to consume the last crc buffer in client request buffer", K(ret)); + } + } else { + // nothing + // cause buffer could be consumed all before, eg: handle internal request } + } - // wait new client request - if (OB_FAIL(setup_client_request_read())) { - LOG_WARN("failed to setup_client_request_read", K_(sm_id), K(ret)); + // it's necessary to end full link trace resource after trans/resp finished + if (OB_SUCC(ret)) { + if (OB_FAIL(handle_resp_for_end_flt_trace(ObMysqlTransact::TRANSACTION_COMPLETE + == trans_state_.current_.state_))) { + LOG_WARN("fail to handle resp for end flt trace", K(ret)); + } else { + cmd_size_stats_.reset(); + if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { + cmd_time_stats_.reset(); + } + if (ObMysqlTransact::is_in_trans(trans_state_) && client_session_->is_trans_internal_routing()) { + trans_state_.server_info_.reset(); + trans_state_.pll_info_.reset(); + trans_state_.current_.attempts_ = 1; + trans_state_.reset_congestion_entry(); + } + trans_state_.reset(); + // reset ps info + if (NULL != server_session_) { + server_session_->get_session_info().reset_server_ps_id(); + } + if (NULL != client_session_) { + client_session_->get_session_info().reset_recv_client_ps_id(); + client_session_->get_session_info().reset_client_ps_id(); + client_session_->get_session_info().reset_ps_entry(); + client_session_->get_session_info().reset_client_cursor_id(); + } + + // wait new client request + if (OB_FAIL(setup_client_request_read())) { + LOG_WARN("failed to setup_client_request_read", K_(sm_id), K(ret)); + } } } } + return ret; } @@ -8500,14 +8955,14 @@ bool ObMysqlSM::need_close_last_used_ss() if (OB_LIKELY(NULL != client_session_) && NULL != (last_ss = client_session_->get_server_session()) && client_session_->get_session_info().is_read_consistency_set() - && client_session_->dummy_ldc_.is_readonly_zone_exist()) { + && client_session_->dummy_ldc_.is_readonly_zone_exist() + && !ObMysqlTransact::is_in_trans(trans_state_)) { common::ObAddr tmp_addr; - (void)tmp_addr.set_ipv4_addr(last_ss->server_ip_.get_ip4_host_order(), static_cast(last_ss->server_ip_.get_port_host_order())); + (void)tmp_addr.set_sockaddr(last_ss->server_ip_.sa_); const bool is_last_route_readonly_zone = client_session_->dummy_ldc_.is_readonly_zone(tmp_addr); const bool is_weak_read = (common::WEAK == static_cast(client_session_->get_session_info().get_read_consistency())); common::ObAddr current_addr; - (void)current_addr.set_ipv4_addr(trans_state_.server_info_.addr_.get_ip4_host_order(), - static_cast(trans_state_.server_info_.addr_.get_port_host_order())); + (void)current_addr.set_sockaddr(trans_state_.server_info_.addr_.sa_); const bool is_current_route_readonly_zone = client_session_->dummy_ldc_.is_readonly_zone(current_addr); // if readonly zone exist, should choose readonly zone when weak read and close connection which connect to readwrite zone if (is_last_route_readonly_zone != is_current_route_readonly_zone) { @@ -8523,7 +8978,9 @@ bool ObMysqlSM::need_close_last_used_ss() bool ObMysqlSM::can_server_session_release() { bool result = false; - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_start_trans_ + || trans_state_.is_hold_xa_start_ + || ObMysqlTransact::is_in_trans(trans_state_)); bool is_allowed_state_ = (ObMysqlTransact::STATE_UNDEFINED == trans_state_.current_.state_ || ObMysqlTransact::TRANSACTION_COMPLETE == trans_state_.current_.state_); // here should handle some case before release @@ -8744,7 +9201,8 @@ inline void ObMysqlSM::update_congestion_entry(const int event) int64_t client_connect_timeout = 0; if ((VC_EVENT_EOS == event || VC_EVENT_INACTIVITY_TIMEOUT == event - || VC_EVENT_ACTIVE_TIMEOUT == event) + || VC_EVENT_ACTIVE_TIMEOUT == event + || VC_EVENT_DETECT_SERVER_DEAD) && ObMysqlTransact::SM_ACTION_OBSERVER_OPEN == trans_state_.next_action_ && 0 == milestones_.server_connect_end_ && OB_LIKELY(NULL != pending_action_) @@ -9225,8 +9683,9 @@ inline void ObMysqlSM::update_cmd_stats() trans_stats_.send_all_session_vars_time_ += cmd_time_stats_.server_send_all_session_variable_time_; trans_stats_.send_use_database_time_ += cmd_time_stats_.server_send_use_database_time_; trans_stats_.send_session_vars_time_ += cmd_time_stats_.server_send_session_variable_time_; - trans_stats_.send_last_insert_id_time_ += cmd_time_stats_.server_send_last_insert_id_time_; + trans_stats_.send_session_user_vars_time_ += cmd_time_stats_.server_send_session_user_variable_time_; trans_stats_.send_start_trans_time_ += cmd_time_stats_.server_send_start_trans_time_; + trans_stats_.send_xa_start_time_ += cmd_time_stats_.server_send_xa_start_time_; trans_stats_.build_server_request_time_ += cmd_time_stats_.build_server_request_time_; int64_t slow_time_threshold = trans_state_.mysql_config_params_->slow_query_time_threshold_; @@ -9258,9 +9717,13 @@ inline void ObMysqlSM::update_cmd_stats() ObString cluster_name; ObString logic_tenant_name; ObString logic_database_name; + ObString trans_internal_routing_state; + bool is_in_trans = ObMysqlTransact::is_in_trans(trans_state_); + bool is_trans_internal_routing = false; if (NULL != client_session_) { proxy_sessid = client_session_->get_proxy_sessid(); cs_id = client_session_->get_cs_id(); + is_trans_internal_routing = client_session_->is_trans_internal_routing(); const ObClientSessionInfo &cs_info = client_session_->get_session_info(); cs_info.get_user_name(user_name); cs_info.get_tenant_name(tenant_name); @@ -9268,6 +9731,7 @@ inline void ObMysqlSM::update_cmd_stats() cs_info.get_logic_database_name(logic_database_name); cs_info.get_logic_tenant_name(logic_tenant_name); } + trans_internal_routing_state = is_in_trans ? (is_trans_internal_routing ? "trans internal routing" : "trans not internal routing") : "not in trans"; get_server_session_ids(server_sessid, ss_id); if (print_info_log) { @@ -9291,7 +9755,8 @@ inline void ObMysqlSM::update_cmd_stats() K_(sm_id), K_(cmd_size_stats), K_(cmd_time_stats), - "sql", trans_state_.trans_info_.get_print_sql()); + "sql", trans_state_.trans_info_.get_print_sql(), + K(trans_internal_routing_state)); } else { LOG_WARN(log_head, "client_ip", trans_state_.client_info_.addr_, @@ -9312,7 +9777,8 @@ inline void ObMysqlSM::update_cmd_stats() K_(sm_id), K_(cmd_size_stats), K_(cmd_time_stats), - "sql", trans_state_.trans_info_.get_print_sql()); + "sql", trans_state_.trans_info_.get_print_sql(), + K(trans_internal_routing_state)); } } @@ -9563,6 +10029,10 @@ inline void ObMysqlSM::set_next_state() do_partition_location_lookup(); break; + case ObMysqlTransact::SM_ACTION_BINLOG_LOCATION_LOOKUP: + do_binlog_location_lookup(); + break; + case ObMysqlTransact::SM_ACTION_CONGESTION_CONTROL_LOOKUP: do_congestion_control_lookup(); break; @@ -9621,6 +10091,44 @@ inline void ObMysqlSM::set_next_state() } } +int ObMysqlSM::state_binlog_location_lookup(int event, void *data) +{ + int ret = OB_SUCCESS; + STATE_ENTER(ObMysqlSM::state_binlog_location_lookup, event); + pending_action_ = NULL; + if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { + milestones_.bl_lookup_end_ = get_based_hrtime(); + cmd_time_stats_.bl_lookup_time_ += milestone_diff(milestones_.bl_lookup_begin_, milestones_.bl_lookup_end_); + milestones_.bl_process_begin_ = milestones_.bl_lookup_end_; + } + + if (OB_UNLIKELY(TABLE_ENTRY_EVENT_LOOKUP_DONE != event) || OB_ISNULL(data)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected event type, it should not happen", K(event), K(data), K(ret)); + } else { + ObMysqlRouteResult *result = reinterpret_cast(data); + if (OB_UNLIKELY(NULL == result || NULL == result->table_entry_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get binlog entry failed", K(result), K(ret)); + } else { + trans_state_.pll_info_.set_route_info(*result); + trans_state_.pll_info_.lookup_success_ = true; + call_transact_and_set_next_state(NULL); + } + } + + if (OB_FAIL(ret)) { + trans_state_.inner_errcode_ = ret; + // failed, disconnect + trans_state_.pll_info_.lookup_success_ = false; + trans_state_.current_.state_ = ObMysqlTransact::INTERNAL_ERROR; + // call ObMysqlTransact::handle_bl_lookup() to handle fail / success + call_transact_and_set_next_state(NULL); + } + + return EVENT_DONE; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_mysql_sm.h b/src/obproxy/proxy/mysql/ob_mysql_sm.h index 15415c24..ec159024 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_sm.h +++ b/src/obproxy/proxy/mysql/ob_mysql_sm.h @@ -33,6 +33,7 @@ #include "utils/ob_proxy_lib.h" #include "utils/ob_proxy_monitor_utils.h" +#include "utils/ob_target_db_server.h" #include "iocore/eventsystem/ob_event_system.h" #include "proxy/mysqllib/ob_mysql_request_analyzer.h" #include "proxy/mysqllib/ob_mysql_compress_analyzer.h" @@ -157,14 +158,15 @@ class ObMysqlSM : public event::ObContinuation int process_shard_ddl_result(ObShardDDLStatus *ddl_status); int setup_handle_execute_plan(); int state_handle_execute_plan(int event, void *data); - int process_executor_result(engine::ObProxyResultResp *result_resp); - + int process_executor_result(event::ObIOBufferReader *resp_reader); + int handle_shard_request(bool &need_response_for_stmt, bool &need_wait_callback); int check_user_identity(const ObString &user_name, const ObString &tenant_name, const ObString &cluster_name); int save_user_login_info(ObClientSessionInfo &session_info, ObHSRResult &hsr_result); void analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool is_mysql_req_in_ob20 = false); int analyze_login_request(ObRequestAnalyzeCtx &ctx, ObMysqlAnalyzeStatus &status); + int analyze_change_user_request(); int analyze_ps_prepare_request(); int do_analyze_ps_prepare_request(const ObString &ps_sql); int analyze_ps_execute_request(bool is_large_request = false); @@ -306,6 +308,7 @@ class ObMysqlSM : public event::ObContinuation int state_watch_for_client_abort(int event, void *data); int state_server_addr_lookup(int event, void *data); int state_partition_location_lookup(int event, void *data); + int state_binlog_location_lookup(int event, void *data); int state_add_to_list(int event, void *data); int state_remove_from_list(int event, void *data); @@ -336,6 +339,7 @@ class ObMysqlSM : public event::ObContinuation int tunnel_handler_plugin_client(int event, ObMysqlTunnelConsumer &c); void do_partition_location_lookup(); + void do_binlog_location_lookup(); void do_congestion_control_lookup(); void do_server_addr_lookup(); int do_observer_open(); @@ -348,6 +352,7 @@ class ObMysqlSM : public event::ObContinuation int do_internal_request_for_sharding_show_db(event::ObMIOBuffer *buf); int do_internal_request_for_sharding_show_table(event::ObMIOBuffer *buf); int do_internal_request_for_sharding_show_table_status(event::ObMIOBuffer *buf); + int do_internal_request_for_sharding_show_elastic_id(event::ObMIOBuffer *buf); int do_internal_request_for_sharding_show_topology(event::ObMIOBuffer *buf); int do_internal_request_for_sharding_select_db(event::ObMIOBuffer *buf); int connect_observer(); @@ -438,7 +443,8 @@ class ObMysqlSM : public event::ObContinuation int handle_req_to_generate_root_span_by_proxy(); int handle_for_end_proxy_trace(trace::UUID &trace_id); int handle_resp_for_end_flt_trace(bool is_trans_completed); - + void set_enable_ob_protocol_v2(const bool enable_ob_protocol_v2) { enable_ob_protocol_v2_ = enable_ob_protocol_v2; } + bool is_enable_ob_protocol_v2() const { return enable_ob_protocol_v2_; } private: static const int64_t HISTORY_SIZE = 32; @@ -486,7 +492,11 @@ class ObMysqlSM : public event::ObContinuation bool enable_cloud_full_username_; bool enable_client_ssl_; bool enable_server_ssl_; + bool enable_read_write_split_; + bool enable_transaction_split_; + bool enable_ob_protocol_v2_; // limit the scope of changing enable_protocol_v2_ to client session level uint64_t config_version_; + ObTargetDbServer *target_db_server_; private: // private functions @@ -589,16 +599,16 @@ inline void ObMysqlSM::set_internal_cmd_timeout(const ObHRTime timeout) inline int64_t ObMysqlSM::get_query_timeout() { int64_t timeout = HRTIME_NSECONDS(trans_state_.mysql_config_params_->observer_query_timeout_delta_); - if (OB_LIKELY(NULL != client_session_) && OB_LIKELY(NULL != server_session_)) { - dbconfig::ObShardProp *shard_prop = client_session_->get_session_info().get_shard_prop(); - if (OB_NOT_NULL(shard_prop)) { - timeout = HRTIME_MSECONDS(shard_prop->get_socket_timeout()); + if (OB_LIKELY(NULL != client_session_)) { + int64_t hint_query_timeout = trans_state_.trans_info_.client_request_.get_parse_result().get_hint_query_timeout(); + // if the request contains query_timeout in hint, we use it + if (hint_query_timeout > 0) { + // the query timeout in hint is in microseconds(us), so convert it into nanoseconds + timeout += HRTIME_USECONDS(hint_query_timeout); } else { - int64_t hint_query_timeout = trans_state_.trans_info_.client_request_.get_parse_result().get_hint_query_timeout(); - // if the request contains query_timeout in hint, we use it - if (hint_query_timeout > 0) { - // the query timeout in hint is in microseconds(us), so convert it into nanoseconds - timeout += HRTIME_USECONDS(hint_query_timeout); + dbconfig::ObShardProp *shard_prop = client_session_->get_session_info().get_shard_prop(); + if (OB_NOT_NULL(shard_prop)) { + timeout = HRTIME_MSECONDS(shard_prop->get_socket_timeout()); } else { // we do parse in trans now, so we can use query_timeout in anycase timeout += client_session_->get_session_info().get_query_timeout(); diff --git a/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.cpp b/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.cpp index f8bd5480..6efcbb0b 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.cpp @@ -37,6 +37,9 @@ int64_t ObCmdTimeStat::to_string(char *buf, const int64_t buf_len) const TO_STRING_TIME_US(pl_lookup_time_); TO_STRING_TIME_US(pl_process_time_); + TO_STRING_TIME_US(bl_lookup_time_); + TO_STRING_TIME_US(bl_process_time_); + #if OB_DETAILED_SLOW_QUERY TO_STRING_TIME_US(debug_assign_time_); TO_STRING_TIME_US(debug_consistency_time_); @@ -58,9 +61,10 @@ int64_t ObCmdTimeStat::to_string(char *buf, const int64_t buf_len) const TO_STRING_TIME_US(server_send_saved_login_time_); TO_STRING_TIME_US(server_send_use_database_time_); TO_STRING_TIME_US(server_send_session_variable_time_); + TO_STRING_TIME_US(server_send_session_user_variable_time_); TO_STRING_TIME_US(server_send_all_session_variable_time_); - TO_STRING_TIME_US(server_send_last_insert_id_time_); TO_STRING_TIME_US(server_send_start_trans_time_); + TO_STRING_TIME_US(server_send_xa_start_time_); TO_STRING_TIME_US(build_server_request_time_); TO_STRING_TIME_US(plugin_compress_request_time_); TO_STRING_TIME_US(prepare_send_request_to_server_time_); @@ -100,9 +104,10 @@ int64_t ObTransactionStat::to_string(char *buf, const int64_t buf_len) const TO_STRING_TIME_US(send_saved_login_time_); TO_STRING_TIME_US(send_use_database_time_); TO_STRING_TIME_US(send_session_vars_time_); + TO_STRING_TIME_US(send_session_user_vars_time_); TO_STRING_TIME_US(send_all_session_vars_time_); - TO_STRING_TIME_US(send_last_insert_id_time_); TO_STRING_TIME_US(send_start_trans_time_); + TO_STRING_TIME_US(send_xa_start_time_); TO_STRING_TIME_US(build_server_request_time_); TO_STRING_TIME_US(plugin_compress_request_time_); TO_STRING_TIME_US(prepare_send_request_to_server_time_); diff --git a/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.h b/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.h index 04b11120..45d19c9d 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.h +++ b/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.h @@ -69,7 +69,8 @@ struct ObTransactionMilestones ObTransactionMilestones() : last_client_cmd_end_(0), server_connect_begin_(0), server_connect_end_(0), server_first_write_begin_(0), pl_lookup_begin_(0), pl_lookup_end_(0), - pl_process_begin_(0), pl_process_end_(0), congestion_control_begin_(0), + pl_process_begin_(0), pl_process_end_(0), bl_lookup_begin_(0), bl_lookup_end_(0), + bl_process_begin_(0), bl_process_end_(0), congestion_control_begin_(0), congestion_control_end_(0), congestion_process_begin_(0), congestion_process_end_(0), cluster_resource_create_begin_(0), cluster_resource_create_end_(0), trans_start_(0), trans_finish_(0), do_observer_open_begin_(0), do_observer_open_end_(0) @@ -111,6 +112,14 @@ struct ObTransactionMilestones ObHRTime pl_process_begin_; ObHRTime pl_process_end_; + // binlog location lookup + ObHRTime bl_lookup_begin_; + ObHRTime bl_lookup_end_; + + // binlog location process + ObHRTime bl_process_begin_; + ObHRTime bl_process_end_; + // congestion_control_lookup ObHRTime congestion_control_begin_; ObHRTime congestion_control_end_; @@ -154,6 +163,8 @@ struct ObCmdTimeStat ObHRTime cluster_resource_create_time_; ObHRTime pl_lookup_time_; ObHRTime pl_process_time_; + ObHRTime bl_lookup_time_; + ObHRTime bl_process_time_; #if OB_DETAILED_SLOW_QUERY ObHRTime debug_assign_time_; @@ -177,9 +188,10 @@ struct ObCmdTimeStat ObHRTime server_send_saved_login_time_; ObHRTime server_send_use_database_time_; ObHRTime server_send_session_variable_time_; + ObHRTime server_send_session_user_variable_time_; ObHRTime server_send_all_session_variable_time_; - ObHRTime server_send_last_insert_id_time_; ObHRTime server_send_start_trans_time_; + ObHRTime server_send_xa_start_time_; ObHRTime build_server_request_time_; ObHRTime plugin_compress_request_time_; @@ -241,9 +253,10 @@ struct ObTransactionStat ObHRTime send_saved_login_time_; ObHRTime send_use_database_time_; ObHRTime send_session_vars_time_; + ObHRTime send_session_user_vars_time_; ObHRTime send_all_session_vars_time_; - ObHRTime send_last_insert_id_time_; ObHRTime send_start_trans_time_; + ObHRTime send_xa_start_time_; ObHRTime build_server_request_time_; ObHRTime plugin_compress_request_time_; diff --git a/src/obproxy/proxy/mysql/ob_mysql_transact.cpp b/src/obproxy/proxy/mysql/ob_mysql_transact.cpp index 9988c2bb..c4d134bd 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_transact.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_transact.cpp @@ -38,6 +38,7 @@ #include "lib/encrypt/ob_encrypted_helper.h" #include "proxy/shard/obproxy_shard_utils.h" #include "rpc/obmysql/packet/ompk_change_user.h" +#include "rpc/obmysql/packet/ompk_prepare_execute.h" #include "omt/ob_proxy_config_table_processor.h" using namespace oceanbase::share; @@ -61,6 +62,62 @@ namespace proxy #define MYSQL_INCREMENT_TRANS_STAT(X) update_stat(s, X, 1); #define MYSQL_SUM_TIME_STAT(X, cost) update_stat(s, X, cost); +bool ObMysqlTransact::is_in_trans(ObTransState &s) +{ + // if a trans is commit, the state will be set to TRANSACTION_COMPLETE, + // so if current state is CMD_COMPLETE, it means that we have send a sql successfully and + // the trans has not commit, that is to say "in trans" + // so far, there are three cases NOT in trans: + // 1. handshake response (login packet) need pl lookup + // 2. the first sql of one transaction + // 3. the second sql of one transaction, if the first sql is 'begin' or 'start transaction' + + // s.current_.state_ may changed to CONNECTION_ALIVE on state_server_response_read, + // here add last_request_in_trans to correct transaction state + + bool is_in_trans = false; + if (!s.is_auth_request_ && !s.is_hold_start_trans_ && !s.is_hold_xa_start_) { + if (ObMysqlTransact::CMD_COMPLETE == s.current_.state_) { + is_in_trans = true; + } else if (ObMysqlTransact::TRANSACTION_COMPLETE != s.current_.state_ + && s.sm_->client_session_ != NULL + && s.sm_->client_session_->is_last_request_in_trans()) { + is_in_trans = true; + } + } + return is_in_trans; +} + +void ObMysqlTransact::record_trans_state(ObTransState &s, bool is_in_trans) +{ + ObMysqlClientSession *client_session = s.sm_->get_client_session(); + bool last_request_in_trans = client_session->is_last_request_in_trans(); + if (client_session->is_proxy_enable_trans_internal_routing()) { + // set distributed transaction route flag + bool server_trans_internal_routing = s.trans_info_.server_response_.get_analyze_result().is_server_trans_internal_routing(); + bool is_trans_internal_routing = ObMysqlTransact::handle_set_trans_internal_routing(s, server_trans_internal_routing); + + if (!last_request_in_trans && is_in_trans) { + client_session->set_trans_coordinator_ss_addr(s.server_info_.addr_.sa_); + LOG_DEBUG("start internal routing transaction", "coordinator addr", client_session->get_trans_coordinator_ss_addr()); + s.trace_log_.set_need_print(is_trans_internal_routing); + s.trace_log_.log_it("[trans_start]", + "proxy_sessid", client_session->get_proxy_sessid(), + "coordinator", s.server_info_.addr_, + "sql_cmd", s.trans_info_.sql_cmd_, + "stmt_type", s.trans_info_.client_request_.get_parse_result().get_stmt_type()); + } else if (last_request_in_trans && !is_in_trans) { + // close txn, refresh enable_transaction_internal_routing_ + LOG_DEBUG("internal routing transaction close", "coordinator addr", client_session->get_trans_coordinator_ss_addr()); + client_session->get_trans_coordinator_ss_addr().reset(); + } + + client_session->set_trans_internal_routing(is_trans_internal_routing); + LOG_DEBUG("set transaction internal routing flag", "internal routing state", is_trans_internal_routing); + } + client_session->set_last_request_in_trans(is_in_trans); +} + void ObMysqlTransact::handle_error_jump(ObTransState &s) { LOG_WARN("[ObMysqlTransact::handle_error_jump]"); @@ -127,6 +184,31 @@ bool ObMysqlTransact::ObTransState::is_for_update_sql(common::ObString src_sql) return bret; } +ObConsistencyLevel ObMysqlTransact::ObTransState::get_read_write_consistency_level(ObClientSessionInfo &session_info) +{ + ObConsistencyLevel ret_level = common::STRONG; + bool enable_weak_read = false; + if (ObMysqlTransact::is_in_trans(sm_->trans_state_) + || 0 == session_info.get_cached_variables().get_autocommit() + || is_hold_start_trans_ + || is_hold_xa_start_) { + if (ObMysqlTransact::is_in_trans(sm_->trans_state_) + || is_hold_start_trans_ + || is_hold_xa_start_) { + enable_weak_read = false; + } else { + enable_weak_read = sm_->enable_read_write_split_ && sm_->enable_transaction_split_; + } + } else { + enable_weak_read = sm_->enable_read_write_split_; + } + + if (enable_weak_read) { + ret_level = common::WEAK; + } + return ret_level; +} + ObConsistencyLevel ObMysqlTransact::ObTransState::get_trans_consistency_level( ObClientSessionInfo &cs_info) { @@ -152,14 +234,20 @@ ObConsistencyLevel ObMysqlTransact::ObTransState::get_trans_consistency_level( trans_info_.client_request_.get_parse_result().is_text_ps_select_stmt()) { const ObConsistencyLevel sql_hint = trans_info_.client_request_.get_parse_result().get_hint_consistency_level(); const ObConsistencyLevel sys_var = static_cast(cs_info.get_read_consistency()); + const ObConsistencyLevel read_write_consistence_level = get_read_write_consistency_level(cs_info); if (common::STRONG == sql_hint || common::WEAK == sql_hint) { ret_level = sql_hint; } else { - if (common::STRONG == sys_var || common::WEAK == sys_var) { + if (common::WEAK == sys_var) { ret_level = sys_var; } else { - PROXY_LOG(DEBUG, "unsupport ob_read_consistency vars, maybe proxy is old, use strong read " + if (common::STRONG == read_write_consistence_level || common::WEAK == read_write_consistence_level) { + ret_level = read_write_consistence_level; + } + if (common::STRONG != sys_var) { + PROXY_LOG(DEBUG, "unsupport ob_read_consistency vars, maybe proxy is old, use strong read " "instead", "sys_var", get_consistency_level_str(sys_var)); + } } } if (common::WEAK == ret_level) { @@ -296,10 +384,8 @@ void ObMysqlTransact::acquire_cached_server_session(ObTransState &s) } else if (get_global_proxy_config().enable_cached_server && !s.sm_->client_session_->is_proxy_mysql_client_ && NULL != last_session && OB_LIKELY(!s.mysql_config_params_->is_random_routing_mode())) { - const int32_t ip = ops_ip4_addr_host_order(last_session->get_netvc()->get_remote_addr()); - const int32_t port = static_cast(ops_ip_port_host_order(last_session->get_netvc()->get_remote_addr())); ObAddr last_addr; - last_addr.set_ipv4_addr(ip, port); + last_addr.set_sockaddr(last_session->get_netvc()->get_remote_addr()); #if OB_DETAILED_SLOW_QUERY ObHRTime t1 = common::get_hrtime_internal(); #endif @@ -367,8 +453,13 @@ bool ObMysqlTransact::can_direct_ok_for_login(ObTransState &s) { bool bret = false; ObClientSessionInfo &cs_info = s.sm_->client_session_->get_session_info(); - if (!(obmysql::OB_MYSQL_COM_LOGIN == s.trans_info_.sql_cmd_ && s.is_auth_request_ && s.sm_->client_session_->is_session_pool_client())) { - // should only session_pool_client and LOGIN for auth + if (!(obmysql::OB_MYSQL_COM_LOGIN == s.trans_info_.sql_cmd_ && s.is_auth_request_)) { + // should only LOGIN for auth + } else if (s.sm_->client_session_->can_direct_send_request_) { + //scan all return ok + bret = true; + } else if (!s.sm_->client_session_->is_session_pool_client()) { + // should only session_pool_client } else if (cs_info.is_sharding_user()) { bret = true; } else if (!s.sm_->client_session_->is_proxy_mysql_client_ && get_global_proxy_config().enable_no_sharding_skip_real_conn) { @@ -497,7 +588,7 @@ void ObMysqlTransact::handle_mysql_request(ObTransState &s) int ret = OB_SUCCESS; sockaddr sa; memset(&sa, 0, sizeof(sa)); - bool need_pl_lookup = ObMysqlTransact::need_pl_lookup(s); + bool need_pl_lookup = (ObMysqlTransact::need_pl_lookup(s) == NEED_PL_LOOKUP); ObMysqlServerSession *last_session = s.sm_->client_session_->get_server_session(); if (need_pl_lookup) { ObMysqlServerSession *svr_session = NULL; @@ -567,32 +658,59 @@ void ObMysqlTransact::handle_ps_close_reset(ObTransState &s) int ret = OB_SUCCESS; ObMysqlClientSession *client_session = s.sm_->get_client_session(); - ObPsIdAddrs::ADDR_HASH_SET &remove_addrs = client_session->get_session_info().get_request_send_addrs(); + ObIArray &remove_addrs = client_session->get_session_info().get_request_send_addrs(); // At the end of each request, server_entry_ and server_session_ will be placed, // including the internal jump of the close command multiple times. if (!client_session->is_first_handle_request()) { s.sm_->release_server_session(); // If it is not the first time to come in, it will also be judged according to the transaction status of the first time. - s.need_pl_lookup_ = s.need_pl_lookup_ && !client_session->is_in_trans_for_close_request(); + bool need_pl_lookup = s.is_need_pl_lookup() && !client_session->is_in_trans_for_close_request(); + // sync pl_lookup_state_ + if (!need_pl_lookup) { + if (client_session->is_proxy_enable_trans_internal_routing()) { + s.pl_lookup_state_ = USE_COORDINATOR_SESSION; + } else { + s.pl_lookup_state_ = USE_LAST_SERVER_SESSION; + } + } } else { // The first time you come in, record the previous transaction status client_session->set_in_trans_for_close_request(is_in_trans(s)); remove_addrs.reuse(); + bool found = false; uint32_t client_ps_id = client_session->get_session_info().get_client_ps_id(); // If greater than 1 << 31L, it means cursor_id; otherwise, it is ps_id if (client_ps_id >= (CURSOR_ID_START)) { ObCursorIdAddr *cursor_id_addr = client_session->get_session_info().get_cursor_id_addr(client_ps_id); if (NULL != cursor_id_addr) { - remove_addrs.set_refactored(cursor_id_addr->get_addr()); + for (int64_t i = 0; !found && i< remove_addrs.count(); i++) { + if (remove_addrs.at(i) == cursor_id_addr->get_addr()) { + found = true; + } + } + if (!found) { + if (OB_FAIL(remove_addrs.push_back(cursor_id_addr->get_addr()))) { + LOG_WARN("fail to push back addr", K(ret)); + } + } } } else { ObPsIdAddrs *ps_id_addrs = client_session->get_session_info().get_ps_id_addrs(client_ps_id); - if (NULL != ps_id_addrs && 0 != ps_id_addrs->get_addrs().size()) { - ObPsIdAddrs::ADDR_HASH_SET::iterator iter = ps_id_addrs->get_addrs().begin(); - ObPsIdAddrs::ADDR_HASH_SET::iterator iter_end = ps_id_addrs->get_addrs().end(); - for (; iter != iter_end; iter++) { - remove_addrs.set_refactored(iter->first); + if (NULL != ps_id_addrs && 0 != ps_id_addrs->get_addrs().count()) { + ObIArray &array = ps_id_addrs->get_addrs(); + for (int64_t i = 0; i < array.count(); i++) { + found = false; + for (int64_t j = 0; !found && j < remove_addrs.count(); j++) { + if (remove_addrs.at(j) == array.at(i)) { + found = true; + } + } + if (!found) { + if (OB_FAIL(remove_addrs.push_back(array.at(i)))) { + LOG_WARN("fail to push back addr", K(ret)); + } + } } } } @@ -605,7 +723,7 @@ void ObMysqlTransact::handle_ps_close_reset(ObTransState &s) * 1. last_session does not exist. * 2. last_bound_session is not null. */ - if (!s.need_pl_lookup_ && client_session->is_first_handle_request() + if (!s.is_need_pl_lookup() && client_session->is_first_handle_request() && (NULL == last_session || NULL != last_bound_session)) { LOG_ERROR("[ObMysqlTransact::handle request] something is wrong, we have to disconnect", "is_first_handle_close_request_", client_session->is_first_handle_request(), @@ -616,35 +734,32 @@ void ObMysqlTransact::handle_ps_close_reset(ObTransState &s) bool is_need_send_to_bound_ss = false; ObIpEndpoint addr; - if (0 != remove_addrs.size()) { + if (0 != remove_addrs.count()) { is_need_send_cmd = true; /* If no routing is required, and it is the first time to come in * Then check if there is any need to send to bound_ss, if so, send it first, * otherwise migrate the connection, and then migrate back */ - if (!s.need_pl_lookup_ + if (!s.is_need_pl_lookup() && client_session->is_first_handle_request()) { - ObPsIdAddrs::ADDR_HASH_SET::iterator iter = remove_addrs.begin(); - ObPsIdAddrs::ADDR_HASH_SET::iterator iter_end = remove_addrs.end(); - - for (; iter != iter_end; iter++) { - if (iter->first == ObIpEndpoint(last_session->get_netvc()->get_remote_addr())) { + for (int64_t i = 0; i < remove_addrs.count(); i++) { + if (remove_addrs.at(i) == ObIpEndpoint(last_session->get_netvc()->get_remote_addr())) { is_need_send_to_bound_ss = true; - addr = iter->first; + addr = remove_addrs.at(i); break; } } } if (!is_need_send_to_bound_ss) { - addr = remove_addrs.begin()->first; + addr = remove_addrs.at(0); } } if (is_need_send_cmd) { // If no routing is required, and there is no last server session in the server to be sent, migrate ObMysqlServerSession *last_bound_session = client_session->get_last_bound_server_session(); - if (!s.need_pl_lookup_ + if (!s.is_need_pl_lookup() && !is_need_send_to_bound_ss && NULL == last_bound_session) { client_session->attach_server_session(NULL); @@ -660,6 +775,7 @@ void ObMysqlTransact::handle_ps_close_reset(ObTransState &s) start_access_control(s); } } else { + LOG_DEBUG("handle_ps_close_reset don't need send cmd"); // This indicates that session migration has occurred and needs to be migrated back if (client_session->is_need_return_last_bound_ss()) { if (NULL != last_bound_session) { @@ -693,12 +809,16 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) int ret = OB_SUCCESS; ObClientSessionInfo &cs_info = get_client_session_info(s); ObProxyMysqlRequest &client_request = s.trans_info_.client_request_; - if (OB_LIKELY(cs_info.is_allow_use_last_session())) { - s.need_pl_lookup_ = need_pl_lookup(s); - } else { - s.need_pl_lookup_ = true; + ObPLLookupState state = need_pl_lookup(s); + // if target db server set + bool hint_target_db = OB_NOT_NULL(client_request.get_parse_result().get_target_db_server()) + && !client_request.get_parse_result().get_target_db_server()->is_empty(); + bool conf_target_db = OB_NOT_NULL(s.sm_->target_db_server_) + && !s.sm_->target_db_server_->is_empty(); + s.pl_lookup_state_ = state; + if (OB_UNLIKELY(!cs_info.is_allow_use_last_session())) { + s.pl_lookup_state_ = NEED_PL_LOOKUP; } - // generate span before each request if (s.sm_->get_client_session()->is_first_handle_request()) { if (OB_FAIL(s.sm_->handle_req_for_begin_proxy_root_span())) { @@ -707,18 +827,25 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } obmysql::ObMySQLCmd cmd = s.trans_info_.sql_cmd_; - - if (OB_UNLIKELY(cs_info.is_sharding_user()) - && OB_FAIL(ObProxyShardUtils::update_sys_read_consistency_if_need(cs_info))) { + if (is_in_trans(s) + && s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing() + && OB_UNLIKELY(!s.sm_->get_client_session()->get_trans_coordinator_ss_addr().is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("coordinator session addr is invalid, we have to disconnect", K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); // disconnect + } else if (OB_UNLIKELY(cs_info.is_sharding_user()) + && OB_FAIL(ObProxyShardUtils::update_sys_read_consistency_if_need(cs_info))) { LOG_WARN("fail to update_sys_read_consistency_if_need", K(ret)); TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); // disconnect + } else if (s.sm_->get_client_session()->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER && s.server_info_.addr_.is_valid()) { + lookup_skip_open_server(s); } else if (OB_UNLIKELY(need_server_session_lookup(s))) { TRANSACT_RETURN(SM_ACTION_SERVER_ADDR_LOOKUP, handle_server_addr_lookup); } else if (OB_UNLIKELY(obmysql::OB_MYSQL_COM_STMT_CLOSE == cmd || obmysql::OB_MYSQL_COM_STMT_RESET == cmd)) { handle_ps_close_reset(s); } else if (client_request.get_parse_result().is_text_ps_drop_stmt()) { handle_ps_close_reset(s); - } else if (OB_LIKELY(s.need_pl_lookup_)) { + } else if (OB_LIKELY(s.is_need_pl_lookup())) { // if need pl lookup, we should extract pl info first if (OB_FAIL(extract_partition_info(s))) { LOG_WARN("fail to extract partition info", K(ret)); @@ -780,26 +907,80 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) LOG_DEBUG("succ to set target addr for send piece/prepare execute/send long data", "address", s.server_info_.addr_, KPC(info)); } - } else if ((s.mysql_config_params_->is_mock_routing_mode() && !s.sm_->client_session_->is_proxy_mysql_client_) - || s.mysql_config_params_->is_mysql_routing_mode()) { - if (OB_FAIL(s.mysql_config_params_->get_one_test_server_addr(s.server_info_.addr_))) { - LOG_INFO("mysql or mock mode, but test server addr in not set, do normal pl lookup", K(ret)); - if (NULL == s.sm_->client_session_->dummy_entry_) { - s.sm_->client_session_->is_need_update_dummy_entry_ = true; - } - ret = OB_SUCCESS; - } else { - s.sm_->client_session_->test_server_addr_ = s.server_info_.addr_; - s.pll_info_.lookup_success_ = true; - LOG_DEBUG("mysql mode, test server is valid, just use it and skip pl lookup", + } else { /* do nothing */} + + // Specified server addr + // 1. target_db_server (comment & multi levle config) + // 2. test_server_addr & server_routing_mode (deprecated global config) + + // target db server (sql comment & multi level config) + if (OB_SUCC(ret) && !s.pll_info_.lookup_success_) { + // Use target_db_server + // exsit in sql comment parsed result + if (hint_target_db) { + if (OB_FAIL(client_request.get_parse_result().get_target_db_server()->get(s.server_info_.addr_))) { + LOG_WARN("fail to get target db server from sql comment", K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + } else { + // in case of dummy entry is NULL + if (NULL == s.sm_->client_session_->dummy_entry_) { + s.sm_->client_session_->is_need_update_dummy_entry_ = true; + } + s.pll_info_.lookup_success_ = true; + LOG_DEBUG("succ to get target db server from sql comment", "address", s.server_info_.addr_); + } + // exist in multi level config target_db_server + } else if (conf_target_db) { + s.sm_->target_db_server_->reuse(); + if (OB_FAIL(s.sm_->target_db_server_->get(s.server_info_.addr_))) { + LOG_WARN("fail to get target db server from multi level config", K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + } else { + // in case of dummy entry is NULL + if (NULL == s.sm_->client_session_->dummy_entry_) { + s.sm_->client_session_->is_need_update_dummy_entry_ = true; + } + s.pll_info_.lookup_success_ = true; + LOG_DEBUG("succ to get target db server from multi level config", + "address", s.server_info_.addr_); + } + } else { /* do nothing */} + } else if (OB_SUCC(ret)) { + if ((hint_target_db && !client_request.get_parse_result().get_target_db_server()->contains(s.server_info_.addr_)) || + (!hint_target_db && conf_target_db && !s.sm_->target_db_server_->contains(s.server_info_.addr_))) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("Not allow to route to", "choosen server", s.server_info_.addr_, K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); } - } else if (OB_UNLIKELY(!s.mysql_config_params_->is_random_routing_mode() + } + // deprecated global config + if (OB_SUCC(ret) && !s.pll_info_.lookup_success_) { + if ((s.mysql_config_params_->is_mock_routing_mode() && !s.sm_->client_session_->is_proxy_mysql_client_) + || s.mysql_config_params_->is_mysql_routing_mode()) { + if (OB_FAIL(s.mysql_config_params_->get_one_test_server_addr(s.server_info_.addr_))) { + LOG_INFO("mysql or mock mode, but test server addr in not set, do normal pl lookup", K(ret)); + if (NULL == s.sm_->client_session_->dummy_entry_) { + s.sm_->client_session_->is_need_update_dummy_entry_ = true; + } + ret = OB_SUCCESS; + } else { + s.sm_->client_session_->test_server_addr_ = s.server_info_.addr_; + s.pll_info_.lookup_success_ = true; + LOG_DEBUG("mysql mode, test server is valid, just use it and skip pl lookup", + "address", s.server_info_.addr_); + } + } else { /* do nothing */} + } + + if (OB_SUCC(ret) && !s.pll_info_.lookup_success_) { + if (OB_UNLIKELY(!s.mysql_config_params_->is_random_routing_mode() && !s.api_server_addr_set_ - && s.pll_info_.te_name_.is_all_dummy_table() + && s.pll_info_.te_name_.is_all_dummy_table() && cs_info.is_allow_use_last_session())) { - acquire_cached_server_session(s); - } // end of !is_in_test_mode + acquire_cached_server_session(s); + } + } if (OB_SUCC(ret)) { TRANSACT_RETURN(SM_ACTION_PARTITION_LOCATION_LOOKUP, handle_pl_lookup); @@ -807,11 +988,30 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } } else { // !need_pl_lookup - LOG_DEBUG("[ObMysqlTransact::handle request] force to use last server session"); - ObMysqlServerSession *last_session = s.sm_->client_session_->get_server_session(); + LOG_DEBUG("[ObMysqlTransact::handle request] force to use last server session/coordinator server session", K(get_pl_lookup_state_string(s.pl_lookup_state_))); ObMysqlClientSession *client_session = s.sm_->get_client_session(); + ObMysqlServerSession *last_session = client_session->get_server_session(); + sockaddr target_addr; + + if (s.pl_lookup_state_ == USE_COORDINATOR_SESSION) { + LOG_DEBUG("use coordinator session"); + target_addr = client_session->get_trans_coordinator_ss_addr().sa_; + } else if (s.pl_lookup_state_ == USE_LAST_SERVER_SESSION) { + LOG_DEBUG("use last server session"); + if (OB_UNLIKELY(NULL == last_session )) { + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[ObMysqlTransact::handle request] last server session is invalid, we have to disconnect", K(ret)); + } else { + target_addr = last_session->get_netvc()->get_remote_addr(); + } + } else { + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[ObMysqlTransact::handle request] unexpected pl lookup state, we have to disconnect", K(s.pl_lookup_state_), K(ret)); + } - if (OB_LIKELY(NULL != last_session)) { + if (OB_SUCC(ret)) { if (obmysql::OB_MYSQL_COM_STMT_FETCH == cmd) { ObCursorIdAddr *cursor_id_addr = NULL; if (OB_FAIL(cs_info.get_cursor_id_addr(cursor_id_addr))) { @@ -822,11 +1022,16 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); } } else { - if (OB_UNLIKELY(cursor_id_addr->get_addr() != last_session->get_netvc()->get_remote_addr())) { - client_session->attach_server_session(NULL); - last_session->do_io_read(client_session, 0, NULL); - client_session->set_last_bound_server_session(last_session); - client_session->set_need_return_last_bound_ss(true); + if (OB_SUCC(ret) && OB_UNLIKELY(!ops_ip_addr_port_eq(cursor_id_addr->get_addr(), target_addr))) { + if (USE_COORDINATOR_SESSION == s.pl_lookup_state_) { + // under internal routing transaction, OB_MYSQL_COM_STMT_FETCH may be routed to participant + // don't need compare target server + } else { + client_session->attach_server_session(NULL); + last_session->do_io_read(client_session, 0, NULL); + client_session->set_last_bound_server_session(last_session); + client_session->set_need_return_last_bound_ss(true); + } } s.server_info_.set_addr(cursor_id_addr->get_addr()); @@ -841,26 +1046,31 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } else { TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); } - } else if (OB_UNLIKELY(cursor_id_addr->get_addr() != last_session->get_netvc()->get_remote_addr())) { - s.mysql_errcode_ = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; - s.mysql_errmsg_ = "fetch cursor target server is not the trans server"; - int tmp_ret = OB_SUCCESS; - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = build_error_packet(s, client_session)))) { - LOG_WARN("fail to build err packet", K(tmp_ret)); + } else if (OB_UNLIKELY(!ops_ip_addr_port_eq(cursor_id_addr->get_addr(), target_addr))) { + if (USE_COORDINATOR_SESSION == s.pl_lookup_state_) { + // under internal routing transaction, OB_MYSQL_COM_STMT_GET_PIECE_DATA may be routed to participant + // don't need compare target server + target_addr = cursor_id_addr->get_addr().sa_; } else { - LOG_WARN("fetch cursor target server is not the trans server", - "fetch cursor target server", cursor_id_addr->get_addr(), - "trans server", ObIpEndpoint(last_session->get_netvc()->get_remote_addr())); - } + s.mysql_errcode_ = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + s.mysql_errmsg_ = "fetch cursor target server is not the trans server"; + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = build_error_packet(s, client_session)))) { + LOG_WARN("fail to build err packet", K(tmp_ret)); + } else { + LOG_WARN("fetch cursor target server is not the trans server", + "fetch cursor target server", cursor_id_addr->get_addr(), + "trans server", ObIpEndpoint(target_addr)); + } - ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; - s.inner_errcode_ = ret; - s.current_.state_ = ObMysqlTransact::INTERNAL_ERROR; - TRANSACT_RETURN(SM_ACTION_INTERNAL_NOOP, NULL); + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + s.inner_errcode_ = ret; + s.current_.state_ = ObMysqlTransact::INTERNAL_ERROR; + TRANSACT_RETURN(SM_ACTION_INTERNAL_NOOP, NULL); + } } - if (OB_SUCC(ret)) { - s.server_info_.set_addr(last_session->get_netvc()->get_remote_addr()); + s.server_info_.set_addr(target_addr); s.pll_info_.lookup_success_ = true; } } else if (obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == cmd @@ -881,7 +1091,7 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) ret = OB_ERR_UNEXPECTED; LOG_WARN("info is invalid", K(ret)); TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); - } else if (OB_UNLIKELY(info->get_addr() != last_session->get_netvc()->get_remote_addr())) { + } else if (OB_UNLIKELY(!ops_ip_addr_port_eq(info->get_addr(), target_addr))) { s.mysql_errcode_ = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; s.mysql_errmsg_ = "send piece info target server is not the trans server"; int tmp_ret = OB_SUCCESS; @@ -890,7 +1100,7 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } else { LOG_WARN("send piece/long data target server is not the trans server", "target server", info->get_addr(), - "trans server", ObIpEndpoint(last_session->get_netvc()->get_remote_addr())); + "trans server", ObIpEndpoint(target_addr)); } ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; @@ -900,22 +1110,29 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } if (OB_SUCC(ret)) { - s.server_info_.set_addr(last_session->get_netvc()->get_remote_addr()); + s.server_info_.set_addr(target_addr); s.pll_info_.lookup_success_ = true; } } else { - s.server_info_.set_addr(last_session->get_netvc()->get_remote_addr()); + s.server_info_.set_addr(target_addr); s.pll_info_.lookup_success_ = true; } if (OB_SUCC(ret)) { - start_access_control(s); + // if target db server set, then make sure target db server is the choosen server + if ((hint_target_db && !client_request.get_parse_result().get_target_db_server()->contains(s.server_info_.addr_)) || + (!hint_target_db && conf_target_db && !s.sm_->target_db_server_->contains(s.server_info_.addr_))) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("Not allow to route to", "choosen server", s.server_info_.addr_, K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + } else { + start_access_control(s); + } } - } else { - LOG_WARN("[ObMysqlTransact::handle request] last session is NULL, we have to disconnect"); - TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); } } // end of !s.need_pl_lookup + + LOG_DEBUG("handle oceanbase request, is addr valid:", K(s.server_info_.addr_.is_valid())); } void ObMysqlTransact::handle_fetch_request(ObTransState &s) @@ -998,6 +1215,8 @@ void ObMysqlTransact::handle_request(ObTransState &s) } // so it's an internal request TRANSACT_RETURN(SM_ACTION_INTERNAL_REQUEST, handle_internal_request); + } else if (OB_UNLIKELY(is_binlog_request(s))) { + handle_binlog_request(s); } else { if (OB_UNLIKELY(get_global_performance_params().enable_stat_)) { if (obmysql::OB_MYSQL_COM_QUERY == s.trans_info_.sql_cmd_) { @@ -1049,31 +1268,131 @@ void ObMysqlTransact::handle_request(ObTransState &s) } } -inline bool ObMysqlTransact::need_use_last_server_session(ObTransState &s) +inline bool ObMysqlTransact::need_use_coordinator_session(ObTransState &s) { + // session in trans internal routing state + bool use_coordinator = false; + int ret = OB_SUCCESS; + ObSqlParseResult &parser_result = s.trans_info_.client_request_.get_parse_result(); + ObClientSessionInfo &session_info = s.sm_->get_client_session()->get_session_info(); + if (ObMysqlTransact::is_trans_specified(s)) { + if (s.sm_->get_client_session() != NULL + && s.sm_->get_client_session()->get_server_session() != NULL + && ops_ip_addr_port_eq (s.sm_->get_client_session()->get_trans_coordinator_ss_addr(), + s.sm_->get_client_session()->get_server_session()->get_netvc()->get_remote_addr())) { + LOG_WARN("internal routing transaction specified, coordinator session not equal with last session", K(ret)); + } + use_coordinator = true; + } else if (s.trans_info_.request_content_length_ > 0) { + // large request, route to coordinator session + use_coordinator = true; + } else if (s.sm_->get_client_session()->is_trans_internal_routing() + && is_sql_able_to_route_participant_in_trans(parser_result, s.trans_info_.sql_cmd_)) { + use_coordinator = false; + } else if (s.sm_->get_client_session()->is_trans_internal_routing() && parser_result.is_text_ps_execute_stmt()) { + ObTextPsEntry* text_ps_entry = NULL; + ObTextPsNameEntry* text_ps_name_entry = session_info.get_text_ps_name_entry(); + if (OB_ISNULL(text_ps_name_entry)) { + use_coordinator = true; + ret = OB_ERR_PREPARE_STMT_NOT_FOUND; + LOG_WARN("need use coordinator on text ps execute stmt, get text ps name entry failed", K(ret)); + } else if (OB_ISNULL(text_ps_entry = text_ps_name_entry->text_ps_entry_) || !text_ps_entry->is_valid()) { + use_coordinator = true; + ret = OB_INVALID_ERROR; + LOG_WARN("need use coordinator on text ps execute stmt, get text ps entry failed", K(ret)); + } else { + use_coordinator = !is_sql_able_to_route_participant_in_trans(text_ps_entry->get_base_ps_parse_result(), s.trans_info_.sql_cmd_); + } + } else { + // the rest of sql, use coordinator session + use_coordinator = true; + } + return use_coordinator; +} + +bool ObMysqlTransact::is_sql_able_to_route_participant_in_trans(obutils::ObSqlParseResult& base_sql_parse_result, obmysql::ObMySQLCmd sql_cmd) { + // transaction internal routing rule + // (1) route dml with table name to participant + // (2) route OB_MYSQL_COM_STMT_EXECUTE or text ps execute with inner sql like (1) to participant + // (3) route sql command except OB_MYSQL_COM_QUERY/OB_MYSQL_COM_STMT_PREPARE/OB_MYSQL_COM_STMT_EXECUTE to coordinator + // (4) route dual request to coordinator, in case of sql like `select DBMS_XA.XA_START(DBMS_XA_XID(?,?,?), 65536) from dual;` start xa transaction + // (5) route multi-stmt to coordinator + + bool able_to_route = false; + switch (sql_cmd) { + case obmysql::OB_MYSQL_COM_QUERY: + case obmysql::OB_MYSQL_COM_STMT_PREPARE: + case obmysql::OB_MYSQL_COM_STMT_EXECUTE: + able_to_route = true; + break; + + default: + able_to_route = false; + break; + } + if (able_to_route) { + if (base_sql_parse_result.is_dual_request()) { + able_to_route = false; + } else { + able_to_route = (base_sql_parse_result.is_text_ps_prepare_stmt() + && base_sql_parse_result.is_text_ps_inner_dml_stmt() + && !base_sql_parse_result.is_text_ps_call_stmt() + && !base_sql_parse_result.is_multi_semicolon_in_stmt() + && base_sql_parse_result.get_table_name_length() > 0) + || (base_sql_parse_result.is_dml_stmt() + && !base_sql_parse_result.is_multi_stmt() + && !base_sql_parse_result.is_multi_semicolon_in_stmt() + && base_sql_parse_result.get_table_name_length() > 0); + } + } + return able_to_route; +} + +inline ObMysqlTransact::ObPLLookupState ObMysqlTransact::need_pl_lookup(ObTransState &s) { - // there are three cases we must force to use last server session - // 1. trans has begin, other sql must send to the same server session - // 2. a func depend on last execute sql - // 3. has already specified transaction characteristics (set transaction xxx), not commit yet, - return (is_in_trans(s) - || OB_UNLIKELY(NULL != s.sm_->client_session_ - && !s.sm_->client_session_->is_session_pool_client() - && (s.trans_info_.client_request_.get_parse_result().has_dependent_func() - || s.sm_->client_session_->get_session_info().is_trans_specified()))); + ObPLLookupState state = NEED_PL_LOOKUP; + bool trans_specified = is_trans_specified(s); + bool is_dep_func = has_dependent_func(s); + bool in_trans = is_in_trans(s); + if (in_trans && s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing()) { + if (is_dep_func) { + state = USE_LAST_SERVER_SESSION; + } else { + state = need_use_coordinator_session(s) ? USE_COORDINATOR_SESSION : NEED_PL_LOOKUP; + } + } else { + state =(in_trans || trans_specified || is_dep_func) ? USE_LAST_SERVER_SESSION : NEED_PL_LOOKUP; + } + // if we don't use last server session/coordinator session, we must do pl lookup + LOG_DEBUG("need pl lookup", "state", get_pl_lookup_state_string(state), + "sql_cmd", ObProxyParserUtils::get_sql_cmd_name(s.trans_info_.sql_cmd_), + "is trans specified", trans_specified, + "has dependent func", is_dep_func, + "is in trans", in_trans); + + return state; +} + +inline bool ObMysqlTransact::is_trans_specified(ObTransState &s) +{ + return OB_UNLIKELY(NULL != s.sm_->client_session_ + && !s.sm_->client_session_->is_session_pool_client() + && s.sm_->client_session_->get_session_info().is_trans_specified()); } -inline bool ObMysqlTransact::need_pl_lookup(ObTransState &s) +inline bool ObMysqlTransact::has_dependent_func(ObTransState &s) { - // if we don't use last server session, we must do pl lookup - return !need_use_last_server_session(s); + return OB_UNLIKELY(NULL != s.sm_->client_session_ + && !s.sm_->client_session_->is_session_pool_client() + && (s.trans_info_.client_request_.get_parse_result().has_dependent_func())); } //reroute conditions: -// 1. Transaction first SQL +// 1. Transaction first SQL/FREE TRANSACTION ROUTE // 2. No reroute has occurred // 3. It is not a large request, and the request is less than 4K // (because the data in the read_buffer will be consumed again here, and the second routing will be copied from the 4K Buffer) // 4. In case of EXECUTE or PREPARE_EXECUTE request, no pieceInfo structure exists +// 5.Non-designated primary zone/IP routing inline bool ObMysqlTransact::is_need_reroute(ObMysqlTransact::ObTransState &s) { int ret = OB_SUCCESS; @@ -1082,10 +1401,17 @@ inline bool ObMysqlTransact::is_need_reroute(ObMysqlTransact::ObTransState &s) bool is_need_reroute = false; is_need_reroute = s.mysql_config_params_->enable_reroute_ - && !s.is_rerouted_ && s.need_pl_lookup_ - && s.is_trans_first_request_ + && '\0' == s.mysql_config_params_->proxy_primary_zone_name_[0] + && !s.is_rerouted_ && s.is_need_pl_lookup() + && (s.is_trans_first_request_ + || (ObMysqlTransact::is_in_trans(s) + && s.sm_->client_session_->is_trans_internal_routing())) && !s.trans_info_.client_request_.is_large_request() - && total_request_packet_len == cached_request_packet_len; + && total_request_packet_len == cached_request_packet_len + && (OB_ISNULL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()) + || s.trans_info_.client_request_.get_parse_result().get_target_db_server()->is_empty()) + && (OB_ISNULL(s.sm_->target_db_server_) || s.sm_->target_db_server_->is_empty()); + if (is_need_reroute && (obmysql::OB_MYSQL_COM_STMT_PREPARE_EXECUTE == s.trans_info_.client_request_.get_packet_meta().cmd_ @@ -1159,37 +1485,48 @@ int ObMysqlTransact::extract_partition_info(ObTransState &s) } else { is_table_name_from_parser = true; - database_name = parse_result.get_database_name(); - if (OB_LIKELY(database_name.empty())) { + if (OB_LIKELY(parse_result.get_database_name().empty())) { if (OB_SUCCESS != cs_info.get_database_name(database_name)) { database_name = OB_SYS_DATABASE_NAME; } + ObProxyParseString tmp_database_name; + tmp_database_name.str_ = database_name.ptr(); + tmp_database_name.end_ptr_ = database_name.ptr() + database_name.length() - 1; + tmp_database_name.str_len_ = database_name.length(); + tmp_database_name.quote_type_ = OBPROXY_QUOTE_T_INVALID; + if (OB_FAIL(parse_result.set_db_name(tmp_database_name))) { + LOG_WARN("parse result set db name failed", K(ret)); + } } else { is_database_name_from_parser = true; } - package_name = parse_result.get_package_name(); - if (OB_UNLIKELY(!package_name.empty())) { - is_package_name_from_parser = true; - } - - // if run here, means table name and db name all come from parse result - if (OB_UNLIKELY(s.sm_->client_session_->get_session_info().is_oracle_mode())) { - if (is_table_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_table_name_quote()) { - string_to_upper_case(table_name.ptr(), table_name.length()); - } - if (is_database_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_database_name_quote()) { - string_to_upper_case(database_name.ptr(), database_name.length()); + if (OB_SUCC(ret)) { + database_name = parse_result.get_database_name(); + package_name = parse_result.get_package_name(); + if (OB_UNLIKELY(!package_name.empty())) { + is_package_name_from_parser = true; } - if (is_package_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_package_name_quote()) { - string_to_upper_case(package_name.ptr(), package_name.length()); + + // if run here, means table name and db name all come from parse result + if (OB_UNLIKELY(s.sm_->client_session_->get_session_info().is_oracle_mode())) { + if (is_table_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_table_name_quote()) { + string_to_upper_case(table_name.ptr(), table_name.length()); + } + if (is_database_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_database_name_quote()) { + string_to_upper_case(database_name.ptr(), database_name.length()); + } + if (is_package_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_package_name_quote()) { + string_to_upper_case(package_name.ptr(), package_name.length()); + } } } } if (OB_SUCC(ret)) { if (IS_CLUSTER_VERSION_LESS_THAN_V4(s.sm_->sm_cluster_resource_->cluster_version_) - && tenant_name == OB_SYS_TENANT_NAME && database_name == OB_SYS_DATABASE_NAME) { + && tenant_name == OB_SYS_TENANT_NAME && database_name == OB_SYS_DATABASE_NAME + && !get_global_proxy_config().enable_qa_mode) { table_name = OB_ALL_DUMMY_TNAME; } } @@ -1550,6 +1887,12 @@ void ObMysqlTransact::handle_congestion_control_lookup(ObTransState &s) "and will expand its retry interval to avoid other connections use this server", KPC(cgt_entry)); cgt_entry->set_alive_failed_at(get_hrtime()); + if (get_global_proxy_config().server_detect_mode != 0) { + if (OB_LIKELY(NULL != s.sm_->sm_cluster_resource_)) { + s.sm_->sm_cluster_resource_->alive_addr_set_.set_refactored(cgt_entry->server_ip_); + } + is_in_alive_congested = true; + } } else { is_in_alive_congested = true; } @@ -1656,8 +1999,7 @@ void ObMysqlTransact::check_safe_read_snapshot(ObTransState &s) ObSafeSnapshotEntry *entry = NULL; const ObProxyPartitionLocation *pl = s.pll_info_.route_.cur_chosen_pl_; ObAddr addr; - addr.set_ipv4_addr(s.server_info_.addr_.get_ip4_host_order(), - static_cast(s.server_info_.addr_.get_port_host_order())); + addr.set_sockaddr(s.server_info_.addr_.sa_); if (OB_ISNULL(pl) || pl->is_server_changed()) { // get the max snapshot server of all server int64_t count = s.sm_->client_session_->dummy_ldc_.count(); @@ -1809,6 +2151,22 @@ void ObMysqlTransact::handle_pl_lookup(ObTransState &s) "addr", s.server_info_.addr_, "attempts", s.current_.attempts_, "sm_id", s.sm_->sm_id_); + } else if (OB_UNLIKELY(is_server_addr_set + && ((OB_NOT_NULL(s.sm_->target_db_server_) && !s.sm_->target_db_server_->is_empty()) + || (OB_NOT_NULL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()) + && !s.trans_info_.client_request_.get_parse_result().get_target_db_server()->is_empty())))) { + if (OB_NOT_NULL(s.sm_->client_session_->dummy_entry_) + && s.sm_->client_session_->dummy_entry_->is_avail_state() + && s.sm_->client_session_->dummy_entry_->is_valid() + && is_addr_logonly(s.server_info_.addr_, s.sm_->client_session_->dummy_entry_->get_tenant_servers())) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("Not allow to route to logonly replica", "choosen server", s.server_info_.addr_, K(ret)); + } + LOG_DEBUG("[ObMysqlTransact::handle_pl_lookup] use target db server and server addr is set, " + "use cached session", + "addr", s.server_info_.addr_, + "attempts", s.current_.attempts_, + "sm_id", s.sm_->sm_id_); } else { const ObProxyReplicaLocation *replica = NULL; #if OB_DETAILED_SLOW_QUERY @@ -1845,7 +2203,7 @@ void ObMysqlTransact::handle_pl_lookup(ObTransState &s) const ObProxyReplicaLocation *replica = pl->get_replica(i); if (NULL != replica && replica->is_leader()) { fill_addr = true; - s.server_info_.set_addr(replica->server_.get_ipv4(), static_cast(replica->server_.get_port())); + s.server_info_.set_addr(ops_ip_sa_cast(replica->server_.get_sockaddr())); LOG_DEBUG("set addr here", K(s.server_info_.addr_)); s.pll_info_.route_.cur_chosen_server_.replica_ = replica; s.pll_info_.route_.leader_item_.is_used_ = true; @@ -1870,7 +2228,7 @@ void ObMysqlTransact::handle_pl_lookup(ObTransState &s) ObSEArray simple_servers_info( ObServerStateRefreshCont::DEFAULT_SERVER_COUNT, *allocator); get_region_name_and_server_info(s, simple_servers_info, region_names); - ObString proxy_primary_zone_name(s.mysql_config_params_->proxy_primary_zone_name_); + ObString proxy_primary_zone_name(s.mysql_config_params_->proxy_primary_zone_name_); if (OB_FAIL(s.pll_info_.route_.fill_replicas( consistency_level, @@ -1927,9 +2285,8 @@ void ObMysqlTransact::handle_pl_lookup(ObTransState &s) ret = OB_ERR_UNEXPECTED; LOG_WARN("no replica avail", K(replica), K(ret)); } else { - s.server_info_.set_addr(replica->server_.get_ipv4(), - static_cast(replica->server_.get_port())); - LOG_DEBUG("set addr here", K(s.server_info_.addr_)); + s.server_info_.set_addr(ops_ip_sa_cast(replica->server_.get_sockaddr())); + LOG_DEBUG("get replica by pl lookup, set addr", K(s.server_info_.addr_)); } if (found_leader_force_congested) { @@ -1981,25 +2338,32 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) // server session lookup failed, response err/ok packet LOG_DEBUG("[ObMysqlTransact::handle_server_addr_lookup] server addr lookup " "failed, response err/ok packet", "errcode", query_info->errcode_); + ObMIOBuffer *buf = NULL; + ObMysqlSM *sm = s.sm_; + // consume data in client buffer reader - if (OB_FAIL(s.sm_->get_client_buffer_reader()->consume_all())) { + if (OB_ISNULL(sm)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect empty sm", K(ret)); + } else if (OB_FAIL(sm->get_client_buffer_reader()->consume_all())) { LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] fail to consume client_buffer_reader_", K(ret)); } else if (OB_FAIL(s.alloc_internal_buffer(MYSQL_BUFFER_SIZE))) { LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] fail to allocate internal miobuffer", K(ret)); } else { buf = s.internal_buffer_; uint8_t seq = static_cast(s.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); - ObMysqlClientSession *client_session = s.sm_->get_client_session(); + ObMysqlClientSession *client_session = sm->get_client_session(); + ObProxyProtocol client_protocol = sm->get_client_session_protocol(); switch (query_info->errcode_) { case OB_SUCCESS: { - if (OB_ISNULL(s.sm_->client_session_)) { + if (OB_ISNULL(client_session)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] client session is NULL, will disconnect", K(ret)); } else { const ObMySQLCapabilityFlags &capability = get_client_session_info(s).get_orig_capability_flags(); - if (OB_FAIL(ObMysqlPacketUtil::encode_ok_packet(*buf, seq, 0, capability))) { + if (ObProxyPacketWriter::write_ok_packet(*buf, *client_session, client_protocol, seq, 0, capability)) { LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] fail to build ok resp " "packet", K(ret)); } @@ -2011,8 +2375,8 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) char *err_msg = NULL; if (OB_FAIL(ObProxyPacketWriter::get_user_err_buf(query_info->errcode_, err_msg, query_info->cs_id_))) { LOG_WARN("fail to get user err buf", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, seq, - query_info->errcode_, err_msg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + seq, query_info->errcode_, err_msg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to build not supported err resp", K(ret)); } break; @@ -2021,8 +2385,8 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) char *err_msg = NULL; if (OB_FAIL(ObProxyPacketWriter::get_user_err_buf(query_info->errcode_, err_msg, query_info->priv_name_))) { LOG_WARN("fail to get user err buf", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, seq, - query_info->errcode_, err_msg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + seq, query_info->errcode_, err_msg))) { LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] fail to build no privilege err resp packet", K(ret), "priv_name", query_info->priv_name_); } @@ -2032,8 +2396,8 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) char *err_msg = NULL; if (OB_FAIL(ObProxyPacketWriter::get_err_buf(query_info->errcode_, err_msg))) { LOG_WARN("fail to get err buf", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, seq, - query_info->errcode_, err_msg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + seq, query_info->errcode_, err_msg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to build err resp packet", K(ret)); } break; @@ -2074,7 +2438,7 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) inline void ObMysqlTransact::start_access_control(ObTransState &s) { - if (s.need_pl_lookup_) { + if (s.is_need_pl_lookup()) { TRANSACT_RETURN(SM_ACTION_API_OBSERVER_PL, ObMysqlTransact::lookup_skip_open_server); s.sm_->set_skip_plugin(true); } else { @@ -2087,26 +2451,6 @@ inline void ObMysqlTransact::lookup_skip_open_server(ObTransState &s) TRANSACT_RETURN(SM_ACTION_OBSERVER_OPEN, ObMysqlTransact::handle_response); } -inline int ObMysqlTransact::build_user_request( - ObTransState &s, ObIOBufferReader *client_buffer_reader, - ObIOBufferReader *&reader, int64_t &request_len) -{ - int ret = OB_SUCCESS; - - if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { - if (OB_FAIL(build_oceanbase_user_request(s, client_buffer_reader, reader, request_len))) { - LOG_WARN("fail to build oceanbase user request", K(ret)); - } - } else { - // no need compress, send directly - int64_t client_request_len = s.trans_info_.client_request_.get_packet_len(); - request_len = client_request_len; - reader = client_buffer_reader; - } - - return ret; -} - int ObMysqlTransact::rewrite_stmt_id(ObTransState &s, ObIOBufferReader *client_buffer_reader) { int ret = OB_SUCCESS; @@ -2172,12 +2516,32 @@ int ObMysqlTransact::rewrite_stmt_id(ObTransState &s, ObIOBufferReader *client_b return ret; } +inline int ObMysqlTransact::build_user_request( + ObTransState &s, ObIOBufferReader *client_buffer_reader, + ObIOBufferReader *&reader, int64_t &request_len) +{ + int ret = OB_SUCCESS; + + if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { + if (OB_FAIL(build_oceanbase_user_request(s, client_buffer_reader, reader, request_len))) { + LOG_WARN("fail to build oceanbase user request", K(ret)); + } + } else { + // no need compress, send directly + int64_t client_request_len = s.trans_info_.client_request_.get_packet_len(); + request_len = client_request_len; + reader = client_buffer_reader; + } + + return ret; +} + inline int ObMysqlTransact::build_oceanbase_user_request( ObTransState &s, ObIOBufferReader *client_buffer_reader, ObIOBufferReader *&reader, int64_t &request_len) { int ret = OB_SUCCESS; - ObProxyProtocol ob_proxy_protocol = s.sm_->get_server_session_protocol(); + ObProxyProtocol server_protocol = s.sm_->get_server_session_protocol(); int64_t client_request_len = s.trans_info_.client_request_.get_packet_len(); // obproxy only send one mysql request packet at once; // if received multi request packets, we will send it one by one; @@ -2197,10 +2561,11 @@ inline int ObMysqlTransact::build_oceanbase_user_request( } else if (OB_FAIL(rewrite_stmt_id(s, client_buffer_reader))) { LOG_WARN("rewrite stmt id failed", K(ret)); } else { + obmysql::ObMySQLCmd req_cmd_type = s.trans_info_.client_request_.get_packet_meta().cmd_; ObIOBufferReader *request_buffer_reader = client_buffer_reader; ObMIOBuffer *write_buffer = NULL; - if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol - || ObProxyProtocol::PROTOCOL_CHECKSUM == ob_proxy_protocol) { // convert standard mysql protocol to compression protocol + if (ObProxyProtocol::PROTOCOL_OB20 == server_protocol + || ObProxyProtocol::PROTOCOL_CHECKSUM == server_protocol) { // convert standard mysql protocol to compression protocol uint8_t compress_seq = 0; if (OB_ISNULL(write_buffer = new_miobuffer(MYSQL_BUFFER_SIZE))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -2208,18 +2573,46 @@ inline int ObMysqlTransact::build_oceanbase_user_request( } else if (OB_ISNULL(reader = write_buffer->alloc_reader())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[ObMysqlTransact::build_user_request] failed to allocate iobuffer reader", K(ret)); - } else if ((obmysql::OB_MYSQL_COM_STMT_CLOSE == s.trans_info_.client_request_.get_packet_meta().cmd_ - || obmysql::OB_MYSQL_COM_STMT_RESET == s.trans_info_.client_request_.get_packet_meta().cmd_ + } else if ((obmysql::OB_MYSQL_COM_STMT_CLOSE == req_cmd_type + || obmysql::OB_MYSQL_COM_STMT_RESET == req_cmd_type || s.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt()) && OB_ISNULL(request_buffer_reader = client_buffer_reader->clone())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[ObMysqlTransact::build_user_request] failed to clone client buffer reader", K(ret)); } else { - if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { + if (ObProxyProtocol::PROTOCOL_OB20 == server_protocol) { if (OB_FAIL(build_oceanbase_ob20_user_request(s, *write_buffer, *request_buffer_reader, client_request_len, compress_seq))) { LOG_WARN("fail to build oceanbase ob20 user request", K(ret), K(client_request_len), K(compress_seq)); - } + } else { + // handle tail crc for other cmd type, close will send to every server, do not clear buf here + if (obmysql::OB_MYSQL_COM_STMT_CLOSE != req_cmd_type + && obmysql::OB_MYSQL_COM_STMT_RESET != req_cmd_type + && !s.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt()) { + ObProxyProtocol client_protocol = s.sm_->get_client_session_protocol(); + if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + ObClientSessionInfo &cs_info = s.sm_->get_client_session()->get_session_info(); + const bool ob20_req_received_done = cs_info.ob20_request_.ob20_request_received_done_; + const int64_t ob20_req_remain_payload_len = cs_info.ob20_request_.remain_payload_len_; + if (ob20_req_received_done + && ob20_req_remain_payload_len == 0) { + cs_info.ob20_request_.ob20_request_received_done_ = false; + int64_t read_avail = client_buffer_reader->read_avail(); + LOG_DEBUG("after build user ob req, handle ob20 tail crc in buffer", + K(ob20_req_received_done), K(ob20_req_remain_payload_len), K(read_avail)); + if (read_avail >= OB20_PROTOCOL_TAILER_LENGTH) { + if (OB_FAIL(client_buffer_reader->consume(OB20_PROTOCOL_TAILER_LENGTH))) { + LOG_WARN("fail to consume the last crc buffer in client request buffer", K(ret)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected enter here, client-proxy use ob2.0, handled mysql packet in payload done," + " unexpected remain buffer len, expect tail crc 4", K(ret), K(read_avail)); + } + } + } + } + } // else } else { // compress protocol const bool use_fast_compress = true; @@ -2231,8 +2624,8 @@ inline int ObMysqlTransact::build_oceanbase_user_request( } } - if (obmysql::OB_MYSQL_COM_STMT_CLOSE == s.trans_info_.client_request_.get_packet_meta().cmd_ - || obmysql::OB_MYSQL_COM_STMT_RESET == s.trans_info_.client_request_.get_packet_meta().cmd_ + if (obmysql::OB_MYSQL_COM_STMT_CLOSE == req_cmd_type + || obmysql::OB_MYSQL_COM_STMT_RESET == req_cmd_type || s.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt()) { request_buffer_reader->dealloc(); request_buffer_reader = NULL; @@ -2241,15 +2634,15 @@ inline int ObMysqlTransact::build_oceanbase_user_request( if (OB_SUCC(ret)) { s.sm_->get_server_session()->set_compressed_seq(compress_seq); request_len = reader->read_avail(); - LOG_DEBUG("build user compressed request succ", K(ob_proxy_protocol), + LOG_DEBUG("build user compressed request succ", K(server_protocol), "origin len", client_request_len, "compress len", request_len, "compress seq", compress_seq); } } } else { // no need compress, send directly request_len = client_request_len; - if (obmysql::OB_MYSQL_COM_STMT_CLOSE == s.trans_info_.client_request_.get_packet_meta().cmd_ - || obmysql::OB_MYSQL_COM_STMT_RESET == s.trans_info_.client_request_.get_packet_meta().cmd_ + if (obmysql::OB_MYSQL_COM_STMT_CLOSE == req_cmd_type + || obmysql::OB_MYSQL_COM_STMT_RESET == req_cmd_type || s.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt()) { int64_t written_len = 0; if (OB_ISNULL(write_buffer = new_miobuffer(MYSQL_BUFFER_SIZE))) { @@ -2280,7 +2673,7 @@ inline int ObMysqlTransact::build_oceanbase_user_request( } LOG_DEBUG("[ObMysqlTransact::build_user_request] send request to observer", - "sm_id", s.sm_->sm_id_, K(ob_proxy_protocol), K(client_request_len), + "sm_id", s.sm_->sm_id_, K(server_protocol), K(client_request_len), "total_client_request_len", (reader != NULL) ? reader->read_avail() : 0, "request len send to server", request_len, K(s.trans_info_.request_content_length_), @@ -2306,11 +2699,13 @@ int ObMysqlTransact::build_oceanbase_ob20_user_request(ObTransState &s, ObMIOBuf bool generated_extra_info = false; bool is_last_packet = false; const bool need_reroute = is_need_reroute(s); + const bool is_weak_read = (WEAK == s.sm_->trans_state_.get_trans_consistency_level(s.sm_->get_client_session()->get_session_info())); ObSEArray extra_info; ObSqlString sess_info_value; - char client_ip_buf[MAX_IP_BUFFER_LEN] = "0"; - char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "0"; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; ObMysqlServerSession *server_session = s.sm_->get_server_session(); + ObMysqlClientSession *client_session = s.sm_->get_client_session(); uint32_t req_id = server_session->get_next_server_request_id(); while (OB_SUCC(ret) && remain_req_len > 0) { @@ -2335,8 +2730,9 @@ int ObMysqlTransact::build_oceanbase_ob20_user_request(ObTransState &s, ObMIOBuf if (OB_SUCC(ret)) { Ob20ProtocolHeaderParam ob20_head_param(server_session->get_server_sessid(), - req_id, compress_seq, compress_seq, is_last_packet, need_reroute, - server_session->get_session_info().is_new_extra_info_supported()); + req_id, compress_seq, compress_seq, is_last_packet, is_weak_read, need_reroute, + server_session->get_session_info().is_new_extra_info_supported(), + client_session->is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::consume_and_compress_data(&request_buffer_reader, &write_buffer, curr_req_len, ob20_head_param, &extra_info))) { LOG_WARN("fail to consume and compress ob20 data", K(ret)); @@ -2353,6 +2749,24 @@ int ObMysqlTransact::build_oceanbase_ob20_user_request(ObTransState &s, ObMIOBuf return ret; } +bool ObMysqlTransact::handle_set_trans_internal_routing(ObMysqlTransact::ObTransState &s, bool server_transaction_routing_flag) +{ + // used to set the header flag + // if session in a transaction, return the config of enable_internal_transaction_routing in server + // else return the config enable_internal_transaction_routing + bool internal_routing_flag = false; + if (is_trans_specified(s)) { + // trans_spcified, disable trans internal routing + internal_routing_flag = false; + } else if (!is_in_trans(s)) { + // do nothing, return config of enable_internal_transaction + internal_routing_flag = s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing(); + } else { + internal_routing_flag = s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing() && server_transaction_routing_flag; + } + return internal_routing_flag; +} + inline int ObMysqlTransact::build_normal_login_request( ObTransState &s, ObIOBufferReader *&reader, int64_t &request_len) { @@ -2429,6 +2843,9 @@ inline int ObMysqlTransact::build_normal_login_request( int ObMysqlTransact::build_server_request(ObTransState &s, ObIOBufferReader *&reader, int64_t &request_len) { int ret = OB_SUCCESS; + LOG_DEBUG("[ObMysqlTransact::build_server_request] checking sending sql", + "cur_send_action", ObMysqlTransact::get_send_action_name(s.current_.send_action_), K(s.trans_info_.get_print_sql()), K(is_in_trans(s)), + K(s.sm_->get_client_session()->get_cs_id())); ObIOBufferReader *client_buffer_reader = NULL; BuildFunc build_func = NULL; reader = NULL; @@ -2476,7 +2893,9 @@ int ObMysqlTransact::build_server_request(ObTransState &s, ObIOBufferReader *&re } case SERVER_SEND_SAVED_LOGIN: - if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { + if (is_binlog_request(s)) { + build_func = ObMysqlRequestBuilder::build_binlog_login_packet; + } else if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { // write the buffor using saved login packet directly build_func = ObMysqlRequestBuilder::build_saved_login_packet; } else { @@ -2497,14 +2916,18 @@ int ObMysqlTransact::build_server_request(ObTransState &s, ObIOBufferReader *&re case SERVER_SEND_SESSION_VARS: build_func = ObMysqlRequestBuilder::build_session_vars_sync_packet; break; - - case SERVER_SEND_LAST_INSERT_ID: - build_func = ObMysqlRequestBuilder::build_last_insert_id_sync_packet; + + case SERVER_SEND_SESSION_USER_VARS: + build_func = ObMysqlRequestBuilder::build_session_user_vars_sync_packet; break; case SERVER_SEND_START_TRANS: build_func = ObMysqlRequestBuilder::build_start_trans_request; break; + + case SERVER_SEND_XA_START: + build_func = ObMysqlRequestBuilder::build_xa_start_request; + break; case SERVER_SEND_PREPARE: build_func = ObMysqlRequestBuilder::build_prepare_request; @@ -2658,7 +3081,7 @@ inline int ObMysqlTransact::do_handle_prepare_succ(ObTransState &s, uint32_t ser ObClientSessionInfo &cs_info = get_client_session_info(s); ObServerSessionInfo &ss_info = get_server_session_info(s); - uint32_t client_ps_id = cs_info.get_client_ps_id(); + uint32_t client_ps_id = s.is_hold_xa_start_? cs_info.get_xa_start_ps_id() : cs_info.get_client_ps_id(); ObPsIdPair *ps_id_pair = ss_info.get_ps_id_pair(client_ps_id); /* here two case: * if first in: @@ -2747,7 +3170,7 @@ inline int ObMysqlTransact::do_handle_execute_succ(ObTransState &s) ObClientSessionInfo &cs_info = get_client_session_info(s); ObServerSessionInfo &ss_info = get_server_session_info(s); - uint32_t client_ps_id = cs_info.get_client_ps_id(); + uint32_t client_ps_id = s.is_hold_xa_start_? cs_info.get_xa_start_ps_id() : cs_info.get_client_ps_id(); ObPsIdPair *ps_id_pair = ss_info.get_ps_id_pair(client_ps_id); ObCursorIdPair *cursor_id_pair = ss_info.get_curosr_id_pair(client_ps_id); if (OB_ISNULL(ps_id_pair)) { @@ -2797,6 +3220,79 @@ inline int ObMysqlTransact::do_handle_execute_succ(ObTransState &s) return ret; } +inline int ObMysqlTransact::do_handle_prepare_execute_xa_succ(ObIOBufferReader &buf_reader) { + int ret = OB_SUCCESS; + int64_t offset = 0; + int64_t content_len = 0; + uint8_t seq = 0; + ObMysqlPacketReader pkt_reader; + ObNewRow row; + ObSMRow sm_row(BINARY, row); + OMPKRow row_pkt(sm_row); + OMPKPrepareExecute prepare_execute_pkt; + int32_t eof_count_before_result_set = 0; + // read prepare execute resp + if (OB_FAIL(pkt_reader.get_packet(buf_reader, prepare_execute_pkt))) { + LOG_WARN("fail to get prepare execute resp of xa start", K(ret)); + } else if (prepare_execute_pkt.get_column_num() > 0 && FALSE_IT(++eof_count_before_result_set)) { + } else if (prepare_execute_pkt.get_param_num() > 0 && FALSE_IT(++eof_count_before_result_set)) { + } else { + LOG_DEBUG("succ to get eof count of resp of xa start sync", K(eof_count_before_result_set)); + } + + int32_t eof_count = 0; + // num-param * coldef & eof & one row coldef & eof + while (OB_SUCC(ret) && eof_count < eof_count_before_result_set) { + bool is_eof = false; + if (OB_FAIL(pkt_reader.is_eof_packet(buf_reader, offset, is_eof))) { + LOG_WARN("fail test eof of resp of xa start sync", K(ret)); + } else if (OB_FAIL(pkt_reader.get_content_len_and_seq(buf_reader, offset, content_len, seq))) { + LOG_WARN("fail to read packet len and seq of resp of xa start sync", K(ret)); + } else { + offset += content_len + MYSQL_NET_HEADER_LENGTH; + } + if (is_eof) { + ++eof_count; + LOG_DEBUG("succ to read eof of resp of xa start sync", K(eof_count)); + } + } + + // read ProtocolBinary::ResultsetRow + if (OB_SUCC(ret)) { + if (OB_FAIL(pkt_reader.get_packet(buf_reader, offset, row_pkt))) { + LOG_WARN("fail to get result set row packet of resp of xa start sync", K(ret)); + } else { + // 0a 00 00 08 00 00 00 00 00 00 00 00 00 00 + // ^^^^^^^^^^^ header + // ^^ packet header + // ^^ bitmap + // ^^^^^^^^^^^^^^^^^^^^^^^ long/int(8/4bytes) + const char *content_buf = row_pkt.get_cdata(); + int64_t content_len = row_pkt.get_clen(); + int8_t pkt_hdr = -1; + int8_t bitmap = -1; + int32_t xa_result = -1; + if (OB_FAIL(ObMysqlPacketUtil::get_int1(content_buf, content_len, pkt_hdr))) { + LOG_WARN("fail to get pkt hdr from row packet of resp of xa start sync", K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_int1(content_buf, content_len, bitmap))) { + LOG_WARN("fail to get bitmap from row packet of resp of xa start sync", K(ret)); + } else if (OB_UNLIKELY(pkt_hdr != 0x00)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("wrong result set row pkt hdr of resp of xa start sync", K(ret), K(pkt_hdr)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_int4(content_buf, content_len, xa_result))) { + LOG_WARN("fail to get xa result of resp of xa start sync", K(ret)); + } else if (OB_UNLIKELY(xa_result != 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to sync xa start", K(xa_result), K(ret)); + } else { + LOG_DEBUG("succ to sync xa start"); + } + } + } + + return ret; +} + inline void ObMysqlTransact::handle_execute_succ(ObTransState &s) { int ret = OB_SUCCESS; @@ -2842,11 +3338,12 @@ inline void ObMysqlTransact::handle_prepare_execute_succ(ObTransState &s) } else if (OB_FAIL(do_handle_prepare_succ(s, server_ps_id))) { LOG_WARN("fail to do handle prepare succ", K(ret)); } - if (OB_SUCC(ret) && s.trans_info_.server_response_.get_analyze_result().is_resultset_resp()) { if (OB_FAIL(do_handle_execute_succ(s))) { LOG_WARN("fail to do handle execute succ", K(ret)); - } + } else if (s.is_hold_xa_start_ && OB_FAIL(do_handle_prepare_execute_xa_succ(*buf_reader))) { + LOG_WARN("fail to do handle prepare execute xa succ", K(ret)); + } else {} } } @@ -2915,6 +3412,7 @@ int ObMysqlTransact::handle_text_ps_drop_succ(ObTransState &s, bool &is_user_req int ret = OB_SUCCESS; is_user_request = false; + // text_ps_drop can not handle session info in trim_ok_packet, handle here ObClientSessionInfo &cs_info = get_client_session_info(s); ObServerSessionInfo &ss_info = get_server_session_info(s); uint32_t ps_id = cs_info.get_client_ps_id(); @@ -2923,8 +3421,14 @@ int ObMysqlTransact::handle_text_ps_drop_succ(ObTransState &s, bool &is_user_req LOG_WARN("fail to erase server addr", K(ret)); } else if (OB_FAIL(ss_info.remove_text_ps_version(ps_id))) { LOG_WARN("fail to remove text ps id", K(ret)); + } else if (OB_FAIL(ObProxySessionInfoHandler::save_changed_sess_info(s.sm_->get_client_session()->get_session_info(), + s.sm_->get_server_session()->get_session_info(), + s.trans_info_.server_response_.get_analyze_result().get_extra_info(), + s.trace_log_, + false))) { + LOG_WARN("fail to save changed session info", K(get_send_action_name(s.current_.send_action_))); + s.current_.state_ = INTERNAL_ERROR; } - return ret; } @@ -3060,7 +3564,7 @@ int ObMysqlTransact::handle_reset_connection_request_succ(ObTransState &s) int ObMysqlTransact::clear_session_related_source(ObTransState &s) { int ret = OB_SUCCESS; - + ObClientSessionInfo &client_info = get_client_session_info(s); ObServerSessionInfo &server_info = get_server_session_info(s); @@ -3086,7 +3590,7 @@ int ObMysqlTransact::clear_session_related_source(ObTransState &s) if (OB_NOT_NULL(client_session)) { client_session->get_session_manager().purge_keepalives(); } - + LOG_DEBUG("succ to clear session related source"); } @@ -3103,46 +3607,45 @@ inline int ObMysqlTransact::handle_user_set_request_succ(ObTransState &s) ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid session, client session is NULL"); } else if (OB_LIKELY(set_info.node_count_ > 0)) { - ObClientSessionInfo &client_info = get_client_session_info(s); for (int i = 0; OB_SUCC(ret) && i < set_info.node_count_; i++) { - SetVarNode &var_node = set_info.var_nodes_.at(i); + SetVarNode* var_node = set_info.var_nodes_.at(i); ObObj value; - if (SET_VALUE_TYPE_INT == var_node.value_type_) { - value.set_int(var_node.int_value_); - } else if (SET_VALUE_TYPE_NUMBER == var_node.value_type_) { - const char *nptr = var_node.str_value_.buf_; + if (SET_VALUE_TYPE_INT == var_node->value_type_) { + value.set_int(var_node->int_value_); + } else if (SET_VALUE_TYPE_NUMBER == var_node->value_type_) { + const char *nptr = var_node->str_value_.ptr(); char *end_ptr = NULL; double double_val = strtod(nptr, &end_ptr); if (*nptr != '\0' && *end_ptr == '\0') { value.set_double(double_val); } else { - OBLOG_LOG(WARN, "invalid double value", "str", var_node.str_value_.string_); - value.set_varchar(var_node.str_value_.string_); + OBLOG_LOG(WARN, "invalid double value", "str", var_node->str_value_); + value.set_varchar(var_node->str_value_.config_string_); } } else { - if (0 == var_node.var_name_.string_.case_compare("character_set_results") - && 0 == var_node.str_value_.string_.case_compare("NULL")) { + if (0 == var_node->var_name_.config_string_.case_compare("character_set_results") + && 0 == var_node->str_value_.config_string_.case_compare("NULL")) { value.set_varchar(ObString::make_empty_string()); } else { - value.set_varchar(var_node.str_value_.string_); + value.set_varchar(var_node->str_value_.config_string_); } } // TODO: if not exist, insert; otherwise, cmp and update - if (SET_VAR_USER == var_node.var_type_) { - if (OB_FAIL(client_info.replace_user_variable(var_node.var_name_.string_, + if (SET_VAR_USER == var_node->var_type_) { + if (OB_FAIL(client_info.replace_user_variable(var_node->var_name_.config_string_, value))) { - LOG_WARN("fail to replace user variable", K(var_node), K(ret)); + LOG_WARN("fail to replace user variable", KPC(var_node), K(ret)); } else { - LOG_DEBUG("succ to update user variables", "key", var_node.var_name_.string_, K(value)); + LOG_DEBUG("succ to update user variables", "key", var_node->var_name_, K(value)); } - } else if (SET_VAR_SYS == var_node.var_type_) { - if (OB_FAIL(client_info.update_common_sys_variable(var_node.var_name_.string_, + } else if (SET_VAR_SYS == var_node->var_type_) { + if (OB_FAIL(client_info.update_common_sys_variable(var_node->var_name_.config_string_, value, true, false))) { - LOG_WARN("fail to update common sys variable", K(var_node), K(ret)); + LOG_WARN("fail to update common sys variable", KPC(var_node), K(ret)); } else { - LOG_DEBUG("succ to update common sys variables", "key", var_node.var_name_.string_, K(value)); + LOG_DEBUG("succ to update common sys variables", "key", var_node->var_name_.config_string_, K(value)); } } } @@ -3298,15 +3801,21 @@ inline void ObMysqlTransact::handle_use_db_succ(ObTransState &s) } } -void ObMysqlTransact::handle_error_resp(ObTransState &s) +void ObMysqlTransact::handle_error_resp(ObTransState &s, bool &is_user_request) { ObRespAnalyzeResult &resp = s.trans_info_.server_response_.get_analyze_result(); ObProxyMysqlRequest& client_request = s.trans_info_.client_request_; - bool is_user_request = false; + is_user_request = false; int64_t max_connect_attempts = get_max_connect_attempts(s); ObServerStateType pre_state = s.current_.state_; s.current_.state_ = RESPONSE_ERROR; + s.trace_log_.log_it("[get_error]", "code", resp.error_pkt_.get_err_code(), "trace_id", resp.server_trace_id_); + if (resp.is_mysql_wrong_arguments_error() + || resp.is_trans_free_route_not_supported_error() + || resp.is_internal_error()) { + LOG_WARN("trace_log", K(s.trace_log_)); + } switch(s.current_.send_action_) { case SERVER_SEND_HANDSHAKE: if (!s.sm_->client_session_->get_session_info().is_oceanbase_server()) { @@ -3445,6 +3954,8 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) } else { is_user_request = true; } + } else if (resp.is_trans_free_route_not_supported_error()) { + s.current_.error_type_ = TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR; } else if (resp.is_ora_fatal_error()) { s.current_.error_type_ = ORA_FATAL_ERROR; } else if (resp.is_standby_weak_readonly_error() @@ -3452,9 +3963,10 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) && OB_DEFAULT_CLUSTER_ID == s.sm_->sm_cluster_resource_->get_cluster_id()) { // if primary switchover, need disconnection when get STANDBY_WEAK_READONLY_ERROR error s.current_.error_type_ = STANDBY_WEAK_READONLY_ERROR; - } else if (s.is_trans_first_request_ - && !s.trans_info_.client_request_.is_large_request() - && (total_request_packet_len == cached_request_packet_len)) { + } else if ((s.is_trans_first_request_ + || (ObMysqlTransact::is_in_trans(s) && s.sm_->get_client_session()->is_trans_internal_routing())) + && !s.trans_info_.client_request_.is_large_request() + && (total_request_packet_len == cached_request_packet_len)) { if (resp.is_reroute_error()) { s.current_.error_type_ = REQUEST_REROUTE_ERROR; // if all attempts were failed, we should transfer the error pkt to client finally @@ -3497,7 +4009,7 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) } case SERVER_SEND_ALL_SESSION_VARS: case SERVER_SEND_SESSION_VARS: - case SERVER_SEND_LAST_INSERT_ID: + case SERVER_SEND_SESSION_USER_VARS: s.current_.error_type_ = RESET_SESSION_VARS_COMMON_ERROR; break; @@ -3508,6 +4020,11 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) case SERVER_SEND_START_TRANS: s.current_.error_type_ = START_TRANS_COMMON_ERROR; break; + + case SERVER_SEND_XA_START: + LOG_DEBUG("[ObMysqlTransact::handle_error_resp] xa start resp error"); + s.current_.error_type_ = START_XA_START_ERROR; + break; case SERVER_SEND_PREPARE: s.current_.error_type_ = SYNC_PREPARE_COMMON_ERROR; @@ -3595,6 +4112,8 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) } s.is_rerouted_ = true; } + } else if (TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR == s.current_.error_type_) { + s.is_rerouted_ = true; } @@ -3635,7 +4154,7 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) } } -inline void ObMysqlTransact::handle_resultset_resp(ObTransState &s) +inline void ObMysqlTransact::handle_resultset_resp(ObTransState &s, bool &is_user_request) { if (OB_UNLIKELY(obmysql::OB_MYSQL_COM_STMT_PREPARE == s.trans_info_.sql_cmd_ || SERVER_SEND_PREPARE == s.current_.send_action_)) { @@ -3647,17 +4166,27 @@ inline void ObMysqlTransact::handle_resultset_resp(ObTransState &s) } // consume response of non-user request + if (OB_UNLIKELY(SERVER_SEND_XA_START == s.current_.send_action_)) { + if (s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing()) { + record_trans_state(s, true); + } + LOG_DEBUG("[ObMysqlTransact::handle_resultset_resp] reset xa start flag s.is_hold_xa_start_"); + s.is_hold_xa_start_ = false; + } if (OB_UNLIKELY(SERVER_SEND_REQUEST != s.current_.send_action_)) { //LOG_WARN("handle_resultset_resp, not expected"); consume_response_packet(s); + is_user_request = false; + } else { + is_user_request = true; } } -inline void ObMysqlTransact::handle_ok_resp(ObTransState &s) +inline void ObMysqlTransact::handle_ok_resp(ObTransState &s, bool &is_user_request) { int ret = OB_SUCCESS; // in fact, we handle ok, eof, resultset and other responses in this function - bool is_user_request = false; + is_user_request = false; if (NULL != s.sm_->client_session_ && NULL != s.sm_->get_server_session()) { ObClientSessionInfo &client_info = get_client_session_info(s); @@ -3677,6 +4206,7 @@ inline void ObMysqlTransact::handle_ok_resp(ObTransState &s) case SERVER_SEND_ALL_SESSION_VARS: case SERVER_SEND_SESSION_VARS: + case SERVER_SEND_SESSION_USER_VARS: ObProxySessionInfoHandler::assign_session_vars_version(client_info, server_info); // send session var function will send last_insert_id in passing ObProxySessionInfoHandler::assign_last_insert_id_version(client_info, server_info); @@ -3688,12 +4218,9 @@ inline void ObMysqlTransact::handle_ok_resp(ObTransState &s) handle_use_db_succ(s); break; - case SERVER_SEND_LAST_INSERT_ID: - ObProxySessionInfoHandler::assign_last_insert_id_version(client_info, server_info); - break; - case SERVER_SEND_START_TRANS: // reset hold start trans flag if receive ok packet + LOG_DEBUG("sync session info from the ok packet of the sql `begin`"); s.is_hold_start_trans_ = false; break; @@ -3711,28 +4238,35 @@ inline void ObMysqlTransact::handle_ok_resp(ObTransState &s) K(client_info), K(server_info)); break; } + + // due to server may retrun reroute error in internal routing trans + // internal routing trans allow to record transaction state after begin statement + if (s.current_.send_action_ == SERVER_SEND_START_TRANS && s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing()) { + record_trans_state(s, true); + } } - if (obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == s.trans_info_.sql_cmd_) { - ObPieceInfo *info = NULL; - ObClientSessionInfo &cs_info = get_client_session_info(s); - if (OB_FAIL(cs_info.get_piece_info(info))) { - if (OB_HASH_NOT_EXIST == ret) { - if (OB_ISNULL(info = op_alloc(ObPieceInfo))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - PROXY_API_LOG(ERROR, "fail to allocate memory for piece info", K(ret)); - } else { - info->set_ps_id(cs_info.get_client_ps_id()); - info->set_addr(s.sm_->get_server_session()->get_netvc()->get_remote_addr()); - if (OB_FAIL(cs_info.add_piece_info(info))) { - PROXY_API_LOG(WARN, "fail to add piece info", K(ret)); - op_free(info); - info = NULL; + if (OB_SUCC(ret)) { + if (obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == s.trans_info_.sql_cmd_) { + ObPieceInfo *info = NULL; + ObClientSessionInfo &cs_info = get_client_session_info(s); + if (OB_FAIL(cs_info.get_piece_info(info))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_ISNULL(info = op_alloc(ObPieceInfo))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_API_LOG(ERROR, "fail to allocate memory for piece info", K(ret)); + } else { + info->set_ps_id(cs_info.get_client_ps_id()); + info->set_addr(s.sm_->get_server_session()->get_netvc()->get_remote_addr()); + if (OB_FAIL(cs_info.add_piece_info(info))) { + PROXY_API_LOG(WARN, "fail to add piece info", K(ret)); + op_free(info); + info = NULL; + } } } } } - if (OB_FAIL(ret)) { s.current_.state_ = INTERNAL_ERROR; LOG_WARN("add piece info failed", K(ret)); @@ -3755,57 +4289,70 @@ inline void ObMysqlTransact::handle_handshake_pkt(ObTransState &s) if (OB_LIKELY(NULL != client_session) && OB_LIKELY(SERVER_SEND_HANDSHAKE == s.current_.send_action_) && OB_LIKELY(NULL != server_session)) { - ObRespAnalyzeResult &result = s.trans_info_.server_response_.get_analyze_result(); - - uint32_t conn_id = 0; - //use connection id from OMPKHandshakeResponse Packet when the follow happened - //1. proxy_mysql_client - //2. client service mode - //3. mysql routing mode - if (client_session->is_proxy_mysql_client_ - || OB_CLIENT_SERVICE_MODE == s.mysql_config_params_->proxy_service_mode_ - || s.mysql_config_params_->is_mysql_routing_mode()) { - conn_id = result.get_connection_id(); - } else { - //if use server service mode, connection id is equal to cs_id - conn_id = client_session->get_cs_id(); - } - server_session->set_server_sessid(conn_id); - ObMySQLCapabilityFlags capability(result.get_server_capability()); - server_session->get_session_info().save_compatible_capability_flags(capability); - ObAddr client_addr = client_session->get_real_client_addr(const_cast(server_session->get_netvc())); - - //we need update proxy_sessid when first connect server - if (0 == client_session->get_proxy_sessid()) { - client_session->set_proxy_sessid(ObMysqlClientSession::get_next_proxy_sessid()); - LOG_INFO("succ to set proxy_sessid", "cs_id", client_session->get_cs_id(), - "proxy_sessid", client_session->get_proxy_sessid(), - "server_ip", server_session->server_ip_, - "ss_id", server_session->ss_id_, - "server_sessid", conn_id, - "is_proxy_mysql_client", client_session->is_proxy_mysql_client_, - "ss_fd", server_session->get_netvc()->get_conn_fd(), - K(client_addr)); - } - LOG_DEBUG("succ to fill conn id for server session", K(conn_id), - "ss_id", server_session->ss_id_, - "cs_id", client_session->get_cs_id(), - "proxy_sessid", client_session->get_proxy_sessid(), - "is_proxy_mysql_client", client_session->is_proxy_mysql_client_, - K(client_addr)); - - if (s.mysql_config_params_->enable_client_ip_checkout_) { - if (OB_UNLIKELY(!client_addr.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("real client add is invalid, it should not happened", K(client_addr), K(ret)); + // for probing SQL + if (client_session->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER) { + // Simulate the return of ERROR messages + LOG_DEBUG("get handshake from detect server success"); + s.mysql_errcode_ = OB_NOT_SUPPORTED; + s.mysql_errmsg_ = "not supported, bad route request"; + if (OB_FAIL(ObMysqlTransact::build_error_packet(s, client_session))) { + LOG_WARN("fail to encode err packet buf", K(ret)); } + ret = OB_NOT_SUPPORTED; } else { - client_addr.reset(); - } - if (OB_SUCC(ret)) { - if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { - if (OB_FAIL(handle_oceanbase_handshake_pkt(s, conn_id, client_addr))) { - LOG_WARN("fail to handle oceanbase handshke pkt", K(conn_id), K(client_addr), K(ret)); + ObRespAnalyzeResult &result = s.trans_info_.server_response_.get_analyze_result(); + + uint32_t conn_id = 0; + //use connection id from OMPKHandshakeResponse Packet when the follow happened + //1. proxy_mysql_client + //2. client service mode + //3. mysql routing mode + if (client_session->is_proxy_mysql_client_ + || OB_CLIENT_SERVICE_MODE == s.mysql_config_params_->proxy_service_mode_ + || s.mysql_config_params_->is_mysql_routing_mode()) { + conn_id = result.get_connection_id(); + } else { + //if use server service mode, connection id is equal to cs_id + conn_id = client_session->get_cs_id(); + } + server_session->set_server_sessid(conn_id); + ObMySQLCapabilityFlags capability(result.get_server_capability()); + server_session->get_session_info().save_compatible_capability_flags(capability); + ObAddr client_addr = client_session->get_real_client_addr(const_cast(server_session->get_netvc())); + + //we need update proxy_sessid when first connect server + if (0 == client_session->get_proxy_sessid()) { + client_session->set_proxy_sessid(ObMysqlClientSession::get_next_proxy_sessid()); + LOG_INFO("succ to set proxy_sessid", "cs_id", client_session->get_cs_id(), + "proxy_sessid", client_session->get_proxy_sessid(), + "server_ip", server_session->server_ip_, + "ss_id", server_session->ss_id_, + "server_sessid", conn_id, + "is_proxy_mysql_client", client_session->is_proxy_mysql_client_, + "ss_fd", server_session->get_netvc()->get_conn_fd(), + K(client_addr)); + } + LOG_DEBUG("succ to fill conn id for server session", K(conn_id), + "ss_id", server_session->ss_id_, + "cs_id", client_session->get_cs_id(), + "proxy_sessid", client_session->get_proxy_sessid(), + "is_proxy_mysql_client", client_session->is_proxy_mysql_client_, + K(client_addr)); + s.trace_log_.log_it("[handshake]", "svr", s.server_info_.addr_, "svr_sessid", server_session->get_server_sessid()); + + if (s.mysql_config_params_->enable_client_ip_checkout_) { + if (OB_UNLIKELY(!client_addr.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("real client add is invalid, it should not happened", K(client_addr), K(ret)); + } + } else { + client_addr.reset(); + } + if (OB_SUCC(ret)) { + if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { + if (OB_FAIL(handle_oceanbase_handshake_pkt(s, conn_id, client_addr))) { + LOG_WARN("fail to handle oceanbase handshke pkt", K(conn_id), K(client_addr), K(ret)); + } } } } @@ -3825,7 +4372,7 @@ inline int ObMysqlTransact::handle_oceanbase_handshake_pkt(ObTransState &s, uint // current proxy support use compress, and inner request also use compress bool use_compress = s.mysql_config_params_->enable_compression_protocol_; - bool use_ob_protocol_v2 = s.mysql_config_params_->enable_ob_protocol_v2_; + bool use_ob_protocol_v2 = s.sm_->is_enable_ob_protocol_v2(); bool use_ssl = s.sm_->enable_server_ssl_ && !s.sm_->client_session_->is_proxy_mysql_client_ && s.trans_info_.server_response_.get_analyze_result().support_ssl() @@ -3950,24 +4497,39 @@ void ObMysqlTransact::handle_db_reset(ObTransState &s) inline void ObMysqlTransact::handle_first_response_packet(ObTransState &s) { ObRespAnalyzeResult &resp = s.trans_info_.server_response_.get_analyze_result(); - + bool is_user_request = false; // handle resp if (resp.is_resultset_resp()) { MYSQL_INCREMENT_TRANS_STAT(SERVER_RESULTSET_RESPONSES); - handle_resultset_resp(s); + handle_resultset_resp(s, is_user_request); } else if (resp.is_ok_resp()) { MYSQL_INCREMENT_TRANS_STAT(SERVER_OK_RESPONSES); - handle_ok_resp(s); + handle_ok_resp(s, is_user_request); } else if (resp.is_error_resp()) { MYSQL_INCREMENT_TRANS_STAT(SERVER_ERROR_RESPONSES); - handle_error_resp(s); + handle_error_resp(s, is_user_request); } else if (resp.is_handshake_pkt()) { MYSQL_INCREMENT_TRANS_STAT(SERVER_OTHER_RESPONSES); handle_handshake_pkt(s); } else { MYSQL_INCREMENT_TRANS_STAT(SERVER_OTHER_RESPONSES); - handle_ok_resp(s); + handle_ok_resp(s, is_user_request); } + + if (s.current_.send_action_ != SERVER_SEND_SAVED_LOGIN + && s.current_.send_action_ != SERVER_SEND_HANDSHAKE + && !is_user_request) { + bool is_only_sync_trans_sess = resp.is_error_resp(); + if (OB_SUCCESS != ObProxySessionInfoHandler::save_changed_sess_info(s.sm_->get_client_session()->get_session_info(), + s.sm_->get_server_session()->get_session_info(), + resp.get_extra_info(), + s.trace_log_, + is_only_sync_trans_sess)) { + s.current_.state_ = INTERNAL_ERROR; + LOG_WARN("fail to save changed session info", K(get_send_action_name(s.current_.send_action_))); + } + } + } inline ObServerSessionInfo &ObMysqlTransact::get_server_session_info(ObTransState &s) @@ -4072,7 +4634,7 @@ inline void ObMysqlTransact::update_trace_stat(ObTransState &s) trace_record->server_state_ = static_cast(s.current_.state_); trace_record->send_action_ = static_cast(s.current_.send_action_); trace_record->resp_error_ = static_cast(s.current_.error_type_); - trace_record->addr_.set_ipv4_addr(s.server_info_.get_ipv4(), s.server_info_.get_port()); + trace_record->addr_.set_sockaddr(s.server_info_.addr_.sa_); if (0 == trace_stats->last_trace_end_time_) { trace_record->cost_time_us_ = static_cast(hrtime_to_usec( milestone_diff(s.sm_->milestones_.pl_lookup_begin_, get_based_hrtime(s)))); @@ -4098,16 +4660,18 @@ void ObMysqlTransact::handle_oceanbase_server_resp_error(ObTransState &s, ObMySQ case REQUEST_CONNECT_ERROR: case REQUEST_SERVER_INIT_ERROR: case REQUEST_REROUTE_ERROR: - case REQUEST_SERVER_STOPPING_ERROR: { - // before retry send request, write the saved packet to client buffer - ObString req_pkt = s.trans_info_.client_request_.get_req_pkt(); - int64_t pkt_len = req_pkt.length(); + case REQUEST_SERVER_STOPPING_ERROR: + case TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR: { + // before retry send request, write the req packet back to client buffer ObIOBufferReader *client_reader = s.sm_->get_client_buffer_reader(); - int64_t written_len = 0; if (OB_ISNULL(client_reader)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[ObMysqlTransact::handle_server_resp_error] client reader is NULL"); } else { + // rewrite request to client buffer in order to retry + ObString req_pkt = s.trans_info_.client_request_.get_req_pkt(); + int64_t pkt_len = req_pkt.length(); + int64_t written_len = 0; if (0 != client_reader->read_avail() || req_pkt.empty()) { ret = OB_INNER_STAT_ERROR; LOG_ERROR("[ObMysqlTransact::handle_server_resp_error] invalid internal state", @@ -4152,6 +4716,7 @@ void ObMysqlTransact::handle_oceanbase_server_resp_error(ObTransState &s, ObMySQ case SAVED_LOGIN_COMMON_ERROR: case RESET_SESSION_VARS_COMMON_ERROR: case START_TRANS_COMMON_ERROR: + case START_XA_START_ERROR: case SYNC_DATABASE_COMMON_ERROR: { //current server session is still ok s.sm_->clear_server_entry(); @@ -4285,7 +4850,7 @@ inline void ObMysqlTransact::handle_response_from_server(ObTransState &s) "request_cmd", get_mysql_cmd_str(s.trans_info_.client_request_.get_packet_meta().cmd_), "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_), "sql", s.trans_info_.get_print_sql()); - } else { + } else if (s.need_retry_) { LOG_WARN("connection error", "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), "request_cmd", get_mysql_cmd_str(s.trans_info_.client_request_.get_packet_meta().cmd_), @@ -4314,13 +4879,16 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) ObPieceInfo *info = NULL; ObSSRetryStatus retry_status = NO_NEED_RETRY; const int64_t max_connect_attempts = get_max_connect_attempts(s); + bool is_reroute_to_coordinator = false; ObIpEndpoint old_target_server; net::ops_ip_copy(old_target_server, s.server_info_.addr_.sa_); int64_t obproxy_route_addr = 0; + bool is_internal_routing = false; if (NULL != s.sm_ && NULL != s.sm_->client_session_) { obproxy_route_addr = s.sm_->client_session_->get_session_info().get_obproxy_route_addr(); + is_internal_routing = s.sm_->client_session_->is_trans_internal_routing(); } if (OB_FAIL(s.sm_->get_client_session()->get_session_info().get_piece_info(info))) { @@ -4332,14 +4900,20 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) if (OB_UNLIKELY(s.mysql_config_params_->is_mysql_routing_mode())) { LOG_DEBUG("in mysql mode, no need retry, will disconnect"); retry_status = NO_NEED_RETRY; + } else if (OB_UNLIKELY(is_in_trans(s) + && s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing() + && !s.sm_->get_client_session()->get_trans_coordinator_ss_addr().is_valid())) { + // check coordinator addr in transaction + LOG_WARN("coordinator add is invalid in transaction, no need retry"); + retry_status = NO_NEED_RETRY; + // we will update retry_status only the follow all happened - // 1. not in transaction + // 1. not in transaction / in internal routing tranaction // 2. attempts_ is less then max_connect_attempts // 3. is not kill query // 4. is not piece info - } else if (!is_in_trans(s) - && s.need_retry_ + } else if (s.need_retry_ && s.current_.attempts_ < max_connect_attempts && 0 == obproxy_route_addr && !s.trans_info_.client_request_.is_kill_query() @@ -4347,17 +4921,30 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) && obmysql::OB_MYSQL_COM_STMT_GET_PIECE_DATA != s.trans_info_.sql_cmd_ && !second_in) { ++s.current_.attempts_; - LOG_DEBUG("start next retry"); - - if (s.pll_info_.is_force_renew()) { // force pl lookup - retry_status = NOT_FOUND_EXISTING_ADDR; - } else if (REQUEST_REROUTE_ERROR == s.current_.error_type_) { - retry_status = FOUND_EXISTING_ADDR; - net::ops_ip_copy(s.server_info_.addr_, s.reroute_info_.replica_.server_.get_ipv4(), - static_cast(s.reroute_info_.replica_.server_.get_port())); - } else { - retry_status = retry_server_connection_not_open(s); + LOG_DEBUG("start next retry", "is in trans:", is_in_trans(s)); + // if use target db server then no need renew, will retry server from target db server + if ((OB_NOT_NULL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()) + && !s.trans_info_.client_request_.get_parse_result().get_target_db_server()->is_empty()) + || (OB_NOT_NULL(s.sm_->target_db_server_) && !s.sm_->target_db_server_->is_empty())) { + s.pll_info_.force_renew_state_ = ObPartitionLookupInfo::ObForceRenewState::NO_NEED_RENEW; + s.pll_info_.is_need_force_flush_ = false; } + if (s.current_.error_type_ == TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR) { + // downgrade transaction internal routing, route the rest of request to coordinator session + LOG_DEBUG("transaction internal routing retry", K(s.trans_info_.sql_cmd_)); + retry_status = FOUND_EXISTING_ADDR; + s.server_info_.set_addr(s.sm_->get_client_session()->get_trans_coordinator_ss_addr()); + is_reroute_to_coordinator = true; + } else if (!is_in_trans(s) || is_internal_routing) { + if (s.pll_info_.is_force_renew()) { // force pl lookup + retry_status = NOT_FOUND_EXISTING_ADDR; + } else if (REQUEST_REROUTE_ERROR == s.current_.error_type_) { + retry_status = FOUND_EXISTING_ADDR; + s.server_info_.set_addr(ops_ip_sa_cast(s.reroute_info_.replica_.server_.get_sockaddr())); + } else { + retry_status = retry_server_connection_not_open(s); + } + } } if (NULL == s.congestion_entry_ || !s.congestion_entry_->is_congested()) { @@ -4403,14 +4990,21 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) s.congestion_entry_->dec_ref(); s.congestion_entry_ = NULL; } - s.congestion_lookup_success_ = false; - s.need_congestion_lookup_ = true; + if (is_reroute_to_coordinator) { + s.congestion_lookup_success_ = true; + s.need_congestion_lookup_ = false; + s.pl_lookup_state_ = USE_COORDINATOR_SESSION; + } else { + s.congestion_lookup_success_ = false; + s.need_congestion_lookup_ = true; + } LOG_DEBUG("FOUND_EXISTING_ADDR, Retrying...", "attempts now", s.current_.attempts_, K(max_connect_attempts), "retry observer", s.server_info_.addr_, - "force_retry_congested", s.force_retry_congested_); + "force_retry_congested", s.force_retry_congested_, + "is reroute to coordinaotr", is_reroute_to_coordinator); TRANSACT_RETURN(SM_ACTION_CONGESTION_CONTROL_LOOKUP, handle_congestion_control_lookup); } else if (NOT_FOUND_EXISTING_ADDR == retry_status) { // before retry another server, reset analyze result @@ -4449,7 +5043,15 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) void ObMysqlTransact::handle_retry_server_connection(ObTransState &s) { - if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { + /* + * reset response transform hook to keep the plugin created as the correct order + * otherwise, the packet handled by plugin will be err, eg, reroute err packet + */ + s.sm_->api_.txn_destroy_hook(OB_MYSQL_RESPONSE_TRANSFORM_HOOK); + + // Binlog requests also do not support retries + if (s.sm_->client_session_->get_session_info().is_oceanbase_server() + && !is_binlog_request(s)) { handle_oceanbase_retry_server_connection(s); } else { handle_server_connection_break(s); @@ -4517,14 +5119,32 @@ ObMysqlTransact::ObSSRetryStatus ObMysqlTransact::retry_server_connection_not_op if (s.current_.attempts_ == get_max_connect_attempts(s)) { handle_retry_last_time(s); } - - if ((s.mysql_config_params_->is_mock_routing_mode() && !s.sm_->client_session_->is_proxy_mysql_client_) + // target db server (sql comment & multi level config) + if (OB_NOT_NULL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()) + && !s.trans_info_.client_request_.get_parse_result().get_target_db_server()->is_empty()) { + if (OB_FAIL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()->get_next(s.server_info_.addr_))) { + LOG_WARN("fail to get target db server from sql comment, will disconnect", K(ret)); + } else { + ret_status = FOUND_EXISTING_ADDR; + LOG_DEBUG("succ to get target db server from sql comment, will retry", + "address", s.server_info_.addr_); + } + } else if (OB_NOT_NULL(s.sm_->target_db_server_) && !s.sm_->target_db_server_->is_empty()) { + if (OB_FAIL(s.sm_->target_db_server_->get_next(s.server_info_.addr_))) { + LOG_WARN("fail to get target db server from multi level config, will disconnect", K(ret)); + } else { + ret_status = FOUND_EXISTING_ADDR; + LOG_DEBUG("succ to get target db server from multi level config, will retry", + "address", s.server_info_.addr_); + } + // config: server_routing_mode & test_server_addr + } else if ((s.mysql_config_params_->is_mock_routing_mode() && !s.sm_->client_session_->is_proxy_mysql_client_) || s.mysql_config_params_->is_mysql_routing_mode()) { if (OB_FAIL(s.mysql_config_params_->get_one_test_server_addr(s.server_info_.addr_))) { LOG_WARN("mysql or mock mode, but test server addr in not set, disconnect", K(ret)); } else { s.sm_->client_session_->test_server_addr_ = s.server_info_.addr_; - LOG_DEBUG("mysql mode, test server is valid, just use it and skip pl lookup", + LOG_DEBUG("mysql mode, test server is valid, just use it to retry", "address", s.server_info_.addr_); } } else if (s.pll_info_.replica_size() > 0) { @@ -4549,7 +5169,8 @@ ObMysqlTransact::ObSSRetryStatus ObMysqlTransact::retry_server_connection_not_op } if ((NULL != replica) && replica->is_valid()) { - s.server_info_.set_addr(replica->server_.get_ipv4(), static_cast(replica->server_.get_port())); + struct sockaddr_storage sockaddr = replica->server_.get_sockaddr(); + s.server_info_.set_addr(*(struct sockaddr*)(&(sockaddr))); LOG_DEBUG("set addr here", K(s.server_info_.addr_)); ret_status = FOUND_EXISTING_ADDR; } else { @@ -4590,35 +5211,51 @@ ObMysqlTransact::ObSSRetryStatus ObMysqlTransact::retry_server_connection_not_op inline void ObMysqlTransact::handle_server_connection_break(ObTransState &s) { if (NULL != s.sm_->client_session_) { - int64_t ss_id = (OB_ISNULL(s.sm_->get_server_session()) ? 0 : s.sm_->get_server_session()->ss_id_); - uint32_t server_sessid = (OB_ISNULL(s.sm_->get_server_session()) ? 0 : s.sm_->get_server_session()->get_server_sessid()); - - LOG_INFO("[ObMysqlTransact::handle_server_connection_break]", - "client_ip", s.client_info_.addr_, - "server_ip", s.server_info_.addr_, - "cs_id", s.sm_->client_session_->get_cs_id(), - "proxy_sessid", s.sm_->client_session_->get_proxy_sessid(), - K(ss_id), - K(server_sessid), - "sm_id", s.sm_->sm_id_, - "proxy_user_name", s.sm_->client_session_->get_session_info().get_priv_info().get_proxy_user_name(), - "database_name", s.sm_->client_session_->get_session_info().get_database_name(), - "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), - "request_cmd", get_mysql_cmd_str(s.trans_info_.client_request_.get_packet_meta().cmd_), - "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_), - "sql", s.trans_info_.get_print_sql()); - - if (obmysql::OB_MYSQL_COM_QUIT != s.trans_info_.sql_cmd_) { - OBPROXY_XF_LOG(INFO, XFH_CONNECTION_SERVER_ABORT, - "client_ip", s.client_info_.addr_, - "server_ip", s.server_info_.addr_, - "cluster_name", s.sm_->client_session_->get_session_info().get_priv_info().cluster_name_, - "tenant_name", s.sm_->client_session_->get_session_info().get_priv_info().tenant_name_, - "user_name", s.sm_->client_session_->get_session_info().get_priv_info().user_name_, - "db", s.sm_->client_session_->get_session_info().get_database_name(), - "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), - "sql", s.trans_info_.client_request_.get_print_sql(), - "request_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + if (s.sm_->client_session_->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER) { + // do nothing + } else { + int64_t ss_id = (OB_ISNULL(s.sm_->get_server_session()) ? 0 : s.sm_->get_server_session()->ss_id_); + uint32_t server_sessid = (OB_ISNULL(s.sm_->get_server_session()) ? 0 : s.sm_->get_server_session()->get_server_sessid()); + + LOG_INFO("[ObMysqlTransact::handle_server_connection_break]", + "client_ip", s.client_info_.addr_, + "server_ip", s.server_info_.addr_, + "cs_id", s.sm_->client_session_->get_cs_id(), + "proxy_sessid", s.sm_->client_session_->get_proxy_sessid(), + K(ss_id), + K(server_sessid), + "sm_id", s.sm_->sm_id_, + "proxy_user_name", s.sm_->client_session_->get_session_info().get_priv_info().get_proxy_user_name(), + "database_name", s.sm_->client_session_->get_session_info().get_database_name(), + "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), + "request_cmd", get_mysql_cmd_str(s.trans_info_.client_request_.get_packet_meta().cmd_), + "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_), + "sql", s.trans_info_.get_print_sql()); + + if (obmysql::OB_MYSQL_COM_QUIT != s.trans_info_.sql_cmd_) { + OBPROXY_XF_LOG(INFO, XFH_CONNECTION_SERVER_ABORT, + "client_ip", s.client_info_.addr_, + "server_ip", s.server_info_.addr_, + "cluster_name", s.sm_->client_session_->get_session_info().get_priv_info().cluster_name_, + "tenant_name", s.sm_->client_session_->get_session_info().get_priv_info().tenant_name_, + "user_name", s.sm_->client_session_->get_session_info().get_priv_info().user_name_, + "db", s.sm_->client_session_->get_session_info().get_database_name(), + "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), + "sql", s.trans_info_.client_request_.get_print_sql(), + "request_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + + s.trace_log_.log_it("[svr_connection_break]", + "cli", s.client_info_.addr_, + "svr", s.server_info_.addr_, + "cluster", s.sm_->client_session_->get_session_info().get_priv_info().cluster_name_, + "tenant", s.sm_->client_session_->get_session_info().get_priv_info().tenant_name_, + "user", s.sm_->client_session_->get_session_info().get_priv_info().user_name_, + "db", s.sm_->client_session_->get_session_info().get_database_name(), + "svr_state", ObMysqlTransact::get_server_state_name(s.current_.state_), + "sql", s.trans_info_.client_request_.get_print_sql(), + "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + LOG_WARN("trace_log", K(s.trace_log_)); + } } } else { LOG_INFO("[ObMysqlTransact::handle_server_connection_break]", @@ -4636,6 +5273,14 @@ inline void ObMysqlTransact::handle_server_connection_break(ObTransState &s) "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), "sql", s.trans_info_.client_request_.get_print_sql(), "request_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + + s.trace_log_.log_it("[svr_connection_break]", + "cli", s.client_info_.addr_, + "svr", s.server_info_.addr_, + "svr_state", ObMysqlTransact::get_server_state_name(s.current_.state_), + "sql", s.trans_info_.client_request_.get_print_sql(), + "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + LOG_WARN("trace_log", K(s.trace_log_)); } } @@ -4652,7 +5297,7 @@ inline void ObMysqlTransact::handle_server_connection_break(ObTransState &s) void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) { LOG_DEBUG("[ObMysqlTransact::handle_on_forward_server_response]", - "cur_send_action", ObMysqlTransact::get_send_action_name(s.current_.send_action_)); + "cur_send_action", ObMysqlTransact::get_send_action_name(s.current_.send_action_),"startm trans", s.is_hold_start_trans_); switch (s.current_.send_action_) { case SERVER_SEND_HANDSHAKE: { @@ -4705,7 +5350,7 @@ void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) break; } else if (client_info.is_oceanbase_server()) { bool is_proxy_mysql_client_ = s.sm_->client_session_->is_proxy_mysql_client_; - if (client_info.need_reset_all_session_vars() && !is_proxy_mysql_client_) { + if (client_info.need_reset_all_session_vars() && !is_binlog_request(s) && !is_proxy_mysql_client_) { // 1.if global vars changed, we need to sync all session vars to keep // server session vars is equal to the snapshot of client session // 2.proxy mysql client no need sync all session vars @@ -4730,7 +5375,9 @@ void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) //obutils::ObSqlParseResult &sql_result = s.trans_info_.client_request_.get_parse_result(); obmysql::ObMySQLCmd cmd = s.trans_info_.client_request_.get_packet_meta().cmd_; if (obmysql::OB_MYSQL_COM_STMT_CLOSE == cmd - || obmysql::OB_MYSQL_COM_STMT_RESET == cmd) { + || obmysql::OB_MYSQL_COM_STMT_RESET == cmd + || is_binlog_request(s) + || s.sm_->client_session_->can_direct_send_request_) { // no need sync var, send to server directly s.current_.send_action_ = SERVER_SEND_REQUEST; s.next_action_ = SM_ACTION_API_SEND_REQUEST; @@ -4757,13 +5404,17 @@ void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) ObClientSessionInfo &client_info = get_client_session_info(s); ObServerSessionInfo &server_info = get_server_session_info(s); //obutils::ObSqlParseResult &sql_result = s.trans_info_.client_request_.get_parse_result(); - if (client_info.need_reset_session_vars(server_info)) { + if (client_info.is_server_support_session_var_sync() && + client_info.need_reset_user_session_vars(server_info)) { + s.current_.send_action_ = SERVER_SEND_SESSION_USER_VARS; + s.next_action_ = SM_ACTION_API_SEND_REQUEST; + break; + } else if (!client_info.is_server_support_session_var_sync() && + client_info.need_reset_session_vars(server_info)) { s.current_.send_action_ = SERVER_SEND_SESSION_VARS; s.next_action_ = SM_ACTION_API_SEND_REQUEST; break; - } else { - // fall through: - } + } else { /* fall through */ } } else { s.current_.state_ = INTERNAL_ERROR; handle_server_connection_break(s); @@ -4775,27 +5426,24 @@ void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) } __attribute__ ((fallthrough)); case SERVER_SEND_SESSION_VARS: - case SERVER_SEND_LAST_INSERT_ID: + case SERVER_SEND_SESSION_USER_VARS: case SERVER_SEND_PREPARE: case SERVER_SEND_TEXT_PS_PREPARE: + case SERVER_SEND_XA_START: case SERVER_SEND_START_TRANS: { if (OB_LIKELY(NULL != s.sm_->client_session_) && OB_LIKELY(NULL != s.sm_->get_server_session())) { ObClientSessionInfo &client_info = get_client_session_info(s); ObServerSessionInfo &server_info = get_server_session_info(s); obmysql::ObMySQLCmd cmd = s.trans_info_.client_request_.get_packet_meta().cmd_; ObProxyMysqlRequest &client_request = s.trans_info_.client_request_; - //obutils::ObSqlParseResult &sql_result = s.trans_info_.client_request_.get_parse_result(); - if (client_info.need_reset_last_insert_id(server_info)) { - // TODO: current version proxy parse can't judge last_insert_id exactly, - // so we do not judge, whether sql_reuslt has_last_insert_id here - // if it is large request, we do not parse the sql, we don't know whether the sql contains - // last_insert_id, in this case we will sync last_insert_id if need - s.current_.send_action_ = SERVER_SEND_LAST_INSERT_ID; - } else if (s.is_hold_start_trans_) { + if (s.is_hold_start_trans_) { s.current_.send_action_ = SERVER_SEND_START_TRANS; + } else if (s.is_hold_xa_start_) { + LOG_DEBUG("[ObMysqlTransact::handle_on_forward_server_response] set send action SERVER_SEND_XA_START for sync xa start"); + s.current_.send_action_ = SERVER_SEND_XA_START; } else if ((obmysql::OB_MYSQL_COM_STMT_EXECUTE == cmd - || obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == cmd - || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == cmd) + || obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == cmd + || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == cmd) && client_info.need_do_prepare(server_info)) { s.current_.send_action_ = SERVER_SEND_PREPARE; } else if (client_request.get_parse_result().is_text_ps_execute_stmt() && @@ -4909,11 +5557,11 @@ inline void ObMysqlTransact::update_sync_session_stat(ObTransState &s) MYSQL_INCREMENT_TRANS_STAT(SEND_CHANGED_SESSION_VARS_REQUESTS); break; - case SERVER_SEND_LAST_INSERT_ID: - s.sm_->cmd_time_stats_.server_send_last_insert_id_time_ += cost; + case SERVER_SEND_SESSION_USER_VARS: + s.sm_->cmd_time_stats_.server_send_session_user_variable_time_ += cost; s.sm_->cmd_time_stats_.server_sync_session_variable_time_ += cost; - MYSQL_SUM_TIME_STAT(TOTAL_SEND_LAST_INSERT_ID_TIME, cost); - MYSQL_INCREMENT_TRANS_STAT(SEND_LAST_INSERT_ID_REQUESTS); + MYSQL_SUM_TIME_STAT(TOTAL_SEND_CHANGED_SESSION_USER_VARS_TIME, cost); + MYSQL_INCREMENT_TRANS_STAT(SEND_CHANGED_SESSION_USER_VARS_REQUESTS); break; case SERVER_SEND_START_TRANS: @@ -4922,6 +5570,13 @@ inline void ObMysqlTransact::update_sync_session_stat(ObTransState &s) MYSQL_SUM_TIME_STAT(TOTAL_SEND_START_TRANS_TIME, cost); MYSQL_INCREMENT_TRANS_STAT(SEND_START_TRANS_REQUESTS); break; + + case SERVER_SEND_XA_START: + s.sm_->cmd_time_stats_.server_send_xa_start_time_ += cost; + s.sm_->cmd_time_stats_.server_sync_session_variable_time_ += cost; + MYSQL_SUM_TIME_STAT(TOTAL_SEND_XA_START_TIME, cost); + MYSQL_INCREMENT_TRANS_STAT(SEND_XA_START_REQUESTS); + break; case SERVER_SEND_HANDSHAKE: case SERVER_SEND_LOGIN: @@ -5177,12 +5832,18 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c } if (OB_SUCC(ret)) { + ObMysqlSM *sm = s.sm_; + ObProxyProtocol client_protocol = ObProxyProtocol::PROTOCOL_NORMAL; + if (sm != NULL) { + client_protocol = sm->get_client_session_protocol(); + } + int errcode = s.mysql_errcode_; s.inner_errcode_ = s.mysql_errcode_; uint8_t next_seq = 0; if (s.is_auth_request_) { - if ((NULL != s.sm_) && (NULL != s.sm_->client_session_)) { - ObMysqlAuthRequest &auth_req = s.sm_->client_session_->get_session_info().get_login_req(); + if (client_session != NULL) { + ObMysqlAuthRequest &auth_req = client_session->get_session_info().get_login_req(); next_seq = static_cast(auth_req.get_packet_meta().pkt_seq_ + 1); } } else { @@ -5192,7 +5853,8 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c if (NULL != s.mysql_errmsg_) { const char *errmsg = s.mysql_errmsg_; - if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, next_seq, errcode, errmsg))) { + if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + next_seq, errcode, errmsg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to encode err pacekt buf", K(next_seq), K(errmsg), K(errcode), K(ret)); } @@ -5207,8 +5869,8 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c int64_t name_len = 0; const char *name_str = NULL; bool has_auth_resp = false; - if ((NULL != s.sm_) && (NULL != s.sm_->client_session_)) { - ObClientSessionInfo &client_info = s.sm_->client_session_->get_session_info(); + if (client_session != NULL) { + ObClientSessionInfo &client_info = client_session->get_session_info(); ObMysqlAuthRequest &auth_req = client_info.get_login_req(); ObHSRResult &result = auth_req.get_hsr_result(); if (!result.is_clustername_from_default_) { @@ -5226,8 +5888,8 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c if (OB_FAIL(databuff_printf(errmsg, BUF_LEN, pos, ob_str_user_error(errcode), name_len, name_str, strlen(ip_buff), ip_buff, (has_auth_resp ? "YES" : "NO")))) { LOG_WARN("fail to fill err_msg", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, next_seq, - errcode, errmsg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + next_seq, errcode, errmsg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to encode err pacekt buf", K(next_seq), K(errcode), K(ret)); } else { @@ -5249,8 +5911,8 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c char *err_msg = NULL; if (OB_FAIL(ObProxyPacketWriter::get_err_buf(errcode, err_msg))) { LOG_WARN("fail to get err buf", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, next_seq, - errcode, err_msg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + next_seq, errcode, err_msg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to build not supported err resp", K(ret)); } else { // nothing @@ -5313,6 +5975,13 @@ void ObMysqlTransact::ObTransState::refresh_mysql_config() } } + // record v2 config + if (is_auth_request_) { + bool enable_v2 = mysql_config_params_->enable_ob_protocol_v2_; + sm_->set_enable_ob_protocol_v2(enable_v2); + PROXY_CS_LOG(DEBUG, "client session start with ", "enable_ob_protocol_v2:", enable_v2, "cs_id", sm_->get_client_session()->get_cs_id()); + } + // Start to get the version number. If there are concurrent modifications, the version will be pushed up. // The next time it is executed, it will continue to be updated. ObNetVConnection *client_vc = static_cast(sm_->get_client_session()->get_netvc()); @@ -5320,11 +5989,9 @@ void ObMysqlTransact::ObTransState::refresh_mysql_config() ObClientSessionInfo &session_info = sm_->get_client_session()->get_session_info(); uint64_t global_version = get_global_proxy_config_table_processor().get_config_version(); if (sm_->config_version_ != global_version && NULL != client_vc) { - int32_t ip = ntohl(client_vc->get_virtual_ip()); - int32_t port = static_cast(client_vc->get_virtual_port()); int64_t vid = static_cast(client_vc->get_virtual_vid()); ObVipAddr addr; - addr.set(ip, port, vid); + addr.set(client_vc->get_virtual_addr(), vid); ObString tenant_name; ObString cluster_name; if (client_session->is_need_convert_vip_to_tname() && client_session->is_vip_lookup_success()) { @@ -5353,7 +6020,9 @@ void ObMysqlTransact::ObTransState::refresh_mysql_config() LOG_DEBUG("get config succ", K(addr), K(cluster_name), K(tenant_name), K_(sm_->proxy_route_policy), K_(sm_->proxy_idc_name), K_(sm_->enable_cloud_full_username), K_(sm_->enable_client_ssl), - K_(sm_->enable_server_ssl), K(ret)); + K_(sm_->enable_server_ssl), K_(sm_->enable_transaction_split), K_(sm_->enable_transaction_split), + K(session_info.is_request_follower_user()), K(session_info.is_read_only_user()), + K_(sm_->target_db_server), K(ret)); } } @@ -5363,6 +6032,7 @@ int ObMysqlTransact::ObTransState::get_config_item(const ObString& cluster_name, const int64_t global_version) { int ret = OB_SUCCESS; + ObClientSessionInfo &session_info = sm_->get_client_session()->get_session_info(); if (OB_SUCC(ret)) { ObConfigItem item; if (OB_FAIL(get_global_config_processor().get_proxy_config( @@ -5413,6 +6083,99 @@ int ObMysqlTransact::ObTransState::get_config_item(const ObString& cluster_name, } } + if (OB_SUCC(ret)) { + ObConfigItem item; + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name, tenant_name, "target_db_server", item))) { + LOG_WARN("fail to get target_db_server", K(addr), K(cluster_name), K(tenant_name), K(ret)); + // if config empty + } else if (OB_ISNULL(item.str()) || strlen(item.str()) == 0 ) { + // target db server not null, reset it + if (OB_NOT_NULL(sm_->target_db_server_)) { + op_free(sm_->target_db_server_); + sm_->target_db_server_ = NULL; + // target db server is null, do nothing + } else { /* do nothing */} + // if config not empty + // target db server is null, allocate and init one + } else if (OB_ISNULL(sm_->target_db_server_) && OB_ISNULL(sm_->target_db_server_ = op_alloc(ObTargetDbServer))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc memory to for target db server", K(ret)); + } else if (OB_FAIL(sm_->target_db_server_->init(item.str(), strlen(item.str())))) { + LOG_WARN("fail to load target db server from multi level config", K(ret)); + } + } + + if (OB_SUCC(ret)) { + ObConfigIntItem int_item; + if (OB_FAIL(get_global_config_processor().get_proxy_config_int_item( + addr, cluster_name, tenant_name, "obproxy_read_only", int_item))) { + LOG_WARN("get vip obproxy_read_only failed", K(addr), K(cluster_name), K(tenant_name), K(ret)); + } else { + bool is_read_only = (ReadOnly == int_item.get_value()); + bool is_sys_var_update = (session_info.is_read_only_user() != is_read_only); + session_info.set_is_read_only_user(is_read_only); + if (is_sys_var_update) { + ObString tx_read_only("tx_read_only"); + ObString tx_read_only_true; + if (session_info.is_read_only_user()) { + tx_read_only_true = "1"; + } else { + tx_read_only_true = "0"; + } + if (OB_FAIL(session_info.update_sys_variable(tx_read_only, tx_read_only_true))) { + LOG_WARN("replace user variables failed", K(tx_read_only_true), K(ret)); + } + } + } + } + + if (OB_SUCC(ret)) { + ObConfigIntItem int_item; + if (OB_FAIL(get_global_config_processor().get_proxy_config_int_item( + addr, cluster_name, tenant_name, "obproxy_read_consistency", int_item))) { + LOG_WARN("get vip obproxy_read_consistency failed", K(addr), K(cluster_name), K(tenant_name), K(ret)); + } else { + bool is_request_follower = (RequestFollower == int_item.get_value()); + bool is_sys_var_update = (session_info.is_request_follower_user() != is_request_follower); + session_info.set_is_request_follower_user(is_request_follower); + if (is_sys_var_update) { + ObString ob_read_consistency("ob_read_consistency"); + ObString weak; + if (session_info.is_request_follower_user()) { + weak = "2"; + } else { + weak = "3"; + } + if (OB_FAIL(session_info.update_sys_variable(ob_read_consistency, weak))) { + LOG_WARN("replace user variables failed", K(weak), K(ret)); + } else { + session_info.set_read_consistency_set_flag(true); + } + } + } + } + + if (OB_SUCC(ret)) { + ObConfigBoolItem bool_item; + if (OB_FAIL(get_global_config_processor().get_proxy_config_bool_item( + addr, cluster_name, tenant_name, "enable_read_write_split", bool_item))) { + LOG_WARN("get enable_read_write_split failed", K(addr), K(cluster_name), K(tenant_name), K(ret)); + } else { + sm_->enable_read_write_split_ = bool_item.get_value(); + } + } + + if (OB_SUCC(ret)) { + ObConfigBoolItem bool_item; + if (OB_FAIL(get_global_config_processor().get_proxy_config_bool_item( + addr, cluster_name, tenant_name, "enable_transaction_split", bool_item))) { + LOG_WARN("get enable_transaction_split failed", K(addr), K(cluster_name), K(tenant_name), K(ret)); + } else { + sm_->enable_transaction_split_ = bool_item.get_value(); + } + } + if (OB_SUCC(ret) && global_version > 0) { sm_->config_version_ = global_version; } @@ -5629,6 +6392,10 @@ const char *ObMysqlTransact::get_server_resp_error_name(ObMysqlTransact::ObServe ret = "START_TRANS_COMMON_ERROR"; break; + case ObMysqlTransact::START_XA_START_ERROR: + ret = "START_XA_START_ERROR"; + break; + case ObMysqlTransact::SYNC_DATABASE_COMMON_ERROR: ret = "SYNC_DATABASE_COMMON_ERROR"; break; @@ -5673,6 +6440,9 @@ const char *ObMysqlTransact::get_server_resp_error_name(ObMysqlTransact::ObServe ret = "SYANDBY_WEAK_READONLY_ERROR"; break; + case ObMysqlTransact::TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR: + ret = "TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR"; + break; case ObMysqlTransact::MAX_RESP_ERROR: ret = "MAX_RESP_ERR"; break; @@ -5788,13 +6558,17 @@ const char *ObMysqlTransact::get_send_action_name( case ObMysqlTransact::SERVER_SEND_SESSION_VARS: ret = "SERVER_SEND_SESSION_VARS"; break; + + case ObMysqlTransact::SERVER_SEND_SESSION_USER_VARS: + ret = "SERVER_SEND_SESSION_USER_VARS"; + break; case ObMysqlTransact::SERVER_SEND_START_TRANS: ret = "SERVER_SEND_START_TRANS"; break; - case ObMysqlTransact::SERVER_SEND_LAST_INSERT_ID: - ret = "SERVER_SEND_LAST_INSERT_ID"; + case ObMysqlTransact::SERVER_SEND_XA_START: + ret = "SERVER_SEND_XA_START"; break; case ObMysqlTransact::SERVER_SEND_REQUEST: @@ -5852,7 +6626,13 @@ bool ObMysqlTransact::is_internal_request(ObTransState &s) || s.trans_info_.client_request_.get_parse_result().is_show_table_status_stmt()) && !is_single_shard_db_table(s)))) || (s.is_trans_first_request_ + && !s.is_hold_xa_start_ && s.trans_info_.client_request_.get_parse_result().need_hold_start_trans()) + || (s.is_trans_first_request_ + && !s.is_hold_start_trans_ + && !s.is_hold_xa_start_ + && s.trans_info_.client_request_.get_parse_result().need_hold_xa_start() + && get_global_proxy_config().enable_xa_route) || s.trans_info_.client_request_.get_parse_result().is_internal_request() || is_bad_route_request(s)) || !is_supported_mysql_cmd(s.trans_info_.sql_cmd_) @@ -5862,6 +6642,95 @@ bool ObMysqlTransact::is_internal_request(ObTransState &s) &&s.trans_info_.client_request_.get_parse_result().is_set_ob_read_consistency()); } +int64_t ObMysqlTransact::get_max_connect_attempts(ObTransState &s) +{ + int64_t target_db_server_num = 0; + if (NULL != s.trans_info_.client_request_.get_parse_result().get_target_db_server() + && 0 < s.trans_info_.client_request_.get_parse_result().get_target_db_server()->num()) { + target_db_server_num = s.trans_info_.client_request_.get_parse_result().get_target_db_server()->num(); + } else if (NULL != s.sm_->target_db_server_ && 0 < s.sm_->target_db_server_->num()) { + target_db_server_num = s.sm_->target_db_server_->num(); + } + return std::max(target_db_server_num, std::max(s.mysql_config_params_->connect_observer_max_retries_, + get_max_connect_attempts_from_replica(s.pll_info_.replica_size()))); +} + +bool ObMysqlTransact::is_binlog_request(const ObTransState &s) +{ + bool bret = false; + if (get_global_proxy_config().enable_binlog_service + && (obmysql::OB_MYSQL_COM_REGISTER_SLAVE == s.trans_info_.client_request_.get_packet_meta().cmd_ + || obmysql::OB_MYSQL_COM_BINLOG_DUMP == s.trans_info_.client_request_.get_packet_meta().cmd_ + || obmysql::OB_MYSQL_COM_BINLOG_DUMP_GTID == s.trans_info_.client_request_.get_packet_meta().cmd_ + || s.trans_info_.client_request_.get_parse_result().is_binlog_stmt())) { + bret = true; + } + + return bret; +} + +void ObMysqlTransact::handle_binlog_request(ObTransState &s) +{ + ObClientSessionInfo &cs_info = get_client_session_info(s); + ObString cluster_name = cs_info.get_priv_info().cluster_name_; + ObString tenant_name = cs_info.get_priv_info().tenant_name_; + + ObTableEntryName &te_name = s.pll_info_.te_name_; + te_name.cluster_name_ = cluster_name; + te_name.tenant_name_ = tenant_name; + // mock database name + te_name.database_name_ = OB_SYS_DATABASE_NAME; + te_name.table_name_ = OB_ALL_BINLOG_DUMMY_TNAME; + LOG_DEBUG("handle binlog request", K(te_name)); + TRANSACT_RETURN(SM_ACTION_BINLOG_LOCATION_LOOKUP, handle_bl_lookup); +} + +void ObMysqlTransact::handle_bl_lookup(ObTransState &s) +{ + int ret = OB_SUCCESS; + ++s.pll_info_.pl_attempts_; + + if (OB_UNLIKELY(!s.pll_info_.lookup_success_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[ObMysqlTransact::handle_bl_lookup] " + "fail to lookup binlog location, will disconnect", K(ret)); + } else if (s.server_info_.addr_.is_valid()) { + // do nothing + } else { + LOG_DEBUG("ObMysqlTransact::handle_bl_lookup] binlog location lookup successful", + "pl_attempts", s.pll_info_.pl_attempts_); + const ObProxyPartitionLocation *pl = s.pll_info_.route_.table_entry_->get_first_pl(); + if (NULL != pl && pl->replica_count() > 0) { + s.server_info_.set_addr(ops_ip_sa_cast(pl->get_replica(0)->server_.get_sockaddr())); + s.pll_info_.route_.cur_chosen_server_.replica_ = pl->get_replica(0); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("not found binlog server replica", K(ret)); + } + } + + if (OB_SUCC(ret)) { + LOG_DEBUG("[ObMysqlTransact::handle_bl_lookup] chosen server, and begin to congestion lookup", + "addr", s.server_info_.addr_, + "attempts", s.current_.attempts_, + "sm_id", s.sm_->sm_id_); + if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { + s.sm_->milestones_.bl_process_end_ = get_based_hrtime(s); + s.sm_->cmd_time_stats_.bl_process_time_ += + milestone_diff(s.sm_->milestones_.bl_process_begin_, s.sm_->milestones_.bl_process_end_); + } + // At present, binlog does not have high-availability features. + // After routing, it directly forwards and does not follow the disaster recovery management process. + TRANSACT_RETURN(SM_ACTION_OBSERVER_OPEN, ObMysqlTransact::handle_response); + } + + if (OB_FAIL(ret)) { + s.inner_errcode_ = ret; + // disconnect + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + } +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_mysql_transact.h b/src/obproxy/proxy/mysql/ob_mysql_transact.h index feaf25dd..6a524295 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_transact.h +++ b/src/obproxy/proxy/mysql/ob_mysql_transact.h @@ -24,10 +24,12 @@ #include "proxy/mysqllib/ob_mysql_config_processor.h" #include "proxy/route/ob_table_cache.h" #include "proxy/route/ob_server_route.h" +#include "proxy/route/ob_tenant_server.h" #include "proxy/mysql/ob_mysql_proxy_port.h" #include "cmd/ob_show_sqlaudit_handler.h" #include "proxy/api/ob_transform.h" #include "proxy/mysqllib/ob_proxy_ob20_request.h" +#include "lib/oblog/ob_simple_trace.h" namespace oceanbase { @@ -68,6 +70,12 @@ class ObMysqlTransact MAYBE_ABORTED, ABORTED }; + enum ObPLLookupState + { + NEED_PL_LOOKUP = 0, + USE_LAST_SERVER_SESSION, + USE_COORDINATOR_SESSION + }; enum ObMysqlTransactMagic { @@ -84,6 +92,8 @@ class ObMysqlTransact }; static common::ObString get_retry_status_string(const ObSSRetryStatus status); + static common::ObString get_pl_lookup_state_string(const ObPLLookupState state); + // Please do not forget to fix ObServerState // (ob_api.h) in case of any modifications in @@ -127,6 +137,8 @@ class ObMysqlTransact RESET_SESSION_VARS_COMMON_ERROR, // sync start trans related START_TRANS_COMMON_ERROR, + // sync xa start related + START_XA_START_ERROR, // sync database related SYNC_DATABASE_COMMON_ERROR, // sync com_stmt_prepare @@ -143,7 +155,7 @@ class ObMysqlTransact REQUEST_READ_ONLY_ERROR, REQUEST_REROUTE_ERROR, STANDBY_WEAK_READONLY_ERROR, - + TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR, // attention!! add error type between MIN_RESP_ERROR and MAX_RESP_ERROR MAX_RESP_ERROR }; @@ -183,6 +195,8 @@ class ObMysqlTransact SM_ACTION_API_SEND_RESPONSE, SM_ACTION_API_CMD_COMPLETE, SM_ACTION_API_SM_SHUTDOWN, + + SM_ACTION_BINLOG_LOCATION_LOOKUP, }; enum ObAttachDummyEntryType @@ -267,12 +281,13 @@ class ObMysqlTransact SERVER_SEND_ALL_SESSION_VARS, SERVER_SEND_USE_DATABASE, SERVER_SEND_SESSION_VARS, - SERVER_SEND_LAST_INSERT_ID, + SERVER_SEND_SESSION_USER_VARS, SERVER_SEND_START_TRANS, + SERVER_SEND_XA_START, SERVER_SEND_REQUEST, SERVER_SEND_PREPARE, SERVER_SEND_SSL_REQUEST, - SERVER_SEND_TEXT_PS_PREPARE, + SERVER_SEND_TEXT_PS_PREPARE }; struct ObCurrentInfo @@ -381,15 +396,11 @@ class ObMysqlTransact { return route_.get_next_avail_replica(); } - const ObProxyReplicaLocation *get_next_replica(const uint32_t cur_ip, const uint16_t cur_port, - const bool is_force_retry) - { - return route_.get_next_replica(cur_ip, cur_port, is_force_retry); - } const ObProxyReplicaLocation *get_leader_replica_from_remote() { return route_.get_leader_replica_from_remote(); } + void reset_consistency(); void reset_pl(); void reset(); @@ -481,11 +492,12 @@ class ObMysqlTransact sm_(NULL), mysql_config_params_(NULL), is_rerouted_(false), - need_pl_lookup_(false), + pl_lookup_state_ (NEED_PL_LOOKUP), is_auth_request_(false), is_trans_first_request_(false), is_proxysys_tenant_(false), is_hold_start_trans_(false), + is_hold_xa_start_(false), send_reqeust_direct_(false), source_(SOURCE_NONE), pre_transform_source_(SOURCE_NONE), @@ -514,7 +526,8 @@ class ObMysqlTransact api_mysql_sm_shutdown_(false), api_server_addr_set_(false), need_retry_(true), - sqlaudit_record_queue_(NULL) + sqlaudit_record_queue_(NULL), + trace_log_() { memset(user_args_, 0, sizeof(user_args_)); } @@ -530,7 +543,7 @@ class ObMysqlTransact PROXY_TXN_LOG(WARN, "invalid argument", K(sm), K(ret)); } else { sm_ = sm; - need_pl_lookup_ = true; + pl_lookup_state_ = NEED_PL_LOOKUP; current_stats_ = &first_stats_; trans_info_.reset(); } @@ -665,30 +678,19 @@ class ObMysqlTransact reroute_info_.reset(); if (CMD_COMPLETE == current_.state_) { - if (!is_hold_start_trans_) { + if (!is_hold_start_trans_ && !is_hold_xa_start_) { is_trans_first_request_ = false; } if (obmysql::OB_MYSQL_COM_LOGIN == trans_info_.sql_cmd_) { is_auth_request_ = false; } + pll_info_.reset_consistency(); } else if (TRANSACTION_COMPLETE == current_.state_) { + trace_log_.reset(); is_trans_first_request_ = true; is_auth_request_ = false; - - if (NULL != congestion_entry_) { - // if this trans succ, just set avlie this server; - if (!is_congestion_entry_updated_) { - congestion_entry_->set_alive_congested_free(); - } - congestion_entry_->dec_ref(); - congestion_entry_ = NULL; - } - is_congestion_entry_updated_ = false; - congestion_entry_not_exist_count_ = 0; - need_congestion_lookup_ = true; - congestion_lookup_success_ = false; - force_retry_congested_ = false; + reset_congestion_entry(); mysql_errmsg_ = NULL; inner_errcode_ = 0; inner_errmsg_ = NULL; @@ -708,6 +710,23 @@ class ObMysqlTransact } else { /* do nothing */ } } + void reset_congestion_entry() + { + if (NULL != congestion_entry_) { + // if this trans succ, just set alive this server; + if (!is_congestion_entry_updated_) { + congestion_entry_->set_alive_congested_free(); + } + congestion_entry_->dec_ref(); + congestion_entry_ = NULL; + } + is_congestion_entry_updated_ = false; + congestion_entry_not_exist_count_ = 0; + need_congestion_lookup_ = true; + congestion_lookup_success_ = false; + force_retry_congested_ = false; + } + void destroy() { record_transaction_stats(); @@ -735,9 +754,11 @@ class ObMysqlTransact static bool is_for_update_sql(common::ObString src_sql); common::ObConsistencyLevel get_trans_consistency_level(ObClientSessionInfo &cs_info); + common::ObConsistencyLevel get_read_write_consistency_level(ObClientSessionInfo &session_info); bool is_request_readonly_zone_support(ObClientSessionInfo &cs_info); ObRoutePolicyEnum get_route_policy(ObMysqlClientSession &cs, const bool need_use_dup_replica); void get_route_policy(ObProxyRoutePolicyEnum policy, ObRoutePolicyEnum& ret_policy); + bool is_need_pl_lookup() { return pl_lookup_state_ == NEED_PL_LOOKUP; } event::ObFixedArenaAllocator<1024> arena_; @@ -754,11 +775,13 @@ class ObMysqlTransact ObTransactInfo trans_info_; bool is_rerouted_; - bool need_pl_lookup_; + // determin if do pl lookup + ObPLLookupState pl_lookup_state_; bool is_auth_request_; bool is_trans_first_request_; bool is_proxysys_tenant_; bool is_hold_start_trans_; // indicate whether hold begin(start transaction) + bool is_hold_xa_start_; bool send_reqeust_direct_; // when send sync all session variables, we can send user request directly ObSourceType source_; @@ -803,6 +826,7 @@ class ObMysqlTransact bool need_retry_; ObSqlauditRecordQueue *sqlaudit_record_queue_; + common::ObSimpleTrace<4096> trace_log_; private: DISALLOW_COPY_AND_ASSIGN(ObTransState); @@ -841,11 +865,13 @@ class ObMysqlTransact static void handle_error_jump(ObTransState &s); static void handle_internal_request(ObTransState &s); + static void handle_binlog_request(ObTransState &s); static void handle_server_addr_lookup(ObTransState &s); static void get_region_name_and_server_info(ObTransState &s, common::ObIArray &simple_servers_info, common::ObIArray ®ion_names); static void handle_pl_lookup(ObTransState &s); + static void handle_bl_lookup(ObTransState &s); static void modify_pl_lookup(ObTransState &s); static void handle_congestion_control_lookup(ObTransState &s); static void handle_congestion_entry_not_exist(ObTransState &s); @@ -868,6 +894,7 @@ class ObMysqlTransact static bool is_dbmesh_pool_user(ObTransState &s); static bool is_internal_request(ObTransState &s); + static bool is_binlog_request(const ObTransState &s); static bool is_single_shard_db_table(ObTransState &s); static bool can_direct_ok_for_login(ObTransState &s); static bool is_in_trans(ObTransState &s); @@ -876,15 +903,15 @@ class ObMysqlTransact static bool is_bad_route_request(ObTransState &s); static bool is_session_memory_overflow(ObTransState &s); static bool need_use_dup_replica(const common::ObConsistencyLevel level, ObTransState &s); - static bool need_pl_lookup(ObTransState &s); - static bool need_use_last_server_session(ObTransState &s); + static ObPLLookupState need_pl_lookup(ObTransState &s); + static bool need_use_coordinator_session(ObTransState &s); static bool is_db_reset(ObTransState &s); static bool need_server_session_lookup(ObTransState &s); static int64_t get_max_connect_attempts_from_replica(const int64_t replica_size); static int64_t get_max_connect_attempts(ObTransState &s); static int build_table_entry_request_packet(ObTransState &s, event::ObIOBufferReader *&reader); - static void handle_resultset_resp(ObTransState &s); + static void handle_resultset_resp(ObTransState &s, bool &is_user_request); static int fetch_table_entry_info(ObTransState &s); static ObClientSessionInfo &get_client_session_info(ObTransState &s); @@ -896,8 +923,8 @@ class ObMysqlTransact static void handle_handshake_pkt(ObTransState &s); static int handle_oceanbase_handshake_pkt(ObTransState &s, uint32_t conn_id, ObAddr &client_addr); - static void handle_error_resp(ObTransState &s); - static void handle_ok_resp(ObTransState &s); + static void handle_error_resp(ObTransState &s, bool &is_user_request); + static void handle_ok_resp(ObTransState &s, bool &is_user_request); static void handle_db_reset(ObTransState &s); static void handle_first_response_packet(ObTransState &s); @@ -920,6 +947,7 @@ class ObMysqlTransact static void handle_execute_succ(ObTransState &s); static int do_handle_execute_succ(ObTransState &s); static void handle_prepare_execute_succ(ObTransState &s); + static int do_handle_prepare_execute_xa_succ(event::ObIOBufferReader &buf_reader); static void handle_text_ps_prepare_succ(ObTransState &s); static int handle_text_ps_drop_succ(ObTransState &s, bool &is_user_request); static int handle_change_user_request_succ(ObTransState &s); @@ -955,12 +983,17 @@ class ObMysqlTransact static const char *get_send_action_name(ObMysqlTransact::ObServerSendActionType type); static const char *get_server_resp_error_name(ObMysqlTransact::ObServerRespErrorType type); - static int64_t build_addr_from_ip_port(const uint32_t ip, const uint16_t port); static void get_ip_port_from_addr(const int64_t addr, uint32_t &ip, uint16_t &port); static void check_safe_read_snapshot(ObTransState &s); static bool is_need_reroute(ObMysqlTransact::ObTransState &s); static bool is_need_use_sql_table_cache(ObMysqlTransact::ObTransState &s); + static bool handle_set_trans_internal_routing(ObMysqlTransact::ObTransState &s, bool server_transaction_routing_flag); + static bool is_sql_able_to_route_participant_in_trans(obutils::ObSqlParseResult& base_sql_parse_result, obmysql::ObMySQLCmd sql_cmd); + static bool is_trans_specified(ObTransState &s); + static bool has_dependent_func(ObTransState &s); + static void record_trans_state(ObTransState &s, bool is_in_trans); + static bool is_addr_logonly(const net::ObIpEndpoint &addr, const ObTenantServer *ts); }; inline bool ObMysqlTransact::is_need_use_sql_table_cache(ObMysqlTransact::ObTransState &s) @@ -974,20 +1007,6 @@ inline bool ObMysqlTransact::is_need_use_sql_table_cache(ObMysqlTransact::ObTran typedef void (*TransactEntryFunc)(ObMysqlTransact::ObTransState &s); -inline bool ObMysqlTransact::is_in_trans(ObTransState &s) -{ - // if a trans is commit, the state will be set to TRANSACTION_COMPLETE, - // so if current state is CMD_COMPLETE, it means that we have send a sql successfully and - // the trans has not commit, that is to say "in trans" - // so far, there are three cases NOT in trans: - // 1. handshake response (login packet) need pl lookup - // 2. the first sql of one transaction - // 3. the second sql of one transaction, if the first sql is 'begin' or 'start transaction' - return (!s.is_auth_request_ - && ObMysqlTransact::CMD_COMPLETE == s.current_.state_ - && !s.is_hold_start_trans_); -} - inline bool ObMysqlTransact::is_user_trans_complete(ObTransState &s) { return (!s.is_trans_first_request_ @@ -998,7 +1017,7 @@ inline bool ObMysqlTransact::is_user_trans_complete(ObTransState &s) inline bool ObMysqlTransact::is_bad_route_request(ObTransState &s) { bool bret = false; - if (s.mysql_config_params_->enable_bad_route_reject_ && s.is_hold_start_trans_) { + if (s.mysql_config_params_->enable_bad_route_reject_ && (s.is_hold_start_trans_ || s.is_hold_xa_start_)) { obutils::ObSqlParseResult &parse_result = s.trans_info_.client_request_.get_parse_result(); const ObString &table_name = parse_result.get_table_name(); bret = table_name.empty(); @@ -1036,11 +1055,6 @@ inline int64_t ObMysqlTransact::get_max_connect_attempts_from_replica(const int6 return (replica_size * 2 + 1); } -inline int64_t ObMysqlTransact::get_max_connect_attempts(ObTransState &s) -{ - return std::max(s.mysql_config_params_->connect_observer_max_retries_, - get_max_connect_attempts_from_replica(s.pll_info_.replica_size())); -} inline bool ObMysqlTransact::is_in_auth_process(ObTransState &s) { @@ -1087,6 +1101,11 @@ inline int64_t milestone_diff(const ObHRTime start, const ObHRTime end) return (start > 0 && end > start) ? (end - start) : 0; } +inline void ObMysqlTransact::ObPartitionLookupInfo::reset_consistency() +{ + route_.set_consistency_level(common::INVALID_CONSISTENCY); +} + inline void ObMysqlTransact::ObPartitionLookupInfo::reset_pl() { route_.reset(); @@ -1129,11 +1148,16 @@ inline void ObMysqlTransact::update_sql_cmd(ObTransState &s) case SERVER_SEND_ALL_SESSION_VARS: case SERVER_SEND_SESSION_VARS: - case SERVER_SEND_LAST_INSERT_ID: + case SERVER_SEND_SESSION_USER_VARS: case SERVER_SEND_START_TRANS: case SERVER_SEND_TEXT_PS_PREPARE: s.trans_info_.sql_cmd_ = obmysql::OB_MYSQL_COM_QUERY; break; + + case SERVER_SEND_XA_START: + PROXY_TXN_LOG(DEBUG, "[ObMysqlTransact::update_sql_cmd] set s.trans_info_.sql_cmd OB_MYSQL_COM_STMT_PREPARE_EXECUTE for sync xa start"); + s.trans_info_.sql_cmd_ = obmysql::OB_MYSQL_COM_STMT_PREPARE_EXECUTE; + break; case SERVER_SEND_PREPARE: s.trans_info_.sql_cmd_ = obmysql::OB_MYSQL_COM_STMT_PREPARE; @@ -1177,9 +1201,23 @@ inline common::ObString ObMysqlTransact::get_retry_status_string(const ObSSRetry return common::ObString::make_string(str); } -inline int64_t ObMysqlTransact::build_addr_from_ip_port(const uint32_t ip, const uint16_t port) +inline common::ObString ObMysqlTransact::get_pl_lookup_state_string(const ObPLLookupState state) { - return (static_cast(port) << 32) | ip; + const char *str = ""; + switch (state) { + case NEED_PL_LOOKUP: + str = "NEED_PL_LOOKUP"; + break; + case USE_LAST_SERVER_SESSION: + str = "USE_LAST_SERVER_SESSION"; + break; + case USE_COORDINATOR_SESSION: + str = "USE_COORDINATOR_SESSION"; + break; + default: + str = "UNKNOWN"; + } + return common::ObString::make_string(str); } inline void ObMysqlTransact::get_ip_port_from_addr(const int64_t addr, uint32_t &ip, uint16_t &port) @@ -1190,6 +1228,28 @@ inline void ObMysqlTransact::get_ip_port_from_addr(const int64_t addr, uint32_t port = static_cast((addr & PORT_MASK) >> 32); } +inline bool ObMysqlTransact::is_addr_logonly(const net::ObIpEndpoint &addr, const ObTenantServer *ts) +{ + bool ret = false; + if (OB_ISNULL(ts)) { + ret = false; + } else { + int64_t cnt = ts->server_count_; + ObAddr tmp_addr; + tmp_addr.reset(); + tmp_addr.set_sockaddr(addr.sa_); + for (int64_t i = 0; i < cnt; ++i) { + if (tmp_addr == ts->get_replica_location(i)->server_ + && (common::REPLICA_TYPE_LOGONLY == ts->get_replica_location(i)->get_replica_type() + || common::REPLICA_TYPE_ENCRYPTION_LOGONLY == ts->get_replica_location(i)->get_replica_type())) { + ret = true; + break; + } + } + } + return ret; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp b/src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp index 7cdcf90b..fa39e157 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp @@ -588,7 +588,8 @@ inline int ObMysqlTunnel::producer_handler_packet(int event, ObMysqlTunnelProduc case VC_EVENT_READ_COMPLETE: case MYSQL_TUNNEL_EVENT_PRECOMPLETE: case VC_EVENT_INACTIVITY_TIMEOUT: - case VC_EVENT_EOS: { + case VC_EVENT_EOS: + case VC_EVENT_DETECT_SERVER_DEAD: { p.packet_analyzer_.last_server_event_ = event; // If we couldn't understand the encoding, return an error @@ -765,6 +766,7 @@ bool ObMysqlTunnel::producer_handler(int event, ObMysqlTunnelProducer &p) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: case MYSQL_TUNNEL_EVENT_CONSUMER_DETACH: p.alive_ = false; p.bytes_read_ = p.read_vio_->ndone_; @@ -915,7 +917,8 @@ bool ObMysqlTunnel::consumer_handler(int event, ObMysqlTunnelConsumer &c) case VC_EVENT_EOS: case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: - case VC_EVENT_INACTIVITY_TIMEOUT: { + case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: { c.alive_ = false; c.bytes_written_ = c.write_vio_ ? c.write_vio_->ndone_ : 0; diff --git a/src/obproxy/proxy/mysql/ob_prepare_statement_struct.cpp b/src/obproxy/proxy/mysql/ob_prepare_statement_struct.cpp index ab925237..e60c7380 100644 --- a/src/obproxy/proxy/mysql/ob_prepare_statement_struct.cpp +++ b/src/obproxy/proxy/mysql/ob_prepare_statement_struct.cpp @@ -96,10 +96,8 @@ DEF_TO_STRING(ObTextPsNameEntry) return pos; } -void ObBasePsEntry::destroy() { - if (NULL != ps_entry_cache_) { - ps_entry_cache_->delete_base_ps_entry(this); - } +void ObBasePsEntry::destroy() +{ base_ps_parse_result_.reset(); } @@ -125,16 +123,22 @@ int ObPsIdAddrs::alloc_ps_id_addrs(uint32_t ps_id, const struct sockaddr &addr, int ObPsIdAddrs::add_addr(const struct sockaddr &socket_addr) { int ret = OB_SUCCESS; net::ObIpEndpoint addr(socket_addr); - if (OB_FAIL(addrs_.set_refactored(addr))) { + if (OB_FAIL(addrs_.push_back(addr))) { LOG_WARN("set refactored failed", K(addr), K(ret)); } return ret; } + int ObPsIdAddrs::remove_addr(const struct sockaddr &socket_addr) { int ret = OB_SUCCESS; net::ObIpEndpoint addr(socket_addr); - if (OB_FAIL(addrs_.erase_refactored(addr))) { - LOG_WARN("set refactored failed", K(addr), K(ret)); + for(int64_t i = 0; OB_SUCC(ret) && i < addrs_.count(); i++) { + if (addr == addrs_.at(i)) { + if (OB_FAIL(addrs_.remove(i))) { + LOG_WARN("fail to remove", K(i), K(ret)); + } + break; + } } return ret; } @@ -217,40 +221,6 @@ int ObPsSqlMeta::set_param_type(const char *param_type, int64_t param_type_len) return ret; } -int ObPsEntry::alloc_and_init_ps_entry(const ObString &ps_sql, - const ObSqlParseResult &parse_result, - ObPsEntry *&entry) -{ - int ret = OB_SUCCESS; - int64_t alloc_size = 0; - char *buf = NULL; - - int64_t obj_size = sizeof(ObPsEntry); - int64_t sql_len = ps_sql.length() + PARSE_EXTRA_CHAR_NUM; - - alloc_size += sizeof(ObPsEntry) + sql_len; - if (OB_ISNULL(buf = static_cast(op_fixed_mem_alloc(alloc_size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem for ps entry", K(alloc_size), K(ret)); - } else { - entry = new (buf) ObPsEntry(); - if (OB_FAIL(entry->init(buf + obj_size, alloc_size - obj_size))) { - LOG_WARN("fail to init ps entry", K(ret)); - } else if (OB_FAIL(entry->set_sql(ps_sql))) { - LOG_WARN("fail to set ps sql", K(ret)); - } else { - entry->set_base_ps_parse_result(parse_result); - } - } - - if (OB_FAIL(ret) && NULL != buf) { - op_fixed_mem_free(buf, alloc_size); - entry = NULL; - alloc_size = 0; - } - return ret; -} - int ObPsEntry::init(char *buf_start, int64_t buf_len) { int ret = OB_SUCCESS; @@ -287,9 +257,17 @@ int ObPsEntry::set_sql(const ObString &ps_sql) return ret; } +void ObPsEntry::free() +{ + if (NULL != ps_entry_cache_) { + ps_entry_cache_->delete_base_ps_entry(this); + } + destroy(); +} + void ObPsEntry::destroy() { - LOG_INFO("ps entry will be destroyed", KPC(this)); + LOG_DEBUG("ps entry will be destroyed", KPC(this)); if (OB_LIKELY(is_inited_)) { ObBasePsEntry::destroy(); is_inited_ = false; @@ -300,96 +278,12 @@ void ObPsEntry::destroy() } } -void ObBasePsEntryCache::destroy() -{ - ObBasePsEntryMap::iterator last = base_ps_map_.end(); - ObBasePsEntryMap::iterator tmp_iter; - for (ObBasePsEntryMap::iterator base_ps_iter = base_ps_map_.begin(); base_ps_iter != last;) { - tmp_iter = base_ps_iter; - ++base_ps_iter; - tmp_iter->destroy(); - } - base_ps_map_.reset(); -} - -int init_ps_entry_cache_for_thread() -{ - int ret = OB_SUCCESS; - const int64_t event_thread_count = g_event_processor.thread_count_for_type_[ET_CALL]; - for (int64_t i = 0; i < event_thread_count && OB_SUCC(ret); ++i) { - if (OB_FAIL(init_ps_entry_cache_for_one_thread(i))) { - PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryCache", K(i), K(ret)); - } - } - return ret; -} - -int init_text_ps_entry_cache_for_thread() -{ - int ret = OB_SUCCESS; - const int64_t event_thread_count = g_event_processor.thread_count_for_type_[ET_CALL]; - for (int64_t i = 0; i < event_thread_count && OB_SUCC(ret); ++i) { - if (OB_FAIL(init_text_ps_entry_cache_for_one_thread(i))) { - PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryCache", K(i), K(ret)); - } - } - return ret; -} - -int init_ps_entry_cache_for_one_thread(int64_t index) +void ObGlobalPsEntry::free() { - int ret = OB_SUCCESS; - if (OB_ISNULL(g_event_processor.event_thread_[ET_CALL][index]->ps_entry_cache_ - = new (std::nothrow) ObBasePsEntryCache())) { - ret = OB_ALLOCATE_MEMORY_FAILED; - PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryCache", K(index), K(ret)); - } - return ret; -} - -int init_text_ps_entry_cache_for_one_thread(int64_t index) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(g_event_processor.event_thread_[ET_CALL][index]->text_ps_entry_cache_ - = new (std::nothrow) ObBasePsEntryCache())) { - ret = OB_ALLOCATE_MEMORY_FAILED; - PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryCache", K(index), K(ret)); - } - return ret; -} - -int ObTextPsEntry::alloc_and_init_text_ps_entry(const ObString &text_ps_sql, - const ObSqlParseResult &parse_result, - ObTextPsEntry *&entry) -{ - int ret = OB_SUCCESS; - int64_t alloc_size = 0; - char *buf = NULL; - - int64_t obj_size = sizeof(ObTextPsEntry); - int64_t sql_len = text_ps_sql.length() + PARSE_EXTRA_CHAR_NUM; - - alloc_size = obj_size + sql_len; - if (OB_ISNULL(buf = static_cast(op_fixed_mem_alloc(alloc_size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem for text ps entry", K(alloc_size), K(ret)); - } else { - entry = new (buf) ObTextPsEntry(); - if (OB_FAIL(entry->init(buf + obj_size, alloc_size - obj_size, text_ps_sql))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem for text ps entry", K(alloc_size), K(ret)); - } else { - entry->set_base_ps_parse_result(parse_result); - } - } - - if (OB_FAIL(ret) && NULL != buf) { - op_fixed_mem_free(buf, alloc_size); - entry = NULL; - alloc_size = 0; + LOG_DEBUG("global ps entry will be destroyed", KPC(this)); + if (NULL != ps_entry_cache_) { + ps_entry_cache_->delete_base_ps_entry(this); } - - return ret; } int ObTextPsEntry::init(char *buf_start, int64_t buf_len, const ObString &text_ps_sql) @@ -419,6 +313,14 @@ int ObTextPsEntry::init(char *buf_start, int64_t buf_len, const ObString &text_p return ret; } +void ObTextPsEntry::free() +{ + if (NULL != ps_entry_cache_) { + ps_entry_cache_->delete_base_ps_entry(this); + } + destroy(); +} + void ObTextPsEntry::destroy() { LOG_INFO("text ps entry will be destroyed", KPC(this)); @@ -432,6 +334,14 @@ void ObTextPsEntry::destroy() } } +void ObGlobalTextPsEntry::free() +{ + LOG_INFO("global text ps entry will be destroyed", KPC(this)); + if (NULL != ps_entry_cache_) { + ps_entry_cache_->delete_base_ps_entry(this); + } +} + int ObTextPsNameEntry::alloc_text_ps_name_entry(const ObString &text_ps_name, ObTextPsEntry *text_ps_entry, ObTextPsNameEntry *&text_ps_name_entry) @@ -466,6 +376,99 @@ void ObTextPsNameEntry::destroy() op_fixed_mem_free(this, total_len); } +void ObBasePsEntryThreadCache::delete_base_ps_entry(ObBasePsEntry *base_ps_entry) +{ + ps_entry_thread_map_.remove(base_ps_entry); +} + +void ObBasePsEntryThreadCache::destroy() +{ + ObBasePsEntryMap::iterator last = ps_entry_thread_map_.end(); + ObBasePsEntryMap::iterator tmp_iter; + for (ObBasePsEntryMap::iterator base_ps_iter = ps_entry_thread_map_.begin(); base_ps_iter != last;) { + tmp_iter = base_ps_iter; + ++base_ps_iter; + tmp_iter->destroy(); + } + ps_entry_thread_map_.reset(); +} + +void ObBasePsEntryGlobalCache::delete_base_ps_entry(ObBasePsEntry *base_ps_entry) +{ + common::DRWLock::WRLockGuard guard(lock_); + ps_entry_global_map_.remove(base_ps_entry); +} + +void ObBasePsEntryGlobalCache::destroy() +{ + ObBasePsEntryGlobalMap::iterator last = ps_entry_global_map_.end(); + ObBasePsEntryGlobalMap::iterator tmp_iter; + for (ObBasePsEntryGlobalMap::iterator base_ps_iter = ps_entry_global_map_.begin(); base_ps_iter != last;) { + tmp_iter = base_ps_iter; + ++base_ps_iter; + tmp_iter->destroy(); + } + ps_entry_global_map_.reset(); +} + +int init_ps_entry_cache_for_thread() +{ + int ret = OB_SUCCESS; + const int64_t event_thread_count = g_event_processor.thread_count_for_type_[ET_CALL]; + for (int64_t i = 0; i < event_thread_count && OB_SUCC(ret); ++i) { + if (OB_FAIL(init_ps_entry_cache_for_one_thread(i))) { + PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryThreadCache", K(i), K(ret)); + } + } + return ret; +} + +int init_text_ps_entry_cache_for_thread() +{ + int ret = OB_SUCCESS; + const int64_t event_thread_count = g_event_processor.thread_count_for_type_[ET_CALL]; + for (int64_t i = 0; i < event_thread_count && OB_SUCC(ret); ++i) { + if (OB_FAIL(init_text_ps_entry_cache_for_one_thread(i))) { + PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryThreadCache", K(i), K(ret)); + } + } + return ret; +} + +int init_ps_entry_cache_for_one_thread(int64_t index) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(g_event_processor.event_thread_[ET_CALL][index]->ps_entry_cache_ + = new (std::nothrow) ObBasePsEntryThreadCache())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryThreadCache", K(index), K(ret)); + } + return ret; +} + +int init_text_ps_entry_cache_for_one_thread(int64_t index) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(g_event_processor.event_thread_[ET_CALL][index]->text_ps_entry_cache_ + = new (std::nothrow) ObBasePsEntryThreadCache())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryThreadCache", K(index), K(ret)); + } + return ret; +} + +ObBasePsEntryGlobalCache &get_global_ps_entry_cache() +{ + static ObBasePsEntryGlobalCache ps_entry_cache; + return ps_entry_cache; +} + +ObBasePsEntryGlobalCache &get_global_text_ps_entry_cache() +{ + static ObBasePsEntryGlobalCache text_ps_entry_cache; + return text_ps_entry_cache; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_prepare_statement_struct.h b/src/obproxy/proxy/mysql/ob_prepare_statement_struct.h index 3e56d534..83fa44aa 100644 --- a/src/obproxy/proxy/mysql/ob_prepare_statement_struct.h +++ b/src/obproxy/proxy/mysql/ob_prepare_statement_struct.h @@ -45,19 +45,9 @@ class ObPsIdAddrs static const int BUCKET_SIZE = 8; static const int NODE_NUM = 8; - // use SimpleAllocer to save mem - typedef common::hash::ObHashSet, - common::hash::equal_to, - common::hash::SimpleAllocer::AllocType, NODE_NUM> - > ADDR_HASH_SET; - ObPsIdAddrs() : ps_id_(0), addrs_() { - addrs_.create(BUCKET_SIZE); } ObPsIdAddrs(uint32_t ps_id) : ps_id_(ps_id), addrs_() { - addrs_.create(BUCKET_SIZE); } ~ObPsIdAddrs() {}; @@ -65,13 +55,12 @@ class ObPsIdAddrs void destroy(); int add_addr(const struct sockaddr &socket_addr); int remove_addr(const struct sockaddr &socket_addr); - ADDR_HASH_SET &get_addrs() { return addrs_; } + ObIArray &get_addrs() { return addrs_; } int64_t to_string(char *buf, const int64_t buf_len) const; public: uint32_t ps_id_; // client ps id - ADDR_HASH_SET addrs_; - + ObSEArray addrs_; LINK(ObPsIdAddrs, ps_id_addrs_link_); }; @@ -115,8 +104,7 @@ class ObBasePsEntry : public common::ObSharedRefCount const common::ObString &get_base_ps_sql() { return base_ps_sql_; } - virtual void free() { destroy(); } - + virtual void free() {} virtual void destroy(); public: @@ -189,13 +177,14 @@ class ObPsEntry : public ObBasePsEntry ObPsEntry() : ObBasePsEntry() {} ~ObPsEntry() {} + template static int alloc_and_init_ps_entry(const common::ObString &ps_sql, const obutils::ObSqlParseResult &parse_result, - ObPsEntry *&entry); + T *&entry); int init(char *buf_start, int64_t buf_len); - void destroy(); + virtual void free(); + virtual void destroy(); int set_sql(const common::ObString &ps_sql); - int64_t to_string(char *buf, const int64_t buf_len) const; private: @@ -205,6 +194,61 @@ class ObPsEntry : public ObBasePsEntry DISALLOW_COPY_AND_ASSIGN(ObPsEntry); }; +class ObGlobalPsEntry : public ObPsEntry +{ +public: + ObGlobalPsEntry() : ObPsEntry() {} + ~ObGlobalPsEntry() {} + virtual void free(); + template + static int alloc_and_init_ps_entry(const common::ObString &ps_sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry); +}; + +template +int ObGlobalPsEntry::alloc_and_init_ps_entry(const ObString &ps_sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry) +{ + return ObPsEntry::alloc_and_init_ps_entry(ps_sql, parse_result, entry); +} + +template +int ObPsEntry::alloc_and_init_ps_entry(const ObString &ps_sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry) +{ + int ret = OB_SUCCESS; + int64_t alloc_size = 0; + char *buf = NULL; + + int64_t obj_size = sizeof(T); + int64_t sql_len = ps_sql.length() + PARSE_EXTRA_CHAR_NUM; + + alloc_size += sizeof(T) + sql_len; + if (OB_ISNULL(buf = static_cast(op_fixed_mem_alloc(alloc_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_SM_LOG(WARN, "fail to alloc mem for ps entry", K(alloc_size), K(ret)); + } else { + entry = new (buf) T(); + if (OB_FAIL(entry->init(buf + obj_size, alloc_size - obj_size))) { + PROXY_SM_LOG(WARN, "fail to init ps entry", K(ret)); + } else if (OB_FAIL(entry->set_sql(ps_sql))) { + PROXY_SM_LOG(WARN, "fail to set ps sql", K(ret)); + } else { + entry->set_base_ps_parse_result(parse_result); + } + } + + if (OB_FAIL(ret) && NULL != buf) { + op_fixed_mem_free(buf, alloc_size); + entry = NULL; + alloc_size = 0; + } + return ret; +} + // stored in client session info class ObPsIdEntry { @@ -212,7 +256,6 @@ class ObPsIdEntry ObPsIdEntry() : ps_id_(0), ps_entry_(NULL), ps_meta_() {} ObPsIdEntry(uint32_t client_id, ObPsEntry *entry) : ps_id_(client_id), ps_entry_(entry) { - ps_entry_->inc_ref(); } ~ObPsIdEntry() {} @@ -268,20 +311,77 @@ class ObPsIdPair class ObTextPsEntry : public ObBasePsEntry { public: - ObTextPsEntry() : ObBasePsEntry() {} - ~ObTextPsEntry() { destroy(); } + ObTextPsEntry() : ObBasePsEntry() {} + ~ObTextPsEntry() { } - static int alloc_and_init_text_ps_entry(const common::ObString &sql, - const obutils::ObSqlParseResult &parse_result, - ObTextPsEntry *&entry); + template + static int alloc_and_init_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry); int init(char *buf_start, int64_t buf_len, const common::ObString &text_ps_sql); - void destroy(); + virtual void free(); + virtual void destroy(); int64_t to_string(char *buf, const int64_t buf_len) const; private: DISALLOW_COPY_AND_ASSIGN(ObTextPsEntry); }; +template +int ObTextPsEntry::alloc_and_init_ps_entry(const ObString &text_ps_sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry) +{ + int ret = OB_SUCCESS; + int64_t alloc_size = 0; + char *buf = NULL; + + int64_t obj_size = sizeof(T); + int64_t sql_len = text_ps_sql.length() + PARSE_EXTRA_CHAR_NUM; + + alloc_size = obj_size + sql_len; + if (OB_ISNULL(buf = static_cast(op_fixed_mem_alloc(alloc_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_SM_LOG(WARN, "fail to alloc mem for text ps entry", K(alloc_size), K(ret)); + } else { + entry = new (buf) T(); + if (OB_FAIL(entry->init(buf + obj_size, alloc_size - obj_size, text_ps_sql))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_SM_LOG(WARN, "fail to alloc mem for text ps entry", K(alloc_size), K(ret)); + } else { + entry->set_base_ps_parse_result(parse_result); + } + } + + if (OB_FAIL(ret) && NULL != buf) { + op_fixed_mem_free(buf, alloc_size); + entry = NULL; + alloc_size = 0; + } + + return ret; +} + +class ObGlobalTextPsEntry : public ObTextPsEntry +{ +public: + ObGlobalTextPsEntry() : ObTextPsEntry() {} + ~ObGlobalTextPsEntry() {} + virtual void free(); + template + static int alloc_and_init_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry); +}; + +template +int ObGlobalTextPsEntry::alloc_and_init_ps_entry(const ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry) +{ + return ObTextPsEntry::alloc_and_init_ps_entry(sql, parse_result, entry); +} + class ObTextPsNameEntry { public: @@ -291,7 +391,6 @@ class ObTextPsNameEntry { text_ps_name_.assign_ptr(buf, static_cast(buf_len)); text_ps_entry_ = entry; - text_ps_entry_->inc_ref(); } static int alloc_text_ps_name_entry(const ObString &text_ps_name, @@ -315,13 +414,28 @@ class ObTextPsNameEntry class ObBasePsEntryCache { public: - ObBasePsEntryCache() : base_ps_map_() {} - ~ObBasePsEntryCache() { destroy(); } + ObBasePsEntryCache() {} + virtual ~ObBasePsEntryCache() { destroy(); } + virtual void destroy() {} + +public: + virtual void delete_base_ps_entry(ObBasePsEntry *base_ps_entry) { + UNUSED(base_ps_entry); + } + +private: + DISALLOW_COPY_AND_ASSIGN(ObBasePsEntryCache); +}; + +class ObBasePsEntryThreadCache : public ObBasePsEntryCache +{ +public: + ObBasePsEntryThreadCache() : ObBasePsEntryCache(), ps_entry_thread_map_() {} + ~ObBasePsEntryThreadCache() { destroy(); } void destroy(); public: static const int64_t HASH_BUCKET_SIZE = 64; - struct ObBasePsEntryHashing { typedef const common::ObString &Key; @@ -332,71 +446,210 @@ class ObBasePsEntryCache static Key key(Value const *value) { return value->base_ps_sql_; } static bool equal(Key lhs, Key rhs) { return lhs == rhs; } }; - typedef common::hash::ObBuildInHashMap ObBasePsEntryMap; public: - int get_ps_entry(const common::ObString &sql, ObPsEntry *&ps_entry) - { - int ret = common::OB_SUCCESS; - ObBasePsEntry *tmp_entry = NULL; - if (OB_FAIL(base_ps_map_.get_refactored(sql, tmp_entry))) { - //do nothing - } else { - ps_entry = static_cast(tmp_entry); - } - return ret; + template + int acquire_ps_entry(const common::ObString &sql, T *&ps_entry); + + template + int create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry); + + template + int acquire_or_create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry); + + void delete_base_ps_entry(ObBasePsEntry *base_ps_entry); + +private: + ObBasePsEntryMap ps_entry_thread_map_; + DISALLOW_COPY_AND_ASSIGN(ObBasePsEntryThreadCache); +}; + +template +int ObBasePsEntryThreadCache::acquire_ps_entry(const ObString &sql, T *&ps_entry) +{ + int ret = OB_SUCCESS; + ObBasePsEntry *tmp_entry = NULL; + if (OB_FAIL(ps_entry_thread_map_.get_refactored(sql, tmp_entry))) { + //do nothing + } else { + ps_entry = static_cast(tmp_entry); + ps_entry->inc_ref(); } + return ret; +} - int set_ps_entry(ObPsEntry *ps_entry) - { - ObBasePsEntry *tmp_entry = static_cast(ps_entry); - tmp_entry->set_ps_entry_cache(this); - return base_ps_map_.unique_set(tmp_entry); +template +int ObBasePsEntryThreadCache::create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry) +{ + int ret = OB_SUCCESS; + ObBasePsEntry* tmp_ps_entry = NULL; + if (OB_FAIL(ps_entry_thread_map_.get_refactored(sql, tmp_ps_entry))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(T::alloc_and_init_ps_entry(sql, parse_result, ps_entry))) { + PROXY_SM_LOG(WARN, "fail to alloc and init ps entry", K(ret)); + } else if (OB_FAIL(ps_entry_thread_map_.unique_set(ps_entry))) { + PROXY_SM_LOG(WARN, "fail to add ps entry to cache", K(ret)); + if (OB_LIKELY(NULL != ps_entry)) { + ps_entry->destroy(); + ps_entry = NULL; + } + } else { + ObBasePsEntry *tmp_entry = static_cast(ps_entry); + tmp_entry->set_ps_entry_cache(this); + } + } + } else { + ps_entry = static_cast(tmp_ps_entry); } + if (OB_SUCC(ret)) { + ps_entry->inc_ref(); + } + return ret; +} - int get_text_ps_entry(const common::ObString &sql, ObTextPsEntry *&text_ps_entry) - { - int ret = common::OB_SUCCESS; - ObBasePsEntry *tmp_entry = NULL; - if (OB_FAIL(base_ps_map_.get_refactored(sql, tmp_entry))) { - //do nothing +template +int ObBasePsEntryThreadCache::acquire_or_create_ps_entry(const ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(acquire_ps_entry(sql, ps_entry))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(create_ps_entry(sql, parse_result, ps_entry))) { + PROXY_SM_LOG(WARN, "fail to create ps entry", K(sql), K(ret)); + } else { + PROXY_SM_LOG(DEBUG, "succ to create ps entry", K(sql), KPC(ps_entry)); + } } else { - text_ps_entry = static_cast(tmp_entry); + PROXY_SM_LOG(WARN, "fail to get ps entry", K(sql), K(ret)); } - return ret; } + return ret; +} + +class ObBasePsEntryGlobalCache : public ObBasePsEntryCache +{ +public: + ObBasePsEntryGlobalCache() : ObBasePsEntryCache(), lock_(), ps_entry_global_map_() {} + ~ObBasePsEntryGlobalCache() { destroy(); } + void destroy(); - int set_text_ps_entry(ObTextPsEntry *text_ps_entry) +public: + static const int64_t HASH_BUCKET_SIZE = 64; + struct ObBasePsEntryHashing { - ObBasePsEntry *tmp_entry = text_ps_entry; - tmp_entry->set_ps_entry_cache(this); - return base_ps_map_.unique_set(tmp_entry); + typedef const common::ObString &Key; + typedef ObBasePsEntry Value; + typedef ObDLList(ObBasePsEntry, base_ps_entry_link_) ListHead; + + static uint64_t hash(Key key) { return key.hash(); } + static Key key(Value const *value) { return value->base_ps_sql_; } + static bool equal(Key lhs, Key rhs) { return lhs == rhs; } + static int64_t inc_ref(Value* value) { return ATOMIC_AAF(&value->ref_count_, 1); } + static bool bcas_ref(Value* value, int64_t cmpv, int64_t newv) { return ATOMIC_BCAS(&value->ref_count_, cmpv, newv); } + static int64_t get_ref(Value* value) { return ATOMIC_LOAD(&value->ref_count_); } + static void destroy(Value* value) { value->destroy(); } + }; + typedef common::hash::ObBuildInHashMapForRefCount ObBasePsEntryGlobalMap; + +public: + template + int acquire_ps_entry(const common::ObString &sql, T *&ps_entry); + + template + int create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry); + + template + int acquire_or_create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry); + + void delete_base_ps_entry(ObBasePsEntry *base_ps_entry); + +private: + common::DRWLock lock_; + ObBasePsEntryGlobalMap ps_entry_global_map_; + DISALLOW_COPY_AND_ASSIGN(ObBasePsEntryGlobalCache); +}; + +template +int ObBasePsEntryGlobalCache::acquire_ps_entry(const ObString &sql, T *&ps_entry) +{ + int ret = OB_SUCCESS; + common::DRWLock::RDLockGuard guard(lock_); + ObBasePsEntry *tmp_entry = NULL; + if (OB_FAIL(ps_entry_global_map_.get_refactored(sql, tmp_entry))) { + //do nothing + } else { + ps_entry = static_cast(tmp_entry); } + return ret; +} - int delete_text_ps_entry(ObTextPsEntry *text_ps_entry) - { - if (NULL != text_ps_entry) { - base_ps_map_.remove(text_ps_entry->base_ps_sql_); - text_ps_entry->destroy(); +template +int ObBasePsEntryGlobalCache::create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry) +{ + int ret = OB_SUCCESS; + DRWLock::WRLockGuard guard(lock_); + ObBasePsEntry* tmp_ps_entry = NULL; + if (OB_FAIL(ps_entry_global_map_.get_refactored(sql, tmp_ps_entry))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(T::alloc_and_init_ps_entry(sql, parse_result, ps_entry))) { + PROXY_SM_LOG(WARN, "fail to alloc and init ps entry", K(ret)); + } else if (OB_FAIL(ps_entry_global_map_.unique_set(ps_entry))) { + PROXY_SM_LOG(WARN, "fail to add ps entry to cache", K(ret)); + if (OB_LIKELY(NULL != ps_entry)) { + ps_entry->destroy(); + ps_entry = NULL; + } + } else { + ObBasePsEntry *tmp_entry = static_cast(ps_entry); + tmp_entry->set_ps_entry_cache(this); + } } - return common::OB_SUCCESS; + } else { + ps_entry = static_cast(tmp_ps_entry); } + return ret; +} - void delete_base_ps_entry(ObBasePsEntry *base_ps_entry) - { - base_ps_map_.remove(base_ps_entry); +template +int ObBasePsEntryGlobalCache::acquire_or_create_ps_entry(const ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(acquire_ps_entry(sql, ps_entry))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(create_ps_entry(sql, parse_result, ps_entry))) { + PROXY_SM_LOG(WARN, "fail to create ps entry", K(sql), K(ret)); + } else { + PROXY_SM_LOG(DEBUG, "succ to create ps entry", K(sql), KPC(ps_entry)); + } + } else { + PROXY_SM_LOG(WARN, "fail to get ps entry", K(sql), K(ret)); + } } - -private: - ObBasePsEntryMap base_ps_map_; - DISALLOW_COPY_AND_ASSIGN(ObBasePsEntryCache); -}; + return ret; +} int init_ps_entry_cache_for_thread(); int init_ps_entry_cache_for_one_thread(int64_t index); int init_text_ps_entry_cache_for_thread(); int init_text_ps_entry_cache_for_one_thread(int64_t index); +ObBasePsEntryGlobalCache &get_global_ps_entry_cache(); +ObBasePsEntryGlobalCache &get_global_text_ps_entry_cache(); } // end of namespace proxy } // end of namespace obproxy diff --git a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_struct.h b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_struct.h index a5b9251c..c0904b97 100644 --- a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_struct.h +++ b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_struct.h @@ -15,6 +15,8 @@ #include "proxy/mysqllib/ob_mysql_common_define.h" #include "obutils/ob_proxy_buf.h" +#include "lib/container/ob_se_array.h" +#include "lib/string/ob_sql_string.h" namespace oceanbase { @@ -54,6 +56,7 @@ union Ob20ProtocolFlags bool is_extra_info_exist() const { return 1 == st_flags_.OB_EXTRA_INFO_EXIST; } bool is_last_packet() const { return 1 == st_flags_.OB_IS_LAST_PACKET; } bool is_new_extra_info() const { return 1 == st_flags_.OB_IS_NEW_EXTRA_INFO; } + bool is_trans_internal_routing() const { return 1 == st_flags_.OB_IS_TRANS_INTERNAL_ROUTING; } uint32_t flags_; struct Protocol20Flags @@ -62,40 +65,103 @@ union Ob20ProtocolFlags uint32_t OB_IS_LAST_PACKET: 1; uint32_t OB_IS_PROXY_REROUTE: 1; uint32_t OB_IS_NEW_EXTRA_INFO: 1; - uint32_t OB_FLAG_RESERVED_NOT_USE: 28; + uint32_t OB_IS_WEAK_READ: 1; + uint32_t OB_IS_TRANS_INTERNAL_ROUTING: 1; + uint32_t OB_FLAG_RESERVED_NOT_USE: 26; } st_flags_; }; +enum SessionSyncInfoType { + //SESSION_SYNC_USER_VAR, // for user variables + SESSION_SYNC_APPLICATION_INFO = 0, // for application info + SESSION_SYNC_APPLICATION_CONTEXT = 1, // for app ctx + SESSION_SYNC_CLIENT_ID = 2, // for client identifier + SESSION_SYNC_CONTROL_INFO = 3, // for full trace link control info + SESSION_SYNC_SYS_VAR = 4, // for system variables + SESSION_SYNC_TXN_STATIC_INFO = 5, // 5: basic txn info + SESSION_SYNC_TXN_DYNAMIC_INFO = 6, // 6: txn dynamic info + SESSION_SYNC_TXN_PARTICIPANTS_INFO = 7, // 7: txn dynamic info + SESSION_SYNC_TXN_EXTRA_INFO = 8, // 8: txn dynamic info + SESSION_SYNC_MAX_TYPE, +}; + struct Ob20ExtraInfo { public: - // for session info sync mechanism - bool is_exist_sess_info_; - obutils::ObVariableLenBuffer<32> extra_info_buf_; // save total extra info kv - obutils::ObVariableLenBuffer<32> sess_info_buf_; // save only session info - common::ObString sess_info_; - - // ob20 info - uint32_t extra_len_; // extra len in ob20 payload, if the flag.exist_extra_info - -public: - Ob20ExtraInfo() : is_exist_sess_info_(false), sess_info_(), extra_len_(0) {} + Ob20ExtraInfo() : is_exist_sess_info_(false), extra_info_buf_(), sess_info_buf_(), + sess_info_count_(0), extra_len_(0), sess_info_length_(), + sess_info_cur_idx_(0), sess_info_offset_(0) {} ~Ob20ExtraInfo() {} void reset() { is_exist_sess_info_ = false; extra_info_buf_.reset(); sess_info_buf_.reset(); - sess_info_.reset(); + sess_info_count_ = 0; extra_len_ = 0; + + sess_info_length_.reset(); + sess_info_cur_idx_ = 0; + sess_info_offset_ = 0; } - inline bool exist_sess_info() const { return is_exist_sess_info_; } - inline common::ObString get_sess_info() const { return sess_info_; } - - TO_STRING_KV(K_(is_exist_sess_info), K_(sess_info), K_(extra_len)); + inline uint32_t get_sess_info_count() { return sess_info_count_; } + inline int get_next_sess_info(common::ObString &sess_info); + void reset_sess_info_iterate_idx() { + sess_info_cur_idx_ = 0; + sess_info_offset_ = 0; + } + int add_sess_info_buf(const char *str, const int64_t len); + TO_STRING_KV(K_(is_exist_sess_info), K_(sess_info_count), K_(extra_len)); +public: + // for session info sync mechanism + bool is_exist_sess_info_; + obutils::ObVariableLenBuffer<32> extra_info_buf_; // save last packet extra info kv + common::ObSqlString sess_info_buf_; // save all sess info + uint32_t sess_info_count_; + uint32_t extra_len_; // extra len in ob20 payload, if the flag.exist_extra_info + +private: + // sess info iterator info + common::ObSEArray sess_info_length_; + uint32_t sess_info_cur_idx_; + uint64_t sess_info_offset_; }; +int Ob20ExtraInfo::get_next_sess_info(common::ObString &sess_info) +{ + sess_info.reset(); + int ret = common::OB_SUCCESS; + uint64_t length = sess_info_length_.at(sess_info_cur_idx_); + uint64_t buf_length = sess_info_buf_.length(); + if (sess_info_offset_ + length > buf_length) { + ret = common::OB_ERR_UNEXPECTED; + PROXY_LOG(WARN, "unexpected length of sess info buffer", K(ret), K(sess_info_offset_), K(length)); + } else { + sess_info.assign_ptr(sess_info_buf_.ptr() + sess_info_offset_, static_cast(length)); + sess_info_offset_ += length; + sess_info_cur_idx_ ++; + } + return ret; +} + +int Ob20ExtraInfo::add_sess_info_buf(const char *value, const int64_t len) +{ + int ret = common::OB_SUCCESS; + if (OB_UNLIKELY(NULL == value || 0 >= len)) { + ret = common::OB_INVALID_ARGUMENT; + PROXY_LOG(WARN, "invalid argument", K(value), K(len), K(ret)); + } else if (OB_FAIL(sess_info_buf_.append(value, len))) { + PROXY_LOG(WARN, "fail to append sess info buf", K(value), K(len), K(ret)); + } else if (OB_FAIL(sess_info_length_.push_back(len))) { + PROXY_LOG(WARN, "fail to record sess info buf length", K(ret)); + } else { + is_exist_sess_info_ = true; + sess_info_count_++; + } + return ret; +} + class Ob20ProtocolHeader { public: @@ -139,13 +205,22 @@ class Ob20ProtocolHeader // used for transfer function argument class Ob20ProtocolHeaderParam { public: - Ob20ProtocolHeaderParam() : connection_id_(0), request_id_(0), compressed_seq_(0), pkt_seq_(0), - is_last_packet_(false), is_need_reroute_(false), is_new_extra_info_(false) {} + Ob20ProtocolHeaderParam() : connection_id_(0), + request_id_(0), + compressed_seq_(0), + pkt_seq_(0), + is_last_packet_(false), + is_weak_read_(false), + is_need_reroute_(false), + is_new_extra_info_(false), + is_trans_internal_routing_(false) {} Ob20ProtocolHeaderParam(uint32_t conn_id, uint32_t req_id, uint8_t compressed_seq, uint8_t pkt_seq, - bool is_last_packet, bool is_need_reroute, bool is_new_extra_info) + bool is_last_packet, bool is_weak_read, bool is_need_reroute, + bool is_new_extra_info, bool is_trans_internal_routing) : connection_id_(conn_id), request_id_(req_id), compressed_seq_(compressed_seq), - pkt_seq_(pkt_seq), is_last_packet_(is_last_packet), is_need_reroute_(is_need_reroute), - is_new_extra_info_(is_new_extra_info) {} + pkt_seq_(pkt_seq), is_last_packet_(is_last_packet), + is_weak_read_(is_weak_read), is_need_reroute_(is_need_reroute), + is_new_extra_info_(is_new_extra_info), is_trans_internal_routing_(is_trans_internal_routing) {} ~Ob20ProtocolHeaderParam() {} Ob20ProtocolHeaderParam(const Ob20ProtocolHeaderParam ¶m) { @@ -159,8 +234,10 @@ class Ob20ProtocolHeaderParam { compressed_seq_ = param.compressed_seq_; pkt_seq_ = param.pkt_seq_; is_last_packet_ = param.is_last_packet_; + is_weak_read_ = param.is_weak_read_; is_need_reroute_ = param.is_need_reroute_; is_new_extra_info_ = param.is_new_extra_info_; + is_trans_internal_routing_ = param.is_trans_internal_routing_; } return *this; } @@ -170,27 +247,32 @@ class Ob20ProtocolHeaderParam { uint8_t get_compressed_seq() const { return compressed_seq_; } uint8_t get_pkt_seq() const { return pkt_seq_; } bool is_last_packet() const { return is_last_packet_; } + bool is_weak_read() const { return is_weak_read_; } bool is_need_reroute() const { return is_need_reroute_; } bool is_new_extra_info() const { return is_new_extra_info_; } - + bool is_trans_internal_routing() const { return is_trans_internal_routing_; } void reset() { MEMSET(this, 0x0, sizeof(Ob20ProtocolHeaderParam)); is_last_packet_ = false; + is_weak_read_ = false; is_need_reroute_ = false; is_new_extra_info_ = false; + is_trans_internal_routing_ = false; } - TO_STRING_KV(K_(connection_id), K_(request_id), K_(compressed_seq), - K_(pkt_seq), K_(is_last_packet), K_(is_need_reroute), K_(is_new_extra_info)); + TO_STRING_KV(K_(connection_id), K_(request_id), K_(compressed_seq), K_(pkt_seq), + K_(is_last_packet), K_(is_need_reroute), K_(is_new_extra_info), K_(is_trans_internal_routing)); private: uint32_t connection_id_; uint32_t request_id_; uint8_t compressed_seq_; uint8_t pkt_seq_; bool is_last_packet_; + bool is_weak_read_; bool is_need_reroute_; bool is_new_extra_info_; + bool is_trans_internal_routing_; }; diff --git a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.cpp b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.cpp index 8650b26a..183a18a5 100644 --- a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.cpp +++ b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.cpp @@ -131,39 +131,6 @@ int ObProto20Utils::encode_err_packet(event::ObMIOBuffer &write_buf, const Ob20P return ret; } -int ObProto20Utils::encode_executor_response_packet(event::ObMIOBuffer *write_buf, - const Ob20ProtocolHeaderParam &ob20_head_param, - uint8_t &seq, engine::ObProxyResultResp *result_resp) -{ - int ret = OB_SUCCESS; - - event::ObIOBufferReader *tmp_mio_reader = NULL; - event::ObMIOBuffer *tmp_mio_buf = NULL; - - if (OB_ISNULL(tmp_mio_buf = new_empty_miobuffer(MYSQL_BUFFER_SIZE))) { - ret = common::OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc miobuffer", K(ret)); - } else if (OB_ISNULL(tmp_mio_reader = tmp_mio_buf->alloc_reader())) { - ret = common::OB_ERR_UNEXPECTED; - LOG_WARN("fail to alloc reader", K(ret)); - } else if (OB_FAIL(ObMysqlPacketUtil::encode_executor_response_packet(write_buf, seq, result_resp))) { - LOG_WARN("fail to encode err packet buf", K(ret)); - } else if (OB_FAIL(ObProto20Utils::consume_and_compress_data(tmp_mio_reader, write_buf, - tmp_mio_reader->read_avail(), ob20_head_param))) { - LOG_WARN("fail to consume and compress data for executor response packet in ob20", K(ret)); - } else { - LOG_DEBUG("succ to executor response in ob20 packet"); - } - - if (OB_LIKELY(tmp_mio_buf != NULL)) { - free_miobuffer(tmp_mio_buf); - tmp_mio_buf = NULL; - tmp_mio_reader = NULL; - } - - return ret; -} - int ObProto20Utils::analyze_ok_packet_and_get_reroute_info(ObIOBufferReader *reader, const int64_t pkt_len, const ObMySQLCapabilityFlags &cap, @@ -350,11 +317,11 @@ inline int ObProto20Utils::reserve_proto20_hdr(ObMIOBuffer *write_buf, char *&hd inline int ObProto20Utils::fill_proto20_header(char *hdr_start, const int64_t payload_len, const uint8_t compressed_seq, const uint8_t packet_seq, const uint32_t request_id, const uint32_t connid, - const bool is_last_packet, const bool is_need_reroute, - const bool is_extra_info_exist, const bool is_new_extra_info) + const bool is_last_packet, const bool is_weak_read, + const bool is_need_reroute, const bool is_extra_info_exist, + const bool is_new_extra_info, const bool is_trans_internal_routing) { int ret = OB_SUCCESS; - //include compress header and ob20 header int64_t header_len = MYSQL_COMPRESSED_HEALDER_LENGTH + OB20_PROTOCOL_HEADER_LENGTH; //compress payload @@ -366,7 +333,9 @@ inline int ObProto20Utils::fill_proto20_header(char *hdr_start, const int64_t pa flag.st_flags_.OB_EXTRA_INFO_EXIST = is_extra_info_exist ? 1 : 0; flag.st_flags_.OB_IS_LAST_PACKET = is_last_packet ? 1 : 0; flag.st_flags_.OB_IS_PROXY_REROUTE = is_need_reroute ? 1 : 0; + flag.st_flags_.OB_IS_WEAK_READ = is_weak_read ? 1 : 0; flag.st_flags_.OB_IS_NEW_EXTRA_INFO = is_new_extra_info ? 1 : 0; + flag.st_flags_.OB_IS_TRANS_INTERNAL_ROUTING = is_trans_internal_routing ? 1 : 0; uint16_t reserved = 0; uint16_t header_checksum = 0; int64_t pos = 0; @@ -571,8 +540,9 @@ int ObProto20Utils::fill_proto20_new_extra_info(ObMIOBuffer *write_buf, const Ob } else if (OB_UNLIKELY(FLT_TYPE_AND_LEN != type_written_len)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected check written len", K(ret), K(type_written_len)); - } else if (OB_FAIL(write_buf->write(ptr, len, value_written_len))) { - LOG_WARN("fail to write obj value to buf", K(ret), K(obj_value)); + } else if (OB_NOT_NULL(ptr) && len > 0 + && OB_FAIL(write_buf->write(ptr, len, value_written_len))) { + LOG_WARN("fail to write obj value to buf", K(ret), K(obj_value), K(len), K(NULL == ptr), K(obj_key)); } else if (OB_UNLIKELY(len != value_written_len)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected check written len", K(ret), K(len), K(value_written_len)); @@ -667,15 +637,17 @@ int ObProto20Utils::consume_and_compress_data(ObIOBufferReader *reader, const uint32_t request_id = ob20_head_param.get_request_id(); const uint32_t conn_id = ob20_head_param.get_connection_id(); const bool is_last_packet = ob20_head_param.is_last_packet(); + const bool is_weak_read = ob20_head_param.is_weak_read(); const bool is_need_reroute = ob20_head_param.is_need_reroute(); const bool is_new_extra_info = ob20_head_param.is_new_extra_info(); + const bool is_trans_internal_routing = ob20_head_param.is_trans_internal_routing(); if (OB_ISNULL(reader) || OB_ISNULL(write_buf) || data_len > reader->read_avail()) { ret = OB_INVALID_ARGUMENT; int64_t tmp_read_avail = ((NULL == reader) ? 0 : reader->read_avail()); LOG_ERROR("invalid input value", K(reader), K(write_buf), K(data_len), K(compressed_seq), - K(packet_seq), K(request_id), K(conn_id), K(is_last_packet), K(is_need_reroute), - "read_avail", tmp_read_avail, K(ret)); + K(packet_seq), K(request_id), K(conn_id), K(is_last_packet), K(is_weak_read), + K(is_need_reroute), "read_avail", tmp_read_avail, K(ret)); } else if (OB_FAIL(reserve_proto20_hdr(write_buf, hdr_start))) { LOG_ERROR("fail to reserve proto20 hdr", K(ret)); } else if (OB_NOT_NULL(extra_info) @@ -688,17 +660,22 @@ int ObProto20Utils::consume_and_compress_data(ObIOBufferReader *reader, LOG_ERROR("fail to fill proto20 tailer", K(crc64), K(ret)); } else if (OB_FAIL(fill_proto20_header(hdr_start, payload_len, compressed_seq, packet_seq, request_id, conn_id, - is_last_packet, is_need_reroute, - is_extra_info_exist, is_new_extra_info))) { + is_last_packet, is_weak_read, is_need_reroute, + is_extra_info_exist, is_new_extra_info, is_trans_internal_routing))) { LOG_ERROR("fail to fill_proto20_header", K(payload_len), K(compressed_seq), K(packet_seq), K(request_id), K(conn_id), K(is_last_packet), - K(is_need_reroute), K(ret)); + K(is_weak_read), K(is_need_reroute), K(ret)); } else { LOG_DEBUG("build mysql compress packet with ob20 succ", "origin len", data_len, K(compressed_seq), K(crc64)); } return ret; } +bool ObProto20Utils::is_trans_related_sess_info(int16_t type) +{ + return SESSION_SYNC_TXN_STATIC_INFO <= type && type <= SESSION_SYNC_TXN_EXTRA_INFO; +} + int ObProxyTraceUtils::build_client_ip(ObIArray &extra_info, char *buf, int64_t buf_len, @@ -742,26 +719,51 @@ int ObProxyTraceUtils::build_client_ip(ObIArray &extra_info, } int ObProxyTraceUtils::build_sync_sess_info(common::ObIArray &extra_info, + common::ObSqlString &info_value, common::hash::ObHashMap &sess_info_hash_map, - common::ObSqlString &info_value) + common::hash::ObHashMap &client_sess_field_version, + common::hash::ObHashMap &server_sess_field_version, + ObMysqlSM *sm) { int ret = OB_SUCCESS; ObObJKV ob_sess_info; - ob_sess_info.key_.set_varchar(OB_V20_PRO_EXTRA_KV_NAME_SYNC_SESSION_INFO, static_cast(STRLEN(OB_V20_PRO_EXTRA_KV_NAME_SYNC_SESSION_INFO))); ob_sess_info.key_.set_default_collation_type(); - common::hash::ObHashMap::iterator last = sess_info_hash_map.end(); - common::hash::ObHashMap::iterator it = sess_info_hash_map.begin(); - for (; it != last; ++it) { - info_value.append(it->second); + const int MAX_TYPE_RECORD = 32; + char type_record[MAX_TYPE_RECORD]; + memset(type_record, '0', MAX_TYPE_RECORD); + bool is_sess_exist = false; + + SessFieldHashMap::iterator last = sess_info_hash_map.end(); + SessFieldHashMap::iterator it = sess_info_hash_map.begin(); + for (; it != last && OB_SUCC(ret); ++it) { + int16_t sess_info_type = it->first; + int64_t client_version = 0; + int64_t server_version = 0; + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(client_version , sess_info_type, client_sess_field_version))) { + LOG_WARN("fail to get client session field version", K(ret), K(sess_info_type)); + } else if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(server_version , sess_info_type, server_sess_field_version))) { + LOG_WARN("fail to get server session field version", K(ret), K(sess_info_type)); + } else if (client_version > server_version) { + is_sess_exist = true; + if (sess_info_type < MAX_TYPE_RECORD) { + type_record[sess_info_type] = '1'; + } + info_value.append(it->second); + } } - ob_sess_info.value_.set_varchar(info_value.string()); - ob_sess_info.value_.set_default_collation_type(); - - if (OB_FAIL(extra_info.push_back(ob_sess_info))) { - LOG_WARN("fail to push back", K(ret)); + if (is_sess_exist) { + type_record[MAX_TYPE_RECORD - 1] = '\0'; + sm->trans_state_.trace_log_.log_it("[send_sess]", "type", type_record); + } + if (OB_SUCC(ret)) { + ob_sess_info.value_.set_varchar(info_value.string()); + ob_sess_info.value_.set_default_collation_type(); + if (OB_FAIL(extra_info.push_back(ob_sess_info))) { + LOG_WARN("fail to push back", K(ret)); + } } return ret; } @@ -894,8 +896,13 @@ int ObProxyTraceUtils::build_related_extra_info_all(ObIArray &extra_inf if (!client_session->is_proxy_mysql_client_ && client_info.need_reset_sess_info_vars(server_info) && is_last_packet) { - SessFieldHashMap& sess_info_hash_map = client_info.get_sess_info_map(); - if (OB_FAIL(ObProxyTraceUtils::build_sync_sess_info(extra_info, sess_info_hash_map, sess_info_value))) { + SessFieldHashMap &sess_info_hash_map = client_info.get_sess_info_map(); + LOG_DEBUG("send session info to server", "server addr", sm->trans_state_.server_info_.addr_); + if (OB_FAIL(ObProxyTraceUtils::build_sync_sess_info(extra_info, sess_info_value, + sess_info_hash_map, + client_info.get_sess_field_version(), + server_info.get_sess_field_version(), + sm))) { LOG_WARN("fail to build sync sess info", K(ret)); } } @@ -905,6 +912,20 @@ int ObProxyTraceUtils::build_related_extra_info_all(ObIArray &extra_inf return ret; } +int ObProxyTraceUtils::get_sess_field_version(int64_t &version, int16_t type, common::hash::ObHashMap &map) +{ + int ret = OB_SUCCESS; + version = 0; + if (OB_FAIL(map.get_refactored(type, version))) { + if (OB_HASH_NOT_EXIST == ret) { + version = 0; + ret = OB_SUCCESS; + } else { + LOG_WARN("query session field version failed", K(type), K(ret)); + } + } + return ret; +} } // end of namespace proxy } // end of namespace obproxy diff --git a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.h b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.h index 0f4dbd8a..883917d7 100644 --- a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.h +++ b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.h @@ -54,9 +54,6 @@ class ObProto20Utils const uint16_t status_flag = 0); static int encode_err_packet(event::ObMIOBuffer &write_buf, const Ob20ProtocolHeaderParam &ob20_head_param, uint8_t &seq, const int err_code, const ObString &msg_buf); - static int encode_executor_response_packet(event::ObMIOBuffer *write_buf, - const Ob20ProtocolHeaderParam &ob20_head_param, - uint8_t &seq, engine::ObProxyResultResp *result_resp); // analyze utils static int analyze_ok_packet_and_get_reroute_info(event::ObIOBufferReader *reader, const int64_t pkt_len, @@ -81,9 +78,11 @@ class ObProto20Utils static int fill_proto20_header(char *hdr_start, const int64_t payload_len, const uint8_t compressed_seq, const uint8_t packet_seq, const uint32_t request_id, const uint32_t connid, - const bool is_last_packet, const bool is_need_reroute, - const bool is_extra_info_exist, const bool is_new_extra_info); + const bool is_last_packet, const bool is_weak_read, + const bool is_need_reroute, const bool is_extra_info_exist, + const bool is_new_extra_info, const bool is_trans_internal_routing); static int reserve_proto20_hdr(event::ObMIOBuffer *write_buf, char *&hdr_start); + static bool is_trans_related_sess_info(int16_t type); private: inline static int analyze_compressed_packet_header(const char *start, const int64_t len, @@ -107,12 +106,17 @@ class ObProxyTraceUtils static int build_extra_info_for_client(ObMysqlSM *sm, char *buf, const int64_t len, common::ObIArray &extra_info); static int build_sync_sess_info(common::ObIArray &extra_info, - common::hash::ObHashMap& sess_info_hash_map, - common::ObSqlString& info_value); + common::ObSqlString &info_value, + common::hash::ObHashMap &sess_info_hash_map, + common::hash::ObHashMap &client_sess_field_version, + common::hash::ObHashMap &server_sess_field_version, + ObMysqlSM *sm); static int build_related_extra_info_all(common::ObIArray &extra_info, ObMysqlSM *sm, char *ip_buf, const int64_t ip_buf_len, char *extra_info_buf, const int64_t extra_info_buf_len, common::ObSqlString &info_value, const bool is_last_packet); + static int get_sess_field_version(int64_t &version, int16_t type, common::hash::ObHashMap &map); + private: DISALLOW_COPY_AND_ASSIGN(ObProxyTraceUtils); }; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_common_define.h b/src/obproxy/proxy/mysqllib/ob_mysql_common_define.h index e21ee9a6..76806ac1 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_common_define.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_common_define.h @@ -176,17 +176,18 @@ bool is_supported_mysql_cmd(const obmysql::ObMySQLCmd mysql_cmd) // Stored Procedures case obmysql::OB_MYSQL_COM_STMT_FETCH: case obmysql::OB_MYSQL_COM_CHANGE_USER: + // binlog related + case obmysql::OB_MYSQL_COM_REGISTER_SLAVE: + case obmysql::OB_MYSQL_COM_BINLOG_DUMP: + case obmysql::OB_MYSQL_COM_BINLOG_DUMP_GTID: // pieceinfo case obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA: case obmysql::OB_MYSQL_COM_STMT_GET_PIECE_DATA: ret = true; break; // Replication Protocol - case obmysql::OB_MYSQL_COM_BINLOG_DUMP: case obmysql::OB_MYSQL_COM_TABLE_DUMP: case obmysql::OB_MYSQL_COM_CONNECT_OUT: - case obmysql::OB_MYSQL_COM_REGISTER_SLAVE: - case obmysql::OB_MYSQL_COM_BINLOG_DUMP_GTID: // Stored Procedures case obmysql::OB_MYSQL_COM_SET_OPTION: ret = false; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.cpp index 97421777..b0e6fbc2 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.cpp @@ -330,17 +330,10 @@ int ObMysqlCompressOB20Analyzer::do_obobj_extra_info_decode(const char *buf, LOG_DEBUG("deserialize extra info", K(key), K(value)); if (0 == key.get_string().case_compare(OB_V20_PRO_EXTRA_KV_NAME_SYNC_SESSION_INFO)) { - extra_info.sess_info_buf_.reset(); const char *value_ptr = value.get_string().ptr(); const int64_t value_len = value.get_string().length(); - if (OB_FAIL(extra_info.sess_info_buf_.init(value_len))) { - LOG_WARN("fail int alloc mem", K(value_len), K(ret)); - } else if (OB_FAIL(extra_info.sess_info_buf_.write(value_ptr, value_len))) { + if (OB_FAIL(extra_info.add_sess_info_buf(value_ptr, value_len))) { LOG_WARN("fail to write sess info to buf", K(ret), K(value)); - } else { - extra_info.sess_info_.assign_ptr(extra_info.sess_info_buf_.ptr(), - static_cast(extra_info.sess_info_buf_.len())); - extra_info.is_exist_sess_info_ = true; } } else if (0 == key.get_string().case_compare(OB_V20_PRO_EXTRA_KV_NAME_FULL_LINK_TRACE)) { int64_t full_pos = 0; @@ -380,14 +373,8 @@ int ObMysqlCompressOB20Analyzer::do_new_extra_info_decode(const char *buf, } else { Ob20NewExtraInfoProtocolKeyType type = static_cast(key_type); if (type == SESS_INFO) { - extra_info.sess_info_buf_.reset(); - if (OB_FAIL(extra_info.sess_info_buf_.init(key_len))) { - LOG_WARN("fail to init sess info buf", K(ret), K(key_len)); - } else if (OB_FAIL(extra_info.sess_info_buf_.write(buf + pos, key_len))) { + if (OB_FAIL(extra_info.add_sess_info_buf(buf+pos, key_len))) { LOG_WARN("fail to write sess info buf", K(ret), K(key_len)); - } else { - extra_info.sess_info_.assign_ptr(extra_info.sess_info_buf_.ptr(), key_len); - extra_info.is_exist_sess_info_ = true; } } else if (type == FULL_TRC) { int64_t full_pos = 0; @@ -570,7 +557,7 @@ int ObMysqlCompressOB20Analyzer::analyze_last_compress_packet( } else if (OB_FAIL(decompress_data(start, len, resp))) { LOG_WARN("fail to decompress last mysql packet", K(ret)); } - + resp.get_analyze_result().is_server_trans_internal_routing_ = curr_compressed_ob20_header_.flag_.is_trans_internal_routing(); return ret; } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.h b/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.h index 17d268a5..7fd1bdb7 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.h @@ -54,7 +54,7 @@ class ObMysqlCompressOB20Analyzer : public ObMysqlCompressAnalyzer ObMysqlCompressOB20Analyzer() : ObMysqlCompressAnalyzer(), last_ob20_seq_(0), request_id_(0), sessid_(0), remain_head_checked_len_(0), extra_header_len_(0), extra_len_(0), extra_checked_len_(0), payload_checked_len_(0), tail_checked_len_(0), - ob20_analyzer_state_(OB20_ANALYZER_MAX), crc64_(0), curr_compressed_ob20_header_() + ob20_analyzer_state_(OB20_ANALYZER_MAX), crc64_(0), result_(), curr_compressed_ob20_header_() {} virtual ~ObMysqlCompressOB20Analyzer() { reset(); } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.cpp index 1c5a2709..b693c595 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.cpp @@ -74,6 +74,7 @@ ObMysqlConfigParams::ObMysqlConfigParams() task_thread_num_(0), block_thread_num_(0), grpc_thread_num_(0), + shard_scan_thread_num_(0), automatic_match_work_thread_(true), enable_congestion_(false), @@ -86,6 +87,7 @@ ObMysqlConfigParams::ObMysqlConfigParams() enable_reroute_(false), enable_index_route_(false), enable_causal_order_read_(true), + enable_transaction_internal_routing_(true), sqlaudit_mem_limited_(0), internal_cmd_mem_limited_(0), @@ -116,7 +118,9 @@ ObMysqlConfigParams::ObMysqlConfigParams() proxy_id_(0), client_max_memory_size_(0), enable_cpu_isolate_(false), - enable_primary_zone_(true) + enable_primary_zone_(true), + ip_listen_mode_(0), + local_bound_ipv6_ip_() { proxy_idc_name_[0] = '\0'; } @@ -169,6 +173,7 @@ int ObMysqlConfigParams::assign_config(const ObProxyConfig &proxy_config) CONFIG_ITEM_ASSIGN(task_thread_num); CONFIG_ITEM_ASSIGN(block_thread_num); CONFIG_ITEM_ASSIGN(grpc_thread_num); + CONFIG_ITEM_ASSIGN(shard_scan_thread_num); CONFIG_ITEM_ASSIGN(automatic_match_work_thread); CONFIG_ITEM_ASSIGN(enable_congestion); @@ -178,6 +183,7 @@ int ObMysqlConfigParams::assign_config(const ObProxyConfig &proxy_config) CONFIG_ITEM_ASSIGN(enable_proxy_scramble); CONFIG_ITEM_ASSIGN(enable_compression_protocol); CONFIG_ITEM_ASSIGN(enable_ob_protocol_v2); + CONFIG_ITEM_ASSIGN(enable_transaction_internal_routing); CONFIG_ITEM_ASSIGN(enable_reroute); CONFIG_ITEM_ASSIGN(enable_index_route); CONFIG_ITEM_ASSIGN(enable_causal_order_read); @@ -210,6 +216,7 @@ int ObMysqlConfigParams::assign_config(const ObProxyConfig &proxy_config) CONFIG_ITEM_ASSIGN(client_max_memory_size); CONFIG_ITEM_ASSIGN(enable_cpu_isolate); CONFIG_ITEM_ASSIGN(enable_primary_zone); + CONFIG_ITEM_ASSIGN(ip_listen_mode); if (OB_SUCC(ret)) { obsys::CRLockGuard guard(proxy_config.rwlock_); @@ -255,6 +262,9 @@ int ObMysqlConfigParams::assign_config(const ObProxyConfig &proxy_config) if(OB_UNLIKELY(0 != local_bound_ip_.load(proxy_config.local_bound_ip))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to assign ip value", K(proxy_config.local_bound_ip.str()), K(ret)); + } else if (OB_UNLIKELY(0 != local_bound_ipv6_ip_.load(proxy_config.local_bound_ipv6_ip))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to assign ipv6 value", K(proxy_config.local_bound_ipv6_ip.str()), K(ret)); } } @@ -308,7 +318,7 @@ DEF_TO_STRING(ObMysqlConfigParams) J_COMMA(); J_KV(K_(short_async_task_timeout), K_(short_async_task_timeout), K_(min_congested_connect_timeout), K_(tenant_location_valid_time), K_(local_bound_ip), K_(listen_port), K_(stack_size), K_(work_thread_num), - K_(task_thread_num), K_(block_thread_num), K_(grpc_thread_num), K_(automatic_match_work_thread), + K_(task_thread_num), K_(block_thread_num), K_(grpc_thread_num), K_(shard_scan_thread_num), K_(automatic_match_work_thread), K_(enable_congestion), K_(enable_bad_route_reject), K_(test_server_addr), K_(sqlaudit_mem_limited), K_(max_connections), K_(client_max_connections), K_(enable_client_connection_lru_disconnect), K_(connect_observer_max_retries), @@ -324,7 +334,8 @@ DEF_TO_STRING(ObMysqlConfigParams) K_(default_inactivity_timeout), K_(enable_partition_table_route), K_(enable_pl_route), K_(enable_cluster_checkout), K_(enable_client_ip_checkout), K_(enable_proxy_scramble), K_(enable_compression_protocol), K_(enable_ob_protocol_v2), - K_(enable_reroute), K_(enable_index_route), K_(enable_causal_order_read)); + K_(enable_reroute), K_(enable_index_route), K_(enable_causal_order_read), + K_(ip_listen_mode), K_(local_bound_ipv6_ip)); J_OBJ_END(); return pos; } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.h b/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.h index 2ae3edbc..86020f9b 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.h @@ -102,6 +102,7 @@ struct ObMysqlConfigParams : public ObConfigInfo CfgInt task_thread_num_; CfgInt block_thread_num_; CfgInt grpc_thread_num_; + CfgInt shard_scan_thread_num_; CfgBool automatic_match_work_thread_; CfgBool enable_congestion_; CfgBool enable_bad_route_reject_; @@ -113,6 +114,7 @@ struct ObMysqlConfigParams : public ObConfigInfo CfgBool enable_reroute_; CfgBool enable_index_route_; CfgBool enable_causal_order_read_; + CfgBool enable_transaction_internal_routing_; CfgIpPortList test_server_addr_; CfgInt sqlaudit_mem_limited_; @@ -145,6 +147,8 @@ struct ObMysqlConfigParams : public ObConfigInfo CfgInt client_max_memory_size_; CfgBool enable_cpu_isolate_; CfgBool enable_primary_zone_; + CfgInt ip_listen_mode_; + CfgIp local_bound_ipv6_ip_; char proxy_idc_name_[OB_PROXY_MAX_IDC_NAME_LENGTH + 1]; char proxy_primary_zone_name_[common::MAX_ZONE_LENGTH + 1]; }; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.cpp index ded4f502..ad197d8b 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.cpp @@ -155,8 +155,10 @@ int ObMysqlOB20PacketWriter::write_request_packet(ObMIOBuffer &mio_buf, const uint8_t compressed_seq, const uint8_t pkt_seq, bool is_last_packet, + bool is_weak_read, bool is_need_reroute, bool is_new_extra_info, + bool is_trans_internal_routing, const common::ObIArray *extra_info) { int ret = OB_SUCCESS; @@ -168,8 +170,9 @@ int ObMysqlOB20PacketWriter::write_request_packet(ObMIOBuffer &mio_buf, LOG_WARN("we cannot support packet which is larger than 16MB", K(sql_str), K(MYSQL_PACKET_MAX_LENGTH), K(ret)); } else { - Ob20ProtocolHeaderParam ob20_head_param(conn_id, req_id, compressed_seq, pkt_seq, is_last_packet, is_need_reroute, - is_new_extra_info); + Ob20ProtocolHeaderParam ob20_head_param(conn_id, req_id, compressed_seq, pkt_seq, is_last_packet, + is_weak_read, is_need_reroute, + is_new_extra_info, is_trans_internal_routing); ObMySQLRawPacket com_pkt(cmd); com_pkt.set_content(sql_str.ptr(), static_cast(sql_str.length())); if (OB_FAIL(ObMysqlOB20PacketWriter::write_compressed_packet(mio_buf, com_pkt, ob20_head_param, extra_info))) { diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.h b/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.h index 82778e9f..f9ab9668 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.h @@ -38,8 +38,8 @@ class ObMysqlOB20PacketWriter static int write_request_packet(event::ObMIOBuffer &mio_buf, const obmysql::ObMySQLCmd cmd, const common::ObString &sql_str, const uint32_t conn_id, const uint32_t req_id, const uint8_t compressed_seq, - const uint8_t pkt_seq, bool is_last_packet, - bool is_need_reroute, bool is_new_extra_info, + const uint8_t pkt_seq, bool is_last_packet, bool is_weak_read, + bool is_need_reroute, bool is_new_extra_info, bool is_trans_internal_routing, const common::ObIArray *extra_info = NULL); static int write_packet(event::ObMIOBuffer &mio_buf, const char *buf, const int64_t buf_len, const Ob20ProtocolHeaderParam &ob20_head_param); diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.cpp index 1a08a57e..97233be2 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.cpp @@ -132,7 +132,7 @@ int ObHandshakeResponseParam::write_client_addr_buf(const common::ObAddr &addr) int ret = OB_SUCCESS; if (OB_UNLIKELY(!addr.is_valid())) { //do not write - } else if (OB_UNLIKELY(!addr.ip_to_string(client_ip_buf_, OB_MAX_IP_BUF_LEN))) { + } else if (OB_UNLIKELY(!addr.ip_to_string(client_ip_buf_, MAX_IP_ADDR_LENGTH))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to ip_to_string", K(addr), K(ret)); } @@ -188,7 +188,7 @@ int ObMysqlPacketRewriter::rewrite_ok_packet(const OMPKOK &src_ok, if (OB_FAIL(des_ok.add_system_var(str_kv))) { LOG_WARN("fail to add system var while rewrite ok packet", K(ret)); } else { - LOG_DEBUG("succ to add system var in ok packet", K(str_kv)); + LOG_DEBUG("succ to add system var in ok packet back to client", K(str_kv), K(cap)); } } } @@ -239,13 +239,13 @@ int ObMysqlPacketRewriter::rewrite_handshake_response_packet( } // find client_ip - if (param.enable_client_ip_checkout_) { + if (RUN_MODE_PROXY == g_run_mode && param.enable_client_ip_checkout_) { ObStringKV string_kv; for (int64_t i = 0; OB_SUCC(ret) && i < tg_hsr.get_connect_attrs().count(); ++i) { string_kv = tg_hsr.get_connect_attrs().at(i); if (0 == string_kv.key_.case_compare(OB_MYSQL_CLIENT_IP)) { if (!string_kv.value_.empty()) { - snprintf(param.client_ip_buf_, ObHandshakeResponseParam::OB_MAX_IP_BUF_LEN, "%.*s", string_kv.value_.length(), string_kv.value_.ptr()); + snprintf(param.client_ip_buf_, MAX_IP_ADDR_LENGTH, "%.*s", string_kv.value_.length(), string_kv.value_.ptr()); } break; } @@ -254,6 +254,26 @@ int ObMysqlPacketRewriter::rewrite_handshake_response_packet( // reset before add tg_hsr.reset_connect_attr(); + // add transparent transit conn attrs & find client_ip + OMPKHandshakeResponse &orig_hsr = orig_auth_req.get_hsr_result().response_; + bool find_client_ip = false; + for (int64_t i = 0; OB_SUCC(ret) && i < orig_hsr.get_connect_attrs().count(); ++i) { + ObStringKV kv; + // transit conn attrs OB_MYSQL_OB_CLIENT + if (OB_FAIL(orig_hsr.get_connect_attrs().at(i, kv))) { + LOG_WARN("fail access handshake response connect attrs", K(i), K(ret)); + } else if (kv.key_.prefix_match(OB_MYSQL_OB_CLIENT)) { + if (OB_FAIL(tg_hsr.get_connect_attrs().push_back(kv))) { + LOG_WARN("fail push back transparent transmit connect attrs", K(kv), K(ret)); + } else { /* succ */ } + } else if (!find_client_ip + && param.enable_client_ip_checkout_ + && 0 == kv.key_.case_compare(OB_MYSQL_CLIENT_IP) + && !kv.value_.empty()){ + snprintf(param.client_ip_buf_, MAX_IP_ADDR_LENGTH, "%.*s", kv.value_.length(), kv.value_.ptr()); + find_client_ip = true; + } else { /* do nothing */ } + } // 4. add obproxy specified connect attrs: // a. proxy_mode // b. connection id @@ -281,9 +301,7 @@ int ObMysqlPacketRewriter::rewrite_handshake_response_packet( LOG_WARN("fail to add client ip", K(param.client_ip_buf_), K(ret)); } else if (OB_FAIL(add_connect_attr(OB_MYSQL_PROXY_VERSION, param.proxy_version_buf_, tg_hsr))) { LOG_WARN("fail to add proxy version", K(param.proxy_version_buf_), K(ret)); - } else { - //do nothing - } + } else { /* succ */ } return ret; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.h b/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.h index 1c75aa83..238ecbcf 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.h @@ -64,7 +64,6 @@ struct ObHandshakeResponseParam static const int64_t OB_MAX_UINT32_BUF_LEN = 11; // string length of max uint32_t(2**32 - 1) static const int64_t OB_MAX_VERSION_BUF_LEN = 22; // string length of (xxx.xxx.xxx.xxx.xxx) - static const int64_t OB_MAX_IP_BUF_LEN = 20; // string length of (xxx.xxx.xxx.xxx.xxx) bool is_saved_login_; bool use_compress_; @@ -81,7 +80,7 @@ struct ObHandshakeResponseParam char global_vars_version_buf_[OB_MAX_UINT64_BUF_LEN]; char cap_buf_[OB_MAX_UINT64_BUF_LEN]; char proxy_scramble_buf_[obmysql::OMPKHandshake::SCRAMBLE_TOTAL_SIZE]; - char client_ip_buf_[OB_MAX_IP_BUF_LEN]; + char client_ip_buf_[MAX_IP_ADDR_LENGTH]; char cluster_id_buf_[OB_MAX_UINT64_BUF_LEN]; private: diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.cpp index 1bd9891d..b95aa448 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.cpp @@ -163,7 +163,8 @@ void ObMysqlRequestAnalyzer::analyze_request(const ObRequestAnalyzeCtx &ctx, && !client_request.is_sharding_user() && !client_request.is_proxysys_user() && !ctx.using_ldg_ - && OB_MYSQL_COM_STMT_SEND_LONG_DATA != sql_cmd) { + && OB_MYSQL_COM_STMT_SEND_LONG_DATA != sql_cmd + && OB_MYSQL_COM_CHANGE_USER != sql_cmd) { if (OB_FAIL(do_analyze_request(ctx, sql_cmd, auth_request, client_request, is_oracle_mode))) { status = ANALYZE_ERROR; LOG_WARN("fail to dispatch mysql cmd", "analyze status", @@ -371,6 +372,7 @@ void ObMysqlRequestAnalyzer::extract_fileds(const ObExprParseResult& result, ObP void ObMysqlRequestAnalyzer::extract_fileds(const ObExprParseResult& result, SqlFieldResult &sql_result) { + int ret = OB_SUCCESS; int64_t total_num = result.all_relation_info_.relation_num_; ObProxyRelationExpr* relation_expr = NULL; ObString name_str; @@ -398,34 +400,43 @@ void ObMysqlRequestAnalyzer::extract_fileds(const ObExprParseResult& result, Sql } if (relation_expr->right_value_ != NULL) { ObProxyTokenNode *token = relation_expr->right_value_->head_; - SqlField field; - field.reset(); - field.column_name_.set(name_str); - SqlColumnValue column_value; - while (NULL != token) { - switch(token->type_) { - case TOKEN_INT_VAL: - column_value.value_type_ = TOKEN_INT_VAL; - column_value.column_int_value_ = token->int_value_; - column_value.column_value_.set_integer(token->int_value_); - field.column_values_.push_back(column_value); - break; - case TOKEN_STR_VAL: - column_value.value_type_ = TOKEN_STR_VAL; - value_str.assign_ptr(token->str_value_.str_, - token->str_value_.str_len_); - column_value.column_value_.set(value_str); - field.column_values_.push_back(column_value); - break; - default: - LOG_DEBUG("invalid token type", "token type", get_obproxy_token_type(token->type_)); - break; + SqlField* field = NULL; + if (OB_FAIL(SqlField::alloc_sql_field(field))) { + LOG_WARN("fail to alloc sql field", K(ret)); + } else { + field->column_name_.set_value(name_str.length(), name_str.ptr()); + SqlColumnValue column_value; + while (OB_SUCC(ret) && NULL != token) { + switch(token->type_) { + case TOKEN_INT_VAL: + column_value.value_type_ = TOKEN_INT_VAL; + column_value.column_int_value_ = token->int_value_; + column_value.column_value_.set_integer(token->int_value_); + if (OB_FAIL(field->column_values_.push_back(column_value))) { + LOG_WARN("fail to push column_value", K(ret)); + } + break; + case TOKEN_STR_VAL: + column_value.value_type_ = TOKEN_STR_VAL; + value_str.assign_ptr(token->str_value_.str_, + token->str_value_.str_len_); + column_value.column_value_.set_value(value_str); + if (OB_FAIL(field->column_values_.push_back(column_value))) { + LOG_WARN("fail to push back column_value", K(ret)); + } + break; + default: + LOG_DEBUG("invalid token type", "token type", get_obproxy_token_type(token->type_)); + break; + } + token = token->next_; + } + if (OB_SUCC(ret) && field->is_valid() && OB_SUCCESS == sql_result.fields_.push_back(field)) { + ++sql_result.field_num_; + } else { + field->reset(); + field = NULL; } - token = token->next_; - } - if (field.is_valid()) { - sql_result.fields_.push_back(field); - ++sql_result.field_num_; } } else { LOG_WARN("right value is null"); @@ -467,7 +478,6 @@ int ObMysqlRequestAnalyzer::parse_sql_fileds(ObProxyMysqlRequest &client_request ObExprParser expr_parser(*allocator, parse_mode); ObString sql = client_request.get_sql(); expr_result.part_key_info_.key_num_ = 0; - expr_result.target_mask_ = 0; ObString expr_sql = ObProxyMysqlRequest::get_expr_sql(sql, sql_parse_result.get_parsed_length()); if (SELECT_STMT_PARSE_MODE == parse_mode) { const char *expr_sql_str = expr_sql.ptr(); @@ -542,6 +552,18 @@ inline int ObMysqlRequestAnalyzer::do_analyze_request( LOG_WARN("fail to parse sql", K(sql), K(ret)); } else if (OB_FAIL(handle_internal_cmd(client_request))) { LOG_WARN("fail to handle internal cmd", K(sql), K(ret)); + } else if (sql_parse_result.is_dual_request() + && OB_MYSQL_COM_STMT_PREPARE_EXECUTE == sql_cmd + && get_global_proxy_config().enable_xa_route) { + // specically check if sql is xa start + // from obci only one format: select DBMS_XA.XA_START(?, ?) from dual + ObString tmp = sql; + tmp.split_on(' '); + ObString dbms_xa_start = tmp.split_on(' ').split_on('(').trim(); + if (0 == dbms_xa_start.case_compare("DBMS_XA.XA_START")) { + sql_parse_result.set_xa_start_stmt(true); + LOG_DEBUG("[ObMysqlRequestAnalyzer::do_analyze_request] receive xa start req in prepare execute packet"); + } } } } else { @@ -574,20 +596,6 @@ inline int ObMysqlRequestAnalyzer::do_analyze_request( } break; } - case OB_MYSQL_COM_PING: { - // proxy handle mysql_ping() by itself - int64_t len = 0; - if (NULL == ctx.reader_) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid buffer reader", K_(ctx.reader), K(ret)); - } else if (MYSQL_NET_META_LENGTH != (len = ctx.reader_->read_avail())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("buffer reader length is not equal to MYSQL_NET_META_LENGTH", K(len)); - ObMysqlPacketReader reader; - reader.print_reader(*ctx.reader_); - } - break; - } case OB_MYSQL_COM_CHANGE_USER: case OB_MYSQL_COM_RESET_CONNECTION: case OB_MYSQL_COM_INIT_DB: { @@ -621,6 +629,7 @@ inline int ObMysqlRequestAnalyzer::do_analyze_request( break; } } + case OB_MYSQL_COM_PING: case OB_MYSQL_COM_HANDSHAKE: case OB_MYSQL_COM_QUIT: { break; @@ -733,7 +742,8 @@ int ObMysqlRequestAnalyzer::handle_internal_cmd(ObProxyMysqlRequest &client_requ parse_result.set_err_stmt_type(OBPROXY_T_ERR_NOT_SUPPORTED); } is_internal_cmd = true; - } else if (client_request.is_sharding_user() && parse_result.is_show_topology_stmt()) { + } else if (client_request.is_sharding_user() && (parse_result.is_show_topology_stmt() + || parse_result.is_show_elastic_id_stmt())) { is_internal_cmd = true; } @@ -800,6 +810,16 @@ int ObMysqlRequestAnalyzer::analyze_execute_header(const int64_t param_num, int ObMysqlRequestAnalyzer::parse_param_type(const int64_t param_num, ObIArray ¶m_types, const char *&buf, int64_t &data_len) +{ + ObSEArray type_infos; + return parse_param_type(param_num, param_types, type_infos, buf, data_len); +} + +// The default data of this method is complete and can only come in once +int ObMysqlRequestAnalyzer::parse_param_type(const int64_t param_num, + ObIArray ¶m_types, + ObIArray &type_infos, + const char *&buf, int64_t &data_len) { int ret = OB_SUCCESS; @@ -813,10 +833,11 @@ int ObMysqlRequestAnalyzer::parse_param_type(const int64_t param_num, LOG_WARN("fail to get int1", K(data_len), K(ret)); } else if (OB_FAIL(param_types.push_back(static_cast(type)))) { LOG_WARN("fail to push back param type", K(type), K(ret)); + } else if (OB_FAIL(type_infos.push_back(TypeInfo()))) { + LOG_WARN("fail to push back empty type info", K(ret)); } else if (OB_MYSQL_TYPE_COMPLEX == type) { - TypeInfo type_name_info; + TypeInfo &type_name_info = type_infos.at(i); uint8_t elem_type = 0; - // skip all complex type bytes if (OB_FAIL(decode_type_info(buf, data_len, type_name_info))) { LOG_WARN("failed to decode type info", K(ret)); } else if (type_name_info.type_name_.empty()) { @@ -1047,9 +1068,8 @@ int ObMysqlRequestAnalyzer::analyze_send_long_data_param(ObProxyMysqlRequest &cl ret = OB_INVALID_ARGUMENT; LOG_WARN("fail to get param name from prepare result", K(ret), K(param_id), K(sql_result.field_num_)); } else { - obutils::SqlField &field = sql_result.fields_.at(param_id); - param_name = field.column_name_.string_; - + obutils::SqlField* field = sql_result.fields_.at(param_id); + param_name = field->column_name_.config_string_; ObProxyPartKeyInfo &key_info = part_info->get_part_key_info(); for (uint64_t i = 0; i < key_info.key_num_; ++i) { ObProxyPartKey &part_key = key_info.part_keys_[i]; @@ -1134,7 +1154,6 @@ int ObMysqlRequestAnalyzer::parse_param_value(ObIAllocator &allocator, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input value", K(data), K(ret)); } else { - ObCollationType cs_type = ObCharset::get_default_collation(charset); switch (type) { case OB_MYSQL_TYPE_TINY: { int8_t value; @@ -1211,10 +1230,13 @@ int ObMysqlRequestAnalyzer::parse_param_value(ObIAllocator &allocator, case OB_MYSQL_TYPE_VARCHAR: case OB_MYSQL_TYPE_VAR_STRING: case OB_MYSQL_TYPE_NEWDECIMAL: - case OB_MYSQL_TYPE_OB_UROWID: { + case OB_MYSQL_TYPE_OB_UROWID: + case OB_MYSQL_TYPE_JSON: + case OB_MYSQL_TYPE_GEOMETRY: { ObString str; ObString dst; uint64_t length = 0; + common::ObCollationType cs_type = common::ObCharset::get_default_collation(charset); if (OB_FAIL(ObMysqlPacketUtil::get_length(data, buf_len, length))) { LOG_ERROR("decode varchar param value failed", K(buf_len), K(ret)); } else if (buf_len < length) { @@ -1223,7 +1245,7 @@ int ObMysqlRequestAnalyzer::parse_param_value(ObIAllocator &allocator, } else { str.assign_ptr(data, static_cast(length)); if (OB_FAIL(ob_write_string(allocator, str, dst))) { - LOG_WARN("Failed to write str", K(ret)); + LOG_WARN("failed to ob write string", K(ret)); } else { if (OB_MYSQL_TYPE_NEWDECIMAL == type) { number::ObNumber nb; @@ -1459,8 +1481,7 @@ int ObMysqlRequestAnalyzer::decode_type_info(const char*& buf, int64_t &buf_len, } } if (OB_SUCC(ret)) { - uint64_t version = 0; - if (OB_FAIL(ObMysqlPacketUtil::get_length(buf, buf_len, version))) { + if (OB_FAIL(ObMysqlPacketUtil::get_length(buf, buf_len, type_info.version_))) { LOG_WARN("failed to get version", K(ret)); } } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h b/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h index dd3a6587..58c88db5 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h @@ -103,6 +103,11 @@ class ObMysqlRequestAnalyzer common::ObIArray ¶m_types, const char *&buf, int64_t &data_len); + static int parse_param_type(const int64_t param_num, + common::ObIArray ¶m_types, + common::ObIArray &type_infos, + const char *&buf, int64_t &data_len); + static int parse_param_type_from_reader(int64_t& param_offset, const int64_t param_num, common::ObIArray ¶m_types, @@ -136,16 +141,6 @@ class ObMysqlRequestAnalyzer static int analyze_sql_id(const ObString &sql, ObProxyMysqlRequest &client_request, common::ObString &sql_id); -private: - struct TypeInfo { - TypeInfo() : relation_name_(), type_name_(), is_elem_type_(false) {} ; - common::ObString relation_name_; - common::ObString type_name_; - ObObjType elem_type_; - bool is_elem_type_; - TO_STRING_KV(K_(relation_name), K_(type_name), K_(elem_type), K_(is_elem_type)); - }; - private: int get_payload_length(const char *buffer); int is_request_finished(const ObRequestBuffer &buff, bool &is_finish); @@ -172,11 +167,11 @@ class ObMysqlRequestAnalyzer const char *&data, int64_t &buf_len, ObObj ¶m); static int parse_mysql_time_value(const char *&data, int64_t &buf_len, ObObj ¶m); - static int decode_type_info(const char*& buf, int64_t &buf_len, TypeInfo &type_info); + static int decode_type_info(const char*& buf, int64_t &buf_len, obmysql::TypeInfo &type_info); static int decode_type_info_from_reader(event::ObIOBufferReader* reader, int64_t &decoded_offset, - TypeInfo &type_info); + obmysql::TypeInfo &type_info); static int get_uint1_from_reader(event::ObIOBufferReader* reader, int64_t &decoded_offset, diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.cpp index 6e22ed9b..4d28b0d4 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.cpp @@ -58,15 +58,19 @@ int ObMysqlRequestBuilder::build_database_sync_packet(ObMysqlSM *sm, uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, db_name, server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, + compressed_seq, compressed_seq, true, false, false, server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -102,16 +106,20 @@ int ObMysqlRequestBuilder::build_all_session_vars_sync_packet(ObMysqlSM *sm, } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, reset_sql.string(), server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, + compressed_seq, compressed_seq, true, false, false, server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -148,16 +156,20 @@ int ObMysqlRequestBuilder::build_session_vars_sync_packet(ObMysqlSM *sm, } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, reset_sql.string(), server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, - server_info.is_new_extra_info_supported(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -177,32 +189,36 @@ int ObMysqlRequestBuilder::build_session_vars_sync_packet(ObMysqlSM *sm, return ret; } -int ObMysqlRequestBuilder::build_last_insert_id_sync_packet(ObMysqlSM *sm, - ObMIOBuffer &mio_buf, - ObClientSessionInfo &client_info, - ObMysqlServerSession *server_session, - const ObProxyProtocol ob_proxy_protocol) +int ObMysqlRequestBuilder::build_session_user_vars_sync_packet(ObMysqlSM *sm, + ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol) { int ret = OB_SUCCESS; ObMySQLCmd cmd = OB_MYSQL_COM_QUERY; ObSqlString reset_sql; ObServerSessionInfo &server_info = server_session->get_session_info(); - if (OB_FAIL(client_info.extract_last_insert_id_reset_sql(server_info, reset_sql))) { - LOG_WARN("fail to extract last_insert_id variable reset sql", K(ret)); + if (OB_FAIL(client_info.extract_user_variable_reset_sql(server_info, reset_sql))) { + LOG_WARN("fail to extract variable reset sql", K(ret)); } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { LOG_WARN("fail to build extra info for server", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, reset_sql.string(), - server_session->get_server_sessid(), - server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, - server_info.is_new_extra_info_supported(), - &extra_info))) { + server_session->get_server_sessid(), + server_session->get_next_server_request_id(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), + &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } } else { @@ -213,12 +229,11 @@ int ObMysqlRequestBuilder::build_last_insert_id_sync_packet(ObMysqlSM *sm, if (OB_SUCC(ret)) { server_session->set_compressed_seq(compressed_seq); - LOG_DEBUG("will sync last_insert_id variable", K(reset_sql)); + LOG_DEBUG("will sync session user variables", K(reset_sql)); } else { LOG_WARN("fail to write packet", K(cmd), K(reset_sql), K(ob_proxy_protocol), K(ret)); } } - return ret; } @@ -235,16 +250,20 @@ int ObMysqlRequestBuilder::build_start_trans_request(ObMysqlSM *sm, uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, sql, server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, + compressed_seq, compressed_seq, true, false, false, server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -264,6 +283,54 @@ int ObMysqlRequestBuilder::build_start_trans_request(ObMysqlSM *sm, return ret; } +int ObMysqlRequestBuilder::build_xa_start_request(ObMysqlSM *sm, + ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol) +{ + LOG_DEBUG("start to build xa start request"); + int ret = OB_SUCCESS; + ObString &xa_start_req_pkt = client_info.get_start_trans_sql(); + ObString xa_pkt_payload(xa_start_req_pkt.length() - MYSQL_NET_META_LENGTH, + xa_start_req_pkt.ptr() + MYSQL_NET_META_LENGTH); + ObServerSessionInfo &server_info = server_session->get_session_info(); + ObMySQLCmd cmd = OB_MYSQL_COM_STMT_PREPARE_EXECUTE; + uint8_t compressed_seq = 0; + if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); + } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, xa_pkt_payload, + server_session->get_server_sessid(), + server_session->get_next_server_request_id(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), + &extra_info))) { + LOG_WARN("fail to write request packet in ob20", K(ret)); + } else { /* nothing */ } + } else { + const bool need_compress = ob_proxy_protocol == ObProxyProtocol::PROTOCOL_CHECKSUM ? true : false; + ret = ObMysqlPacketWriter::write_request_packet(mio_buf, cmd, xa_pkt_payload, compressed_seq, + need_compress, server_info.is_checksum_on()); + } + + if (OB_SUCC(ret)) { + server_session->set_compressed_seq(compressed_seq); + LOG_DEBUG("will send to sync xa start", K(xa_pkt_payload)); + } else { + LOG_WARN("fail to write xa start request to buffer", K(cmd), K(xa_pkt_payload), K(ob_proxy_protocol), K(ret)); + } + + return OB_SUCCESS; +} + int ObMysqlRequestBuilder::build_prepare_request(ObMysqlSM *sm, ObMIOBuffer &mio_buf, ObClientSessionInfo &client_info, @@ -279,16 +346,20 @@ int ObMysqlRequestBuilder::build_prepare_request(ObMysqlSM *sm, } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, ps_sql, server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, - server_info.is_new_extra_info_supported(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -338,16 +409,20 @@ int ObMysqlRequestBuilder::build_text_ps_prepare_request(ObMysqlSM *sm, } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, sql, server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, - server_info.is_new_extra_info_supported(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -368,6 +443,24 @@ int ObMysqlRequestBuilder::build_text_ps_prepare_request(ObMysqlSM *sm, return ret; } +int ObMysqlRequestBuilder::build_binlog_login_packet(ObMysqlSM *sm, + ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol) +{ + UNUSED(sm); + UNUSED(server_session); + UNUSED(ob_proxy_protocol); + + OMPKHandshakeResponse tg_hsr = client_info.get_login_req().get_hsr_result().response_; + tg_hsr.set_username(client_info.get_login_req().get_hsr_result().full_name_); + tg_hsr.set_seq(1); + tg_hsr.reset_connect_attr(); + + return packet::ObMysqlPacketWriter::write_packet(mio_buf, tg_hsr); +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.h b/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.h index e7ea39e3..137b4097 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.h @@ -53,6 +53,13 @@ class ObMysqlRequestBuilder ObClientSessionInfo &client_info, ObMysqlServerSession *server_session, const ObProxyProtocol ob_proxy_protocol); + + // build binlog login request + static int build_binlog_login_packet(ObMysqlSM *sm, + event::ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol); // build saved login packet to send saved login request static int build_saved_login_packet(ObMysqlSM *sm, @@ -88,12 +95,12 @@ class ObMysqlRequestBuilder ObMysqlServerSession *server_session, const ObProxyProtocol ob_proxy_protocol); - // build OB_MYSQL_COM_QUERY packet to sync last_insert_id var - static int build_last_insert_id_sync_packet(ObMysqlSM *sm, - event::ObMIOBuffer &mio_buf, - ObClientSessionInfo &client_info, - ObMysqlServerSession *server_session, - const ObProxyProtocol ob_proxy_protocol); + // build OB_MYSQL_COM_QUERY packet to sync session user vars + static int build_session_user_vars_sync_packet(ObMysqlSM *sm, + event::ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol); // build start transaction request packet static int build_start_trans_request(ObMysqlSM *sm, @@ -101,6 +108,12 @@ class ObMysqlRequestBuilder ObClientSessionInfo &client_info, ObMysqlServerSession *server_session, const ObProxyProtocol ob_proxy_protocol); + + static int build_xa_start_request(ObMysqlSM *sm, + event::ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol); // build mysql request packet static int build_mysql_request(event::ObMIOBuffer &mio_buf, diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_resp_analyzer.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_resp_analyzer.cpp index 4c8813dd..b8b752c5 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_resp_analyzer.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_resp_analyzer.cpp @@ -75,7 +75,10 @@ inline int ObMysqlPacketMetaAnalyzer::update_cur_type(ObRespResult &result, cons // paket will treat as ok packet. // so in ResultSet Protocol, a packet can be detemined as ok packet by // both 0x00 === pkt_type and 1 != has_already_recived_eof_pkt_cnt - if (OB_MYSQL_COM_STMT_PREPARE == result.get_cmd()) { + if (OB_MYSQL_COM_BINLOG_DUMP == result.get_cmd() + || OB_MYSQL_COM_BINLOG_DUMP_GTID == result.get_cmd()) { + break; + } else if (OB_MYSQL_COM_STMT_PREPARE == result.get_cmd()) { /* Preapre Request, in OCEANBASE, maybe error + ok. in this case, should set OK_PACKET_ENDING_TYPE */ if (0 == prepare_ok_pkt_cnt && 0 == err_pkt_cnt) { cur_type_ = PREPARE_OK_PACKET_ENDING_TYPE; @@ -176,7 +179,10 @@ ObRespResult::ObRespResult() mysql_mode_(UNDEFINED_MYSQL_PROTOCOL_MODE), resp_type_(MAX_RESP_TYPE), trans_state_(IN_TRANS_STATE_BY_DEFAULT), - reserved_len_(0) + reserved_len_(0), + all_pkt_cnt_(0), + expect_pkt_cnt_(0), + is_recv_resultset_(false) { MEMSET(pkt_cnt_, 0, sizeof(pkt_cnt_)); } @@ -480,6 +486,27 @@ int ObRespResult::is_resp_finished(bool &finished, ObMysqlRespEndingType &ending } break; } + case OB_MYSQL_COM_BINLOG_DUMP: + case OB_MYSQL_COM_BINLOG_DUMP_GTID : { + if (1 == pkt_cnt_[EOF_PACKET_ENDING_TYPE]) { + finished = true; + ending_type = EOF_PACKET_ENDING_TYPE; + } else if (1 == pkt_cnt_[ERROR_PACKET_ENDING_TYPE]) { + finished = true; + ending_type = ERROR_PACKET_ENDING_TYPE; + } + break; + } + case OB_MYSQL_COM_REGISTER_SLAVE: { + if (1 == pkt_cnt_[ERROR_PACKET_ENDING_TYPE]) { + finished = true; + ending_type = ERROR_PACKET_ENDING_TYPE; + } else if (1 == pkt_cnt_[OK_PACKET_ENDING_TYPE]) { + finished = true; + ending_type = OK_PACKET_ENDING_TYPE; + } + break; + } default : { if (!is_supported_mysql_cmd(cmd_)) { ret = OB_NOT_SUPPORTED; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_response.h b/src/obproxy/proxy/mysqllib/ob_mysql_response.h index 1003e916..de5431d0 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_response.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_response.h @@ -78,7 +78,7 @@ struct ObRespAnalyzeResult bool is_server_can_use_compress() const { return (1 == server_capabilities_lower_.capability_flag_.OB_SERVER_CAN_USE_COMPRESS); } void set_server_trace_id(const common::ObString &trace_id); bool support_ssl() const { return 1 == server_capabilities_lower_.capability_flag_.OB_SERVER_SSL; } - + bool is_server_trans_internal_routing() const { return is_server_trans_internal_routing_; } bool is_not_supported_error() const { return (is_error_resp() && ER_NOT_SUPPORTED_YET == error_pkt_.get_err_code()); @@ -135,6 +135,18 @@ struct ObRespAnalyzeResult { return (is_error_resp() && -common::OB_STANDBY_WEAK_READ_ONLY == error_pkt_.get_err_code()); } + bool is_trans_free_route_not_supported_error() const + { + return (is_error_resp() && -common::OB_TRANS_FREE_ROUTE_NOT_SUPPORTED == error_pkt_.get_err_code()); + } + bool is_mysql_wrong_arguments_error() const + { + return (is_error_resp() && ER_WRONG_ARGUMENTS == error_pkt_.get_err_code()); + } + bool is_internal_error() const + { + return (is_error_resp() && -common::OB_INTERNAL_ERROR == error_pkt_.get_err_code()); + } inline uint32_t get_server_capability() const { @@ -186,7 +198,7 @@ struct ObRespAnalyzeResult Ob20ExtraInfo extra_info_; common::FLTObjManage flt_; - + bool is_server_trans_internal_routing_; DISALLOW_COPY_AND_ASSIGN(ObRespAnalyzeResult); }; @@ -235,6 +247,7 @@ inline void ObRespAnalyzeResult::reset() server_trace_id_.reset(); extra_info_.reset(); flt_.reset(); + is_server_trans_internal_routing_ = false; } inline void ObRespAnalyzeResult::set_server_trace_id(const common::ObString &trace_id) diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.cpp index 39727b65..596b68c0 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.cpp @@ -13,6 +13,9 @@ #define USING_LOG_PREFIX PROXY #include "proxy/mysqllib/ob_mysql_response_builder.h" #include "rpc/obmysql/packet/ompk_ok.h" +#include "rpc/obmysql/packet/ompk_prepare_execute.h" +#include "rpc/obmysql/packet/ompk_prepare_execute_req.h" +#include "rpc/obmysql/packet/ompk_eof.h" #include "packet/ob_proxy_cached_packets.h" #include "packet/ob_mysql_packet_writer.h" #include "packet/ob_mysql_packet_util.h" @@ -38,6 +41,7 @@ const ObString ObMysqlResponseBuilder::OBPROXY_PROXY_VERSION_NAME = "proxy_versi int ObMysqlResponseBuilder::build_ok_resp(ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans, const bool is_state_changed) { @@ -60,8 +64,8 @@ int ObMysqlResponseBuilder::build_ok_resp(ObMIOBuffer &mio_buf, if (is_state_changed) { ssf.status_flags_.OB_SERVER_SESSION_STATE_CHANGED = 1; } - if (0 != autocommit) { - ssf.status_flags_.OB_SERVER_STATUS_AUTOCOMMIT = 1; + if (0 == autocommit) { + ssf.status_flags_.OB_SERVER_STATUS_AUTOCOMMIT = 0; } //ok_packet.set_server_status(ssf.status_flags_); ok_packet->set_status_flags(ssf.flags_); @@ -69,7 +73,7 @@ int ObMysqlResponseBuilder::build_ok_resp(ObMIOBuffer &mio_buf, ObString pkt_str; if (OB_FAIL(ok_packet->get_packet_str(pkt_str))) { LOG_WARN("fail to get ok packet str", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_raw_packet(mio_buf, client_session, pkt_str))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_raw_packet(mio_buf, client_session, protocol, pkt_str))) { LOG_WARN("fail to write packet", K(ret)); } } @@ -77,9 +81,187 @@ int ObMysqlResponseBuilder::build_ok_resp(ObMIOBuffer &mio_buf, return ret; } +/** + * @brief build OB_MYSQL_COM_STMT_PREPARE_EXECUTE response of XA_START request + * OB_MYSQL_COM_STMT_PREPARE_EXECUTE + * struct of OB_MYSQL_COM_STMT_PREPARE_EXECUTE RESPONSE: + * Prepare + * param_num > 0 ? ColDef * param_num + * Eof + * col_num > 0 ? ColDef * col_num + * Eof + * Row + * Eof + * Ok + * + * @param mio_buf + * @param client_request + * @param info + * @return int + */ +int ObMysqlResponseBuilder::build_prepare_execute_xa_start_resp(ObMIOBuffer &mio_buf, + ObProxyMysqlRequest &client_request, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol) +{ + int ret = OB_SUCCESS; + ObClientSessionInfo &info = client_session.get_session_info(); + OMPKPrepareExecuteReq prepare_req_pkt; + ObIOBufferReader *tmp_mio_reader = NULL; + ObMIOBuffer *tmp_mio_buf = &mio_buf; + + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { + if (OB_ISNULL(tmp_mio_buf = new_empty_miobuffer())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new miobuffer", K(ret)); + } else if (OB_ISNULL(tmp_mio_reader = tmp_mio_buf->alloc_reader())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to alloc reader", K(ret)); + } + } + + if (OB_SUCC(ret)) { + // decode the prepare execute request + prepare_req_pkt.set_content(client_request.get_req_pkt().ptr() + MYSQL_NET_HEADER_LENGTH, + static_cast(client_request.get_packet_len())); + if (OB_FAIL(prepare_req_pkt.decode())) { + LOG_WARN("fail to decode the xa start prepare execute", K(ret)); + } + } + + if (OB_SUCC(ret)) { + // get seq + uint8_t seq = static_cast(client_request.get_packet_meta().pkt_seq_ + 1); + uint32_t sid = info.get_client_ps_id(); + int64_t autocommit = info.get_cached_variables().get_autocommit(); + // write prepare execute resp + OMPKPrepareExecute prepare_pkt; + prepare_pkt.set_seq(seq++); + prepare_pkt.set_status(0); + prepare_pkt.set_statement_id(sid); + prepare_pkt.set_column_num(1); + prepare_pkt.set_param_num(static_cast(prepare_req_pkt.get_param_num())); + prepare_pkt.set_warning_count(0); + prepare_pkt.set_extend_flag(0); + prepare_pkt.set_has_result_set(1); + if (OB_FAIL(ObMysqlPacketWriter::write_packet(*tmp_mio_buf, prepare_pkt))) { + seq--; + LOG_WARN("fail to write prepare pkt of resp of xa start hold", K(ret)); + } + // write params Coldef + for (int32_t i = 0; OB_SUCC(ret) && i < prepare_req_pkt.get_param_num(); i++) { + ObMySQLField param_field; + param_field.cname_ = "?"; + param_field.type_ = prepare_req_pkt.get_param_types().at(i); + param_field.type_info_ = prepare_req_pkt.get_type_infos().at(i); + param_field.flags_ = 0; + param_field.charsetnr_ = static_cast(info.get_collation_connection()); + param_field.length_ = 0; + if (OB_FAIL(ObMysqlPacketUtil::encode_field_packet(*tmp_mio_buf, seq, param_field))) { + LOG_WARN("fail to write field pkt of resp of xa start hold", K(ret), K(param_field)); + } + } + // write Eof + if (prepare_req_pkt.get_param_num() > 0 && OB_SUCC(ret)) { + uint16_t status_flag_0 = 0; + status_flag_0 |= (1 << OB_SERVER_STATUS_IN_TRANS_POS); + if (0 != autocommit) { + status_flag_0 |= (1 << OB_SERVER_STATUS_AUTOCOMMIT_POS); + } + if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*tmp_mio_buf, seq, status_flag_0))){ + LOG_WARN("fail to write eof pkt of resp of xa start hold", K(ret)); + } + } + // ColDef: row field + if (OB_SUCC(ret)) { + ObMySQLField row_col_field; + row_col_field.cname_ = client_request.get_parse_sql(); + row_col_field.org_cname_ = client_request.get_parse_sql(); + row_col_field.type_ = OB_MYSQL_TYPE_LONG; + row_col_field.flags_ = OB_MYSQL_BINARY_FLAG; + row_col_field.charsetnr_ = CS_TYPE_BINARY; + row_col_field.length_ = 0; + if (OB_FAIL(ObMysqlPacketUtil::encode_field_packet(*tmp_mio_buf, seq, row_col_field))) { + LOG_WARN("fail to write field pkt of resp of xa start hold", K(ret)); + } + } + // Eof + if (OB_SUCC(ret)) { + uint16_t status_flag_1 = 0; + if (0 != autocommit) { + status_flag_1 |= (1 << OB_SERVER_STATUS_AUTOCOMMIT_POS); + } + status_flag_1 |= (1 << OB_SERVER_STATUS_IN_TRANS_POS); + status_flag_1 |= (1 << OB_SERVER_STATUS_CURSOR_EXISTS_POS); + if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*tmp_mio_buf, seq, status_flag_1))) { + LOG_WARN("fail to write eof pkt of resp of xa start hold", K(ret)); + } + } + // Row + if (OB_SUCC(ret)) { + ObObj field_value; + field_value.set_int32(0); + ObNewRow row; + row.cells_ = &field_value; + row.count_ = 1; + if (ObMysqlPacketUtil::encode_row_packet(*tmp_mio_buf, BINARY, seq, row)) { + LOG_WARN("fail to write row pkt", K(ret)); + } + } + // write Eof + if (OB_SUCC(ret)) { + uint16_t status_flag_2 = 0; + if (0 != autocommit) { + status_flag_2 |= (1 << OB_SERVER_STATUS_AUTOCOMMIT_POS); + } + status_flag_2 |= (1 << OB_SERVER_STATUS_IN_TRANS_POS); + status_flag_2 |= (1 << OB_SERVER_STATUS_LAST_ROW_SENT_POS); + if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*tmp_mio_buf, seq, status_flag_2))) { + LOG_WARN("fail to write eof pkt of resp of xa start hold", K(ret)); + } + } + // Ok + if (OB_SUCC(ret)) { + uint16_t status_flag_3 = 0; + if (0 != autocommit) { + status_flag_3 |= (1 << OB_SERVER_STATUS_AUTOCOMMIT_POS); + } + status_flag_3 |= (1 << OB_SERVER_STATUS_IN_TRANS_POS); + status_flag_3 |= (1 << OB_SERVER_STATUS_NO_INDEX_USED_POS); + status_flag_3 |= (1 << OB_SERVER_STATUS_CURSOR_EXISTS_POS); + status_flag_3 |= (1 << OB_SERVER_STATUS_LAST_ROW_SENT_POS); + status_flag_3 |= (1 << OB_SERVER_SESSION_STATE_CHANGED_POS); + if (OB_FAIL(ObMysqlPacketUtil::encode_ok_packet(*tmp_mio_buf, seq, 0, info.get_orig_capability_flags(), status_flag_3))) { + LOG_WARN("fail to write last ok pkt of resp of xa start hold", K(ret)); + } else { + LOG_DEBUG("succ to write prepare execute packets of resp of xa start hold"); + } + } else { + LOG_WARN("fail to write prepare execute packets of resp of xa start hold", K(ret)); + } + + if (OB_SUCC(ret) && protocol == ObProxyProtocol::PROTOCOL_OB20) { + Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; + uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); + Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, compressed_seq, + compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); + if (OB_FAIL(ObProto20Utils::consume_and_compress_data(tmp_mio_reader, &mio_buf, + tmp_mio_reader->read_avail(), ob20_head_param))) { + LOG_WARN("fail to consume and compress data for executor response packet in ob20", K(ret)); + } else { + LOG_DEBUG("succ to executor response in ob20 packet"); + } + } + } + return ret; +} + int ObMysqlResponseBuilder::build_select_tx_ro_resp(ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans) { int ret = OB_SUCCESS; @@ -111,7 +293,7 @@ int ObMysqlResponseBuilder::build_select_tx_ro_resp(ObMIOBuffer &mio_buf, } // encode to mio_buf - if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, seq, + if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, protocol, seq, field, field_value, status_flag))) { LOG_WARN("fail to write kv resultset", K(ret)); } @@ -122,8 +304,9 @@ int ObMysqlResponseBuilder::build_select_tx_ro_resp(ObMIOBuffer &mio_buf, int ObMysqlResponseBuilder::build_select_route_addr_resp(ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans, - int64_t addr) + const struct sockaddr &addr) { int ret = OB_SUCCESS; ObClientSessionInfo &info = client_session.get_session_info(); @@ -135,13 +318,16 @@ int ObMysqlResponseBuilder::build_select_route_addr_resp(ObMIOBuffer &mio_buf, ObMySQLField field; field.cname_ = OBPROXY_ROUTE_ADDR_NAME; field.org_cname_ = OBPROXY_ROUTE_ADDR_NAME; - field.type_ = OB_MYSQL_TYPE_LONGLONG; + field.type_ = OB_MYSQL_TYPE_VARCHAR; field.charsetnr_ = CS_TYPE_BINARY; field.flags_ = OB_MYSQL_BINARY_FLAG; // get filed value ObObj field_value; - field_value.set_int(addr); + char buf[MAX_IP_ADDR_LENGTH]; + memset(buf, 0, sizeof(buf)); + net::ops_ip_ntop(addr, buf, MAX_IP_ADDR_LENGTH); + field_value.set_varchar(buf); // get status flag uint16_t status_flag = 0; @@ -154,7 +340,7 @@ int ObMysqlResponseBuilder::build_select_route_addr_resp(ObMIOBuffer &mio_buf, } // encode to mio_buf - if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, seq, + if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, protocol, seq, field, field_value, status_flag))) { LOG_WARN("fail to write kv resultset", K(ret)); } @@ -165,6 +351,7 @@ int ObMysqlResponseBuilder::build_select_route_addr_resp(ObMIOBuffer &mio_buf, int ObMysqlResponseBuilder::build_select_proxy_version_resp(ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans) { int ret = OB_SUCCESS; @@ -201,7 +388,8 @@ int ObMysqlResponseBuilder::build_select_proxy_version_resp(ObMIOBuffer &mio_buf } // encode to mio_buf - if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, seq, field, field_value, status_flag))) { + if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, protocol, + seq, field, field_value, status_flag))) { LOG_WARN("fail to write kv resultset", K(ret)); } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.h b/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.h index 0c0cbb10..e021a0ce 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.h @@ -13,6 +13,8 @@ #ifndef OBPROXY_MYSQL_RESPONSE_BUILDER_H #define OBPROXY_MYSQL_RESPONSE_BUILDER_H #include "utils/ob_proxy_lib.h" +#include "common/obsm_row.h" +#include "proxy/mysqllib/ob_mysql_common_define.h" namespace oceanbase { @@ -34,60 +36,77 @@ class ObMysqlResponseBuilder static const common::ObString OBPROXY_PROXY_VERSION_NAME; static int build_ok_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, - ObMysqlClientSession &client_session, const bool is_in_trans, const bool is_state_changed); + ObMysqlClientSession &client_session, const ObProxyProtocol protocol, + const bool is_in_trans, const bool is_state_changed); static int build_start_trans_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, - ObMysqlClientSession &client_session); + ObMysqlClientSession &client_session, const ObProxyProtocol protocol); + + static int build_prepare_execute_xa_start_resp(event::ObMIOBuffer &mio_buf, + ObProxyMysqlRequest &client_request, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol); static int build_select_tx_ro_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans); static int build_ok_resq_with_state_changed(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans); - static int build_select_route_addr_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, - ObMysqlClientSession &client_session, const bool is_in_trans, int64_t addr); + static int build_select_route_addr_resp(event::ObMIOBuffer &mio_buf, + ObProxyMysqlRequest &client_request, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, + const bool is_in_trans, + const struct sockaddr &addr); static int build_set_route_addr_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans); static int build_select_proxy_version_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans); }; inline int ObMysqlResponseBuilder::build_start_trans_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, - ObMysqlClientSession &client_session) + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol) { static const bool is_in_trans = true; static const bool is_state_changed = false; - return build_ok_resp(mio_buf, client_request, client_session, is_in_trans, is_state_changed); + return build_ok_resp(mio_buf, client_request, client_session, protocol, is_in_trans, is_state_changed); } inline int ObMysqlResponseBuilder::build_ok_resq_with_state_changed(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans) { static const bool is_state_changed = true; - return build_ok_resp(mio_buf, client_request, client_session, is_in_trans, is_state_changed); + return build_ok_resp(mio_buf, client_request, client_session, protocol, is_in_trans, is_state_changed); } inline int ObMysqlResponseBuilder::build_set_route_addr_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans) { static const bool is_state_changed = false; - return build_ok_resp(mio_buf, client_request, client_session, is_in_trans, is_state_changed); + return build_ok_resp(mio_buf, client_request, client_session, protocol, is_in_trans, is_state_changed); } } // end of namespace proxy diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_mysql_request.h b/src/obproxy/proxy/mysqllib/ob_proxy_mysql_request.h index 40d0fd1d..39e9a86a 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_mysql_request.h +++ b/src/obproxy/proxy/mysqllib/ob_proxy_mysql_request.h @@ -78,6 +78,7 @@ class ObProxyMysqlRequest static common::ObString get_print_sql(const common::ObString &req_sql, const int64_t sql_len = PRINT_SQL_LEN); common::ObString get_req_pkt(); obutils::ObSqlParseResult &get_parse_result(); + const obutils::ObSqlParseResult &get_parse_result() const; obutils::ObSqlParseResult *get_ps_parse_result() { return ps_result_; } void set_ps_parse_result(obutils::ObSqlParseResult *ps_result) { ps_result_ = ps_result; } void set_text_ps_parse_result(obutils::ObSqlParseResult *text_ps_result) @@ -111,6 +112,7 @@ class ObProxyMysqlRequest int64_t get_packet_len() { return meta_.pkt_len_; } ObMysqlPacketMeta &get_packet_meta() { return meta_; } + const ObMysqlPacketMeta &get_packet_meta() const { return meta_; } void set_packet_meta(const ObMysqlPacketMeta &meta) { meta_ = meta; } // add received request @@ -196,7 +198,17 @@ inline void ObProxyMysqlRequest::reset(bool is_reset_origin_db_table /* true */) inline obutils::ObSqlParseResult &ObProxyMysqlRequest::get_parse_result() { obutils::ObSqlParseResult *result = &result_; - if ((obmysql::OB_MYSQL_COM_STMT_EXECUTE == meta_.cmd_ || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == meta_.cmd_) + if ((obmysql::OB_MYSQL_COM_STMT_EXECUTE == meta_.cmd_ || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == meta_.cmd_) + && NULL != ps_result_) { + result = ps_result_; + } + return *result; +} + +const obutils::ObSqlParseResult &ObProxyMysqlRequest::get_parse_result() const +{ + const obutils::ObSqlParseResult *result = &result_; + if ((obmysql::OB_MYSQL_COM_STMT_EXECUTE == meta_.cmd_ || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == meta_.cmd_) && NULL != ps_result_) { result = ps_result_; } diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_ob20_request.h b/src/obproxy/proxy/mysqllib/ob_proxy_ob20_request.h index 2fe65132..befc9619 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_ob20_request.h +++ b/src/obproxy/proxy/mysqllib/ob_proxy_ob20_request.h @@ -40,7 +40,7 @@ struct ObProxyObProto20Request { // ob20 payload could contain more than one mysql packet, the total mysql packet len stored here int64_t remain_payload_len_; - bool ob20_request_received_done_; + bool ob20_request_received_done_; // ob2.0 request from client received done, and tail crc not handled yet Ob20ProtocolHeader ob20_header_; TO_STRING_KV(K_(remain_payload_len), K_(ob20_request_received_done), K_(ob20_header)); diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_session_info.cpp b/src/obproxy/proxy/mysqllib/ob_proxy_session_info.cpp index aa945369..6268bd3b 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_session_info.cpp +++ b/src/obproxy/proxy/mysqllib/ob_proxy_session_info.cpp @@ -182,7 +182,7 @@ void ObServerSessionInfo::reuse_text_ps_version_set() ObClientSessionInfo::ObClientSessionInfo() : is_inited_(false), is_trans_specified_(false), is_global_vars_changed_(false), - is_user_idc_name_set_(false), is_read_consistency_set_(false), is_oracle_mode_(false), + is_user_idc_name_set_(false), is_read_consistency_set_(false), is_oracle_mode_(false), is_proxy_route_policy_set_(false), enable_shard_authority_(false), enable_reset_db_(true), client_cap_(0), server_cap_(0), safe_read_snapshot_(0), @@ -192,7 +192,8 @@ ObClientSessionInfo::ObClientSessionInfo() var_set_processor_(NULL), cluster_id_(OB_INVALID_CLUSTER_ID), real_meta_cluster_name_(), real_meta_cluster_name_str_(NULL), server_type_(DB_OB_MYSQL), shard_conn_(NULL), shard_prop_(NULL), - group_id_(OBPROXY_MAX_DBMESH_ID), is_allow_use_last_session_(true), + group_id_(OBPROXY_MAX_DBMESH_ID), table_id_(OBPROXY_MAX_DBMESH_ID), es_id_(OBPROXY_MAX_DBMESH_ID), + is_allow_use_last_session_(true), consistency_level_prop_(INVALID_CONSISTENCY), recv_client_ps_id_(0), ps_id_(0), ps_entry_(NULL), ps_id_entry_(NULL), ps_id_entry_map_(), text_ps_name_entry_(NULL), text_ps_name_entry_map_(), cursor_id_(0), cursor_id_addr_map_(), @@ -200,14 +201,13 @@ ObClientSessionInfo::ObClientSessionInfo() is_read_only_user_(false), is_request_follower_user_(false) { - const int BUCKET_SIZE = 8; is_session_pool_client_ = true; MEMSET(scramble_buf_, 0, sizeof(scramble_buf_)); MEMSET(idc_name_buf_, 0, sizeof(idc_name_buf_)); MEMSET(client_host_buf_, 0, sizeof(client_host_buf_)); MEMSET(username_buf_, 0, sizeof(username_buf_)); - request_send_addrs_.create(BUCKET_SIZE); ob20_request_.reset(); + ob20_request_.reset(); } ObClientSessionInfo::~ObClientSessionInfo() @@ -319,7 +319,7 @@ int ObClientSessionInfo::set_tenant_name(const ObString &tenant_name) int ObClientSessionInfo::set_vip_addr_name(const common::ObAddr &vip_addr) { int ret = OB_SUCCESS; - char vip_name[OB_IP_STR_BUFF]; + char vip_name[MAX_IP_ADDR_LENGTH]; if (OB_UNLIKELY(!vip_addr.ip_to_string(vip_name, static_cast(sizeof(vip_name))))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to covert ip to string", K(vip_name), K(ret)); @@ -377,19 +377,25 @@ int ObClientSessionInfo::set_ldg_logical_tenant_name(const ObString &tenant_name return field_mgr_.set_ldg_logical_tenant_name(tenant_name); } -int ObClientSessionInfo::update_sess_sync_info(const ObString& sess_info) +int ObClientSessionInfo::update_sess_sync_info(const ObString& sess_info, common::ObSimpleTrace<4096> &trace_log) { int ret = OB_SUCCESS; const char *buf = sess_info.ptr(); const int64_t len = sess_info.length(); const char *end = buf + len; // decode sess_info + const int MAX_TYPE_RECORD = 32; + char type_record[MAX_TYPE_RECORD]; + memset(type_record, '0', MAX_TYPE_RECORD); if (NULL != sess_info.ptr()) { while (OB_SUCC(ret) && buf < end) { int16_t info_type = 0; int32_t info_len = 0; ObMySQLUtil::get_int2(buf, info_type); ObMySQLUtil::get_int4(buf, info_len); + if(info_type < MAX_TYPE_RECORD) { + type_record[info_type] = '1'; + } if (buf + info_len > end) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("data is error", K(info_type), K(info_len), K(len), K(ret)); @@ -397,11 +403,19 @@ int ObClientSessionInfo::update_sess_sync_info(const ObString& sess_info) LOG_DEBUG("extra info", K(info_type), K(info_len), K(len)); char* info_value = NULL; ObString info_value_string; + if (OB_FAIL(inc_sess_field_version(info_type))) { + LOG_WARN("fail to update sess field versoin", K(info_type), K(ret)); + } if (OB_SUCC(sess_info_hash_map_.get_refactored(info_type, info_value_string))) { sess_info_hash_map_.erase_refactored(info_type); int64_t total_len = info_value_string.length(); op_fixed_mem_free(info_value_string.ptr(), total_len); } + int64_t client_version = 0; + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(client_version , info_type, version_.sess_field_version_))) { + LOG_WARN("fail to set client session field version", K(info_type), K(ret)); + } else { + } info_value_string.reset(); if (OB_ISNULL(info_value = static_cast(op_fixed_mem_alloc(info_len + 6)))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -417,6 +431,8 @@ int ObClientSessionInfo::update_sess_sync_info(const ObString& sess_info) } } } + type_record[MAX_TYPE_RECORD - 1] = '\0'; + trace_log.log_it("[get_sess]", "type", type_record); if (OB_SUCC(ret)) { version_.inc_sess_info_version(); LOG_DEBUG("update sess info succ", K(sess_info)); @@ -879,6 +895,46 @@ int ObClientSessionInfo::extract_all_variable_reset_sql(ObSqlString &sql) return ret; } +int ObClientSessionInfo::extract_user_variable_reset_sql(ObServerSessionInfo &server_info, + ObSqlString &sql) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("client session is not inited", K(ret)); + } else { + bool need_reset = false; + if (OB_FAIL(sql.append_fmt("SET"))) { + LOG_WARN("fail to append_fmt 'SET'", K(ret)); + } else if (!is_oceanbase_server()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("extract user variable reset sql only for oceanbase server"); + } else { /* do nothing */ } + + //reset user variable + if (OB_SUCC(ret)) { + if (need_reset_user_session_vars(server_info)) { + need_reset = true; + if (OB_FAIL(field_mgr_.format_user_var(sql))) { + LOG_WARN("fail to format_user_var.", K(sql), K(*this), + K(server_info), K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + if (need_reset) { + *(sql.ptr() + sql.length() - 1) = ';'; //replace ',' with ';' + } else { + sql.reset(); + } + } else { + sql.reset(); + } + } + return ret; +} + int ObClientSessionInfo::extract_variable_reset_sql(ObServerSessionInfo &server_info, ObSqlString &sql) { @@ -1215,7 +1271,7 @@ void ObClientSessionInfo::destroy() field_mgr_.destroy(); login_req_.destroy(); destroy_sess_info_map(); - is_inited_ = false; + is_inited_ = false; } if (NULL != var_set_processor_) { ObDefaultSysVarSet *sys_set = field_mgr_.get_sys_var_set(); @@ -1267,6 +1323,8 @@ void ObClientSessionInfo::destroy() shard_prop_ = NULL; } group_id_ = OBPROXY_MAX_DBMESH_ID; + table_id_ = OBPROXY_MAX_DBMESH_ID; + es_id_ = OBPROXY_MAX_DBMESH_ID; is_allow_use_last_session_ = true; up_info_.reset(); } diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_session_info.h b/src/obproxy/proxy/mysqllib/ob_proxy_session_info.h index 3d3e17a8..ec50f4f6 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_session_info.h +++ b/src/obproxy/proxy/mysqllib/ob_proxy_session_info.h @@ -19,10 +19,12 @@ #include "lib/hash_func/murmur_hash.h" #include "lib/hash/ob_build_in_hashmap.h" #include "lib/hash/ob_hashset.h" +#include "lib/oblog/ob_simple_trace.h" #include "utils/ob_proxy_utils.h" #include "obutils/ob_cached_variables.h" #include "proxy/mysqllib/ob_session_field_mgr.h" #include "proxy/mysqllib/ob_proxy_auth_parser.h" +#include "proxy/mysqllib/ob_2_0_protocol_utils.h" #include "proxy/route/ob_ldc_struct.h" #include "proxy/mysql/ob_prepare_statement_struct.h" #include "proxy/mysql/ob_cursor_struct.h" @@ -48,6 +50,7 @@ class ObDefaultSysVarSet; namespace proxy { typedef common::hash::ObHashMap SessFieldHashMap; +typedef common::hash::ObHashMap SessFieldVersionHashMap; enum ObProxyChecksumSwitch { @@ -59,9 +62,9 @@ enum ObProxyChecksumSwitch class ObSessionVarVersion { public: - ObSessionVarVersion() { reset(); } + ObSessionVarVersion() { reset(); sess_field_version_.create(32, ObModIds::OB_PROXY_SESS_SYNC); } ~ObSessionVarVersion() { reset(); } - void reset() { memset(this, 0, sizeof(ObSessionVarVersion)); } + void reset(); void inc_common_hot_sys_var_version() { common_hot_sys_var_version_++; } void inc_common_sys_var_version() { common_sys_var_version_++; } @@ -73,6 +76,10 @@ class ObSessionVarVersion void inc_db_name_version() { db_name_version_++; } void inc_last_insert_id_version() { last_insert_id_version_++; } void inc_sess_info_version() { sess_info_version_++; } + int inc_sess_field_version(int16_t type); + SessFieldVersionHashMap& get_sess_field_version() { return sess_field_version_; } + + TO_STRING_KV(K_(common_hot_sys_var_version), K_(common_sys_var_version), K_(mysql_hot_sys_var_version), K_(mysql_sys_var_version), K_(hot_sys_var_version), K_(sys_var_version), K_(user_var_version), @@ -88,11 +95,44 @@ class ObSessionVarVersion int64_t db_name_version_; int64_t last_insert_id_version_; int64_t sess_info_version_; + SessFieldVersionHashMap sess_field_version_; private: DISALLOW_COPY_AND_ASSIGN(ObSessionVarVersion); }; + +inline int ObSessionVarVersion::inc_sess_field_version(int16_t type) +{ + int ret = OB_SUCCESS; + int64_t new_version = 0; + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(new_version, type, sess_field_version_))) { + _PROXY_LOG(WARN, "fail to update session field versoin, query version failed, field type:%d, ret:%d",type, ret); + } + + if (OB_SUCC(ret)) { + new_version++; + if (OB_FAIL(sess_field_version_.set_refactored(type, new_version, 1))) { + _PROXY_LOG(WARN, "update session field versoin failed, field type:%d, ret:%d", type, ret); + } + } + return ret; +} + +inline void ObSessionVarVersion::reset() { + common_hot_sys_var_version_ = 0; + common_sys_var_version_ = 0; + mysql_hot_sys_var_version_ = 0; + mysql_sys_var_version_ = 0; + hot_sys_var_version_ = 0; + sys_var_version_ = 0; + user_var_version_ = 0; + db_name_version_ = 0; + last_insert_id_version_ = 0; + sess_info_version_ = 0; + sess_field_version_.clear(); +} + class ObSessionVarValHash { public: @@ -184,7 +224,7 @@ class ObServerSessionInfo int64_t get_db_name_version() const { return version_.db_name_version_; } int64_t get_last_insert_id_version() const { return version_.last_insert_id_version_; } int64_t get_sess_info_version() const { return version_.sess_info_version_; } - + SessFieldVersionHashMap& get_sess_field_version() { return version_.sess_field_version_; } void set_common_hot_sys_var_version(const int64_t version) { version_.common_hot_sys_var_version_ = version; } void set_common_sys_var_version(const int64_t version) { version_.common_sys_var_version_ = version; } void set_mysql_hot_sys_var_version(const int64_t version) { version_.mysql_hot_sys_var_version_ = version; } @@ -455,6 +495,12 @@ class ObClientSessionInfo return OB_TEST_CAPABILITY(server_cap_, OB_CAP_PL_ROUTE); } + bool is_server_support_session_var_sync() const { + return OB_TEST_CAPABILITY(server_cap_, OB_CAP_OB_PROTOCOL_V2) + && OB_TEST_CAPABILITY(server_cap_, OB_CAP_PROXY_SESSION_SYNC) + && OB_TEST_CAPABILITY(server_cap_, OB_CAP_PROXY_SESSION_VAR_SYNC); + } + bool is_oracle_mode() const { bool is_oracle_mode = false; if (is_sharding_user()) { @@ -486,6 +532,9 @@ class ObClientSessionInfo int64_t get_db_name_version() const { return version_.db_name_version_; } int64_t get_last_insert_id_version() const { return version_.last_insert_id_version_; } int64_t get_sess_info_version() const { return version_.sess_info_version_; } + SessFieldVersionHashMap& get_sess_field_version() { return version_.sess_field_version_; } + int inc_sess_field_version(int16_t type) { return version_.inc_sess_field_version(type); } + void set_db_name_version(const int64_t version) { version_.db_name_version_ = version; } @@ -499,7 +548,7 @@ class ObClientSessionInfo int set_ldg_logical_tenant_name(const common::ObString &tenant_name); int set_logic_tenant_name(const common::ObString &logic_tenant_name); int set_logic_database_name(const common::ObString &logic_database_name); - int update_sess_sync_info(const common::ObString& sess_info); + int update_sess_sync_info(const common::ObString& sess_info, common::ObSimpleTrace<4096> &trace_log); int get_cluster_name(common::ObString &cluster_name) const; int get_tenant_name(common::ObString &tenant_name) const; int get_vip_addr_name(common::ObString &vip_addr_name) const; @@ -571,6 +620,7 @@ class ObClientSessionInfo int extract_all_variable_reset_sql(common::ObSqlString &sql); int extract_variable_reset_sql(ObServerSessionInfo &server_info, common::ObSqlString &sql); + int extract_user_variable_reset_sql(ObServerSessionInfo &server_info, ObSqlString &sql); int extract_oceanbase_variable_reset_sql(ObServerSessionInfo &server_info, common::ObSqlString &sql, bool &need_reset); int extract_mysql_variable_reset_sql(ObServerSessionInfo &server_info, @@ -607,7 +657,7 @@ class ObClientSessionInfo //proxy route policy ObProxyRoutePolicyEnum get_proxy_route_policy() const { return proxy_route_policy_; } - void set_proxy_route_policy(ObProxyRoutePolicyEnum policy) { + void set_proxy_route_policy(ObProxyRoutePolicyEnum policy) { proxy_route_policy_ = policy; is_proxy_route_policy_set_ = true; } @@ -618,7 +668,6 @@ class ObClientSessionInfo void set_trans_specified_flag() { is_trans_specified_ = true; } void clear_trans_specified_flag() { is_trans_specified_ = false; } bool is_trans_specified() const { return is_trans_specified_; } - void set_user_identity(const ObProxyLoginUserType identity) { user_identity_ = identity; } ObProxyLoginUserType get_user_identity() const { return user_identity_; } bool enable_analyze_internal_cmd() const; @@ -666,10 +715,12 @@ class ObClientSessionInfo // deep copy, this function will alloc buf int set_start_trans_sql(const common::ObString &sql); + void set_xa_start_ps_id(const int32_t ps_id) { xa_start_ps_id_ = ps_id; } // reset start trans sql, free buf void reset_start_trans_sql(); - // get start trans sql + // get start trans sql / xa start req pkt common::ObString &get_start_trans_sql() { return saved_start_trans_sql_; } + int32_t get_xa_start_ps_id() const { return xa_start_ps_id_; }; obproxy::ObDefaultSysVarSet *get_sys_var_set() { return field_mgr_.get_sys_var_set(); } void set_sysvar_set_processor(ObSysVarSetProcessor &var_set_processor) { var_set_processor_ = &var_set_processor; } @@ -731,6 +782,12 @@ class ObClientSessionInfo void set_group_id(const int64_t group_id) { group_id_ = group_id; } int64_t get_group_id() { return group_id_; } + void set_table_id(const int64_t table_id) { table_id_ = table_id; } + int64_t get_table_id() { return table_id_; } + + void set_es_id(const int64_t es_id) { es_id_ = es_id; } + int64_t get_es_id() { return es_id_; } + bool is_sys_hot_version_changed() const { return hash_version_.hot_sys_var_version_ != version_.hot_sys_var_version_; } @@ -861,12 +918,17 @@ class ObClientSessionInfo void destroy_ps_id_addrs_map(); void destroy_sess_info_map(); - ObPsIdAddrs::ADDR_HASH_SET &get_request_send_addrs() { return request_send_addrs_; } + common::ObIArray &get_request_send_addrs() { return request_send_addrs_; } int remove_request_send_addr(const struct sockaddr &socket_addr) { int ret = OB_SUCCESS; net::ObIpEndpoint addr(socket_addr); - if (OB_FAIL(request_send_addrs_.erase_refactored(addr))) { - PROXY_LOG(WARN, "fail to erase refactored", K(addr), K(ret)); + for (int64_t i = 0; OB_SUCC(ret) && i < request_send_addrs_.count(); i++) { + if (addr == request_send_addrs_.at(i)) { + if (OB_FAIL(request_send_addrs_.remove(i))) { + PROXY_LOG(WARN, "fail to remove item", K(i), K(ret)); + } + break; + } } return ret; } @@ -941,8 +1003,12 @@ class ObClientSessionInfo dbconfig::ObShardUserPrivInfo up_info_; // saved start transaction sql + // saved xa start request packet (prepare execute) common::ObString saved_start_trans_sql_; + // saved xa start request's ps id + uint32_t xa_start_ps_id_; + ObProxyLoginUserType user_identity_; ObSessionVarVersion version_; // cached variables @@ -950,6 +1016,7 @@ class ObClientSessionInfo // global variables version, will be set at the first time get login responce(OK packet) int64_t global_vars_version_; // obproxy_route_addr + // TODO: only support IPv4, IPv6 unsupported int64_t obproxy_route_addr_; ObSysVarSetProcessor *var_set_processor_; @@ -967,6 +1034,8 @@ class ObClientSessionInfo dbconfig::ObShardConnector *shard_conn_; dbconfig::ObShardProp *shard_prop_; int64_t group_id_; + int64_t table_id_; + int64_t es_id_; bool is_allow_use_last_session_; common::ObString client_host_; @@ -991,14 +1060,14 @@ class ObClientSessionInfo ObPsIdAddrsMap ps_id_addrs_map_; ObPieceInfoMap piece_info_map_; - ObPsIdAddrs::ADDR_HASH_SET request_send_addrs_; + common::ObSEArray request_send_addrs_; bool is_read_only_user_; bool is_request_follower_user_; char text_ps_name_buf_[common::OB_MAX_TEXT_PS_NAME_LENGTH]; - - SessFieldHashMap sess_info_hash_map_; + + SessFieldHashMap sess_info_hash_map_; DISALLOW_COPY_AND_ASSIGN(ObClientSessionInfo); }; @@ -1231,7 +1300,8 @@ inline bool ObClientSessionInfo::need_reset_session_vars(const ObServerSessionIn || need_reset_hot_session_vars(server_info) || need_reset_cold_session_vars(server_info) || need_reset_user_session_vars(server_info) - || need_reset_safe_read_snapshot(server_info); + || need_reset_safe_read_snapshot(server_info) + || need_reset_last_insert_id(server_info); } else { bret = need_reset_common_hot_session_vars(server_info) || need_reset_common_cold_session_vars(server_info) @@ -1247,7 +1317,7 @@ inline bool ObClientSessionInfo::need_reset_sess_info_vars(const ObServerSession bool bret = false; // TODO: Processing for sharding connection pools bret = get_sess_info_version() > server_info.get_sess_info_version(); - PROXY_LOG(DEBUG, "need_reset_sess_info_vars", K(bret), + PROXY_LOG(DEBUG, "need_reset_sess_info_vars", K(bret), K(get_sess_info_version()), K(server_info.get_sess_info_version())); return bret; } diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.cpp b/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.cpp index f8f79f1b..2ffd5e99 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.cpp +++ b/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.cpp @@ -49,7 +49,8 @@ int ObProxySessionInfoHandler::analyze_extra_ok_packet(ObIOBufferReader &reader, ObClientSessionInfo &client_info, ObServerSessionInfo &server_info, const bool need_handle_sysvar, - ObRespAnalyzeResult &resp_result) + ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log) { int ret = OB_SUCCESS; @@ -65,7 +66,7 @@ int ObProxySessionInfoHandler::analyze_extra_ok_packet(ObIOBufferReader &reader, LOG_WARN("fail to get ok packet", K(ret)); // save changed info } else if (OB_FAIL(save_changed_session_info(client_info, server_info, false, - need_handle_sysvar, src_ok, resp_result, false))) { + need_handle_sysvar, src_ok, resp_result, trace_log, false))) { LOG_WARN("fail to save changed session info", K(ret)); } else { LOG_DEBUG("analyze_extra_ok_packet", K(src_ok)); @@ -95,6 +96,7 @@ int ObProxySessionInfoHandler::rebuild_ok_packet(ObIOBufferReader &reader, const bool is_auth_request, const bool need_handle_sysvar, ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log, const bool is_save_to_common_sys) { int ret = OB_SUCCESS; @@ -118,6 +120,7 @@ int ObProxySessionInfoHandler::rebuild_ok_packet(ObIOBufferReader &reader, need_handle_sysvar, src_ok, resp_result, + trace_log, is_save_to_common_sys))) { LOG_WARN("fail to save changed session info", K(is_auth_request), K(ret)); } else { @@ -173,6 +176,7 @@ int ObProxySessionInfoHandler::rewrite_query_req_by_sharding(ObClientSessionInfo obmysql::ObMySQLCmd tmp_req_cmd = obmysql::OB_MYSQL_COM_MAX_NUM; client_request.reset(false); + client_request.set_user_identity(USER_TYPE_SHARDING); ObMysqlRequestAnalyzer::analyze_request(target_ctx, tmp_auth_req, client_request, tmp_req_cmd, status); @@ -605,9 +609,9 @@ inline int ObProxySessionInfoHandler::rewrite_common_login_req(ObClientSessionIn } if (param.use_ob_protocol_v2_) { - cap |= (OB_CAP_OB_PROTOCOL_V2 | OB_CAP_PROXY_NEW_EXTRA_INFO | OB_CAP_PROXY_REROUTE | OB_CAP_PROXY_SESSION_SYNC); + cap |= (OB_CAP_OB_PROTOCOL_V2 | OB_CAP_PROXY_NEW_EXTRA_INFO | OB_CAP_PROXY_REROUTE | OB_CAP_PROXY_SESSION_SYNC | OB_CAP_PROXY_SESSION_VAR_SYNC); } else { - cap &= ~(OB_CAP_OB_PROTOCOL_V2 | OB_CAP_PROXY_NEW_EXTRA_INFO | OB_CAP_PROXY_REROUTE | OB_CAP_PROXY_SESSION_SYNC); + cap &= ~(OB_CAP_OB_PROTOCOL_V2 | OB_CAP_PROXY_NEW_EXTRA_INFO | OB_CAP_PROXY_REROUTE | OB_CAP_PROXY_SESSION_SYNC | OB_CAP_PROXY_SESSION_VAR_SYNC); } param.cluster_name_ = cluster_name; @@ -727,7 +731,9 @@ int ObProxySessionInfoHandler::handle_capability_flag_var(ObClientSessionInfo &c client_info.set_client_ob_capability(client_cap); client_info.set_server_ob_capability(server_cap); - LOG_INFO("succ to set ob_capability_flag", K(client_cap), K(server_cap), K(orig_client_cap), K(orig_server_cap), + LOG_INFO("succ to set ob_capability_flag in negotiation", + K(client_cap), K(server_cap), K(orig_client_cap), K(orig_server_cap), + "client_support_ob_v2", client_info.is_client_support_ob20_protocol(), "server_support_checksum", server_info.is_checksum_supported(), "server_support_ob_v2", server_info.is_ob_protocol_v2_supported(), K(is_auth_request)); @@ -1113,10 +1119,13 @@ int ObProxySessionInfoHandler::save_changed_session_info(ObClientSessionInfo &cl const bool need_handle_sysvar, OMPKOK &ok_pkt, ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log, const bool is_save_to_common_sys) { int ret = OB_SUCCESS; // 1. save server status + trace_log.log_it("[svr_status]", "in_trans", ok_pkt.get_server_status().status_flags_.OB_SERVER_STATUS_IN_TRANS, + "ac", ok_pkt.get_server_status().status_flags_.OB_SERVER_STATUS_AUTOCOMMIT); if (is_auth_request) { bool is_oracle_mode = 1 == ok_pkt.get_server_status().status_flags_.OB_SERVER_STATUS_RESERVED; LOG_DEBUG("will set oracle mode ", K(is_oracle_mode)); @@ -1384,19 +1393,48 @@ int ObProxySessionInfoHandler::assign_session_vars_version( } int ObProxySessionInfoHandler::save_changed_sess_info(ObClientSessionInfo& client_info, - ObServerSessionInfo& server_info, Ob20ExtraInfo& extra_info) + ObServerSessionInfo& server_info, Ob20ExtraInfo& extra_info, common::ObSimpleTrace<4096> &trace_log, bool is_only_sync_trans_sess) { int ret = OB_SUCCESS; if (extra_info.exist_sess_info()) { - if (OB_FAIL(client_info.update_sess_sync_info(extra_info.get_sess_info()))) { - LOG_WARN("failed to update sess sync info", K(ret), K(extra_info)); + ObString sess_info; + extra_info.reset_sess_info_iterate_idx(); + for (uint32_t i = 0; OB_SUCC(ret) && i < extra_info.get_sess_info_count(); i++) { + if (OB_FAIL(extra_info.get_next_sess_info(sess_info))) { + LOG_WARN("fail to update sess sync info", K(ret)); + } else if (OB_FAIL(client_info.update_sess_sync_info(sess_info, trace_log))) { + LOG_WARN("fail to update sess sync info", K(ret), K(extra_info)); + } } } + bool need_update_version = true; if (OB_SUCC(ret)) { - int64_t c_sess_info_version = client_info.get_sess_info_version(); - server_info.set_sess_info_version(c_sess_info_version); + SessFieldVersionHashMap::iterator last = client_info.get_sess_field_version().end(); + SessFieldVersionHashMap::iterator it = client_info.get_sess_field_version().begin(); + for (; it != last && OB_SUCC(ret); ++it) { + int16_t sess_info_type = it->first; + int64_t client_version = 0; + + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(client_version , sess_info_type, client_info.get_sess_field_version()))) { + LOG_WARN("fail to set client session field version", K(ret), K(sess_info_type)); + } else if (is_only_sync_trans_sess && !ObProto20Utils::is_trans_related_sess_info(sess_info_type)) { + // internal routing trans not support sync session info idempotent + // here keep session info syncing in some case for only internal routing trans as temporary processing + int64_t server_version = 0; + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(server_version, sess_info_type, server_info.get_sess_field_version()))) { + LOG_WARN("fail to get server session field version", K(ret), K(sess_info_type)); + } else if (client_version > server_version) { + need_update_version = false; + } + } else if (OB_FAIL(server_info.get_sess_field_version().set_refactored(sess_info_type, client_version, 1))) { + LOG_WARN("fail to set sess field versoin", K(sess_info_type), K(ret)); + } + } } + if (OB_SUCC(ret) && need_update_version) { + server_info.set_sess_info_version(client_info.get_sess_info_version()); + } return ret; } diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.h b/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.h index 63086547..aac0cc17 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.h +++ b/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.h @@ -15,6 +15,7 @@ #include "rpc/obmysql/ob_mysql_packet.h" #include "utils/ob_proxy_lib.h" #include "proxy/mysqllib/ob_2_0_protocol_struct.h" +#include "lib/oblog/ob_simple_trace.h" namespace oceanbase { @@ -73,6 +74,7 @@ class ObProxySessionInfoHandler const bool need_handle_sysvar, obmysql::OMPKOK &ok_pkt, ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log, const bool is_save_to_common_sys = false); // The @reader must has only one receive completed ok packet, @@ -85,13 +87,15 @@ class ObProxySessionInfoHandler const bool is_auth_request, const bool need_handle_sysvar, ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log, const bool is_save_to_common_sys); static int analyze_extra_ok_packet(event::ObIOBufferReader &reader, ObClientSessionInfo &client_info, ObServerSessionInfo &server_info, const bool need_handle_sysvar, - ObRespAnalyzeResult &resp_result); + ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log); static int rewrite_query_req_by_sharding(ObClientSessionInfo &client_info, ObProxyMysqlRequest &client_request, @@ -171,7 +175,9 @@ class ObProxySessionInfoHandler bool &need_save); static int save_changed_sess_info(ObClientSessionInfo& client_info, ObServerSessionInfo& server_info, - Ob20ExtraInfo& extra_info); + Ob20ExtraInfo& extra_info, + common::ObSimpleTrace<4096> &trace_log, + bool is_only_sync_trans_sess); private: static ObProxySysVarType get_sys_var_type(const common::ObString &var_name); diff --git a/src/obproxy/proxy/mysqllib/ob_resultset_fetcher.h b/src/obproxy/proxy/mysqllib/ob_resultset_fetcher.h index 465b246a..a188b38a 100644 --- a/src/obproxy/proxy/mysqllib/ob_resultset_fetcher.h +++ b/src/obproxy/proxy/mysqllib/ob_resultset_fetcher.h @@ -45,6 +45,7 @@ } \ } +// limit max length #define PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result, column_name, field, max_length, real_length) \ if (OB_SUCCESS == ret) { \ ObString str_value; \ @@ -66,6 +67,27 @@ } \ } +// unlimit max length +#define PROXY_EXTRACT_STRBUF_FIELD_MYSQL_UNLIMIT_LENGTH(result, column_name, field, real_length, allocator) \ +if (OB_SUCCESS == ret) { \ + ObString str_value; \ + if (OB_SUCCESS == (ret = (result).get_varchar(column_name, str_value))) { \ + if (str_value.empty()) { \ + real_length = 0; \ + field = NULL; \ + } else if (OB_ISNULL(field = static_cast(allocator.alloc(str_value.length() + 1)))) { \ + ret = OB_ALLOCATE_MEMORY_FAILED; \ + LOG_WARN("fail to allc part key name", K(field), K(str_value.length()), K(ret)); \ + } else { \ + MEMCPY(field, str_value.ptr(), str_value.length()); \ + real_length = str_value.length(); \ + field[str_value.length()] = '\0'; \ + } \ + } else { \ + PROXY_LOG(WARN, "fail to extract strbuf field mysql", K(column_name), K(real_length), K(ret)); \ + } \ +} + namespace oceanbase { namespace common diff --git a/src/obproxy/proxy/mysqllib/ob_session_field_mgr.h b/src/obproxy/proxy/mysqllib/ob_session_field_mgr.h index cbe09956..7d21e0cf 100644 --- a/src/obproxy/proxy/mysqllib/ob_session_field_mgr.h +++ b/src/obproxy/proxy/mysqllib/ob_session_field_mgr.h @@ -108,10 +108,10 @@ enum ObSessionFieldStat enum ObSessionVarType { - OB_SESSION_USER_VAR = 0, - OB_SESSION_SYS_VAR, - OB_SESSION_COMMON_SYS_VAR, - OB_SESSION_MYSQL_SYS_VAR, + OB_SESSION_USER_VAR = 0, // user variable + OB_SESSION_SYS_VAR, // system variable only oceanbase supported + OB_SESSION_COMMON_SYS_VAR, // system variable oceanbase and mysql both supported + OB_SESSION_MYSQL_SYS_VAR, // system variable only mysql supported OB_SESSION_VAR_MAX, }; diff --git a/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.cpp b/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.cpp index a7feb83e..d886b612 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.cpp +++ b/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.cpp @@ -149,9 +149,12 @@ int ObMysqlRequestCompressTransformPlugin::build_compressed_packet(bool is_last_ PROXY_API_LOG(WARN, "fail to build related extra info all", K(ret)); } else { ObMysqlServerSession *server_session = sm_->get_server_session(); + ObMysqlClientSession *client_session = sm_->get_client_session(); + const bool is_weak_read = (WEAK == sm_->trans_state_.get_trans_consistency_level(client_session->get_session_info())); Ob20ProtocolHeaderParam ob20_head_param(server_session->get_server_sessid(), request_id_, compressed_seq_, - compressed_seq_, is_last_segment, is_need_reroute, - server_session->get_session_info().is_new_extra_info_supported()); + compressed_seq_, is_last_segment, is_weak_read, is_need_reroute, + server_session->get_session_info().is_new_extra_info_supported(), + client_session->is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::consume_and_compress_data(local_reader_, mio_buffer_, local_reader_->read_avail(), ob20_head_param, &extra_info))) { PROXY_API_LOG(WARN, "fail to consume and compress data with OB20", K(ret)); diff --git a/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.h b/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.h index f586fffd..6a463892 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.h +++ b/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.h @@ -101,10 +101,10 @@ class ObMysqlRequestCompressGlobalPlugin : public ObGlobalPlugin PROXY_API_LOG(DEBUG, "need_enable_plugin", "request_content_length", sm->trans_state_.trans_info_.request_content_length_, "enable_compression_protocol", sm->trans_state_.mysql_config_params_->enable_compression_protocol_, - "enable_ob_protocol_v2", sm->trans_state_.mysql_config_params_->enable_ob_protocol_v2_); + "enable_ob_protocol_v2", sm->is_enable_ob_protocol_v2()); return (sm->trans_state_.trans_info_.request_content_length_ > 0 && (sm->trans_state_.mysql_config_params_->enable_compression_protocol_ - || sm->trans_state_.mysql_config_params_->enable_ob_protocol_v2_)); + || sm->is_enable_ob_protocol_v2())); } private: diff --git a/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.cpp b/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.cpp index f85cda26..ea4105a5 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.cpp +++ b/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.cpp @@ -152,13 +152,31 @@ int ObMysqlResponseCompressTransformPlugin::consume(event::ObIOBufferReader *rea // get consume size again, for trim the last packet consume_size = local_transfer_reader_->read_avail() - analyze_result.get_reserved_len_for_ob20_ok(); - // just send all data in local_transfer_reader_ - if (consume_size != (produce_size = produce(local_transfer_reader_, consume_size))) { - ret = OB_ERR_UNEXPECTED; - PROXY_API_LOG(WARN, "fail to produce", "expected size", consume_size, - "actual size", produce_size, K(ret)); - } else if (OB_FAIL(local_transfer_reader_->consume(consume_size))) { - PROXY_API_LOG(WARN, "fail to consume local transfer reader", K(consume_size), K(ret)); + // Here is a situation: + // under the 2.0 protocol, the last 4 tail checksum bytes were not read, + // but the Tunnel sent all the MySQL content. + // For ClientVC, after receiving all MySQL content, + // it does not judge the end of the response based on the content, + // but judges based on write_state_.vio_.ntodo(), + // but because Tunnel has not read the last 4 tail checksum bytes, + // Tunnel will not modify nbytes in ntodo, + // causing ClientVC to think Have not finished receiving, continue to wait, do not continue to process. + // After the Tunnel receives the last 4 tail checksum bytes, + // since these 4 bytes are not sent to the Client, + // the Client VC will not be triggered again. + // As a result, the Tunnel ends directly, and the ClientVC How Hung lives + // + // Therefore, it is modified here that if the entire Tunnel is not over, + // the last bit of MySQL packet content will not be sent, and will not be sent until the entire Tunnel is over + if (!analyze_result.is_last_ok_handled() || analyzer_->is_stream_finished()) { + // just send all data in local_transfer_reader_ + if (consume_size != (produce_size = produce(local_transfer_reader_, consume_size))) { + ret = OB_ERR_UNEXPECTED; + PROXY_API_LOG(WARN, "fail to produce", "expected size", consume_size, + "actual size", produce_size, K(ret)); + } else if (OB_FAIL(local_transfer_reader_->consume(consume_size))) { + PROXY_API_LOG(WARN, "fail to consume local transfer reader", K(consume_size), K(ret)); + } } } } diff --git a/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.h b/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.h index d054c431..d2c24835 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.h +++ b/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.h @@ -95,8 +95,6 @@ class ObMysqlResponseCompressGlobalPlugin : public ObGlobalPlugin { return (!sm->trans_state_.trans_info_.client_request_.is_internal_cmd() && NULL != sm->client_session_ - // inner sql will received compeleted, no need plugin - && !sm->client_session_->is_proxy_mysql_client_ && ObMysqlTransact::SERVER_SEND_REQUEST == sm->trans_state_.current_.send_action_ && !sm->trans_state_.trans_info_.server_response_.get_analyze_result().is_decompressed() && (ObProxyProtocol::PROTOCOL_CHECKSUM == sm->get_server_session_protocol() diff --git a/src/obproxy/proxy/plugins/ob_mysql_response_cursor_transform_plugin.cpp b/src/obproxy/proxy/plugins/ob_mysql_response_cursor_transform_plugin.cpp index 2c9bbea3..5850cb38 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_response_cursor_transform_plugin.cpp +++ b/src/obproxy/proxy/plugins/ob_mysql_response_cursor_transform_plugin.cpp @@ -343,6 +343,7 @@ int ObMysqlResponseCursorTransformPlugin::skip_field_value(const char *&data, in break; } case OB_MYSQL_TYPE_GEOMETRY: + case OB_MYSQL_TYPE_JSON: case OB_MYSQL_TYPE_BLOB: case OB_MYSQL_TYPE_LONG_BLOB: case OB_MYSQL_TYPE_MEDIUM_BLOB: diff --git a/src/obproxy/proxy/plugins/ob_mysql_response_ob20_transform_plugin.cpp b/src/obproxy/proxy/plugins/ob_mysql_response_ob20_transform_plugin.cpp index 3111dff6..613690e2 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_response_ob20_transform_plugin.cpp +++ b/src/obproxy/proxy/plugins/ob_mysql_response_ob20_transform_plugin.cpp @@ -154,6 +154,7 @@ int ObMysqlResponseOb20ProtocolTransformPlugin::build_ob20_head_and_extra(ObMIOB uint8_t last_compressed_seq = static_cast(client_session->get_compressed_seq() + 1); const bool is_new_extra_info = client_session->get_session_info().is_client_support_new_extra_info(); bool is_extra_info_exist = false; + bool is_trans_internal_routing = false; if (OB_FAIL(ObProto20Utils::fill_proto20_extra_info(write_buf, &extra_info, is_new_extra_info, payload_len, tail_crc_, is_extra_info_exist))) { @@ -165,9 +166,10 @@ int ObMysqlResponseOb20ProtocolTransformPlugin::build_ob20_head_and_extra(ObMIOB ob20_head.request_id_, client_session->get_cs_id(), is_last_packet, - false, + false, false, is_extra_info_exist, - is_new_extra_info))) { + is_new_extra_info, + is_trans_internal_routing))) { LOG_WARN("fail to fill ob20 head", K(ret)); } else { client_session->set_compressed_seq(last_compressed_seq); diff --git a/src/obproxy/proxy/plugins/ob_trim_okpacket_transform_plugin.h b/src/obproxy/proxy/plugins/ob_trim_okpacket_transform_plugin.h index f92e4662..d95dc327 100644 --- a/src/obproxy/proxy/plugins/ob_trim_okpacket_transform_plugin.h +++ b/src/obproxy/proxy/plugins/ob_trim_okpacket_transform_plugin.h @@ -181,7 +181,7 @@ class ObTrimOkPakcetTransformPlugin : public ObTransformationPlugin if (OB_SUCCESS != (ret = src_ok.decode())) { PROXY_API_LOG(WARN, "fail to decode ok packet", K(src_ok), K(ret)); } else if (OB_SUCCESS != (ret = ObProxySessionInfoHandler::save_changed_session_info( - client_info, server_info, sm_->trans_state_.is_auth_request_, NULL, src_ok, analyze_result))) { + client_info, server_info, sm_->trans_state_.is_auth_request_, NULL, src_ok, analyze_result, sm_->trans_state_.trace_log_))) { _PROXY_API_LOG(WARN, "fail to save changed session info, is_auth_request=%d, ret=%d", sm_->trans_state_.is_auth_request_, ret); } diff --git a/src/obproxy/proxy/route/ob_mysql_route.cpp b/src/obproxy/proxy/route/ob_mysql_route.cpp index 60cd0ecc..008ba529 100644 --- a/src/obproxy/proxy/route/ob_mysql_route.cpp +++ b/src/obproxy/proxy/route/ob_mysql_route.cpp @@ -493,35 +493,33 @@ inline int ObMysqlRoute::check_and_rebuild_call_params() ObSessionSysField *sys_filed = NULL; ObSessionUserField *user_filed = NULL; for (int32_t i = 0; OB_SUCC(ret) && i < call_info.param_count_; ++i) { - ObProxyCallParam &call_param = call_info.params_.at(i); - if (CALL_TOKEN_SYS_VAR == call_param.type_) { + ObProxyCallParam* call_param = call_info.params_.at(i); + if (CALL_TOKEN_SYS_VAR == call_param->type_) { sys_filed = NULL; - if (OB_FAIL(client_info.get_sys_variable(call_param.str_value_.string_, sys_filed))) { - LOG_INFO("fail to find sys variables", "name", call_param.str_value_.string_, K(ret)); + if (OB_FAIL(client_info.get_sys_variable(call_param->str_value_.config_string_, sys_filed))) { + LOG_INFO("fail to find sys variables", "name", call_param->str_value_.config_string_, K(ret)); } else if (NULL != sys_filed) { - char *buf = call_param.str_value_.buf_; - const int64_t max_size = call_param.str_value_.get_max_size(); + char buf[OBPROXY_MAX_STRING_VALUE_LENGTH]; int64_t pos = 0; - if (OB_FAIL(sys_filed->value_.print_sql_literal(buf, max_size, pos))) { + if (OB_FAIL(sys_filed->value_.print_sql_literal(buf, OBPROXY_MAX_STRING_VALUE_LENGTH, pos))) { LOG_INFO("fail to print sql literal", K(pos), K(i), KPC(sys_filed), K(ret)); } else { ObString new_value(pos, buf); - call_param.str_value_.set(new_value); + call_param->str_value_.set_value(new_value); } } - } else if (CALL_TOKEN_USER_VAR == call_param.type_) { + } else if (CALL_TOKEN_USER_VAR == call_param->type_) { user_filed = NULL; - if (OB_FAIL(client_info.get_user_variable(call_param.str_value_.string_, user_filed))) { - LOG_INFO("fail to find sys variables, ignore", "name", call_param.str_value_.string_, K(ret)); + if (OB_FAIL(client_info.get_user_variable(call_param->str_value_.config_string_, user_filed))) { + LOG_INFO("fail to find sys variables", K_(call_param->str_value_.config_string), K(ret)); } else if (NULL != user_filed) { - char *buf = call_param.str_value_.buf_; - const int64_t max_size = call_param.str_value_.get_max_size(); + char buf[OBPROXY_MAX_STRING_VALUE_LENGTH]; int64_t pos = 0; - if (OB_FAIL(user_filed->value_.print_plain_str_literal(buf, max_size, pos))) { + if (OB_FAIL(user_filed->value_.print_plain_str_literal(buf, OBPROXY_MAX_STRING_VALUE_LENGTH, pos))) { LOG_INFO("fail to print sql literal, ignore", K(pos), K(i), KPC(user_filed), K(ret)); } else { ObString new_value(pos, buf); - call_param.str_value_.set(new_value); + call_param->str_value_.set_value(new_value); } } } diff --git a/src/obproxy/proxy/route/ob_route_struct.h b/src/obproxy/proxy/route/ob_route_struct.h index 6ca19bce..d6bfbdba 100644 --- a/src/obproxy/proxy/route/ob_route_struct.h +++ b/src/obproxy/proxy/route/ob_route_struct.h @@ -203,9 +203,7 @@ int ObProxyRerouteInfo::deserialize_struct_content(const char *buf, const int64_ if (ObAddr::IPV4 == version) { replica_.server_.set_ipv4_addr(ipv4, port); } else { - // must IPV6, not support yet, TODO open below later - //server_.set_ipv6_addr(ipv6_high, ipv6_low, port); - replica_.server_.reset(); + replica_.server_.set_ipv6_addr(ipv6_high, ipv6_low, port); } } int64_t table_name_len = 0; @@ -233,7 +231,7 @@ inline int ObProxyReplicaLocation::add_addr(const char *ip, const int64_t port) int ret = common::OB_SUCCESS; if (OB_UNLIKELY(NULL == ip || port <= 0)) { ret = common::OB_INVALID_ARGUMENT; - } else if (OB_UNLIKELY(!server_.set_ipv4_addr(ip, static_cast(port)))) { + } else if (OB_UNLIKELY(!server_.set_ip_addr(ip, static_cast(port)))) { ret = common::OB_INVALID_ARGUMENT; } return ret; @@ -517,6 +515,7 @@ struct ObTableEntryName bool is_sys_tenant() const; bool is_oceanbase_db() const; bool is_all_dummy_table() const; + bool is_binlog_table() const; int deep_copy(const ObTableEntryName &name, char *buf, const int64_t buf_len); void shallow_copy(const ObTableEntryName &name); void shallow_copy(const common::ObString &cluster_name, const common::ObString &tenant_name, @@ -525,7 +524,6 @@ struct ObTableEntryName const common::ObString &database_name, const common::ObString &package_name, const common::ObString &table_name); - common::ObString cluster_name_; common::ObString tenant_name_; common::ObString database_name_; @@ -585,6 +583,12 @@ inline bool ObTableEntryName::is_all_dummy_table() const return is_valid() && table_name_[0] == '_' && all_dummy_tname_str == table_name_; } +inline bool ObTableEntryName::is_binlog_table() const +{ + static const common::ObString binlog_tname_str(share::OB_ALL_BINLOG_DUMMY_TNAME); + return is_valid() && binlog_tname_str == table_name_; +} + inline bool ObTableEntryName::is_ob_dummy() const { return is_oceanbase_db() && is_all_dummy_table(); diff --git a/src/obproxy/proxy/route/ob_route_utils.cpp b/src/obproxy/proxy/route/ob_route_utils.cpp index cf72edb6..0b702046 100644 --- a/src/obproxy/proxy/route/ob_route_utils.cpp +++ b/src/obproxy/proxy/route/ob_route_utils.cpp @@ -64,20 +64,12 @@ static const char *PROXY_TENANT_SCHEMA_SQL = "ORDER BY %s ASC, role ASC LIMIT %ld"; static const char *PROXY_PART_INFO_SQL = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ template_num, part_level, part_num, part_type, part_space, part_expr, " - "part_interval_bin, interval_start_bin, sub_part_num, sub_part_type, sub_part_space, " - "sub_part_expr, def_sub_part_interval_bin, def_sub_interval_start_bin, " - "part_key_num, part_key_name, part_key_type, part_key_idx, part_key_level, part_key_extra, " - "spare1, spare2, spare4, spare5 " + "SELECT /*+READ_CONSISTENCY(WEAK)*/ * " "FROM oceanbase.%s " "WHERE table_id = %lu order by part_key_idx LIMIT %d;"; static const char *PROXY_PART_INFO_SQL_V4 = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ template_num, part_level, part_num, part_type, part_space, part_expr, " - "part_interval_bin, interval_start_bin, sub_part_num, sub_part_type, sub_part_space, " - "sub_part_expr, def_sub_part_interval_bin, def_sub_interval_start_bin, " - "part_key_num, part_key_name, part_key_type, part_key_idx, part_key_level, part_key_extra, " - "part_key_collation_type, part_key_rowkey_idx, part_key_expr, part_key_length, part_key_precision, part_key_scale " + "SELECT /*+READ_CONSISTENCY(WEAK)*/ * " "FROM oceanbase.%s " "WHERE table_id = %lu and tenant_name = '%.*s' order by part_key_idx LIMIT %d;"; @@ -98,17 +90,17 @@ static const char *PROXY_FIRST_PART_SQL_V4 = "WHERE table_id = %lu and tenant_name = '%.*s' LIMIT %ld;"; static const char *PROXY_SUB_PART_SQL = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ part_id, sub_part_id, high_bound_val_bin " + "SELECT /*+READ_CONSISTENCY(WEAK)*/ part_id, sub_part_id, part_name, high_bound_val_bin " "FROM oceanbase.%s " "WHERE table_id = %lu and part_id = %ld LIMIT %ld;"; static const char *PROXY_NON_TEMPLATE_SUB_PART_SQL = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ part_id, sub_part_id, high_bound_val_bin " + "SELECT /*+READ_CONSISTENCY(WEAK)*/ part_id, sub_part_id, part_name, high_bound_val_bin " "FROM oceanbase.%s " "WHERE table_id = %lu LIMIT %ld;"; -static const char *PROXY_SUB_PART_SQL_V4 = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ tablet_id, part_id, sub_part_id, high_bound_val_bin " +static const char *PROXY_SUB_PART_SQL_V4 = + "SELECT /*+READ_CONSISTENCY(WEAK)*/ tablet_id, part_id, sub_part_id, part_name, high_bound_val_bin " "FROM oceanbase.%s " "WHERE table_id = %lu and tenant_name = '%.*s' LIMIT %ld;"; @@ -132,6 +124,9 @@ static const char *PROXY_ROUTINE_SCHEMA_SQL_V4 = "WHERE tenant_name = '%.*s' and database_name = '%.*s' and package_name = '%.*s' " "and routine_name = '%.*s';"; +static const char *PROXY_BINLOG_ADDR_SQL = + "show binlog server for tenant `%.*s`.`%.*s`"; + static void get_tenant_name(const ObString &origin_tenant_name, char *new_tenant_name_buf, ObString &new_tenant_name) { new_tenant_name = origin_tenant_name; int32_t pos = 0; @@ -315,6 +310,32 @@ int ObRouteUtils::get_sub_part_sql(char *sql_buf, return ret; } +int ObRouteUtils::get_binlog_entry_sql(char *sql_buf, + const int64_t buf_len, + const ObString &cluster_name, + const ObString &tenant_name) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(sql_buf) || OB_UNLIKELY(buf_len <= 0) + || OB_UNLIKELY(cluster_name.empty()) + || OB_UNLIKELY(tenant_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid input value", LITERAL_K(sql_buf), K(buf_len), K(cluster_name), K(tenant_name), K(ret)); + } else { + int64_t len = 0; + len = static_cast(snprintf(sql_buf, buf_len, PROXY_BINLOG_ADDR_SQL, + cluster_name.length(), cluster_name.ptr(), + tenant_name.length(), tenant_name.ptr())); + + if (OB_UNLIKELY(len <= 0) || OB_UNLIKELY(len >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to fill binlog sql", K(sql_buf), K(len), K(buf_len), K(ret)); + } + } + + return ret; +} + bool is_fake_ip_port(const char *ip_str, const int64_t port) { const ObString fake_ip("0.0.0.0"); @@ -328,7 +349,7 @@ int ObRouteUtils::fetch_table_entry(ObResultSetFetcher &rs_fetcher, { int ret = OB_SUCCESS; int64_t tmp_real_str_len = 0; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; ip_str[0] = '\0'; int64_t port = 0; uint64_t table_id = OB_INVALID_ID; @@ -355,7 +376,7 @@ int ObRouteUtils::fetch_table_entry(ObResultSetFetcher &rs_fetcher, replica_type = -1; table_type = -1; - PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "svr_ip", ip_str, OB_IP_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "svr_ip", ip_str, MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sql_port", port, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "table_id", table_id, uint64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "role", role, int64_t); @@ -515,6 +536,32 @@ int ObRouteUtils::fetch_table_entry(ObResultSetFetcher &rs_fetcher, return ret; } +int ObRouteUtils::split_part_expr(ObString expr, ObIArray &arr) +{ + int ret = OB_SUCCESS; + ObString tmp; + while (OB_SUCC(ret) && !expr.empty()) { + tmp = expr.split_on(',').trim(); + if (tmp.empty()) { + tmp = expr.trim(); + expr.reset(); + } + if (tmp[0] == '`') { + tmp.assign_ptr(tmp.ptr() + 1, tmp.length() - 1); + } + if (tmp[tmp.length() - 1] == '`') { + tmp.assign_ptr(tmp.ptr(), tmp.length() - 1); + } + if (OB_FAIL(arr.push_back(tmp))) { + LOG_WARN("fail to push back", K(tmp), K(ret)); + } else { + LOG_DEBUG("succ to push back", K(tmp)); + } + } + return ret; +} + + int ObRouteUtils::fetch_part_info(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo &part_info, const int64_t cluster_version) { int ret = OB_SUCCESS; @@ -522,6 +569,8 @@ int ObRouteUtils::fetch_part_info(ObResultSetFetcher &rs_fetcher, ObProxyPartInf ObPartitionLevel part_level = PARTITION_LEVEL_ONE; int64_t part_key_num = 1; int64_t template_num = 1; + ObString part_expr; + ObString sub_part_expr; // init part key info part_info.get_part_key_info().key_num_ = 0; @@ -557,6 +606,39 @@ int ObRouteUtils::fetch_part_info(ObResultSetFetcher &rs_fetcher, ObProxyPartInf part_key_num = OBPROXY_MAX_PART_KEY_NUM; } + // get part expr + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_expr", part_expr); + char *buf = NULL; + if (part_expr.empty()) { + LOG_DEBUG("part expression is empty"); + } else if (OB_ISNULL(buf = static_cast(part_info.get_allocator().alloc(part_expr.length())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allc part key name", K(buf), K(part_expr.length()), K(ret)); + } else { + memcpy(buf, part_expr.ptr(), part_expr.length()); + part_expr.assign_ptr(buf, part_expr.length()); + } + + // get sub part expr + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "sub_part_expr", sub_part_expr); + if (sub_part_expr.empty()) { + LOG_DEBUG("sub part expression is empty"); + } else if (OB_ISNULL(buf = static_cast(part_info.get_allocator().alloc(sub_part_expr.length())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allc part key name", K(buf), K(sub_part_expr.length()), K(ret)); + } else { + memcpy(buf, sub_part_expr.ptr(), sub_part_expr.length()); + sub_part_expr.assign_ptr(buf, sub_part_expr.length()); + } + // split part expression + if (part_info.get_part_level() >= PARTITION_LEVEL_ONE + && OB_FAIL(split_part_expr(part_expr, part_info.get_part_columns()))) { + LOG_WARN("fail to split part expr", K(ret)); + } else if (part_info.get_part_level() == PARTITION_LEVEL_TWO + && OB_FAIL(split_part_expr(sub_part_expr, part_info.get_sub_part_columns())) ) { + LOG_WARN("fail to split sub part expr", K(ret)); + } + if (OB_FAIL(fetch_part_option(rs_fetcher, part_info))) { LOG_WARN("fail to get part option", K(ret)); } @@ -568,73 +650,25 @@ int ObRouteUtils::fetch_part_info(ObResultSetFetcher &rs_fetcher, ObProxyPartInf if (OB_SUCC(ret)) { if (OB_FAIL(fetch_part_key(rs_fetcher, part_info, cluster_version))) { LOG_WARN("fail to get part key", K(ret)); - } // end of if + } } // end of if (OB_SUCC(ret)) } // end of else } // end of for - - if (OB_SUCC(ret) && IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - if (OB_FAIL(build_part_desc(part_info, cluster_version))) { - LOG_WARN("fail to build part desc ", K(part_info), K(ret)); - } - } - return ret; -} - -int ObRouteUtils::build_part_desc(ObProxyPartInfo &part_info, const int64_t cluster_version) { - int ret = OB_SUCCESS; - ObProxyPartOption &sub_part_opt = part_info.get_sub_part_option(); - - // for first part, we will build part desc in fetch_first_part - if (part_info.has_unknown_part_key()) { - LOG_INFO("part key type is unsopported, no need build part_desc", K(part_info)); - } else if (!part_info.is_template_table()) { - LOG_INFO("part table is non-template table, build hash and key part_desc later", K(part_info)); - } else if (OB_FAIL(build_part_desc(part_info, PARTITION_LEVEL_TWO, sub_part_opt, cluster_version))) { - LOG_WARN("fail to build sub part", K(sub_part_opt), K(ret)); - } else { - // do nothing - } - - return ret; -} - -int ObRouteUtils::build_part_desc(ObProxyPartInfo &part_info, - const ObPartitionLevel part_level, - ObProxyPartOption &part_opt, - const int64_t cluster_version) { - int ret = OB_SUCCESS; - ObProxyPartMgr &part_mgr = part_info.get_part_mgr(); - - if (part_level != PARTITION_LEVEL_TWO) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(part_level), K(ret)); - } else { - if (part_opt.is_hash_part(cluster_version)) { - if (OB_FAIL(part_mgr.build_hash_part(part_info.is_oracle_mode(), - part_level, - part_opt.part_func_type_, - part_opt.part_num_, - part_opt.part_space_, - part_info.is_template_table(), - part_info.get_part_key_info(), - NULL, - cluster_version))) { - LOG_WARN("fail to build hash part", K(part_opt), K(ret)); - } - } else if (part_opt.is_key_part(cluster_version)) { - if (OB_FAIL(part_mgr.build_key_part(part_level, - part_opt.part_func_type_, - part_opt.part_num_, - part_opt.part_space_, - part_info.is_template_table(), - part_info.get_part_key_info(), - NULL, - cluster_version))) { - LOG_WARN("fail to build key part", K(part_opt), K(ret)); + if (OB_SUCC(ret)) { + // handle generated key, map the key for generated key calculation to real key + for (int64_t i = 0; i < part_info.get_part_key_info().key_num_; ++i) { + if (part_info.get_part_key_info().part_keys_[i].generated_col_idx_ >= 0) { + for (int64_t j = 0; j < part_info.get_part_key_info().key_num_; ++j) { + ObProxyParseString *l = &part_info.get_part_key_info().part_keys_[i].name_; + ObProxyParseString *r = &part_info.get_part_key_info().part_keys_[j].name_; + if (i != j && l->str_ != NULL + && r->str_ != NULL + && l->str_len_ == r->str_len_ + && 0 == strncasecmp(l->str_, r->str_, l->str_len_)) { + part_info.get_part_key_info().part_keys_[i].real_source_idx_ = j; + } + } } - } else { - // we will build range part desc when fetch the range column } } return ret; @@ -744,120 +778,153 @@ inline int ObRouteUtils::fetch_part_key(ObResultSetFetcher &rs_fetcher, { int ret = OB_SUCCESS; - ObProxyPartKeyInfo &part_key_info = part_info.get_part_key_info(); - ObIAllocator &allocator = part_info.get_allocator(); - ObPartitionLevel part_key_level = PARTITION_LEVEL_ONE; - int64_t part_key_idx = -1; - ObObjType part_key_type = ObMaxType; - ObCollationType part_key_cs_type = CS_TYPE_INVALID; - ObString part_key_name; - ObString part_key_extra; - ObString constraint_part_key; - int64_t idx_in_rowid = -1; - ObString part_key_accuracy; - int64_t part_key_length = -1; - int64_t part_key_precision = -1; - int64_t part_key_scale = -1; - - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_level", part_key_level, ObPartitionLevel); - // part key idx is the order of part key in all columns - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_idx", part_key_idx, int64_t); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_type", part_key_type, ObObjType); - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_name", part_key_name); - // use part_key_extra as generated key expr - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_extra", part_key_extra); - if (IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "spare4", constraint_part_key); - // use spare1 as table collation type - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "spare1", part_key_cs_type, ObCollationType); - // use spare2 as rowid index - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "spare2", idx_in_rowid, int64_t); - // use spare5 as the accuracy of the part key - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "spare5", part_key_accuracy); + // only process OBPROXY_MAX_PART_KEY_NUM part key + if (OBPROXY_MAX_PART_KEY_NUM <= part_info.get_part_key_info().key_num_) { + LOG_WARN("proxy does not support to fetch more part key", K(OBPROXY_MAX_PART_KEY_NUM)); } else { - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_expr", constraint_part_key); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_collation_type", part_key_cs_type, ObCollationType); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_rowkey_idx", idx_in_rowid, int64_t); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_length", part_key_length, int64_t); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_precision", part_key_precision, int64_t); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_scale", part_key_scale, int64_t); - } - - LOG_DEBUG("fetch part key", K(part_key_level), K(part_key_idx), K(part_key_type), K(part_key_name), - K(part_key_extra), K(constraint_part_key), K(part_key_cs_type), K(idx_in_rowid), K(part_key_accuracy), - K(part_key_length), K(part_key_precision), K(part_key_scale)); - - if (!is_obj_type_supported(part_key_type)) { - part_info.set_unknown_part_key(true); - } + ObProxyPartKeyInfo &part_key_info = part_info.get_part_key_info(); + ObIAllocator &allocator = part_info.get_allocator(); + ObPartitionLevel part_key_level = PARTITION_LEVEL_ONE; + int64_t part_key_idx = -1; + ObObjType part_key_type = ObMaxType; + ObCollationType part_key_cs_type = CS_TYPE_INVALID; + ObString part_key_name; + ObString part_key_extra; + + // here store serialized default value + // mysql mode return serialized ObObj with relevant column's type + // oracle mode return serialized ObObj with varchar type + char *part_key_default_value = NULL; + int default_val_len = 0; + + ObString constraint_part_key; + int64_t idx_in_rowid = -1; + ObString part_key_accuracy; + int64_t part_key_length = -1; + int64_t part_key_precision = -1; + int64_t part_key_scale = -1; + + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_level", part_key_level, ObPartitionLevel); + // part key idx is the order of part key in all columns + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_idx", part_key_idx, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_type", part_key_type, ObObjType); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_name", part_key_name); + // use part_key_extra as generated key expr + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_extra", part_key_extra); + if (IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "spare4", constraint_part_key); + // use spare1 as table collation type + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "spare1", part_key_cs_type, ObCollationType); + // use spare2 as rowid index + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "spare2", idx_in_rowid, int64_t); + // use spare5 as the accuracy of the part key + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "spare5", part_key_accuracy); + } else { + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_expr", constraint_part_key); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_collation_type", part_key_cs_type, ObCollationType); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_rowkey_idx", idx_in_rowid, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_length", part_key_length, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_precision", part_key_precision, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_scale", part_key_scale, int64_t); + } - ObProxyPartKey *part_key = &part_key_info.part_keys_[part_key_info.key_num_]; + if (OB_SUCC(ret)){ + PROXY_EXTRACT_STRBUF_FIELD_MYSQL_UNLIMIT_LENGTH(rs_fetcher, "part_key_default_value", part_key_default_value, default_val_len, allocator); + if (OB_ERR_COLUMN_NOT_FOUND == ret) { + LOG_DEBUG("part key default value not exist, continue", K(ret)); + ret = OB_SUCCESS; + } + } - if (PARTITION_LEVEL_ONE == part_key_level) { - part_key->level_ = PART_KEY_LEVEL_ONE; - } else if (PARTITION_LEVEL_TWO == part_key_level) { - part_key->level_ = PART_KEY_LEVEL_TWO; - } else { - ret = OB_INVALID_ARGUMENT_FOR_EXTRACT; - LOG_WARN("part key level is invalid", K(part_key_level), K(ret)); - } + LOG_DEBUG("fetch part key", K(part_key_level), K(part_key_idx), K(part_key_type), K(part_key_name), + K(part_key_extra), K(constraint_part_key), K(part_key_cs_type), + K(idx_in_rowid), K(part_key_accuracy), K(part_key_default_value), + K(part_key_length), K(part_key_precision), K(part_key_scale)); - char *buf = NULL; - if (OB_ISNULL(buf = static_cast(allocator.alloc(part_key_name.length())))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to allc part key name", K(buf), K(part_key_name.length()), K(ret)); - } else { - memcpy(buf, part_key_name.ptr(), part_key_name.length()); - } + if (!is_obj_type_supported(part_key_type)) { + part_info.set_unknown_part_key(true); + } - if (OB_SUCC(ret)) { - part_key->idx_ = part_key_idx; - part_key->name_.str_len_ = part_key_name.length(); - part_key->name_.str_ = buf; - part_key->obj_type_ = part_key_type; - part_key->idx_in_rowid_ = idx_in_rowid; - part_key->accuracy_.valid_ = 0; // not valid accuracy + ObProxyPartKey *part_key = &part_key_info.part_keys_[part_key_info.key_num_]; - if (IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - parse_part_key_accuracy(part_key, part_key_type, &allocator, part_key_accuracy); + if (PARTITION_LEVEL_ONE == part_key_level) { + part_key->level_ = PART_KEY_LEVEL_ONE; + } else if (PARTITION_LEVEL_TWO == part_key_level) { + part_key->level_ = PART_KEY_LEVEL_TWO; } else { - set_part_key_accuracy(part_key, part_key_type, - static_cast(part_key_length), - static_cast(part_key_precision), - static_cast(part_key_scale)); + ret = OB_INVALID_ARGUMENT_FOR_EXTRACT; + LOG_WARN("part key level is invalid", K(part_key_level), K(ret)); } - if (CS_TYPE_INVALID == part_key_cs_type) { - part_key->cs_type_ = ObCharset::get_default_collation(ObCharset::get_default_charset()); + char *buf = NULL; + if (OB_ISNULL(buf = static_cast(allocator.alloc(part_key_name.length())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allc part key name", K(buf), K(part_key_name.length()), K(ret)); } else { - part_key->cs_type_ = part_key_cs_type; + memcpy(buf, part_key_name.ptr(), part_key_name.length()); } - if (!part_key_extra.empty() || !constraint_part_key.empty()) { - part_key->is_generated_ = true; - part_info.set_has_generated_key(true); - int64_t generated_key_idx = part_key_info.key_num_; - ++part_key_info.key_num_; - if (OB_FAIL(add_generated_part_key(part_key_extra, generated_key_idx, part_info))) { - LOG_WARN("fail to add generated key", K(part_key_extra), K(ret)); - } - const char *sep_pos = NULL; - ObString tmp_str; - while (NULL != (sep_pos = (constraint_part_key.find(PART_KEY_EXTRA_SEPARATOR)))) { - tmp_str = constraint_part_key.split_on(sep_pos); - if (OB_FAIL(add_generated_part_key(tmp_str, generated_key_idx, part_info))) { - LOG_WARN("fail to add generated key", K(tmp_str), K(ret)); + if (OB_SUCC(ret)) { + part_key->idx_ = part_key_idx; + part_key->name_.str_len_ = part_key_name.length(); + part_key->name_.str_ = buf; + part_key->obj_type_ = part_key_type; + part_key->idx_in_rowid_ = idx_in_rowid; + part_key->accuracy_.valid_ = 0; // not valid accuracy + ObIArray &columns = (part_key->level_ == PART_KEY_LEVEL_ONE ? + part_info.get_part_columns() : part_info.get_sub_part_columns()); + for (int i = 0; i < columns.count(); i++) { + ObString col(part_key->name_.str_len_, part_key->name_.str_); + if (columns.at(i).case_compare(col) == 0) { + part_key->idx_in_part_columns_ = i; + break; } } - if (OB_FAIL(add_generated_part_key(constraint_part_key, generated_key_idx, part_info))) { - LOG_WARN("fail to add generated key", K(constraint_part_key), K(ret)); + part_key->default_value_.str_len_ = default_val_len; + part_key->default_value_.str_ = part_key_default_value; + part_key->generated_col_idx_ = -1; + part_key->real_source_idx_ = -1; + + if (IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + parse_part_key_accuracy(part_key, part_key_type, &allocator, part_key_accuracy); + } else { + set_part_key_accuracy(part_key, part_key_type, + static_cast(part_key_length), + static_cast(part_key_precision), + static_cast(part_key_scale)); + } + + if (CS_TYPE_INVALID == part_key_cs_type) { + part_key->cs_type_ = ObCharset::get_default_collation(ObCharset::get_default_charset()); + } else { + part_key->cs_type_ = part_key_cs_type; + } + + if (!part_key_extra.empty() || !constraint_part_key.empty()) { + part_key->is_generated_ = true; + part_info.set_has_generated_key(true); + int64_t generated_key_idx = part_key_info.key_num_; + ++part_key_info.key_num_; + if (OB_FAIL(add_generated_part_key(part_key_extra, generated_key_idx, part_info))) { + LOG_WARN("fail to add generated key", K(part_key_extra), K(ret)); + } + const char *sep_pos = NULL; + ObString tmp_str; + while (NULL != (sep_pos = (constraint_part_key.find(PART_KEY_EXTRA_SEPARATOR)))) { + tmp_str = constraint_part_key.split_on(sep_pos); + if (OB_FAIL(add_generated_part_key(tmp_str, generated_key_idx, part_info))) { + LOG_WARN("fail to add generated key", K(tmp_str), K(ret)); + } + } + if (OB_FAIL(add_generated_part_key(constraint_part_key, generated_key_idx, part_info))) { + LOG_WARN("fail to add generated key", K(constraint_part_key), K(ret)); + } + } else { + part_key->is_generated_ = false; + ++part_key_info.key_num_; } - } else { - part_key->is_generated_ = false; - ++part_key_info.key_num_; } } - return ret; } @@ -892,7 +959,6 @@ int ObRouteUtils::add_generated_part_key(const ObString &part_key_extra, LOG_WARN("generated function param num is unexpectedlly larger than 3", "child num", child->child_num_, K(OBPROXY_MAX_PARAM_NUM), K(ret)); } else { - LOG_DEBUG("succ to parse generated function expr", "func_expr_result:", ObFuncExprParseResultPrintWrapper(result)); part_key_info.part_keys_[part_key_info.key_num_].func_type_ = func_expr_node->func_type_; part_key_info.part_keys_[part_key_info.key_num_].param_num_ = child->child_num_; part_key_info.part_keys_[part_key_info.key_num_].generated_col_idx_ = generated_key_idx; @@ -910,6 +976,7 @@ int ObRouteUtils::add_generated_part_key(const ObString &part_key_extra, part_key_info.part_keys_[part_key_info.key_num_].level_ = part_key.level_; part_key_info.part_keys_[part_key_info.key_num_].obj_type_ = part_key.obj_type_; part_key_info.part_keys_[part_key_info.key_num_].cs_type_ = part_key.cs_type_; + part_key_info.part_keys_[part_key_info.key_num_].idx_in_part_columns_ = part_key.idx_in_part_columns_; part_key_info.part_keys_[part_key_info.key_num_].is_generated_ = false; } child_param_node = child_param_node->next_; @@ -928,6 +995,12 @@ inline int ObRouteUtils::fetch_part_option(ObResultSetFetcher &rs_fetcher, ObProxyPartOption &first_part_opt = part_info.get_first_part_option(); ObProxyPartOption &sub_part_opt = part_info.get_sub_part_option(); + //get all sub part num + int64_t all_sub_part_num=0; + //"all_part_num" in __all_virtual_proxy_partition_info + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "all_part_num", all_sub_part_num, int64_t); + part_info.get_part_mgr().set_all_sub_part_num(all_sub_part_num); + // get first part PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_num", first_part_opt.part_num_, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_type", first_part_opt.part_func_type_, @@ -951,6 +1024,7 @@ int ObRouteUtils::fetch_first_part(ObResultSetFetcher &rs_fetcher, ObProxyPartIn if (OB_FAIL(part_info.get_part_mgr().build_range_part(share::schema::PARTITION_LEVEL_ONE, part_info.get_first_part_option().part_func_type_, part_info.get_first_part_option().part_num_, + part_info.get_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), rs_fetcher, @@ -961,6 +1035,7 @@ int ObRouteUtils::fetch_first_part(ObResultSetFetcher &rs_fetcher, ObProxyPartIn if (OB_FAIL(part_info.get_part_mgr().build_list_part(share::schema::PARTITION_LEVEL_ONE, part_info.get_first_part_option().part_func_type_, part_info.get_first_part_option().part_num_, + part_info.get_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), rs_fetcher, @@ -973,6 +1048,7 @@ int ObRouteUtils::fetch_first_part(ObResultSetFetcher &rs_fetcher, ObProxyPartIn part_info.get_first_part_option().part_func_type_, part_info.get_first_part_option().part_num_, part_info.get_first_part_option().part_space_, + part_info.get_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), &rs_fetcher, @@ -984,6 +1060,7 @@ int ObRouteUtils::fetch_first_part(ObResultSetFetcher &rs_fetcher, ObProxyPartIn part_info.get_first_part_option().part_func_type_, part_info.get_first_part_option().part_num_, part_info.get_first_part_option().part_space_, + part_info.get_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), &rs_fetcher, @@ -1006,6 +1083,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo if (OB_FAIL(part_info.get_part_mgr().build_range_part(share::schema::PARTITION_LEVEL_TWO, part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_num_, + part_info.get_sub_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), rs_fetcher, @@ -1014,6 +1092,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo } } else { if (OB_FAIL(part_info.get_part_mgr().build_sub_range_part_with_non_template(part_info.get_sub_part_option().part_func_type_, + part_info.get_sub_part_columns().count(), part_info.get_part_key_info(), rs_fetcher, cluster_version))) { @@ -1025,6 +1104,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo if (OB_FAIL(part_info.get_part_mgr().build_list_part(share::schema::PARTITION_LEVEL_TWO, part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_num_, + part_info.get_sub_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), rs_fetcher, @@ -1033,6 +1113,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo } } else { if (OB_FAIL(part_info.get_part_mgr().build_sub_list_part_with_non_template(part_info.get_sub_part_option().part_func_type_, + part_info.get_sub_part_columns().count(), part_info.get_part_key_info(), rs_fetcher, cluster_version))) { @@ -1046,6 +1127,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_num_, part_info.get_sub_part_option().part_space_, + part_info.get_sub_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), &rs_fetcher, @@ -1056,6 +1138,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo if (OB_FAIL(part_info.get_part_mgr().build_sub_hash_part_with_non_template(part_info.is_oracle_mode(), part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_space_, + part_info.get_sub_part_columns().count(), part_info.get_part_key_info(), rs_fetcher, cluster_version))) { @@ -1068,6 +1151,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_num_, part_info.get_sub_part_option().part_space_, + part_info.get_sub_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), &rs_fetcher, @@ -1077,6 +1161,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo } else { if (OB_FAIL(part_info.get_part_mgr().build_sub_key_part_with_non_template(part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_space_, + part_info.get_sub_part_columns().count(), part_info.get_part_key_info(), rs_fetcher, cluster_version))) { @@ -1321,7 +1406,7 @@ int ObRouteUtils::fetch_one_partition_entry_info( { int ret = OB_SUCCESS; int64_t tmp_real_str_len = 0; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; ip_str[0] = '\0'; int64_t port = 0; uint64_t table_id = OB_INVALID_ID; @@ -1341,7 +1426,7 @@ int ObRouteUtils::fetch_one_partition_entry_info( ip_str[0] = '\0'; port = 0; - PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "svr_ip", ip_str, OB_IP_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "svr_ip", ip_str, MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sql_port", port, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "table_id", table_id, uint64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "role", role, int64_t); @@ -1554,6 +1639,73 @@ int ObRouteUtils::fetch_one_routine_entry_info( return ret; } +int ObRouteUtils::fetch_binlog_entry(ObResultSetFetcher &rs_fetcher, + ObTableEntry &entry) +{ + int ret = OB_SUCCESS; + int64_t tmp_real_str_len = 0; + char ip[OB_IP_PORT_STR_BUFF]; + char status[32]; + int64_t port = 0; + ObProxyReplicaLocation prl; + ObProxyPartitionLocation *ppl = NULL; + ObSEArray server_list; + + while (OB_SUCC(ret) && OB_SUCC(rs_fetcher.next())) { + ip[0] = '\0'; + status[0] = '\0'; + prl.reset(); + bool binlog_service_ok = false; + + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "ip", ip, OB_IP_PORT_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "status", status, sizeof(status), tmp_real_str_len); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "port", port, int64_t); + + if (0 == strcasecmp("OK", status)) { + binlog_service_ok = true; + } + + if (OB_SUCC(ret) && binlog_service_ok) { + if (OB_FAIL(prl.add_addr(ip, port))) { + LOG_WARN("invalid ip or port in fetching binlog entry", K(ret)); + } else if (server_list.push_back(prl)) { + LOG_WARN("fail to add server", K(prl), K(ret)); + } + } + } + + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + + if (OB_SUCC(ret) && !server_list.empty()) { + if (OB_ISNULL(ppl = op_alloc(ObProxyPartitionLocation))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for ObProxyPartitionLocation", K(ret)); + } else if (OB_FAIL(ppl->set_replicas(server_list))) { + LOG_WARN("fail to set replicas", K(server_list), K(ret)); + } else if (!server_list.empty() && OB_UNLIKELY(!ppl->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ppl should not unavailabe", KPC(ppl), K(ret)); + } else { + if (ppl->is_valid()) { + if (OB_FAIL(entry.set_first_partition_location(ppl))) { + LOG_WARN("fail to set first partition location", K(ret)); + } else { + ppl = NULL; + } + } + } + } + + if (NULL != ppl) { + op_free(ppl); + ppl = NULL; + } + + return ret; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/route/ob_route_utils.h b/src/obproxy/proxy/route/ob_route_utils.h index ceddfa25..c908b22d 100644 --- a/src/obproxy/proxy/route/ob_route_utils.h +++ b/src/obproxy/proxy/route/ob_route_utils.h @@ -48,7 +48,7 @@ class ObRouteUtils static int get_first_part_sql(char *sql_buf, const int64_t buf_len, const uint64_t table_id, const bool is_hash_part, ObTableEntryName &name, const int64_t cluster_version); static int get_sub_part_sql(char *sql_buf, const int64_t buf_len, const uint64_t table_id, - const bool is_template_table, ObTableEntryName &name, const int64_t cluster_version); + const bool is_template_table, ObTableEntryName &name, const int64_t cluster_version); static int fetch_table_entry(obproxy::ObResultSetFetcher &rs_fetcher, ObTableEntry &entry, const int64_t cluster_version); @@ -59,6 +59,14 @@ class ObRouteUtils static int fetch_sub_part(obproxy::ObResultSetFetcher &rs_fetcher, ObProxyPartInfo &part_info, const int64_t cluster_version); + static int get_binlog_entry_sql(char *sql_buf, + const int64_t buf_len, + const ObString &cluster_name, + const ObString &tenant_name); + + static int fetch_binlog_entry(obproxy::ObResultSetFetcher &rs_fetcher, ObTableEntry &entry); + static int split_part_expr(common::ObString expr, common::ObIArray &arr); + static int build_sys_dummy_entry(const common::ObString &cluster_name, const int64_t cluster_id, const obutils::LocationList &rs_list, @@ -112,12 +120,6 @@ class ObRouteUtils const int64_t generated_key_idx, ObProxyPartInfo &part_info); static int fetch_part_option(obproxy::ObResultSetFetcher &rs_fetcher, ObProxyPartInfo &part_info); - static int build_part_desc(ObProxyPartInfo &part_info, const int64_t cluster_version); - static int build_part_desc(ObProxyPartInfo &part_info, - const share::schema::ObPartitionLevel part_level, - ObProxyPartOption &part_opt, - const int64_t cluster_version); - }; bool is_fake_ip_port(const char *ip_str, const int64_t port); diff --git a/src/obproxy/proxy/route/ob_server_route.h b/src/obproxy/proxy/route/ob_server_route.h index 905ba273..64b9afbe 100644 --- a/src/obproxy/proxy/route/ob_server_route.h +++ b/src/obproxy/proxy/route/ob_server_route.h @@ -53,8 +53,6 @@ class ObServerRoute // | | // +<---------------------------------------+ const ObProxyReplicaLocation *get_next_avail_replica(); - const ObProxyReplicaLocation *get_next_replica(const uint32_t cur_ip, const uint16_t cur_port, - const bool is_force_retry); const ObProxyReplicaLocation *get_leader_replica_from_remote() const; ObTableEntry *get_dummy_entry(); @@ -437,27 +435,6 @@ inline const ObProxyReplicaLocation *ObServerRoute::get_next_avail_replica() return cur_chosen_server_.replica_; } -inline const ObProxyReplicaLocation *ObServerRoute::get_next_replica( - const uint32_t cur_ip, - const uint16_t cur_port, - const bool is_force_retry) -{ - UNUSED(is_force_retry); - const ObProxyReplicaLocation *replica = NULL; - bool found = false; - leader_item_.is_used_ = true; - while (!found) { - replica = get_next_avail_replica(); - if (NULL == replica) { - found = true; - } else if ((cur_ip != replica->server_.get_ipv4()) - || (cur_port != static_cast(replica->server_.get_port()))) { - found = true; - } - } - return replica; -} - inline bool ObServerRoute::is_partition_table() const { return ((NULL != table_entry_) && table_entry_->is_partition_table()); diff --git a/src/obproxy/proxy/route/ob_table_entry.cpp b/src/obproxy/proxy/route/ob_table_entry.cpp index 42155b32..409e07c8 100644 --- a/src/obproxy/proxy/route/ob_table_entry.cpp +++ b/src/obproxy/proxy/route/ob_table_entry.cpp @@ -118,6 +118,7 @@ int ObTableEntry::set_names(const ObTableEntryName &name) LOG_WARN("fail to deep copy table entry names", K(ret)); } else { is_dummy_entry_ = name_.is_all_dummy_table(); + is_binlog_entry_ = name_.is_binlog_table(); } return ret; } diff --git a/src/obproxy/proxy/route/ob_table_entry.h b/src/obproxy/proxy/route/ob_table_entry.h index b04cd276..34edf185 100644 --- a/src/obproxy/proxy/route/ob_table_entry.h +++ b/src/obproxy/proxy/route/ob_table_entry.h @@ -40,7 +40,7 @@ class ObTableEntry : public ObRouteEntry { public: ObTableEntry() - : ObRouteEntry(), is_inited_(false), is_dummy_entry_(false), is_entry_from_rslist_(false), + : ObRouteEntry(), is_inited_(false), is_dummy_entry_(false), is_binlog_entry_(NULL), is_entry_from_rslist_(false), is_empty_entry_allowed_(false), is_need_force_flush_(false), has_dup_replica_(false), table_id_(common::OB_INVALID_ID), table_type_(share::schema::MAX_TABLE_TYPE), part_num_(0), replica_num_(0), name_(), buf_len_(0), buf_start_(NULL), first_pl_(NULL) @@ -70,7 +70,7 @@ class ObTableEntry : public ObRouteEntry bool is_dummy_entry() const { return is_dummy_entry_; } bool is_sys_dummy_entry() const { return is_dummy_entry_ && name_.is_sys_tenant(); } bool is_common_dummy_entry() const { return is_dummy_entry_ && !name_.is_sys_tenant(); } - bool is_location_entry() const { return !is_dummy_entry_ && 1 == part_num_; } + bool is_location_entry() const { return (!is_dummy_entry_ && 1 == part_num_) || is_binlog_entry_; } bool is_part_info_entry() const { return !is_dummy_entry_ && part_num_ > 1; } bool is_non_partition_table() const { return (1 == get_part_num()); } bool is_partition_table() const { return (get_part_num() > 1); } @@ -125,6 +125,7 @@ class ObTableEntry : public ObRouteEntry private: bool is_inited_; bool is_dummy_entry_; + bool is_binlog_entry_; bool is_entry_from_rslist_; bool is_empty_entry_allowed_; bool is_need_force_flush_; @@ -164,7 +165,7 @@ inline bool ObTableEntry::is_valid() const || (is_location_entry() && NULL != first_pl_ && OB_LIKELY(first_pl_->is_valid())) || (is_part_info_entry() && NULL != part_info_ && OB_LIKELY(part_info_->is_valid())))) ) - ); + ) || is_binlog_entry_; } inline int64_t ObTableEntry::get_server_count() const diff --git a/src/obproxy/proxy/route/ob_table_entry_cont.cpp b/src/obproxy/proxy/route/ob_table_entry_cont.cpp index 7f4cc91b..a5a4950b 100644 --- a/src/obproxy/proxy/route/ob_table_entry_cont.cpp +++ b/src/obproxy/proxy/route/ob_table_entry_cont.cpp @@ -240,6 +240,9 @@ const char *ObTableEntryCont::get_state_name(const ObTableEntryLookupState state case LOOKUP_DONE_STATE: name = "LOOKUP_DONE_STATE"; break; + case LOOKUP_BINLOG_ENTRY_STATE: + name = "LOOKUP_BINLOG_ENTRY_STATE"; + break; default: name = "Unknown State"; LOG_WARN("Unknown State", K(state)); @@ -392,6 +395,7 @@ inline int ObTableEntryCont::set_next_state() bool is_part_table_route_supported = table_param_.is_partition_table_route_supported_; switch (state_) { case LOOKUP_TABLE_ENTRY_STATE: + case LOOKUP_BINLOG_ENTRY_STATE: if (OB_ISNULL(newest_table_entry_)) { next_state = LOOKUP_DONE_STATE; } else if (newest_table_entry_->is_partition_table() && is_part_table_route_supported) { @@ -428,12 +432,7 @@ inline int ObTableEntryCont::set_next_state() next_state = LOOKUP_DONE_STATE; ret = OB_ERR_UNEXPECTED; LOG_WARN("part info should not be null here", K(ret)); - } else if ((!IS_CLUSTER_VERSION_LESS_THAN_V4(table_param_.cluster_version_) - && PARTITION_LEVEL_TWO == newest_table_entry_->get_part_info()->get_part_level()) - || (IS_CLUSTER_VERSION_LESS_THAN_V4(table_param_.cluster_version_) - && (!newest_table_entry_->get_part_info()->is_template_table() - || newest_table_entry_->get_part_info()->get_sub_part_option().is_range_part(table_param_.cluster_version_) - || newest_table_entry_->get_part_info()->get_sub_part_option().is_list_part(table_param_.cluster_version_)))) { + } else if (newest_table_entry_->get_part_info()->has_sub_part()) { next_state = LOOKUP_SUB_PART_STATE; } else { next_state = LOOKUP_DONE_STATE; @@ -483,6 +482,9 @@ inline int ObTableEntryCont::handle_client_resp(void *data) case LOOKUP_SUB_PART_STATE: ret = handle_sub_part_resp(*rs_fetcher); break; + case LOOKUP_BINLOG_ENTRY_STATE: + ret = handle_binlog_entry_resp(*rs_fetcher); + break; case LOOKUP_DONE_STATE: default: ret = OB_ERR_UNEXPECTED; @@ -541,6 +543,22 @@ inline int ObTableEntryCont::handle_table_entry_resp(ObResultSetFetcher &rs_fetc return ret; } +int ObTableEntryCont::handle_binlog_entry_resp(ObResultSetFetcher &rs_fetcher) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObTableEntry::alloc_and_init_table_entry(table_param_.name_, 0, 0, newest_table_entry_))) { + LOG_WARN("fail to alloc and init table entry", "name", table_param_.name_, K(ret)); + } else if (OB_ISNULL(newest_table_entry_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table entry should not be NULL", K_(newest_table_entry), K(ret)); + } else if (OB_FAIL(ObRouteUtils::fetch_binlog_entry(rs_fetcher, + *newest_table_entry_))) { + LOG_WARN("fail to fetch binlog entry info", K(ret)); + } + + return ret; +} + inline int ObTableEntryCont::handle_part_info_resp(ObResultSetFetcher &rs_fetcher) { int ret = OB_SUCCESS; @@ -887,13 +905,33 @@ inline int ObTableEntryCont::lookup_entry_remote() ObMysqlProxy *mysql_proxy = table_param_.mysql_proxy_; char sql[OB_SHORT_SQL_LENGTH]; sql[0] = '\0'; - if (OB_FAIL(ObRouteUtils::get_table_entry_sql(sql, OB_SHORT_SQL_LENGTH, table_param_.name_, - table_param_.is_need_force_flush_, table_param_.cluster_version_))) { - LOG_WARN("fail to get table entry sql", K(sql), K(ret)); + if (table_param_.name_.table_name_ == OB_ALL_BINLOG_DUMMY_TNAME) { + if (OB_FAIL(ObRouteUtils::get_binlog_entry_sql(sql, OB_SHORT_SQL_LENGTH, + table_param_.name_.cluster_name_, table_param_.name_.tenant_name_))) { + LOG_WARN("fail to get binlog entry sql", K(ret)); + } else { + state_ = LOOKUP_BINLOG_ENTRY_STATE; + ObMysqlRequestParam request_param(sql); + ObAddr addr; + if (OB_FAIL(addr.parse_from_cstring(get_global_proxy_config().binlog_service_ip.str()))) { + LOG_WARN("parse from cstring failed", K(ret)); + } else { + request_param.set_target_addr(addr); + request_param.ob_client_flags_.client_flags_.OB_CLIENT_SKIP_AUTOCOMMIT = 1; + if (OB_FAIL(mysql_proxy->async_read(this, request_param, pending_action_))) { + LOG_WARN("fail to aysnc read", K(sql), K(addr), K(ret)); + } + } + } } else { - const ObMysqlRequestParam request_param(sql, table_param_.current_idc_name_); - if (OB_FAIL(mysql_proxy->async_read(this, request_param, pending_action_))) { - LOG_WARN("fail to nonblock read", K(sql), K_(table_param), K(ret)); + if (OB_FAIL(ObRouteUtils::get_table_entry_sql(sql, OB_SHORT_SQL_LENGTH, table_param_.name_, + table_param_.is_need_force_flush_, table_param_.cluster_version_))) { + LOG_WARN("fail to get table entry sql", K(sql), K(ret)); + } else { + const ObMysqlRequestParam request_param(sql, table_param_.current_idc_name_); + if (OB_FAIL(mysql_proxy->async_read(this, request_param, pending_action_))) { + LOG_WARN("fail to nonblock read", K(sql), K_(table_param), K(ret)); + } } } diff --git a/src/obproxy/proxy/route/ob_table_entry_cont.h b/src/obproxy/proxy/route/ob_table_entry_cont.h index a330b6e6..189bae91 100644 --- a/src/obproxy/proxy/route/ob_table_entry_cont.h +++ b/src/obproxy/proxy/route/ob_table_entry_cont.h @@ -50,6 +50,7 @@ enum ObTableEntryLookupState LOOKUP_PART_INFO_STATE, LOOKUP_FIRST_PART_STATE, LOOKUP_SUB_PART_STATE, + LOOKUP_BINLOG_ENTRY_STATE, LOOKUP_DONE_STATE, }; @@ -142,6 +143,7 @@ class ObTableEntryCont : public obutils::ObAsyncCommonTask int handle_sub_part_resp(ObResultSetFetcher &rs_fetcher); int handle_lookup_remote(); int handle_lookup_remote_done(); + int handle_binlog_entry_resp(ObResultSetFetcher &rs_fetcher); int handle_lookup_remote_for_update(); int add_to_global_cache(bool &add_succ); diff --git a/src/obproxy/proxy/route/obproxy_expr_calculator.cpp b/src/obproxy/proxy/route/obproxy_expr_calculator.cpp index 27c16303..c22bc800 100644 --- a/src/obproxy/proxy/route/obproxy_expr_calculator.cpp +++ b/src/obproxy/proxy/route/obproxy_expr_calculator.cpp @@ -47,8 +47,10 @@ int ObProxyExprCalculator::calculate_partition_id(common::ObArenaAllocator &allo { int ret = OB_SUCCESS; ObString part_name = parse_result.get_part_name(); + bool old_is_oracle_mode = lib::is_oracle_mode(); + lib::set_oracle_mode(client_info.is_oracle_mode()); if (!part_name.empty()) { - if (OB_FAIL(part_info.get_part_mgr().get_part_with_part_name(part_name, partition_id))) { + if (OB_FAIL(part_info.get_part_mgr().get_part_with_part_name(part_name, partition_id, part_info, route, *this))) { LOG_WARN("fail to get part id with part name", K(part_name), K(ret)); } } @@ -92,7 +94,8 @@ int ObProxyExprCalculator::calculate_partition_id(common::ObArenaAllocator &allo LOG_INFO("fail to do expr parse", K(print_sql), K(part_info), "expr_parse_result", ObExprParseResultPrintWrapper(expr_parse_result)); } else if (OB_FAIL(do_expr_resolve(expr_parse_result, client_request, &client_info, ps_id_entry, - text_ps_entry, part_info, allocator, resolve_result, partition_id))) { + text_ps_entry, part_info, allocator, resolve_result, + parse_result, partition_id))) { LOG_INFO("fail to do expr resolve", K(print_sql), "expr_parse_result", ObExprParseResultPrintWrapper(expr_parse_result), K(part_info), KPC(ps_id_entry), KPC(text_ps_entry), K(resolve_result)); @@ -126,6 +129,7 @@ int ObProxyExprCalculator::calculate_partition_id(common::ObArenaAllocator &allo } } + lib::set_oracle_mode(old_is_oracle_mode); return ret; } @@ -197,14 +201,6 @@ int ObProxyExprCalculator::do_expr_parse(const common::ObString &req_sql, expr_result.part_key_info_.part_keys_[i] = key_info.part_keys_[i]; } - expr_result.target_mask_ = 0; - if (PARTITION_LEVEL_ONE == part_info.get_part_level()) { - expr_result.target_mask_ = FIRST_PART_MASK; - } else if (PARTITION_LEVEL_TWO == part_info.get_part_level()) { - expr_result.target_mask_ = BOTH_PART_MASK; - } else { - // do nothing - } if (OB_FAIL(expr_parser.parse_reqsql(req_sql, parse_result.get_parsed_length(), expr_result, parse_result.get_stmt_type(), connection_collation))) { LOG_DEBUG("fail to do expr parse_reqsql", K(req_sql), K(ret)); @@ -247,6 +243,7 @@ int ObProxyExprCalculator::do_expr_resolve(ObExprParseResult &parse_result, ObProxyPartInfo &part_info, ObIAllocator &allocator, ObExprResolverResult &resolve_result, + const ObSqlParseResult &sql_parse_result, int64_t &partition_id) { int ret = OB_SUCCESS; @@ -257,7 +254,10 @@ int ObProxyExprCalculator::do_expr_resolve(ObExprParseResult &parse_result, ctx.ps_id_entry_ = ps_id_entry; ctx.text_ps_entry_ = text_ps_entry; ctx.client_info_ = client_info; - + ctx.parse_result_ = &parse_result; + ctx.is_insert_stm_ = sql_parse_result.is_insert_stmt(); + ObSqlParseResult &result = const_cast(sql_parse_result); + ctx.sql_field_result_ = &result.get_sql_filed_result(); ObExprResolver expr_resolver(allocator); if (parse_result.has_rowid_) { @@ -332,7 +332,8 @@ int ObProxyExprCalculator::do_partition_id_calc(ObExprResolverResult &resolve_re LOG_DEBUG("do partition id calc", K(sub_part_id), K(tablet_id), K(part_info.has_sub_part())); - if (OB_SUCC(ret)) { + if (OB_SUCC(ret) + && (tablet_id != -1 || (first_part_id != OB_INVALID_INDEX && (!part_info.has_sub_part() || sub_part_id != OB_INVALID_INDEX)))) { if (tablet_id == -1) { partition_id = generate_phy_part_id(first_part_id, sub_part_id, part_info.get_part_level()); } else { @@ -378,8 +379,10 @@ int ObProxyExprCalculator::calc_part_id_by_random_choose_from_exist(ObProxyPartI if (OB_FAIL(ObRandomNumUtils::get_random_num(0, first_part_num - 1, rand_num))) { LOG_WARN("fail to get random num in first part", K(first_part_num), K(ret)); } else { - if (OB_FAIL(part_mgr.get_first_part_id_by_idx(rand_num, first_part_id, tablet_id))) { - LOG_WARN("failed to random get first part id by idx", K(rand_num), K(ret)); + if (OB_FAIL(part_mgr.get_first_part_id_by_random(rand_num, first_part_id, tablet_id))) { + LOG_WARN("failed to get first part id by random", K(rand_num), K(ret)); + } else { + //nothing; } } } @@ -434,6 +437,7 @@ int ObProxyExprCalculator::calc_partition_id_using_rowid(ObExprResolverContext & { int ret = OB_SUCCESS; const ObProxyRelationInfo *relation_info = ctx.relation_info_; + if (OB_ISNULL(relation_info)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid ctx relation info", K(ret)); @@ -458,7 +462,7 @@ int ObProxyExprCalculator::calc_partition_id_using_rowid(ObExprResolverContext & } } // for } - + return ret; } @@ -470,21 +474,30 @@ int ObProxyExprCalculator::calc_partition_id_with_rowid(ObProxyRelationExpr *rel { int ret = OB_SUCCESS; - ObNewRange &range = resolve_result.ranges_[0]; - ObExprResolver expr_resolver(allocator); - if (OB_FAIL(expr_resolver.resolve_token_list(relation, ctx.part_info_, ctx.client_request_, ctx.client_info_, - ctx.ps_id_entry_, ctx.text_ps_entry_, range, true))) { - LOG_INFO("fail to resolve token list with rowid", K(ret)); + ObObj *target_obj = NULL; + void *buf = NULL; + if (OB_ISNULL(buf = allocator.alloc(sizeof(ObObj)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem", K(ret)); + } else if (OB_ISNULL(target_obj = new (buf) ObObj())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new mem", K(ret)); } else { - ObObj &obj = const_cast(range.get_start_key().get_obj_ptr()[0]); - if (!obj.is_varchar()) { - ret = OB_ERR_UNEXPECTED; - LOG_INFO("expected obj type after resolved from execute", K(ret), K(obj.get_type())); + ObExprResolver expr_resolver(allocator); + if (OB_FAIL(expr_resolver.resolve_token_list(relation, ctx.part_info_, ctx.client_request_, ctx.client_info_, + ctx.ps_id_entry_, ctx.text_ps_entry_, + target_obj, ctx.sql_field_result_, true))) { + LOG_INFO("fail to resolve token list with rowid", K(ret)); } else { - ObString obj_str = obj.get_varchar(); - if (OB_FAIL(calc_partition_id_with_rowid_str(obj_str.ptr(), obj_str.length(), allocator, resolve_result, - *ctx.part_info_, partition_id))) { - LOG_INFO("fail to calc partition id with rowid str within execute", K(ret)); + if (!target_obj->is_varchar()) { + ret = OB_ERR_UNEXPECTED; + LOG_INFO("expected obj type after resolved from execute", K(ret), K(target_obj->get_type())); + } else { + ObString obj_str = target_obj->get_varchar(); + if (OB_FAIL(calc_partition_id_with_rowid_str(obj_str.ptr(), obj_str.length(), allocator, + resolve_result, *ctx.part_info_, partition_id))) { + LOG_INFO("fail to calc partition id with rowid str within execute", K(ret)); + } } } } @@ -502,10 +515,9 @@ int ObProxyExprCalculator::calc_partition_id_with_rowid_str(const char *str, int ret = OB_SUCCESS; ObURowIDData rowid_data; - ObArray pk_vals; if (OB_FAIL(ObURowIDData::decode2urowid(str, str_len, allocator, rowid_data))) { LOG_WARN("decode2urowid failed", K(ret)); - } else if (OB_FAIL(rowid_data.get_obobj_or_partition_id_from_decoded(part_info, resolve_result, partition_id))) { + } else if (OB_FAIL(rowid_data.get_obobj_or_partition_id_from_decoded(part_info, resolve_result, partition_id, allocator))) { LOG_WARN("fail to get obobj or partition id by rowid data", K(ret)); } else { // nothing @@ -533,7 +545,7 @@ int ObExprCalcTool::build_dtc_params_with_tz_info(ObClientSessionInfo *session_i } /* - * for ObTimestampLTZType, input timestamp string, and we also need time_zone from session + * for ObTimestampLTZType, ObTimestampTZType input timestamp string, and we also need time_zone from session * in order to decide the absolutely time */ int ObExprCalcTool::build_tz_info(ObClientSessionInfo *session_info, @@ -541,22 +553,31 @@ int ObExprCalcTool::build_tz_info(ObClientSessionInfo *session_info, ObTimeZoneInfo &tz_info) { int ret = OB_SUCCESS; + if (ObTimestampLTZType == obj_type || ObTimestampTZType == obj_type) { + if (OB_FAIL(build_tz_info_for_all_type(session_info, tz_info))) { + LOG_WARN("fail to build time zone info with session", K(ret)); + } + } + return ret; +} + +int ObExprCalcTool::build_tz_info_for_all_type(ObClientSessionInfo *session_info, + ObTimeZoneInfo &tz_info) +{ + int ret = OB_SUCCESS; + ObObj value_obj; + ObString sys_key_name = ObString::make_string(oceanbase::sql::OB_SV_TIME_ZONE); - if (ObTimestampLTZType == obj_type) { - ObObj value_obj; - ObString sys_key_name = ObString::make_string(oceanbase::sql::OB_SV_TIME_ZONE); - if (OB_FAIL(session_info->get_sys_variable_value(sys_key_name, value_obj))) { - LOG_WARN("fail to get sys var from session", K(ret), K(sys_key_name)); + if (OB_FAIL(session_info->get_sys_variable_value(sys_key_name, value_obj))) { + LOG_WARN("fail to get sys var from session", K(ret), K(sys_key_name)); + } else { + ObString value_str = value_obj.get_string(); + if (OB_FAIL(tz_info.set_timezone(value_str))) { + LOG_WARN("fail to set time zone for tz_info", K(ret), K(value_str)); } else { - ObString value_str = value_obj.get_string(); - if (OB_FAIL(tz_info.set_timezone(value_str))) { - LOG_WARN("fail to set time zone for tz_info", K(ret), K(value_str)); - } else { - LOG_DEBUG("succ to set time zone for tz_info", K(value_str)); - } + LOG_DEBUG("succ to set time zone for tz_info", K(value_str)); } } - return ret; } diff --git a/src/obproxy/proxy/route/obproxy_expr_calculator.h b/src/obproxy/proxy/route/obproxy_expr_calculator.h index 484eabf4..a657c074 100644 --- a/src/obproxy/proxy/route/obproxy_expr_calculator.h +++ b/src/obproxy/proxy/route/obproxy_expr_calculator.h @@ -59,6 +59,10 @@ class ObProxyExprCalculator ObServerRoute &route, ObProxyPartInfo &part_info, int64_t &partition_id); + int calc_part_id_by_random_choose_from_exist(ObProxyPartInfo &part_info, + int64_t &first_part_id, + int64_t &sub_part_id, + int64_t &phy_part_id); private: // do parse -> do resolve -> do partition id calc int do_expr_parse(const common::ObString &req_sql, @@ -75,6 +79,7 @@ class ObProxyExprCalculator ObProxyPartInfo &part_info, common::ObIAllocator &allocator, opsql::ObExprResolverResult &resolve_result, + const obutils::ObSqlParseResult &sql_parse_result, int64_t &partition_id); int do_partition_id_calc(opsql::ObExprResolverResult &resolve_result, ObClientSessionInfo &client_info, @@ -96,21 +101,17 @@ class ObProxyExprCalculator opsql::ObExprResolverResult &resolve_result, common::ObIAllocator &allocator, int64_t &partition_id); + int calc_partition_id_with_rowid(ObProxyRelationExpr *relation, + opsql::ObExprResolverContext &ctx, + common::ObIAllocator &allocator, + opsql::ObExprResolverResult &resolve_result, + int64_t &partition_id); int calc_partition_id_with_rowid_str(const char *str, const int64_t str_len, common::ObIAllocator &allocator, opsql::ObExprResolverResult &resolve_result, ObProxyPartInfo &part_info, int64_t &partition_id); - int calc_partition_id_with_rowid(ObProxyRelationExpr *relation, - opsql::ObExprResolverContext &ctx, - common::ObIAllocator &allocator, - opsql::ObExprResolverResult &resolve_result, - int64_t &partition_id); - int calc_part_id_by_random_choose_from_exist(ObProxyPartInfo &part_info, - int64_t &first_part_id, - int64_t &sub_part_id, - int64_t &phy_part_id); }; class ObExprCalcTool { @@ -122,6 +123,9 @@ class ObExprCalcTool { static int build_tz_info(ObClientSessionInfo *session_info, common::ObObjType obj_type, common::ObTimeZoneInfo &tz_info); + + static int build_tz_info_for_all_type(ObClientSessionInfo *session_info, + common::ObTimeZoneInfo &tz_info); static int build_dtc_params(ObClientSessionInfo *session_info, common::ObObjType obj_type, common::ObDataTypeCastParams &dtc_params); diff --git a/src/obproxy/proxy/route/obproxy_part_info.cpp b/src/obproxy/proxy/route/obproxy_part_info.cpp index 7ff2a902..d5621c04 100644 --- a/src/obproxy/proxy/route/obproxy_part_info.cpp +++ b/src/obproxy/proxy/route/obproxy_part_info.cpp @@ -94,6 +94,7 @@ int ObProxyPartInfo::alloc(ObProxyPartInfo *&part_info) void ObProxyPartInfo::free() { + part_mgr_.destroy(); allocator_.reset(); op_fixed_mem_free(this, sizeof(ObProxyPartInfo)); } diff --git a/src/obproxy/proxy/route/obproxy_part_info.h b/src/obproxy/proxy/route/obproxy_part_info.h index cd15e414..2f2a0bbe 100644 --- a/src/obproxy/proxy/route/obproxy_part_info.h +++ b/src/obproxy/proxy/route/obproxy_part_info.h @@ -68,6 +68,8 @@ class ObProxyPartInfo share::schema::ObPartitionLevel get_part_level() const { return part_level_; } common::ObCollationType get_table_cs_type() const { return table_cs_type_; } + common::ObIArray &get_part_columns() { return part_columns_; } + common::ObIArray &get_sub_part_columns() { return sub_part_columns_; } ObProxyPartOption &get_first_part_option() { return first_part_option_; } ObProxyPartOption &get_sub_part_option() { return sub_part_option_; } ObProxyPartMgr &get_part_mgr() { return part_mgr_; } @@ -91,6 +93,9 @@ class ObProxyPartInfo share::schema::ObPartitionLevel part_level_; common::ObCollationType table_cs_type_; + common::ObSEArray part_columns_; + common::ObSEArray sub_part_columns_; + common::ObArenaAllocator allocator_; ObProxyPartOption first_part_option_; ObProxyPartOption sub_part_option_; diff --git a/src/obproxy/proxy/route/obproxy_part_mgr.cpp b/src/obproxy/proxy/route/obproxy_part_mgr.cpp index 2e0e76a0..a6188304 100644 --- a/src/obproxy/proxy/route/obproxy_part_mgr.cpp +++ b/src/obproxy/proxy/route/obproxy_part_mgr.cpp @@ -17,7 +17,11 @@ #include "share/part/ob_part_desc_key.h" #include "share/part/ob_part_desc_range.h" #include "share/part/ob_part_desc_list.h" +#include "share/part/ob_part_mgr_util.h" #include "proxy/mysqllib/ob_resultset_fetcher.h" +#include "utils/ob_proxy_utils.h" +#include "proxy/route/obproxy_expr_calculator.h" +#include "proxy/route/ob_server_route.h" using namespace oceanbase::common; using namespace oceanbase::share::schema; @@ -27,59 +31,101 @@ namespace obproxy { namespace proxy { -int64_t ObPartNameIdPair::to_string(char *buf, const int64_t buf_len) const -{ - int64_t pos = 0; - J_OBJ_START(); - J_KV(K_(part_name), K_(part_id), K_(tablet_id)); - J_OBJ_END(); - return pos; -} ObProxyPartMgr::ObProxyPartMgr(ObIAllocator &allocator) : first_part_desc_(NULL) , sub_part_desc_(NULL) , first_part_num_(0) , sub_part_num_(NULL) - , part_pair_array_(NULL) + , all_first_part_name_buf_(NULL) + , all_sub_part_name_buf_(NULL) + , all_first_part_name_length_(0) + , all_sub_part_name_length_(0) + , first_part_name_id_map_() + , sub_part_name_id_map_() , allocator_(allocator) , cluster_version_(0) { } +void ObProxyPartMgr::destroy() +{ + if(first_part_name_id_map_.created()) { + first_part_name_id_map_.destroy(); + } + if(sub_part_name_id_map_.created()) { + sub_part_name_id_map_.destroy(); + } +} int ObProxyPartMgr::get_part_with_part_name(const ObString &part_name, - int64_t &part_id) + int64_t &part_id, + ObProxyPartInfo &part_info, + ObServerRoute &route, + ObProxyExprCalculator &expr_calculator) { int ret = OB_SUCCESS; - if (NULL != part_pair_array_&& first_part_num_ > 0) { - bool found = false; - for (int64_t i = 0; !found && i < first_part_num_; ++i) { - if (part_pair_array_[i].get_part_name().case_compare(part_name) == 0) { - int64_t tablet_id = part_pair_array_[i].get_tablet_id(); - if (tablet_id != -1) { - part_id = tablet_id; + if ( part_name.length() <= 0 || part_name.length() > MAX_PART_NAME_LENGTH) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("error part name", K(part_name)); + } else { + ObPartitionLevel part_level = part_info.get_part_level(); + ObString store_part_name; + int64_t * part_id_ptr = NULL; + PART_NAME_BUF tmp_buf;//64 byte stack buf + store_part_name.assign_ptr((char *)&tmp_buf, part_name.length()); + MEMCPY(store_part_name.ptr(), part_name.ptr(), store_part_name.length()); + string_to_upper_case(store_part_name.ptr(), store_part_name.length()); + if ((sub_part_name_id_map_.created()) && OB_NOT_NULL(part_id_ptr = (int64_t *)sub_part_name_id_map_.get(store_part_name))) { + //find sub part name, get ptr->(physical part id) + part_id = *part_id_ptr; + LOG_DEBUG("succ to get part id by sub part name", K(part_id), K(part_name)); + } else if ((first_part_name_id_map_.created()) && OB_NOT_NULL(part_id_ptr = (int64_t *)first_part_name_id_map_.get(store_part_name))) { + //find first part name, get ptr->(first part id) + LOG_DEBUG("succ to get part id by first part name", K(*part_id_ptr), K(part_name)); + if(OB_LIKELY(PARTITION_LEVEL_ONE == part_level)) { + part_id = *part_id_ptr; + } else if((PARTITION_LEVEL_TWO == part_level) + && !obutils::get_global_proxy_config().enable_primary_zone + && !obutils::get_global_proxy_config().enable_cached_server) { + int64_t first_part_id = *part_id_ptr; + int64_t sub_part_id = OB_INVALID_INDEX; + if(OB_FAIL(expr_calculator.calc_part_id_by_random_choose_from_exist(part_info, first_part_id, sub_part_id, part_id))) { + LOG_DEBUG("fail to get random part id by first part name", K(first_part_id), K(part_id), K(part_name)); } else { - part_id = part_pair_array_[i].get_part_id(); + // get part id by random, no need update pl + route.no_need_pl_update_ = true; + LOG_DEBUG("succ to get random part id by first part name", K(first_part_id), K(sub_part_id), K(part_id)); } - found = true; + } else { + //do nothing } } - if (found) { - LOG_DEBUG("succ to get part id with part name", K(part_id), K(part_name)); - } } return ret; } -int ObProxyPartMgr::get_first_part_id_by_idx(const int64_t idx, int64_t &part_id, int64_t &tablet_id) +int ObProxyPartMgr::get_first_part_id_by_random(const int64_t rand_num, + int64_t &first_part_id, + int64_t &tablet_id) { int ret = OB_SUCCESS; - if (idx < 0 || idx >= first_part_num_ || OB_ISNULL(part_pair_array_)) { + ObSEArray part_ids; + ObSEArray tablet_ids; + if (OB_ISNULL(first_part_desc_)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("fail to get part id by idx", K(ret), K(idx), K(first_part_num_), K(part_pair_array_)); + LOG_WARN("fail to get first part, null ptr", K(ret)); } else { - part_id = part_pair_array_[idx].get_part_id(); - tablet_id = part_pair_array_[idx].get_tablet_id(); + if (OB_FAIL(first_part_desc_->get_part_by_num(rand_num, part_ids, tablet_ids))) { + LOG_WARN("fail to get first part by random", K(first_part_desc_), K(ret)); + } else { + if (part_ids.count() >= 1) { + first_part_id = part_ids[0]; + } + if (tablet_ids.count() >= 1) { + tablet_id = tablet_ids[0]; + } + } } + return ret; } @@ -211,6 +257,7 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, const ObPartitionFuncType part_func_type, const int64_t part_num, const int64_t part_space, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher *rs_fetcher /*NULL*/, @@ -219,10 +266,11 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, int ret = OB_SUCCESS; void *tmp_buf = NULL; ObPartDescHash *desc_hash = NULL; - int64_t part_id = -1; - ObString part_name; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; int64_t sub_part_num = 0; - int64_t tablet_id = -1; + ObString part_name; int64_t *part_array = NULL; // After observer v4.0, there is no concept of template partition @@ -235,6 +283,8 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, } else if (OB_ISNULL(desc_hash = new (tmp_buf) ObPartDescHash())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("part mgr reach memory limit", K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_WARN("fail to alloc name buf", K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_hash->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit, alloc tablet id array failed", K(ret), K(part_num)); @@ -242,44 +292,68 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit, alloc part array failed", K(ret), K(part_num)); } else { - if (NULL != rs_fetcher && PARTITION_LEVEL_ONE == part_level) { - first_part_num_ = part_num; - if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartNameIdPair) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } else if (OB_ISNULL(part_pair_array_ = new (tmp_buf) ObPartNameIdPair[part_num])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); - } else if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } - for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { - if (OB_FAIL(rs_fetcher->next())) { - LOG_DEBUG("failed to get next rs_fetcher", K(ret)); - } else { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "part_id", part_id, int64_t); - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); - part_pair_array_[i].set_part_id(part_id); - if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "tablet_id", tablet_id, int64_t); - part_pair_array_[i].set_tablet_id(tablet_id); - desc_hash->tablet_id_array_[i] = tablet_id; - part_array[i] = part_id; - } - if (OB_FAIL(part_pair_array_[i].set_part_name(part_name))) { - LOG_WARN("fail to set part name", K(part_name), K(ret)); - } else if (!is_template_table) { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_num", sub_part_num, int64_t); - sub_part_num_[i] = sub_part_num; + if (NULL != rs_fetcher) { + if (PARTITION_LEVEL_ONE == part_level) { + first_part_num_ = part_num; + if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit", K(ret)); + } + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { + if (OB_FAIL(rs_fetcher->next())) { + LOG_DEBUG("fail to get next rs_fetcher", K(ret)); + } else { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "part_id", part_id_buf[i], int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); + + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + int64_t tablet_id = -1; + part_array[i] = part_id_buf[i]; + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "tablet_id", tablet_id, int64_t); + desc_hash->tablet_id_array_[i] = tablet_id; + if ((tablet_id != -1) && (tablet_id != 0)) { + part_id_buf[i] = tablet_id; + } + } + + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_first_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + + if (!is_template_table) { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_num", sub_part_num, int64_t); + sub_part_num_[i] = sub_part_num; + } } + } // end for + if (OB_ITER_END == ret) { + LOG_DEBUG("empty first hash part info, maybe ob version < 2.1", K(ret)); + ret = OB_SUCCESS; } - } // end for - if (OB_ITER_END == ret) { - LOG_DEBUG("empty first hash part info, maybe ob version < 2.1", K(ret)); - ret = OB_SUCCESS; + } else if (PARTITION_LEVEL_TWO == part_level) { + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) {//part_num=sub part num + if (OB_FAIL(rs_fetcher->next())) { + LOG_DEBUG("fail to get next rs_fetcher", K(ret)); + } else { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_id", part_id_buf[i], int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_sub_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + } + } // end for + } else { + //nothing } - } // end NULL != rs_fetcher && PARTITION_LEVEL_ONE == part_level + } // end NULL != rs_fetcher } if (OB_SUCC(ret)) { @@ -291,30 +365,52 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, desc_hash->set_part_num(part_num); desc_hash->set_part_level(part_level); desc_hash->set_part_func_type(part_func_type); - // find the first match key, should consider whether the key is both part one and part two? + for (int i = 0; i < part_col_num; i++) { + desc_hash->get_accuracies().push_back(ObAccuracy()); + desc_hash->get_obj_types().push_back(ObObjType()); + desc_hash->get_cs_types().push_back(ObCollationType()); + } + // find all keys in this level for (int i = 0; i < key_info.key_num_; ++i) { if (static_cast(key_info.part_keys_[i].level_) == part_level) { - desc_hash->set_part_key_type(static_cast(key_info.part_keys_[i].obj_type_)); - desc_hash->set_part_key_cs_type(static_cast(key_info.part_keys_[i].cs_type_)); - desc_hash->set_accuracy(key_info.part_keys_[i].accuracy_); - break; + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_hash->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; + desc_hash->get_obj_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].obj_type_); + desc_hash->get_cs_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].cs_type_); } } + if (PARTITION_LEVEL_ONE == part_level) { first_part_desc_ = desc_hash; + if (OB_FAIL(init_first_part_map())) { + LOG_DEBUG("fail to create first part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_first_part_name_buf_, all_first_part_name_length_, part_num, first_part_name_id_map_))) { + LOG_DEBUG("fail to build first part name id map", K(ret)); + } } else if (PARTITION_LEVEL_TWO == part_level) { sub_part_desc_ = desc_hash; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_temp_sub_part_name_id_map(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_DEBUG("fail to build temp sub part name id map", K(ret)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("part level invalid", K(part_level), K(ret)); } } + + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_mode, const ObPartitionFuncType part_func_type, const int64_t part_space, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version) @@ -323,7 +419,12 @@ int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_m void *tmp_buf = NULL; ObPartDescHash *desc_hash = NULL; common::ObPartDesc *sub_part_desc = NULL; - int64_t part_id = -1; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; + int64_t first_part_id = -1; + int64_t sub_part_id = -1; + ObString sub_part_name; // alloc desc_range if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartDescHash) * first_part_num_))) { @@ -331,9 +432,12 @@ int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_m LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(sub_part_desc = new (tmp_buf) ObPartDescHash[first_part_num_])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, all_sub_part_num_))) { + LOG_WARN("fail to alloc name buf", K(ret)); } + int64_t index=0; for (int64_t i = 0; i < first_part_num_ && OB_SUCC(ret); ++i) { desc_hash = (((ObPartDescHash *)sub_part_desc) + i); if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_hash->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * sub_part_num_[i]))) { @@ -342,30 +446,52 @@ int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_m } for (int64_t j = 0; j < sub_part_num_[i] && OB_SUCC(ret); ++j) { - if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + if (OB_FAIL(rs_fetcher.next()) || index >= all_sub_part_num_) { + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_id, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", first_part_id, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", sub_part_id, int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", sub_part_name); if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", desc_hash->tablet_id_array_[j], int64_t); } + if (sub_part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[index], sub_part_name.ptr(), sub_part_name.length()); + name_len_buf[index] = sub_part_name.length(); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + part_id_buf[index] = desc_hash->tablet_id_array_[j]; + } else { + part_id_buf[index] = generate_phy_part_id(first_part_id, sub_part_id); + } + all_sub_part_name_length_ += sub_part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[index] = 0; + } + ++index; } } - if (OB_SUCC(ret)) { desc_hash->set_oracle_mode(is_oracle_mode); - desc_hash->set_first_part_id(part_id); + desc_hash->set_first_part_id(first_part_id); desc_hash->set_part_space(part_space); desc_hash->set_part_num(sub_part_num_[i]); desc_hash->set_part_level(PARTITION_LEVEL_TWO); desc_hash->set_part_func_type(part_func_type); - // find the first match key, should consider whether the key is both part one and part two? + for (int i = 0; i < part_col_num; i++) { + desc_hash->get_accuracies().push_back(ObAccuracy()); + desc_hash->get_obj_types().push_back(ObObjType()); + desc_hash->get_cs_types().push_back(ObCollationType()); + } + // find all keys in this level for (int i = 0; i < key_info.key_num_; ++i) { if (static_cast(key_info.part_keys_[i].level_) == PARTITION_LEVEL_TWO) { - desc_hash->set_part_key_type(static_cast(key_info.part_keys_[i].obj_type_)); - desc_hash->set_part_key_cs_type(static_cast(key_info.part_keys_[i].cs_type_)); - desc_hash->set_accuracy(key_info.part_keys_[i].accuracy_); - break; + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_hash->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; + desc_hash->get_obj_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].obj_type_); + desc_hash->get_cs_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].cs_type_); } } } @@ -373,8 +499,14 @@ int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_m if (OB_SUCC(ret)) { sub_part_desc_ = sub_part_desc; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create non temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_sub_part_name_buf_, all_sub_part_name_length_, all_sub_part_num_, sub_part_name_id_map_))) { + LOG_DEBUG("fail to build non temp sub part name id map", K(ret)); + } } + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } @@ -382,6 +514,7 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, const ObPartitionFuncType part_func_type, const int64_t part_num, const int64_t part_space, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher *rs_fetcher /*NULL*/, @@ -390,9 +523,11 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, int ret = OB_SUCCESS; void *tmp_buf = NULL; ObPartDescKey *desc_key = NULL; - int64_t part_id = -1; - ObString part_name; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; int64_t sub_part_num = 0; + ObString part_name; int64_t *part_array = NULL; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && PARTITION_LEVEL_TWO == part_level) { @@ -404,6 +539,8 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, } else if (OB_ISNULL(desc_key = new (tmp_buf) ObPartDescKey())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("part mgr reach memory limit", K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_WARN("fail to alloc name buf", K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_key->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret), K(part_num)); @@ -411,46 +548,70 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("fail to alloc part array", K(ret), K(part_num)); } else { - if (NULL != rs_fetcher && PARTITION_LEVEL_ONE == part_level) { - first_part_num_ = part_num; - if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartNameIdPair) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } else if (OB_ISNULL(part_pair_array_ = new (tmp_buf) ObPartNameIdPair[part_num])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); - } else if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } - for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { - if (OB_FAIL(rs_fetcher->next())) { - LOG_DEBUG("failed to get next rs_fetcher", K(ret)); - } else { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "part_id", part_id, int64_t); - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); - part_pair_array_[i].set_part_id(part_id); - if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - int64_t tablet_id = -1; - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "tablet_id", tablet_id, int64_t); - part_pair_array_[i].set_tablet_id(tablet_id); - desc_key->tablet_id_array_[i] = tablet_id; - part_array[i] = part_id; - } - if (OB_FAIL(part_pair_array_[i].set_part_name(part_name))) { - LOG_WARN("fail to set part name", K(part_name), K(ret)); - } else if (!is_template_table) { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_num", sub_part_num, int64_t); - sub_part_num_[i] = sub_part_num; + if (NULL != rs_fetcher) { + if (PARTITION_LEVEL_ONE == part_level) { + first_part_num_ = part_num; + if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit", K(ret)); + } + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { + if (OB_FAIL(rs_fetcher->next())) { + LOG_DEBUG("fail to get next rs_fetcher", K(ret)); + } else { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "part_id", part_id_buf[i], int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); + + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + int64_t tablet_id = -1; + part_array[i] = part_id_buf[i]; + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "tablet_id", tablet_id, int64_t); + desc_key->tablet_id_array_[i] = tablet_id; + if ((tablet_id != -1) && (tablet_id != 0)) { + part_id_buf[i] = tablet_id; + } + } + + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_first_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + + if (!is_template_table) { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_num", sub_part_num, int64_t); + sub_part_num_[i] = sub_part_num; + } } + } // end for + if (OB_ITER_END == ret) { + LOG_DEBUG("empty first key part info, maybe ob version < 2.1", K(ret)); + ret = OB_SUCCESS; } - } // end for - if (OB_ITER_END == ret) { - LOG_DEBUG("empty first key part info, maybe ob version < 2.1", K(ret)); - ret = OB_SUCCESS; + } else if (PARTITION_LEVEL_TWO == part_level) { + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) {//part_num=sub part num + if (OB_FAIL(rs_fetcher->next())) { + LOG_DEBUG("fail to get next rs_fetcher", K(ret)); + } else { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_id", part_id_buf[i], int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_sub_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + } + } // end for + } else { + //nothing } - } // end NULL != rs_fetcher && PARTITION_LEVEL_ONE == part_level + } // end NULL != rs_fetcher } + if (OB_SUCC(ret)) { if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { desc_key->set_part_array(part_array); @@ -459,29 +620,50 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, desc_key->set_part_num(part_num); desc_key->set_part_level(part_level); desc_key->set_part_func_type(part_func_type); - // find the first match key, should consider whether the key is both part one and part two? + for (int i = 0; i < part_col_num; i++) { + desc_key->get_accuracies().push_back(ObAccuracy()); + desc_key->get_obj_types().push_back(ObObjType()); + desc_key->get_cs_types().push_back(ObCollationType()); + } + // find all keys in this level for (int i = 0; i < key_info.key_num_; ++i) { if (static_cast(key_info.part_keys_[i].level_) == part_level) { - desc_key->set_part_key_type(static_cast(key_info.part_keys_[i].obj_type_)); - desc_key->set_part_key_cs_type(static_cast(key_info.part_keys_[i].cs_type_)); - desc_key->set_accuracy(key_info.part_keys_[i].accuracy_); - break; + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_key->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; + desc_key->get_obj_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].obj_type_); + desc_key->get_cs_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].cs_type_); } } if (PARTITION_LEVEL_ONE == part_level) { first_part_desc_ = desc_key; + if (OB_FAIL(init_first_part_map())) { + LOG_DEBUG("fail to create first part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_first_part_name_buf_, all_first_part_name_length_, part_num, first_part_name_id_map_))) { + LOG_DEBUG("fail to build first part name id map", K(ret)); + } } else if (PARTITION_LEVEL_TWO == part_level) { sub_part_desc_ = desc_key; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_temp_sub_part_name_id_map(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_DEBUG("fail to build temp sub part name id map", K(ret)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("part level invalid", K(part_level), K(ret)); } } + + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncType part_func_type, const int64_t part_space, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version) @@ -490,7 +672,12 @@ int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncTy void *tmp_buf = NULL; ObPartDescKey *desc_key = NULL; common::ObPartDesc *sub_part_desc = NULL; - int64_t part_id = -1; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; + int64_t first_part_id = -1; + int64_t sub_part_id = -1; + ObString sub_part_name; // alloc desc_range if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartDescKey) * first_part_num_))) { @@ -498,9 +685,12 @@ int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncTy LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(sub_part_desc = new (tmp_buf) ObPartDescKey[first_part_num_])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, all_sub_part_num_))) { + LOG_WARN("fail to alloc name buf", K(ret)); } + int64_t index=0; for (int64_t i = 0; i < first_part_num_ && OB_SUCC(ret); ++i) { desc_key = (((ObPartDescKey *)sub_part_desc) + i); if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_key->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * sub_part_num_[i]))) { @@ -509,29 +699,52 @@ int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncTy } for (int64_t j = 0; j < sub_part_num_[i] && OB_SUCC(ret); ++j) { - if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + if (OB_FAIL(rs_fetcher.next()) || index >= all_sub_part_num_) { + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_id, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", first_part_id, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", sub_part_id, int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", sub_part_name); if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", desc_key->tablet_id_array_[j], int64_t); } + if (sub_part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[index], sub_part_name.ptr(), sub_part_name.length()); + name_len_buf[index] = sub_part_name.length(); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + part_id_buf[index] = desc_key->tablet_id_array_[j]; + } else { + part_id_buf[index] = generate_phy_part_id(first_part_id, sub_part_id); + } + all_sub_part_name_length_ += sub_part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[index] = 0; + } + ++index; } } if (OB_SUCC(ret)) { - desc_key->set_first_part_id(part_id); + desc_key->set_first_part_id(first_part_id); desc_key->set_part_space(part_space); desc_key->set_part_num(sub_part_num_[i]); desc_key->set_part_level(PARTITION_LEVEL_TWO); desc_key->set_part_func_type(part_func_type); - // find the first match key, should consider whether the key is both part one and part two? + for (int i = 0; i < part_col_num; i++) { + desc_key->get_accuracies().push_back(ObAccuracy()); + desc_key->get_obj_types().push_back(ObObjType()); + desc_key->get_cs_types().push_back(ObCollationType()); + } + // find all keys in this level for (int i = 0; i < key_info.key_num_; ++i) { if (static_cast(key_info.part_keys_[i].level_) == PARTITION_LEVEL_TWO) { - desc_key->set_part_key_type(static_cast(key_info.part_keys_[i].obj_type_)); - desc_key->set_part_key_cs_type(static_cast(key_info.part_keys_[i].cs_type_)); - desc_key->set_accuracy(key_info.part_keys_[i].accuracy_); - break; + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_key->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; + desc_key->get_obj_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].obj_type_); + desc_key->get_cs_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].cs_type_); } } } @@ -539,14 +752,21 @@ int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncTy if (OB_SUCC(ret)) { sub_part_desc_ = sub_part_desc; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create non temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_sub_part_name_buf_, all_sub_part_name_length_, all_sub_part_num_, sub_part_name_id_map_))) { + LOG_DEBUG("fail to build non temp sub part name id map", K(ret)); + } } + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, const ObPartitionFuncType part_func_type, const int64_t part_num, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, @@ -556,8 +776,11 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, void *tmp_buf = NULL; ObPartDescRange *desc_range = NULL; RangePartition *part_array = NULL; - ObString part_name; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; int64_t sub_part_num = 0; + ObString part_name; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && PARTITION_LEVEL_TWO == part_level) { ret = OB_ERR_UNEXPECTED; @@ -568,7 +791,7 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(desc_range = new (tmp_buf) ObPartDescRange())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_range->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret)); @@ -577,17 +800,13 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(part_array = new (tmp_buf) RangePartition[part_num])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(part_num), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_WARN("fail to alloc name buf", K(ret)); } else { if (PARTITION_LEVEL_ONE == part_level) { first_part_num_ = part_num; - if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartNameIdPair) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } else if (OB_ISNULL(part_pair_array_ = new (tmp_buf) ObPartNameIdPair[part_num])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); - } else if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret)); } @@ -599,27 +818,42 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, int64_t pos = 0; for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { if (PARTITION_LEVEL_ONE == part_level) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_array[i].part_id_, int64_t); + part_id_buf[i] = part_array[i].part_id_; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { int64_t tablet_id = -1; PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", tablet_id, int64_t); - part_pair_array_[i].tablet_id_ = tablet_id; desc_range->tablet_id_array_[i] = tablet_id; + if ((tablet_id != -1) && (tablet_id != 0)) { + part_id_buf[i] = tablet_id; + } } PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); - - part_pair_array_[i].set_part_id(part_array[i].part_id_); - if (OB_FAIL(part_pair_array_[i].set_part_name(part_name))) { - LOG_WARN("fail to set part name", K(part_name), K(ret)); - } else if (!is_template_table) { + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_first_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + if (!is_template_table) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_num", sub_part_num, int64_t); sub_part_num_[i] = sub_part_num; } } else if (PARTITION_LEVEL_TWO == part_level) { - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[i].part_id_, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[i].part_id_, int64_t);//sub_part_id + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); + part_id_buf[i] = part_array[i].part_id_; + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_sub_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } } else { ret = OB_INVALID_ARGUMENT; } @@ -627,10 +861,10 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, pos = 0; if (OB_FAIL(ret)) { - LOG_WARN("failed to fetch result", K(ret)); + LOG_WARN("fail to fetch result", K(ret)); } else if (OB_FAIL(part_array[i].high_bound_val_.deserialize(allocator_, tmp_str.ptr(), tmp_str.length(), pos))) { - LOG_WARN("failed to deserialize", K(tmp_str), K(ret)); + LOG_WARN("fail to deserialize", K(tmp_str), K(ret)); } else { // do nothing } @@ -641,7 +875,7 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, if (OB_SUCC(ret)) { if (OB_FAIL(desc_range->set_part_array(part_array, part_num))) { - LOG_WARN("failed to set_part_array, unexpected ", K(ret)); + LOG_WARN("fail to set_part_array, unexpected ", K(ret)); } } @@ -649,25 +883,45 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, if (OB_SUCC(ret)) { desc_range->set_part_level(part_level); desc_range->set_part_func_type(part_func_type); - for (int k = 0; k < key_info.key_num_; ++k) { - if (static_cast(key_info.part_keys_[k].level_) == part_level) { - desc_range->set_accuracy(key_info.part_keys_[k].accuracy_); - break; + for (int i = 0; i < part_col_num; i++) { + desc_range->get_accuracies().push_back(ObAccuracy()); + } + // find all keys in this level + for (int i = 0; i < key_info.key_num_; ++i) { + if (static_cast(key_info.part_keys_[i].level_) == part_level) { + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_range->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; } } if (PARTITION_LEVEL_ONE == part_level) { first_part_desc_ = desc_range; + if (OB_FAIL(init_first_part_map())) { + LOG_DEBUG("fail to create first part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_first_part_name_buf_, all_first_part_name_length_, part_num, first_part_name_id_map_))) { + LOG_DEBUG("fail to build first part name id map", K(ret)); + } } else if (PARTITION_LEVEL_TWO == part_level) { sub_part_desc_ = desc_range; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_temp_sub_part_name_id_map(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_DEBUG("fail to build temp sub part name id map", K(ret)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("part level invalid", K(part_level), K(ret)); } } + + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFuncType part_func_type, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version) @@ -676,6 +930,10 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc void *tmp_buf = NULL; RangePartition *part_array = NULL; common::ObPartDesc *sub_part_desc = NULL; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; + ObString sub_part_name; // alloc desc_range if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartDescRange) * first_part_num_))) { @@ -683,11 +941,13 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(sub_part_desc = new (tmp_buf) ObPartDescRange[first_part_num_])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, all_sub_part_num_))) { + LOG_WARN("fail to alloc name buf", K(ret)); } - // build desc_range ObString tmp_str; + int64_t index = 0; int64_t pos = 0; ObPartDescRange *desc_range = NULL; for (int64_t i = 0; i < first_part_num_ && OB_SUCC(ret); ++i) { @@ -698,7 +958,7 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(part_array = new (tmp_buf) RangePartition[sub_part_num_[i]])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), "sub_part_index", i, + LOG_WARN("fail to do placement new", K(tmp_buf), "sub_part_index", i, "sub_part_num", sub_part_num_[i], K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_range->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * sub_part_num_[i]))) { ret = OB_REACH_MEMORY_LIMIT; @@ -706,22 +966,37 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc } for (int64_t j = 0; j < sub_part_num_[i] && OB_SUCC(ret); ++j) { - if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + if (OB_FAIL(rs_fetcher.next()) || index >= all_sub_part_num_) { + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_array[j].first_part_id_, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[j].part_id_, int64_t); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "high_bound_val_bin", tmp_str); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", desc_range->tablet_id_array_[j], int64_t); } + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", sub_part_name); + if (sub_part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[index], sub_part_name.ptr(), sub_part_name.length()); + name_len_buf[index] = sub_part_name.length(); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + part_id_buf[index] = desc_range->tablet_id_array_[j]; + } else { + part_id_buf[index] = generate_phy_part_id(part_array[j].first_part_id_, part_array[j].part_id_); + } + all_sub_part_name_length_ += sub_part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[index] = 0; + } + ++index; pos = 0; if (OB_FAIL(ret)) { - LOG_WARN("failed to fetch result", K(ret)); + LOG_WARN("fail to fetch result", K(ret)); } else if (OB_FAIL(part_array[j].high_bound_val_.deserialize(allocator_, tmp_str.ptr(), tmp_str.length(), pos))) { - LOG_WARN("failed to deserialize", K(tmp_str), K(ret)); + LOG_WARN("fail to deserialize", K(tmp_str), K(ret)); } else { // do nothing } @@ -731,28 +1006,42 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc if (OB_SUCC(ret)) { desc_range->set_part_level(PARTITION_LEVEL_TWO); desc_range->set_part_func_type(part_func_type); - for (int k = 0; k < key_info.key_num_; ++k) { - if (static_cast(key_info.part_keys_[k].level_) == PARTITION_LEVEL_TWO) { - desc_range->set_accuracy(key_info.part_keys_[k].accuracy_); - break; + for (int i = 0; i < part_col_num; i++) { + desc_range->get_accuracies().push_back(ObAccuracy()); + } + // find all keys in this level + for (int i = 0; i < key_info.key_num_; ++i) { + if (static_cast(key_info.part_keys_[i].level_) == PARTITION_LEVEL_TWO) { + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_range->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; } } if (OB_FAIL(desc_range->set_part_array(part_array, sub_part_num_[i]))) { - LOG_WARN("failed to set_part_array, unexpected ", K(ret)); + LOG_WARN("fail to set_part_array, unexpected ", K(ret)); } } } // end of for if (OB_SUCC(ret)) { sub_part_desc_ = sub_part_desc; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create non temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_sub_part_name_buf_, all_sub_part_name_length_, all_sub_part_num_, sub_part_name_id_map_))) { + LOG_DEBUG("fail to build non temp sub part name id map", K(ret)); + } } + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, const ObPartitionFuncType part_func_type, const int64_t part_num, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, @@ -762,8 +1051,11 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, void *tmp_buf = NULL; ObPartDescList *desc_list = NULL; ListPartition *part_array = NULL; - ObString part_name; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; int64_t sub_part_num = 0; + ObString part_name; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && PARTITION_LEVEL_TWO == part_level) { ret = OB_ERR_UNEXPECTED; @@ -774,7 +1066,7 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(desc_list = new (tmp_buf) ObPartDescList())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_list->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit, alloc tablet id array failed", K(ret)); @@ -783,17 +1075,13 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(part_array = new (tmp_buf) ListPartition[part_num])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(part_num), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_WARN("fail to alloc name buf", K(ret)); } else { if (PARTITION_LEVEL_ONE == part_level) { first_part_num_ = part_num; - if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartNameIdPair) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } else if (OB_ISNULL(part_pair_array_ = new (tmp_buf) ObPartNameIdPair[part_num])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); - } else if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret)); } @@ -806,29 +1094,44 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, ObNewRow row; ObNewRow tmp_row; ObObj obj_array[OB_USER_ROW_MAX_COLUMNS_COUNT]; - row.assign(obj_array, OB_USER_ROW_MAX_COLUMNS_COUNT); for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { if (PARTITION_LEVEL_ONE == part_level) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_array[i].part_id_, int64_t); - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); + part_id_buf[i] = part_array[i].part_id_; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { int64_t tablet_id = -1; PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", tablet_id, int64_t); - part_pair_array_[i].tablet_id_ = tablet_id; desc_list->tablet_id_array_[i] = tablet_id; + if ((tablet_id != -1) && (tablet_id != 0)) { + part_id_buf[i] = tablet_id; + } } - part_pair_array_[i].set_part_id(part_array[i].part_id_); - if (OB_FAIL(part_pair_array_[i].set_part_name(part_name))) { - LOG_WARN("fail to set part name", K(part_name), K(ret)); - } else if (!is_template_table) { + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_first_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + if (!is_template_table) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_num", sub_part_num, int64_t); sub_part_num_[i] = sub_part_num; } } else if (PARTITION_LEVEL_TWO == part_level) { - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[i].part_id_, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[i].part_id_, int64_t);//sub_part_id + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); + part_id_buf[i] = part_array[i].part_id_; + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_sub_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } } else { ret = OB_INVALID_ARGUMENT; } @@ -839,6 +1142,7 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, } else { // deserialize ob rows array while (OB_SUCC(ret) && pos < tmp_str.length()) { + row.assign(obj_array, OB_USER_ROW_MAX_COLUMNS_COUNT); if (OB_FAIL(row.deserialize(tmp_str.ptr(), tmp_str.length(), pos))) { LOG_WARN("fail to deserialize ob row", K(tmp_str), K(ret)); } else if (OB_FAIL(ob_write_row(allocator_, row, tmp_row))) { @@ -858,7 +1162,7 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, if (OB_SUCC(ret)) { if (OB_FAIL(desc_list->set_part_array(part_array, part_num))) { - LOG_WARN("failed to set_part_array, unexpected ", K(ret)); + LOG_WARN("fail to set_part_array, unexpected ", K(ret)); } } @@ -866,25 +1170,45 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, if (OB_SUCC(ret)) { desc_list->set_part_level(part_level); desc_list->set_part_func_type(part_func_type); - for (int k = 0; k < key_info.key_num_; ++k) { - if (static_cast(key_info.part_keys_[k].level_) == part_level) { - desc_list->set_accuracy(key_info.part_keys_[k].accuracy_); - break; + for (int i = 0; i < part_col_num; i++) { + desc_list->get_accuracies().push_back(ObAccuracy()); + } + // find all keys in this level + for (int i = 0; i < key_info.key_num_; ++i) { + if (static_cast(key_info.part_keys_[i].level_) == part_level) { + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_list->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; } } if (PARTITION_LEVEL_ONE == part_level) { first_part_desc_ = desc_list; + if (OB_FAIL(init_first_part_map())) { + LOG_DEBUG("fail to create first part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_first_part_name_buf_, all_first_part_name_length_, part_num, first_part_name_id_map_))) { + LOG_DEBUG("fail to build first part name id map", K(ret)); + } } else if (PARTITION_LEVEL_TWO == part_level) { sub_part_desc_ = desc_list; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_temp_sub_part_name_id_map(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_DEBUG("fail to build temp sub part name id map", K(ret)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("part level invalid", K(part_level), K(ret)); } } + + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncType part_func_type, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version) @@ -893,23 +1217,28 @@ int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncT void *tmp_buf = NULL; ListPartition *part_array = NULL; common::ObPartDesc *sub_part_desc = NULL; - + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; + ObString sub_part_name; + // alloc desc_range if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartDescList) * first_part_num_))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(sub_part_desc = new (tmp_buf) ObPartDescList[first_part_num_])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, all_sub_part_num_))) { + LOG_WARN("fail to alloc name buf", K(ret)); } - // build desc_list ObString tmp_str; + int64_t index = 0; int64_t pos = 0; ObNewRow row; ObNewRow tmp_row; ObObj obj_array[OB_USER_ROW_MAX_COLUMNS_COUNT]; - row.assign(obj_array, OB_USER_ROW_MAX_COLUMNS_COUNT); ObPartDescList *desc_list = NULL; for (int64_t i = 0; i < first_part_num_ && OB_SUCC(ret); ++i) { tmp_buf = NULL; @@ -919,7 +1248,7 @@ int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncT LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(part_array = new (tmp_buf) ListPartition[sub_part_num_[i]])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), "sub_part_index", i, + LOG_WARN("fail to do placement new", K(tmp_buf), "sub_part_index", i, "sub_part_num", sub_part_num_[i], K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_list->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * sub_part_num_[i]))) { ret = OB_REACH_MEMORY_LIMIT; @@ -927,22 +1256,38 @@ int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncT } for (int64_t j = 0; j < sub_part_num_[i] && OB_SUCC(ret); ++j) { - if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + if (OB_FAIL(rs_fetcher.next()) || index >= all_sub_part_num_) { + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_array[j].first_part_id_, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[j].part_id_, int64_t); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "high_bound_val_bin", tmp_str); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", desc_list->tablet_id_array_[j], int64_t); } + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", sub_part_name); + if (sub_part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[index], sub_part_name.ptr(), sub_part_name.length()); + name_len_buf[index] = sub_part_name.length(); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + part_id_buf[index] = desc_list->tablet_id_array_[j]; + } else { + part_id_buf[index] = generate_phy_part_id(part_array[j].first_part_id_, part_array[j].part_id_); + } + all_sub_part_name_length_ += sub_part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[index] = 0; + } + ++index; pos = 0; if (OB_FAIL(ret)) { LOG_WARN("fail to fetch result", K(ret)); } else { // deserialize ob rows array while (OB_SUCC(ret) && pos < tmp_str.length()) { + row.assign(obj_array, OB_USER_ROW_MAX_COLUMNS_COUNT); if (OB_FAIL(row.deserialize(tmp_str.ptr(), tmp_str.length(), pos))) { LOG_WARN("fail to deserialize ob row", K(tmp_str), K(ret)); } else if (OB_FAIL(ob_write_row(allocator_, row, tmp_row))) { @@ -963,22 +1308,35 @@ int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncT if (OB_SUCC(ret)) { desc_list->set_part_level(PARTITION_LEVEL_TWO); desc_list->set_part_func_type(part_func_type); - for (int k = 0; k < key_info.key_num_; ++k) { - if (static_cast(key_info.part_keys_[k].level_) == PARTITION_LEVEL_TWO) { - desc_list->set_accuracy(key_info.part_keys_[k].accuracy_); - break; + for (int i = 0; i < part_col_num; i++) { + desc_list->get_accuracies().push_back(ObAccuracy()); + } + // find all keys in this level + for (int i = 0; i < key_info.key_num_; ++i) { + if (static_cast(key_info.part_keys_[i].level_) == PARTITION_LEVEL_TWO) { + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_list->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; } } if (OB_FAIL(desc_list->set_part_array(part_array, sub_part_num_[i]))) { - LOG_WARN("failed to set_part_array, unexpected ", K(ret)); + LOG_WARN("fail to set_part_array, unexpected ", K(ret)); } } } // end of for if (OB_SUCC(ret)) { sub_part_desc_ = sub_part_desc; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create non temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_sub_part_name_buf_, all_sub_part_name_length_, all_sub_part_num_, sub_part_name_id_map_))) { + LOG_DEBUG("fail to build non temp sub part name id map", K(ret)); + } } + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } @@ -1057,6 +1415,112 @@ int ObProxyPartMgr::get_sub_part_num_by_first_part_id(ObProxyPartInfo &part_info return ret; } +int ObProxyPartMgr::build_part_name_id_map(const PART_NAME_BUF * const name_buf, + const int64_t * const name_len_buf, + const int64_t * const part_id_buf, + char * target_part_name_buf, + const int64_t total_part_name_len, + const int64_t part_num, + PartNameIdMap& part_name_id_map) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(name_buf) || OB_ISNULL(name_len_buf) || OB_ISNULL(part_id_buf)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to get part name buf", K(ret)); + } else if (OB_NOT_NULL(target_part_name_buf)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("part name buf is alloc twice", K(ret)); + } else if (OB_ISNULL(target_part_name_buf = (char *)allocator_.alloc(total_part_name_len))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc all first part name buf", K(ret)); + } else { + ObString part_name; + int64_t pos = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < part_num; ++i) { + if (OB_LIKELY( 0 != name_len_buf[i])) { + part_name.assign_ptr(target_part_name_buf + pos, static_cast(name_len_buf[i])); + MEMCPY(target_part_name_buf + pos, name_buf[i], name_len_buf[i]); + string_to_upper_case(part_name.ptr(), part_name.length()); + part_name_id_map.set_refactored(part_name, part_id_buf[i]); + pos += name_len_buf[i]; + } + } + } + return ret; +} + +int ObProxyPartMgr::build_temp_sub_part_name_id_map(const PART_NAME_BUF * const name_buf, + const int64_t * const name_len_buf, + const int64_t * const part_id_buf, + const int64_t part_num) +{ + int ret = OB_SUCCESS; + all_sub_part_name_length_ = (all_first_part_name_length_ * part_num) //total length of first-part-name + + (all_sub_part_name_length_ * first_part_num_) //total length of sub-part-name + + (part_num * first_part_num_); //total length of 's' + if (OB_ISNULL(name_buf) || OB_ISNULL(name_len_buf) || OB_ISNULL(part_id_buf)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to get part name buf", K(ret)); + } else if (OB_ISNULL(all_sub_part_name_buf_ = (char *)allocator_.alloc(sizeof(char) * all_sub_part_name_length_))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc all first part name buf", K(ret)); + } else { + ObString part_name; + int64_t pos = 0; + int64_t tmp_len = 0; + PartNameIdMap::const_iterator iter = first_part_name_id_map_.begin(); + PartNameIdMap::const_iterator end = first_part_name_id_map_.end(); + for (; OB_SUCC(ret) && iter !=end; iter++) { + for (int64_t i = 0; OB_SUCC(ret) && i < part_num; ++i) { + if (OB_LIKELY(0 != name_len_buf[i])) { + tmp_len = iter->first.length() + 1 + name_len_buf[i];//first part name + 's' + sub part name + if (OB_LIKELY(tmp_len <= MAX_PART_NAME_LENGTH)) { + part_name.assign_ptr(all_sub_part_name_buf_ + pos, static_cast(tmp_len)); + MEMCPY(all_sub_part_name_buf_ + pos, iter->first.ptr(), iter->first.length()); + pos += iter->first.length(); + all_sub_part_name_buf_[pos++] = 'S'; + MEMCPY(all_sub_part_name_buf_ + pos, name_buf[i], name_len_buf[i]); + pos += name_len_buf[i]; + string_to_upper_case(part_name.ptr(), part_name.length()); + sub_part_name_id_map_.set_refactored(part_name, generate_phy_part_id(iter->second, part_id_buf[i])); + } + } + } + } + } + return ret; +} + +int ObProxyPartMgr::alloc_name_buf(PART_NAME_BUF *&name_buf, int64_t *&name_len_buf, int64_t *&part_id_buf, const int64_t part_num) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(name_buf = (PART_NAME_BUF *)allocator_.alloc(sizeof(PART_NAME_BUF) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc name buf", K(ret)); + } else if (OB_ISNULL(name_len_buf = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc name len buf", K(ret)); + } else if (OB_ISNULL(part_id_buf = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc part id buf", K(ret)); + } + + return ret; +} + +void ObProxyPartMgr::free_name_buf(PART_NAME_BUF *name_buf, int64_t *name_len_buf, int64_t *part_id_buf) +{ + if (OB_NOT_NULL(part_id_buf)) { + allocator_.free(part_id_buf); + } + if (OB_NOT_NULL(name_len_buf)) { + allocator_.free(name_len_buf); + } + if (OB_NOT_NULL(name_buf)) { + allocator_.free(name_buf); + } +} + int64_t ObProxyPartMgr::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; diff --git a/src/obproxy/proxy/route/obproxy_part_mgr.h b/src/obproxy/proxy/route/obproxy_part_mgr.h index ff82ae00..f1c8e341 100644 --- a/src/obproxy/proxy/route/obproxy_part_mgr.h +++ b/src/obproxy/proxy/route/obproxy_part_mgr.h @@ -29,67 +29,28 @@ namespace obproxy class ObResultSetFetcher; namespace proxy { - -class ObPartNameIdPair -{ -public: - ObPartNameIdPair() : part_id_(-1), tablet_id_(-1) - { - part_name_buf_[0] = '\0'; - } - ~ObPartNameIdPair() {} - - int set_part_name(const common::ObString &part_name); - void set_part_id(int64_t part_id) { part_id_ = part_id; } - void set_tablet_id(const int64_t tablet_id) { tablet_id_ = tablet_id; } - - const common::ObString get_part_name() const { return part_name_; } - int64_t get_part_id() const { return part_id_; } - int64_t get_tablet_id() const { return tablet_id_; } - - int assign(const ObPartNameIdPair &other); - int64_t to_string(char *buf, const int64_t buf_len) const; -public: - common::ObString part_name_; - int64_t part_id_; - int64_t tablet_id_; - -private: - char part_name_buf_[common::OB_MAX_PARTITION_NAME_LENGTH]; - DISALLOW_COPY_AND_ASSIGN(ObPartNameIdPair); -}; - -inline int ObPartNameIdPair::set_part_name(const common::ObString &part_name) -{ - int ret = common::OB_SUCCESS; - if (part_name.length() > common::OB_MAX_PARTITION_NAME_LENGTH) { - ret = common::OB_INVALID_ARGUMENT; - PROXY_LOG(WARN, "invalid part name", K(part_name), K(ret)); - } else { - MEMCPY(part_name_buf_, part_name.ptr(), part_name.length()); - part_name_.assign_ptr(part_name_buf_, part_name.length()); - } - return ret; -} - -inline int ObPartNameIdPair::assign(const ObPartNameIdPair &other) -{ - int ret = common::OB_SUCCESS; - set_part_id(other.get_part_id()); - set_tablet_id(other.get_tablet_id()); - ret = set_part_name(other.get_part_name()); - return ret; -} +class ObProxyExprCalculator; +class ObServerRoute; class ObProxyPartMgr { +private: + const static int64_t MAX_PART_NAME_LENGTH = common::OB_MAX_PARTITION_NAME_LENGTH;//64 + typedef char PART_NAME_BUF[MAX_PART_NAME_LENGTH]; + typedef hash::ObHashMap PartNameIdMap; public: explicit ObProxyPartMgr(common::ObIAllocator &allocator); ~ObProxyPartMgr() { } - + void destroy(); + int get_part_with_part_name(const common::ObString &part_name, - int64_t &part_id_); - int get_first_part_id_by_idx(const int64_t idx, int64_t &part_id, int64_t &tablet_id); + int64_t &part_id, + ObProxyPartInfo &part_info, + ObServerRoute &route, + ObProxyExprCalculator &expr_calculator); + int get_first_part_id_by_random(const int64_t rand_num, + int64_t &first_part_id, + int64_t &tablet_id); int get_first_part(common::ObNewRange &range, common::ObIAllocator &allocator, common::ObIArray &part_ids, @@ -112,6 +73,7 @@ class ObProxyPartMgr const share::schema::ObPartitionFuncType part_func_type, const int64_t part_num, const int64_t part_space, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher *rs_fetcher, @@ -119,6 +81,7 @@ class ObProxyPartMgr int build_sub_hash_part_with_non_template(const bool is_oracle_mode, const share::schema::ObPartitionFuncType part_func_type, const int64_t part_space, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); @@ -126,34 +89,40 @@ class ObProxyPartMgr const share::schema::ObPartitionFuncType part_func_type, const int64_t part_num, const int64_t part_space, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher *rs_fetcher, const int64_t cluster_version); int build_sub_key_part_with_non_template(const share::schema::ObPartitionFuncType part_func_type, const int64_t part_space, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); int build_range_part(const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_func_type, const int64_t part_num, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); int build_sub_range_part_with_non_template(const share::schema::ObPartitionFuncType part_func_type, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_verison); int build_list_part(const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_func_type, const int64_t part_num, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); int build_sub_list_part_with_non_template(const share::schema::ObPartitionFuncType part_func_type, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); @@ -169,21 +138,57 @@ class ObProxyPartMgr ObPartDesc *&sub_part_desc_ptr, const int64_t cluster_version); + void set_all_sub_part_num(int64_t all_sub_part_num); common::ObObjType get_first_part_type() const; common::ObObjType get_sub_part_type() const; void set_cluster_version(const int64_t cluster_version) { cluster_version_ = cluster_version; } int64_t to_string(char *buf, const int64_t buf_len) const; +private: + int init_first_part_map(); + int init_sub_part_map(); + int alloc_name_buf(PART_NAME_BUF *&name_buf, int64_t *&name_len_buf, int64_t *&part_id_buf, const int64_t part_num); + void free_name_buf(PART_NAME_BUF *name_buf, int64_t *name_len_buf, int64_t *part_id_buf); + int build_part_name_id_map(const PART_NAME_BUF * const name_buf, + const int64_t * const name_len_buf, + const int64_t * const part_id_buf, + char * target_part_name_buf, + const int64_t total_part_name_len, + const int64_t part_num, + PartNameIdMap& part_name_id_map); + int build_temp_sub_part_name_id_map(const PART_NAME_BUF * const name_buf, + const int64_t * const name_len_buf, + const int64_t * const part_id_buf, + const int64_t part_num); private: common::ObPartDesc *first_part_desc_; common::ObPartDesc *sub_part_desc_; // may be we need a array here int64_t first_part_num_; int64_t *sub_part_num_; - ObPartNameIdPair* part_pair_array_; // first part name id pair array + int64_t all_sub_part_num_; + char * all_first_part_name_buf_; // first part name cancatenation string: "p1|p2|···|pn" + char * all_sub_part_name_buf_;// sub part name cancatenation string: "p1sp1|p1sp2|···|pnspn" + int64_t all_first_part_name_length_; + int64_t all_sub_part_name_length_; + PartNameIdMap first_part_name_id_map_; // map K(first part name) to V(first part id) + PartNameIdMap sub_part_name_id_map_; // map K(sub part name) to V(physical part id) common::ObIAllocator &allocator_; int64_t cluster_version_; }; +inline void ObProxyPartMgr::set_all_sub_part_num(int64_t all_sub_part_num) +{ + all_sub_part_num_ = all_sub_part_num; +} +inline int ObProxyPartMgr::init_first_part_map() +{ + return first_part_name_id_map_.create(first_part_num_ * 1, ObModIds::OB_HASH_BUCKET, ObModIds::OB_HASH_NODE);//default load factor = 1.0 +} +inline int ObProxyPartMgr::init_sub_part_map() +{ + return sub_part_name_id_map_.create(all_sub_part_num_ * 1, ObModIds::OB_HASH_BUCKET, ObModIds::OB_HASH_NODE);//default load factor = 1.0 +} + } // namespace proxy } // namespace obproxy } // namespace oceanbase diff --git a/src/obproxy/proxy/shard/obproxy_shard_utils.cpp b/src/obproxy/proxy/shard/obproxy_shard_utils.cpp index 0e7501dc..a6d983cf 100644 --- a/src/obproxy/proxy/shard/obproxy_shard_utils.cpp +++ b/src/obproxy/proxy/shard/obproxy_shard_utils.cpp @@ -94,6 +94,8 @@ int ObProxyShardUtils::check_logic_database(ObMysqlTransact::ObTransState &trans if (OB_SUCC(ret)) { session_info.set_group_id(OBPROXY_MAX_DBMESH_ID); + session_info.set_table_id(OBPROXY_MAX_DBMESH_ID); + session_info.set_es_id(OBPROXY_MAX_DBMESH_ID); session_info.set_logic_database_name(db_name); LOG_DEBUG("check logic database success", K(db_name)); } @@ -128,6 +130,7 @@ int ObProxyShardUtils::change_connector(ObDbConfigLogicDb &logic_db_info, LOG_WARN("not support distributed transaction", K(trans_state.current_.state_), K(trans_state.is_auth_request_), K(trans_state.is_hold_start_trans_), + K(trans_state.is_hold_xa_start_), KPC(prev_shard_conn), KPC(shard_conn), K(ret)); } else { @@ -231,27 +234,26 @@ void ObProxyShardUtils::replace_oracle_table(ObSqlString &new_sql, const ObStrin hava_quoto = false; } -int ObProxyShardUtils::do_rewrite_shard_select_request(const ObString &sql, - ObSqlParseResult &parse_result, - bool is_oracle_mode, - const ObHashMap &table_name_map, - const ObString &real_database_name, - bool is_single_shard_db_table, - ObSqlString &new_sql) +int ObProxyShardUtils::rewrite_shard_dml_request(const ObString &sql, + ObSqlString &new_sql, + ObSqlParseResult &parse_result, + bool is_oracle_mode, + const ObHashMap &table_name_map, + const ObString &real_database_name, + bool is_single_shard_db_table) { int ret = OB_SUCCESS; - const uint32_t PARSE_EXTRA_CHAR_NUM = 2; const char *sql_ptr = sql.ptr(); int64_t sql_len = sql.length(); int64_t copy_pos = 0; - ObProxySelectStmt *select_stmt = static_cast(parse_result.get_proxy_stmt()); - if (OB_ISNULL(select_stmt)) { + ObProxyDMLStmt *dml_stmt = static_cast(parse_result.get_proxy_stmt()); + if (OB_ISNULL(dml_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null select stmt", K(ret)); } else { - ObProxySelectStmt::TablePosArray &table_pos_array = select_stmt->get_table_pos_array(); + ObProxyDMLStmt::TablePosArray &table_pos_array = dml_stmt->get_table_pos_array(); std::sort(table_pos_array.begin(), table_pos_array.end()); for (int64_t i = 0; OB_SUCC(ret) && i < table_pos_array.count(); i++) { @@ -284,48 +286,12 @@ int ObProxyShardUtils::do_rewrite_shard_select_request(const ObString &sql, if (OB_SUCC(ret)) { - new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos - PARSE_EXTRA_CHAR_NUM); + new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos); } return ret; } -int ObProxyShardUtils::rewrite_shard_select_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, - const ObHashMap &table_name_map, - const ObString &real_database_name, - bool is_single_shard_db_table) -{ - int ret = OB_SUCCESS; - - ObSqlParseResult &parse_result = client_request.get_parse_result(); - ObSqlString new_sql; - - if (OB_FAIL(do_rewrite_shard_select_request(client_request.get_parse_sql(), parse_result, - session_info.is_oracle_mode(), table_name_map, - real_database_name, is_single_shard_db_table, - new_sql))) { - } else { - // 4. push reader forward by consuming old buffer and write new sql into buffer - if (OB_FAIL(client_buffer_reader.consume_all())) { - LOG_WARN("fail to consume all", K(ret)); - } else { - ObMIOBuffer *writer = client_buffer_reader.mbuf_; - if (OB_ISNULL(writer)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null values ", K(writer), K(ret)); - // no need compress here, if server session support compress, it will compress later - } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, new_sql.string(), false, false))) { - LOG_WARN("fail to build_mysql_request", K(new_sql), K(ret)); - } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(session_info, client_request, client_buffer_reader))) { - LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); - } - } - } - - return ret; -} int ObProxyShardUtils::rewrite_shard_request_db(const char *sql_ptr, int64_t database_pos, int64_t table_pos, uint64_t database_len, @@ -373,6 +339,35 @@ int ObProxyShardUtils::rewrite_shard_request_db(const char *sql_ptr, int64_t dat return ret; } +int ObProxyShardUtils::rewrite_shard_request_table_no_db(const char *sql_ptr, + int64_t table_pos, uint64_t table_len, + const ObString &real_table_name, + bool is_oracle_mode, bool is_single_shard_db_table, + ObSqlString &new_sql, int64_t ©_pos) +{ + int ret = OB_SUCCESS; + + bool table_have_quoto = false; + + if (*(sql_ptr + table_pos - 1) == '`' || *(sql_ptr + table_pos - 1) == '"') { + table_have_quoto = true; + table_pos -= 1; + table_len += 2; + } + + new_sql.append(sql_ptr + copy_pos, table_pos - copy_pos); + if (is_oracle_mode) { + replace_oracle_table(new_sql, real_table_name, table_have_quoto, is_single_shard_db_table, false); + } else { + new_sql.append(real_table_name); + } + + copy_pos = table_pos + table_len; + + return ret; +} + + int ObProxyShardUtils::rewrite_shard_request_table(const char *sql_ptr, int64_t database_pos, uint64_t database_len, int64_t table_pos, uint64_t table_len, @@ -444,24 +439,22 @@ int ObProxyShardUtils::rewrite_shard_request_hint_table(const char *sql_ptr, int // if no quoto, not add quoto // if sharding mode, table from config, both add quoto int ObProxyShardUtils::rewrite_shard_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, + ObSqlParseResult &parse_result, const ObString &table_name, const ObString &database_name, const ObString &real_table_name, const ObString &real_database_name, - bool is_single_shard_db_table) + bool is_single_shard_db_table, + const ObString& sql, + ObSqlString& new_sql) { int ret = OB_SUCCESS; - const uint32_t PARSE_EXTRA_CHAR_NUM = 2; uint64_t table_len = table_name.length(); uint64_t database_len = database_name.length(); uint64_t index_table_len = table_name.length(); - int64_t table_pos = client_request.get_parse_result().get_dbmesh_route_info().tb_pos_; - int64_t database_pos = client_request.get_parse_result().get_dbmesh_route_info().db_pos_; - int64_t index_table_pos = client_request.get_parse_result().get_dbmesh_route_info().index_tb_pos_; + int64_t table_pos = parse_result.get_dbmesh_route_info().tb_pos_; + int64_t database_pos = parse_result.get_dbmesh_route_info().db_pos_; + int64_t index_table_pos = parse_result.get_dbmesh_route_info().index_tb_pos_; - ObString sql = client_request.get_parse_sql(); - common::ObSqlString new_sql; const char *sql_ptr = sql.ptr(); int64_t sql_len = sql.length(); @@ -493,23 +486,8 @@ int ObProxyShardUtils::rewrite_shard_request(ObClientSessionInfo &session_info, } if (OB_SUCC(ret)) { - new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos - PARSE_EXTRA_CHAR_NUM); - - // 4. push reader forward by consuming old buffer and write new sql into buffer - if (OB_FAIL(client_buffer_reader.consume_all())) { - LOG_WARN("fail to consume all", K(ret)); - } else { - ObMIOBuffer *writer = client_buffer_reader.mbuf_; - if (OB_ISNULL(writer)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null values ", K(writer), K(ret)); - // no need compress here, if server session support compress, it will compress later - } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, new_sql.string(), false, false))) { - LOG_WARN("fail to build_mysql_request", K(new_sql), K(ret)); - } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(session_info, client_request, client_buffer_reader))) { - LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); - } - } + new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos); + LOG_DEBUG("succ to rewrite sql", K(sql), K(new_sql)); } return ret; @@ -729,25 +707,21 @@ int ObProxyShardUtils::testload_check_and_rewrite_testload_hint_index(common::Ob * Args: * @param session_info : client session info * @param client_request : client request - * @param client_buffer_reader : buffer to rewrite request * @param is_single_shard_db_table: * @param real_database_name : real database name in Server * @param logic_db_info : config info for database * */ -int ObProxyShardUtils::testload_check_and_rewrite_testload_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, +int ObProxyShardUtils::testload_check_and_rewrite_testload_request(ObSqlParseResult &parse_result, bool is_single_shard_db_table, const ObString &hint_table, const ObString &real_database_name, - ObDbConfigLogicDb &logic_db_info) + ObDbConfigLogicDb &logic_db_info, + const ObString& sql, + common::ObSqlString& new_sql) { int ret = OB_SUCCESS; UNUSED(is_single_shard_db_table); - ObSqlParseResult &parse_result = client_request.get_parse_result(); - ObString sql = client_request.get_sql(); - common::ObSqlString new_sql; //init by default const char *sql_ptr = sql.ptr(); int64_t sql_len = sql.length(); ObArenaAllocator allocator; @@ -878,30 +852,13 @@ int ObProxyShardUtils::testload_check_and_rewrite_testload_request(ObClientSessi } } LOG_DEBUG("ObProxyShardUtils::check_and_rewrite_testload_request all", K(ret), K(new_sql)); - //rewrite sql base on new_sql - if (OB_SUCC(ret)) { - if (OB_FAIL(client_buffer_reader.consume_all())) { - LOG_WARN("fail to consume all", K(ret)); - } else { - ObMIOBuffer *writer = client_buffer_reader.mbuf_; - if (OB_ISNULL(writer)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null values ", K(writer), K(ret)); - // no need compress here, if server session support compress, it will compress later - } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, new_sql.string(), false, false))) { - LOG_WARN("fail to build_mysql_request", K(new_sql), K(ret)); - } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(session_info, client_request, client_buffer_reader))) { - LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); - } - } - } -//*/ + return ret; } -bool ObProxyShardUtils::is_special_db(ObMysqlTransact::ObTransState &s) +bool ObProxyShardUtils::is_special_db(obutils::ObSqlParseResult& parse_result) { - const ObString &database_name = s.trans_info_.client_request_.get_parse_result().get_origin_database_name(); + const ObString &database_name = parse_result.get_origin_database_name(); if (!database_name.empty() && 0 == database_name.case_compare("information_schema")) { return true; } @@ -984,19 +941,73 @@ int ObProxyShardUtils::check_shard_request(ObMysqlClientSession &client_session, return ret; } -int ObProxyShardUtils::get_shard_hint(ObDbConfigLogicDb &logic_db_info, +int ObProxyShardUtils::get_shard_hint(const ObString &table_name, + ObClientSessionInfo &session_info, + ObDbConfigLogicDb &logic_db_info, ObSqlParseResult &parse_result, int64_t &group_index, int64_t &tb_index, - int64_t &es_index, ObString &table_name, + int64_t &es_index, ObString &hint_table_name, ObTestLoadType &testload_type) { int ret = OB_SUCCESS; + + bool is_sticky_session = false; + + if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + group_index, tb_index, es_index, + hint_table_name, testload_type, + is_sticky_session))) { + LOG_WARN("fail to get shard hint", K(ret)); + } else if (is_sticky_session) { + group_index = session_info.get_group_id(); + tb_index = session_info.get_table_id(); + es_index = session_info.get_es_id(); + + if (group_index == OBPROXY_MAX_DBMESH_ID) { + group_index = 0; + } + + if (tb_index == OBPROXY_MAX_DBMESH_ID) { + tb_index = 0; + } + + if (es_index == OBPROXY_MAX_DBMESH_ID) { + es_index = 0; + } + + if (tb_index == 0 && group_index > 0) { + tb_index = group_index; + } + } + + if (OB_SUCC(ret) && !logic_db_info.is_single_shard_db_table()) { + ObShardRule *logic_tb_info = NULL; + if (OB_FAIL(logic_db_info.get_shard_rule(logic_tb_info, table_name))) { + LOG_WARN("fail to get shard rule", K(table_name), K(ret)); + } else if (group_index != OBPROXY_MAX_DBMESH_ID && group_index >= logic_tb_info->db_size_) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("sql with group hint and greater than db size", + "db_size", logic_tb_info->db_size_, K(group_index), K(ret)); + } + } + + return ret; +} + +int ObProxyShardUtils::get_shard_hint(ObDbConfigLogicDb &logic_db_info, + ObSqlParseResult &parse_result, + int64_t &group_index, int64_t &tb_index, + int64_t &es_index, ObString &hint_table_name, + ObTestLoadType &testload_type, + bool &is_sticky_session) +{ + int ret = OB_SUCCESS; DbMeshRouteInfo &odp_route_info = parse_result.get_dbmesh_route_info(); DbpRouteInfo &dbp_route_info = parse_result.get_dbp_route_info(); if (odp_route_info.is_valid()) { group_index = parse_result.get_dbmesh_route_info().group_idx_; - table_name = parse_result.get_dbmesh_route_info().table_name_; - if (table_name.empty()) { + hint_table_name = parse_result.get_dbmesh_route_info().table_name_; + if (hint_table_name.empty()) { tb_index = parse_result.get_dbmesh_route_info().tb_idx_; } es_index = parse_result.get_dbmesh_route_info().es_idx_; @@ -1011,7 +1022,9 @@ int ObProxyShardUtils::get_shard_hint(ObDbConfigLogicDb &logic_db_info, } else if (dbp_route_info.is_valid()) { if (parse_result.get_dbp_route_info().is_group_info_valid()) { group_index = dbp_route_info.group_idx_; - table_name = dbp_route_info.table_name_; + hint_table_name = dbp_route_info.table_name_; + } else if (parse_result.get_dbp_route_info().sticky_session_) { + is_sticky_session = true; } } return ret; @@ -1031,6 +1044,172 @@ bool ObProxyShardUtils::is_read_stmt(ObClientSessionInfo &session_info, ObMysqlT || parse_result.has_explain())); } +bool ObProxyShardUtils::is_unsupport_type_in_multi_stmt(ObSqlParseResult& parse_result) +{ + return parse_result.is_shard_special_cmd() + || ObProxyShardUtils::is_special_db(parse_result) + || parse_result.is_ddl_stmt() + || parse_result.is_multi_stmt() + || parse_result.is_show_tables_stmt() + || parse_result.is_show_full_tables_stmt() + || parse_result.is_show_table_status_stmt(); +} + +int ObProxyShardUtils::handle_information_schema_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObIOBufferReader &client_buffer_reader) +{ + int ret = OB_SUCCESS; + + ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; + ObSqlParseResult &parse_result = client_request.get_parse_result(); + SqlFieldResult& sql_result = parse_result.get_sql_filed_result(); + ObProxySqlParser sql_parser; + ObString sql = client_request.get_parse_sql(); + ObProxyDMLStmt *dml_stmt = NULL; + if (OB_FAIL(sql_parser.parse_sql_by_obparser(sql, NORMAL_PARSE_MODE, parse_result, true))) { + LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); + } else if (OB_ISNULL(dml_stmt = dynamic_cast(parse_result.get_proxy_stmt()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dml stmt is null, unexpected", K(ret)); + } else { + ObClientSessionInfo &cs_info = client_session.get_session_info(); + ObDbConfigLogicDb *logic_db_info = NULL; + ObShardConnector *shard_conn = NULL; + bool is_rewrite_sql = false; + bool is_single_shard_db_table = false; + + common::ObSqlString new_sql; + const char *sql_ptr = sql.ptr(); + int64_t sql_len = sql.length(); + int64_t copy_pos = 0; + + ObString last_database_name; + char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; + char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; + + ObProxyDMLStmt::DbTablePosArray &db_table_pos_array = dml_stmt->get_db_table_pos_array(); + std::sort(db_table_pos_array.begin(), db_table_pos_array.end()); + + for (int64_t i = 0; OB_SUCC(ret) && i < db_table_pos_array.count(); i++) { + ObProxyDbTablePos &db_table_pos = db_table_pos_array.at(i); + if (SHARDING_POS_DB == db_table_pos.get_type()) { + const ObString &database_name = db_table_pos.get_name(); + + if (last_database_name.empty()) { + last_database_name = database_name; + } else if (0 != last_database_name.case_compare(database_name)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("do not support two schema", K(database_name), K(last_database_name), K(ret)); + } + + if (OB_SUCC(ret) && NULL == shard_conn) { + ObShardConnector *prev_shard_conn = cs_info.get_shard_connector(); + ObString logic_tenant_name; + ObDbConfigCache &dbconfig_cache = get_global_dbconfig_cache(); + if (OB_ISNULL(prev_shard_conn)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("prev shard connector info is null", K(ret)); + } else if (OB_FAIL(cs_info.get_logic_tenant_name(logic_tenant_name))) { + ret = OB_ERR_UNEXPECTED; // no need response, just return ret and disconnect + LOG_ERROR("fail to get logic tenant name", K(ret)); + } else if (OB_ISNULL(logic_db_info = dbconfig_cache.get_exist_db_info(logic_tenant_name, database_name))) { + ret = OB_ERR_BAD_DATABASE; + LOG_WARN("database not exist", K(logic_tenant_name), K(database_name)); + } else if (OB_FAIL(logic_db_info->get_first_group_shard_connector(shard_conn, OBPROXY_MAX_DBMESH_ID, false, TESTLOAD_NON))) { + LOG_WARN("fail to get random shard connector", K(ret), KPC(logic_db_info)); + } else if (*prev_shard_conn != *shard_conn) { + if (OB_FAIL(change_connector(*logic_db_info, client_session, trans_state, prev_shard_conn, shard_conn))) { + LOG_WARN("fail to change connector", KPC(prev_shard_conn), KPC(shard_conn), K(ret)); + } + } + + if (OB_SUCC(ret)) { + snprintf(real_database_name, OB_MAX_DATABASE_NAME_LENGTH, "%.*s", + shard_conn->database_name_.length(), shard_conn->database_name_.ptr()); + is_single_shard_db_table = logic_db_info->is_single_shard_db_table(); + } + } + } + } + + if (OB_SUCC(ret) && last_database_name.empty()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("do not support zero schema", K(ret)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < db_table_pos_array.count(); i++) { + ObProxyDbTablePos &db_table_pos = db_table_pos_array.at(i); + if (SHARDING_POS_DB == db_table_pos.get_type()) { + const ObString &database_name = db_table_pos.get_name(); + int32_t database_pos = db_table_pos.get_pos(); + if (OB_FAIL(rewrite_shard_request_db(sql_ptr, database_pos, 0, database_name.length(), + real_database_name, cs_info.is_oracle_mode(), + is_single_shard_db_table, new_sql, copy_pos))) { + LOG_WARN("fail to rewrite db", K(ret)); + } else { + is_rewrite_sql = true; + } + } else if (!is_single_shard_db_table && SHARDING_POS_TABLE == db_table_pos.get_type()) { + int32_t table_pos = db_table_pos.get_pos(); + const ObString &table_name = db_table_pos.get_name(); + int64_t tb_index = 0; + ObTestLoadType testload_type = TESTLOAD_NON; + ObString hint_table; + if (OB_FAIL(logic_db_info->get_real_table_name(table_name, sql_result, + real_table_name, OB_MAX_TABLE_NAME_LENGTH, + tb_index, hint_table, testload_type))) { + if (OB_ENTRY_NOT_EXIST == ret) { + // If the table does not exist, ignore the table name + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get real table name", K(table_name), K(tb_index), K(testload_type), K(ret)); + } + } else if (OB_FAIL(rewrite_shard_request_table_no_db(sql_ptr, table_pos, table_name.length(), real_table_name, + cs_info.is_oracle_mode(), is_single_shard_db_table, + new_sql, copy_pos))) { + LOG_WARN("fail to rewrite table", K(ret)); + } else { + is_rewrite_sql = true; + } + } + } + + if (OB_SUCC(ret) && is_rewrite_sql) { + const uint32_t PARSE_EXTRA_CHAR_NUM = 2; + new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos - PARSE_EXTRA_CHAR_NUM); + + // 4. push reader forward by consuming old buffer and write new sql into buffer + if (OB_FAIL(client_buffer_reader.consume_all())) { + LOG_WARN("fail to consume all", K(ret)); + } else { + ObMIOBuffer *writer = client_buffer_reader.mbuf_; + if (OB_ISNULL(writer)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null values ", K(writer), K(ret)); + // no need compress here, if server session support compress, it will compress later + } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, new_sql.string(), false, false))) { + LOG_WARN("fail to build_mysql_request", K(new_sql), K(ret)); + } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(cs_info, client_request, client_buffer_reader))) { + LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); + } + } + } + + if (NULL != shard_conn) { + shard_conn->dec_ref(); + shard_conn = NULL; + } + + if (NULL != logic_db_info) { + logic_db_info->dec_ref(); + logic_db_info = NULL; + } + } + + return ret; +} + /* * if no table name * use last shard connector @@ -1049,8 +1228,13 @@ bool ObProxyShardUtils::is_read_stmt(ObClientSessionInfo &session_info, ObMysqlT */ int ObProxyShardUtils::do_handle_single_shard_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - ObDbConfigLogicDb &logic_db_info) + ObDbConfigLogicDb &logic_db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index) { int ret = OB_SUCCESS; @@ -1060,30 +1244,19 @@ int ObProxyShardUtils::do_handle_single_shard_request(ObMysqlClientSession &clie ObShardConnector *shard_conn = NULL; ObShardConnector *prev_shard_conn = session_info.get_shard_connector(); - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); - ObString table_name = client_request.get_parse_result().get_origin_table_name(); - int64_t group_index = OBPROXY_MAX_DBMESH_ID; + ObString table_name = parse_result.get_origin_table_name(); + es_index = OBPROXY_MAX_DBMESH_ID; + group_index = OBPROXY_MAX_DBMESH_ID; int64_t tb_index = OBPROXY_MAX_DBMESH_ID; - int64_t es_index = OBPROXY_MAX_DBMESH_ID; ObTestLoadType testload_type = TESTLOAD_NON; ObString hint_table; bool is_need_rewrite_sql = false; bool is_skip_rewrite_check = false; - bool is_need_skip_router = false; + bool is_sticky_session = false; if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, - group_index, tb_index, es_index, hint_table, testload_type))) { + group_index, tb_index, es_index, hint_table, testload_type, is_sticky_session))) { LOG_WARN("fail to get shard hint", K(ret)); } else { - // some case can skip route: - // 1. if specify group_index, tb_index, es_index - // 2. if in trans, use last shard connector - // 3. special sql, use last shard connector - is_need_skip_router = (!(OBPROXY_MAX_DBMESH_ID != es_index && 0 != es_index) - && ((is_sharding_in_trans(session_info, trans_state)) - || parse_result.is_show_stmt() - || (parse_result.is_select_stmt() && parse_result.has_last_insert_id()))); - // some case can skip rewrite check: // 1. if sql have table name, can not skip // 2. if sql have no table name @@ -1101,7 +1274,7 @@ int ObProxyShardUtils::do_handle_single_shard_request(ObMysqlClientSession &clie // 1. sql have db // 2. have testload flag // 3. specify table in hint - is_need_rewrite_sql = (!is_skip_rewrite_check) && (!client_request.get_parse_result().get_origin_database_name().empty() + is_need_rewrite_sql = (!is_skip_rewrite_check) && (!parse_result.get_origin_database_name().empty() || TESTLOAD_NON != testload_type || !hint_table.empty()); @@ -1111,159 +1284,328 @@ int ObProxyShardUtils::do_handle_single_shard_request(ObMysqlClientSession &clie || (is_need_rewrite_sql && table_name.empty())) { ret = OB_NOT_SUPPORTED; LOG_WARN("sql with dbmesh route hint and no table name is unsupported", K(tb_index), K(group_index), K(is_need_rewrite_sql), K(ret)); - } + } } if (OB_SUCC(ret)) { char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; - if (!is_need_skip_router) { - bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); + // The write request takes the write weight, and the request in the transaction is considered to be write + // Read Request Walk Weight + bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); - if (OB_FAIL(logic_db_info.get_single_table_info(table_name, shard_conn, - real_database_name, OB_MAX_DATABASE_NAME_LENGTH, - real_table_name, OB_MAX_TABLE_NAME_LENGTH, - group_index, tb_index, es_index, - hint_table, testload_type, is_read_stmt))) { - LOG_WARN("shard tpo info is null", K(ret)); - } else if (OB_ISNULL(shard_conn) || OB_ISNULL(prev_shard_conn)) { - ret = OB_EXPR_CALC_ERROR; - LOG_WARN("shard connector info or prev shard connector info is null", KP(shard_conn), - KP(prev_shard_conn), K(ret)); - } else if (*prev_shard_conn != *shard_conn) { - if (OB_FAIL(change_connector(logic_db_info, client_session, trans_state, prev_shard_conn, shard_conn))) { - LOG_WARN("fail to change connector", KPC(prev_shard_conn), KPC(shard_conn), K(ret)); - } - } - if (OB_NOT_NULL(shard_conn)) { - shard_conn->dec_ref(); - shard_conn = NULL; - } - } else { // is_need_skip_router == true, write new table_name and database_name - if (OB_NOT_NULL(prev_shard_conn) && OB_FAIL(logic_db_info.get_single_real_table_info(table_name, *prev_shard_conn, - real_database_name, OB_MAX_DATABASE_NAME_LENGTH, - real_table_name, OB_MAX_TABLE_NAME_LENGTH, - hint_table))) { - LOG_WARN("fail to get real table info", K(table_name), K(ret)); - } else if (OB_ISNULL(prev_shard_conn)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("shard previous connection info is null to use", K(is_need_skip_router), K(ret)); + if (OB_FAIL(logic_db_info.get_single_table_info(table_name, shard_conn, + real_database_name, OB_MAX_DATABASE_NAME_LENGTH, + real_table_name, OB_MAX_TABLE_NAME_LENGTH, + group_index, tb_index, es_index, + hint_table, testload_type, is_read_stmt, last_es_index))) { + LOG_WARN("shard tpo info is null", K(ret)); + } else if (OB_ISNULL(shard_conn) || OB_ISNULL(prev_shard_conn)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("shard connector info or prev shard connector info is null", KP(shard_conn), + KP(prev_shard_conn), K(ret)); + } else if (*prev_shard_conn != *shard_conn) { + if (OB_FAIL(change_connector(logic_db_info, client_session, trans_state, prev_shard_conn, shard_conn))) { + LOG_WARN("fail to change connector", KPC(prev_shard_conn), KPC(shard_conn), K(ret)); } } + if (OB_NOT_NULL(shard_conn)) { + shard_conn->dec_ref(); + shard_conn = NULL; + } - if (!is_skip_rewrite_check) { - LOG_DEBUG("check_and_rewrite_testload_request", K(testload_type), K(ret)); - if (OB_SUCC(ret) && TESTLOAD_ALIPAY_COMPATIBLE == testload_type && hint_table.empty()) { /* testload = 8 */ - ret = OB_ERR_TESTLOAD_ALIPAY_COMPATIBLE; - LOG_WARN("not have table_name's hint for 'testload=8' (TESTLOAD_ALIPAY_COMPATIBLE)", K(ret)); - } else if (OB_SUCC(ret) && TESTLOAD_NON != testload_type) { //rewrite table name for testload - ObProxySqlParser sql_parser; - ObSqlParseResult &sql_parse_result = client_request.get_parse_result(); - ObString sql = client_request.get_parse_sql(); - if (OB_FAIL(sql_parser.parse_sql_by_obparser(sql, NORMAL_PARSE_MODE, sql_parse_result, false))) { - LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); - } else if (OB_FAIL(testload_check_and_rewrite_testload_request(session_info, client_request, client_buffer_reader, - false, hint_table, ObString::make_string(real_database_name), logic_db_info))) { - LOG_WARN("fail to check and rewrite testload request"); + if (OB_SUCC(ret)) { + if (!is_skip_rewrite_check) { + if (TESTLOAD_ALIPAY_COMPATIBLE == testload_type && hint_table.empty()) { /* testload = 8 */ + ret = OB_ERR_TESTLOAD_ALIPAY_COMPATIBLE; + LOG_WARN("not have table_name's hint for 'testload=8' (TESTLOAD_ALIPAY_COMPATIBLE)", K(ret)); + } else if (TESTLOAD_NON != testload_type) { //rewrite table name for testload + LOG_DEBUG("check_and_rewrite_testload_request", K(testload_type), K(ret)); + ObProxySqlParser sql_parser; + if (OB_FAIL(sql_parser.parse_sql_by_obparser(ObProxyMysqlRequest::get_parse_sql(sql), + NORMAL_PARSE_MODE, parse_result, false))) { + LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); + } else if (OB_FAIL(testload_check_and_rewrite_testload_request(parse_result, false, hint_table, + ObString::make_string(real_database_name), + logic_db_info, sql, new_sql))) { + LOG_WARN("fail to check and rewrite testload request"); + } + } else if (is_need_rewrite_sql) { + if (OB_FAIL(rewrite_shard_request(session_info, parse_result, table_name, + logic_db_info.db_name_.config_string_, ObString::make_string(real_table_name), + ObString::make_string(real_database_name), true, sql, new_sql))) { + LOG_WARN("fail to rewrite shard request", K(ret), K(table_name), + K(logic_db_info.db_name_), K(real_table_name), K(real_database_name)); + } } else { - is_need_rewrite_sql = false; - LOG_DEBUG("check and rewrite testload data"); - } - } - - if (OB_SUCC(ret) && is_need_rewrite_sql) { - if (OB_FAIL(rewrite_shard_request(session_info, client_request, client_buffer_reader, - table_name, logic_db_info.db_name_.config_string_, ObString::make_string(real_table_name), - ObString::make_string(real_database_name), true))) { - LOG_WARN("fail to rewrite shard request", K(ret), K(table_name), - K(logic_db_info.db_name_), K(real_table_name), K(real_database_name)); + //no need to rewrite sql, just append to new sql; + ret = new_sql.append(sql); + LOG_DEBUG("not need to rewrite sql by rules", K(real_database_name), K(real_table_name)); } + } else { + //no need to rewrite sql, just append to new sql; + ret = new_sql.append(sql); + LOG_DEBUG("not need to rewrite sql by rules", K(real_database_name), K(real_table_name)); } - } else { - LOG_DEBUG("not need to rewrite sql by rules", K(real_database_name), K(real_table_name)); - } + } } - return ret; } -int ObProxyShardUtils::handle_single_shard_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, +int ObProxyShardUtils::handle_single_shard_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, ObIOBufferReader &client_buffer_reader, - ObDbConfigLogicDb &logic_db_info, - bool &need_wait_callback) + ObDbConfigLogicDb &logic_db_info) { int ret = OB_SUCCESS; + ObClientSessionInfo &session_info = client_session.get_session_info(); ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); - const ObString runtime_env = get_global_proxy_config().runtime_env.str(); - if (parse_result.is_ddl_stmt() && 0 == runtime_env.case_compare(OB_PROXY_DBP_RUNTIME_ENV)) { - if (OB_FAIL(handle_ddl_request(sm, client_session, trans_state, logic_db_info, need_wait_callback))) { - LOG_WARN("fail to handle ddl request", K(ret)); + ObSqlParseResult &origin_parse_result = client_request.get_parse_result(); + ObString origin_sql = client_request.get_sql();//should not use get_parse_sql() + ObSqlString new_sql; + ObSEArray sql_array; + ObArenaAllocator &allocator = origin_parse_result.allocator_; + char * multi_sql_buf = NULL; + int64_t es_index = OBPROXY_MAX_DBMESH_ID; + int64_t group_index = OBPROXY_MAX_DBMESH_ID; + int64_t last_es_index = OBPROXY_MAX_DBMESH_ID; + int64_t last_group_index = OBPROXY_MAX_DBMESH_ID; + if (OB_FAIL(ObProxySqlParser::split_multiple_stmt(origin_sql, sql_array))) { + LOG_WARN("fail to split sql", K(ret)); + } else if (OB_UNLIKELY(sql_array.count() <= 0)){ + ret = OB_ERR_PARSER_SYNTAX; + LOG_WARN("fail to split sql and the sql num is wrong", K(ret)); + } else if (OB_UNLIKELY((sql_array.count() > 1) + && OB_FAIL(ObProxySqlParser::preprocess_multi_stmt(allocator, + multi_sql_buf, + origin_sql.length(), + sql_array)))) { + LOG_WARN("fail to preprocess multi stmt", K(ret)); + } else { + bool is_multi_stmt = sql_array.count() > 1; + ObSqlParseResult parse_result; + ObSqlParseResult* real_parse_result = NULL; + ObProxySqlParser sql_parser; + for (int64_t i = 0; OB_SUCC(ret) && i < sql_array.count(); ++i) { + const ObString& sql = sql_array.at(i); + if (0 == i) { + real_parse_result = &origin_parse_result; + } else if (OB_FAIL(sql_parser.parse_sql(ObProxyMysqlRequest::get_parse_sql(sql), + NORMAL_PARSE_MODE/*parse_mode*/, parse_result, + false/*use_lower_case_name*/, + static_cast(client_session.get_session_info().get_collation_connection()), + false/*drop_origin_db_table_name*/, + true /*is sharding user*/))) { + LOG_WARN("fail to handle single shard request for single sql", K(ret), K(sql)); + } else { + real_parse_result = &parse_result; + } + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(real_parse_result->is_invalid_stmt() && real_parse_result->has_shard_comment())) { + ret = OB_ERR_PARSER_SYNTAX; + LOG_WARN("fail to parse shard sql with shard comment","sql", client_request.get_sql(), K(ret)); + } else if (OB_UNLIKELY(is_multi_stmt && ObProxyShardUtils::is_unsupport_type_in_multi_stmt(*real_parse_result))) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("unsupport type in multi stmt", K(ret), K(sql)); + } else if (OB_FAIL(do_handle_single_shard_request(client_session, trans_state, logic_db_info, sql, new_sql, + *real_parse_result, es_index, group_index, last_es_index))) { + LOG_WARN("fail to handle single shard request for single sql", K(ret), K(sql), K(new_sql)); + } else if (OB_UNLIKELY((i > 0) && ((es_index != last_es_index) || (group_index != last_group_index)))) { + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + LOG_WARN("different elastic index or group index for multi stmt is not supported", K(es_index), K(last_es_index), K(group_index), + K(last_group_index), K(sql), K(new_sql), K(ret)); + } else { + last_es_index = es_index; + last_group_index = group_index; + if (i > 0) { + real_parse_result->reset(); + } + } + } + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(build_shard_request_packet(session_info, client_request, client_buffer_reader, new_sql.string()))) { + LOG_WARN("fail to build sharding request packet", K(ret)); } - } else if (OB_FAIL(do_handle_single_shard_request(client_session, trans_state, - client_buffer_reader, logic_db_info))) { - LOG_WARN("fail to handle single shard request", K(ret)); + } + + if(NULL != multi_sql_buf) { + allocator.free(multi_sql_buf); } return ret; } -int ObProxyShardUtils::handle_shard_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - ObDbConfigLogicDb &db_info, - bool &need_wait_callback) +int ObProxyShardUtils::handle_shard_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObIOBufferReader &client_buffer_reader, + ObDbConfigLogicDb &logic_db_info) { int ret = OB_SUCCESS; + ObClientSessionInfo &session_info = client_session.get_session_info(); session_info.set_enable_reset_db(false); ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); - ObString table_name = client_request.get_parse_result().get_origin_table_name(); - if (parse_result.is_ddl_stmt()) { - const ObString runtime_env = get_global_proxy_config().runtime_env.str(); - if (0 == runtime_env.case_compare(OB_PROXY_DBP_RUNTIME_ENV)) { - if (OB_FAIL(handle_ddl_request(sm, client_session, trans_state, db_info, need_wait_callback))) { - LOG_WARN("fail to handle ddl request", K(ret)); + ObSqlParseResult &origin_parse_result = client_request.get_parse_result(); + ObString first_table_name = origin_parse_result.get_origin_table_name(); + ObString origin_sql = client_request.get_sql();//should not use get_parse_sql() + ObSqlString new_sql; + ObSEArray sql_array; + ObArenaAllocator &allocator = origin_parse_result.allocator_; + char * multi_sql_buf = NULL; + int64_t es_index = OBPROXY_MAX_DBMESH_ID; + int64_t group_index = OBPROXY_MAX_DBMESH_ID; + int64_t last_es_index = OBPROXY_MAX_DBMESH_ID; + int64_t last_group_index = OBPROXY_MAX_DBMESH_ID; + bool is_scan_all = false; + + if (OB_FAIL(ObProxySqlParser::split_multiple_stmt(origin_sql, sql_array))) { + LOG_WARN("fail to split sql", K(ret)); + } else if (OB_UNLIKELY(sql_array.count() <= 0)){ + ret = OB_ERR_PARSER_SYNTAX; + LOG_WARN("fail to split sql and the sql num is wrong", K(ret)); + } else if (OB_UNLIKELY((sql_array.count() > 1) + && OB_FAIL(ObProxySqlParser::preprocess_multi_stmt(allocator, + multi_sql_buf, + origin_sql.length(), + sql_array)))) { + LOG_WARN("fail to preprocess multi stmt", K(ret)); + } else { + bool is_multi_stmt = sql_array.count() > 1; + ObSqlParseResult parse_result; + ObSqlParseResult* real_parse_result = NULL; + ObProxySqlParser sql_parser; + for (int64_t i = 0; OB_SUCC(ret) && i < sql_array.count(); ++i) { + const ObString& sql = sql_array.at(i); + if (0 == i) { + real_parse_result = &origin_parse_result; + } else if (OB_FAIL(sql_parser.parse_sql(ObProxyMysqlRequest::get_parse_sql(sql), + NORMAL_PARSE_MODE/*parse_mode*/, parse_result, + false/*use_lower_case_name*/, + static_cast(client_session.get_session_info().get_collation_connection()), + false/*drop_origin_db_table_name*/, + true /*is sharding user*/))) { + LOG_WARN("fail to handle single shard request for single sql", K(ret), K(sql)); + } else { + real_parse_result = &parse_result; } - } else { - ret = OB_NOT_SUPPORTED; - LOG_WARN("ddl stmt is unsupported for sharding table", K(ret)); - } - } else if (parse_result.is_show_tables_stmt() - || parse_result.is_show_full_tables_stmt() - || parse_result.is_show_table_status_stmt() - || (table_name.empty() && !parse_result.is_dml_stmt())) { - //do nothing - } else if (table_name.empty()) { - // keep compatible, skip - } else if (parse_result.is_multi_stmt()) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("multi stmt is unsupported for sharding table", "stmt type", parse_result.get_stmt_type(), K(ret)); + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(real_parse_result->is_invalid_stmt() && real_parse_result->has_shard_comment())) { + ret = OB_ERR_PARSER_SYNTAX; + LOG_WARN("fail to parse shard sql with shard comment","sql", client_request.get_sql(), K(ret)); + } else if (OB_UNLIKELY(is_multi_stmt && ObProxyShardUtils::is_unsupport_type_in_multi_stmt(*real_parse_result))) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("unsupport type in multi stmt", K(ret), K(sql)); + } else if (OB_FAIL(do_handle_shard_request(client_session, trans_state, logic_db_info, sql, new_sql, *real_parse_result, + es_index, group_index, last_es_index, is_scan_all))) { + LOG_WARN("fail to handle single shard request for single sql", K(ret), K(sql), K(new_sql)); + } else if (OB_UNLIKELY((i > 0) && ((es_index != last_es_index) || (group_index != last_group_index)))) { + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + LOG_WARN("different elastic index or group index for multi stmt is not supported", K(es_index), K(last_es_index), K(group_index), + K(last_group_index), K(sql), K(new_sql), K(ret)); + } else if (OB_UNLIKELY(is_multi_stmt && is_scan_all)) { + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + LOG_WARN("scan all sql in multi stmt is not supported", K(sql), K(new_sql), K(ret)); + } else { + last_es_index = es_index; + last_group_index = group_index; + if (i > 0) { + real_parse_result->reset(); + } + } + } + } + + if (OB_SUCC(ret)) { + if (is_scan_all) { + if (OB_FAIL(handle_scan_all_real_info(logic_db_info, client_session, trans_state, first_table_name))) { + LOG_WARN("fail to handle scan all real info", K(first_table_name), K(ret)); + } + } else { + if (OB_FAIL(build_shard_request_packet(session_info, client_request, client_buffer_reader, new_sql.string()))) { + LOG_WARN("fail to build sharding request packet", K(new_sql), K(ret)); + } + } + } + } + + if(NULL != multi_sql_buf) { + allocator.free(multi_sql_buf); + } + + return ret; +} + +int ObProxyShardUtils::do_handle_shard_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index, + bool& is_scan_all) +{ + int ret = OB_SUCCESS; + + ObString table_name = parse_result.get_origin_table_name(); + if (OB_UNLIKELY(is_unsupport_type_in_multi_stmt(parse_result) + || table_name.empty())) { + // Let it go for now, keep compatible + new_sql.append(sql); } else if (parse_result.is_show_stmt() || parse_result.is_desc_table_stmt()) { - if (OB_FAIL(handle_other_request(client_session, trans_state, - client_buffer_reader, table_name, db_info))) { - LOG_WARN("fail to handle other request", K(ret), K(session_info), K(table_name)); + if (OB_FAIL(handle_other_request(client_session, trans_state, table_name, db_info, + sql, new_sql, parse_result, es_index, group_index))) { + LOG_WARN("fail to handle other request", K(ret), K(sql), K(new_sql), K(table_name)); } } else if (parse_result.is_select_stmt()) { - if (OB_FAIL(handle_select_request(client_session, trans_state, - client_buffer_reader, table_name, db_info))) { - LOG_WARN("fail to handle select request", K(ret), K(session_info), K(table_name)); + if (OB_FAIL(handle_select_request(client_session, trans_state, table_name, db_info, + sql, new_sql, parse_result, es_index, group_index, last_es_index, is_scan_all))) { + LOG_WARN("fail to handle select request", K(ret), K(sql), K(new_sql), K(table_name)); } } else if (parse_result.is_dml_stmt()) { - if (OB_FAIL(handle_dml_request(client_session, trans_state, - client_buffer_reader, table_name, db_info))) { - LOG_WARN("fail to handle dml request", K(table_name), K(ret)); + if (OB_FAIL(handle_dml_request(client_session, trans_state, table_name, db_info, + sql, new_sql, parse_result, es_index, group_index, last_es_index))) { + LOG_WARN("fail to handle dml request", K(table_name), K(sql), K(new_sql), K(ret)); } } else { ret = OB_NOT_SUPPORTED; LOG_WARN("stmt is unsupported for sharding table", "stmt type", parse_result.get_stmt_type(), K(ret)); + } + + return ret; } + +int ObProxyShardUtils::build_shard_request_packet(ObClientSessionInfo &session_info, + ObProxyMysqlRequest &client_request, + ObIOBufferReader &client_buffer_reader, + const ObString& sql) +{ + int ret = OB_SUCCESS; + + // 4. push reader forward by consuming old buffer and write new sql into buffer + if (OB_FAIL(client_buffer_reader.consume_all())) { + LOG_WARN("fail to consume all", K(ret)); + } else { + ObMIOBuffer *writer = client_buffer_reader.mbuf_; + if (OB_ISNULL(writer)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null values ", K(writer), K(ret)); + // no need compress here, if server session support compress, it will compress later + } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, sql, false, false))) { + LOG_WARN("fail to build_mysql_request", K(sql), K(ret)); + } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(session_info, client_request, client_buffer_reader))) { + LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); + } + } + return ret; } @@ -1314,25 +1656,29 @@ int ObProxyShardUtils::handle_ddl_request(ObMysqlSM *sm, int ObProxyShardUtils::handle_other_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, const ObString &table_name, - ObDbConfigLogicDb &db_info) + ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index) { int ret = OB_SUCCESS; ObClientSessionInfo &session_info = client_session.get_session_info(); - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; if (OB_FAIL(handle_other_real_info(db_info, client_session, trans_state, table_name, real_database_name, OB_MAX_DATABASE_NAME_LENGTH, - real_table_name, OB_MAX_TABLE_NAME_LENGTH))) { + real_table_name, OB_MAX_TABLE_NAME_LENGTH, + parse_result, es_index, group_index))) { LOG_WARN("fail to handle other real info", K(ret), K(session_info), K(table_name)); - } else if (OB_FAIL(rewrite_shard_request(session_info, client_request, client_buffer_reader, + } else if (OB_FAIL(rewrite_shard_request(session_info, parse_result, table_name, db_info.db_name_.config_string_, ObString::make_string(real_table_name), - ObString::make_string(real_database_name), false))) { + ObString::make_string(real_database_name), false, sql, new_sql))) { LOG_WARN("fail to rewrite shard request", K(ret), K(table_name), K(db_info.db_name_), K(real_table_name), K(real_database_name)); } @@ -1342,19 +1688,20 @@ int ObProxyShardUtils::handle_other_request(ObMysqlClientSession &client_session int ObProxyShardUtils::handle_select_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, const ObString &table_name, - ObDbConfigLogicDb &db_info) + ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index, + bool& is_scan_all) { int ret = OB_SUCCESS; - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); SqlFieldResult& sql_result = parse_result.get_sql_filed_result(); - - bool is_scan_all = false; ObProxySqlParser sql_parser; - ObString sql = client_request.get_parse_sql(); - if (OB_FAIL(sql_parser.parse_sql_by_obparser(sql, NORMAL_PARSE_MODE, parse_result, true))) { + if (OB_FAIL(sql_parser.parse_sql_by_obparser(ObProxyMysqlRequest::get_parse_sql(sql), NORMAL_PARSE_MODE, parse_result, true))) { LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); } else if (FALSE_IT(is_scan_all = need_scan_all(parse_result))) { // impossible @@ -1366,12 +1713,10 @@ int ObProxyShardUtils::handle_select_request(ObMysqlClientSession &client_sessio if (OB_SUCC(ret)) { if (is_scan_all) { - if (OB_FAIL(handle_scan_all_real_info(db_info, client_session, trans_state, table_name))) { - LOG_WARN("fail to handle scan all real info", K(table_name), K(ret)); - } + //handle scan all later } else { - if (OB_FAIL(handle_select_real_info(db_info, client_session, trans_state, - table_name, client_buffer_reader))) { + if (OB_FAIL(handle_dml_real_info(db_info, client_session, trans_state, table_name, + sql, new_sql, parse_result, es_index, group_index, last_es_index))) { LOG_WARN("fail to handle dml real info", K(table_name), K(ret)); } } @@ -1382,37 +1727,22 @@ int ObProxyShardUtils::handle_select_request(ObMysqlClientSession &client_sessio int ObProxyShardUtils::handle_dml_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, const ObString &table_name, - ObDbConfigLogicDb &db_info) + ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index) { int ret = OB_SUCCESS; - ObClientSessionInfo &session_info = client_session.get_session_info(); - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); - char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; - char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; - ObProxySqlParser sql_parser; - ObString sql = client_request.get_parse_sql(); - if (OB_FAIL(sql_parser.parse_sql_by_obparser(sql, NORMAL_PARSE_MODE, parse_result, true))) { + if (OB_FAIL(sql_parser.parse_sql_by_obparser(ObProxyMysqlRequest::get_parse_sql(sql), NORMAL_PARSE_MODE, parse_result, true))) { LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); - } - if(OB_FAIL(ret)) { - // doing nothing - } else if ((parse_result.is_insert_stmt() || parse_result.is_replace_stmt() - || parse_result.is_update_stmt()) && parse_result.get_batch_insert_values_count() > 1) { - ret = OB_ERR_BATCH_INSERT_FOUND; - LOG_WARN("batch insert not supported in sharding sql", K(ret), K(parse_result.get_batch_insert_values_count())); - } else if (OB_FAIL(handle_dml_real_info(db_info, client_session, trans_state, table_name, - real_database_name, OB_MAX_DATABASE_NAME_LENGTH, - real_table_name, OB_MAX_TABLE_NAME_LENGTH))) { - LOG_WARN("fail to handle dml real info", K(ret), K(session_info), K(table_name)); - } else if (OB_FAIL(rewrite_shard_request(session_info, client_request, client_buffer_reader, - table_name, db_info.db_name_.config_string_, ObString::make_string(real_table_name), - ObString::make_string(real_database_name), false))) { - LOG_WARN("fail to rewrite shard request", K(ret), K(table_name), - K(db_info.db_name_), K(real_table_name), K(real_database_name)); + } else if (OB_FAIL(handle_dml_real_info(db_info, client_session, trans_state, table_name, + sql, new_sql, parse_result, es_index, group_index, last_es_index))) { + LOG_WARN("fail to handle dml real info", K(table_name), K(ret)); } return ret; @@ -1423,16 +1753,16 @@ int ObProxyShardUtils::check_topology(ObSqlParseResult &parse_result, { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(parse_result.get_proxy_stmt()); - if (OB_ISNULL(select_stmt)) { + ObProxyDMLStmt *dml_stmt = static_cast(parse_result.get_proxy_stmt()); + if (OB_ISNULL(dml_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("select stmt is null, unexpected", K(ret)); } else { int64_t last_db_size = -1; int64_t last_tb_size = -1; - ObProxySelectStmt::ExprMap &table_exprs_map = select_stmt->get_table_exprs_map(); - ObProxySelectStmt::ExprMap::iterator iter = table_exprs_map.begin(); - ObProxySelectStmt::ExprMap::iterator end = table_exprs_map.end(); + ObProxyDMLStmt::ExprMap &table_exprs_map = dml_stmt->get_table_exprs_map(); + ObProxyDMLStmt::ExprMap::iterator iter = table_exprs_map.begin(); + ObProxyDMLStmt::ExprMap::iterator end = table_exprs_map.end(); for (; OB_SUCC(ret) && iter != end; iter++) { ObProxyExpr *expr = iter->second; @@ -1802,6 +2132,10 @@ int ObProxyShardUtils::get_db_version(const ObString &logic_tenant_name, } else { db_version = logic_db_info->get_version(); } + if (NULL != logic_db_info) { + logic_db_info->dec_ref(); + logic_db_info = NULL; + } return ret; } @@ -1869,26 +2203,27 @@ int ObProxyShardUtils::handle_other_real_info(ObDbConfigLogicDb &logic_db_info, ObMysqlTransact::ObTransState &trans_state, const ObString &table_name, char *real_database_name, int64_t db_name_len, - char *real_table_name, int64_t tb_name_len) + char *real_table_name, int64_t tb_name_len, + ObSqlParseResult &parse_result, + int64_t& es_id, int64_t& group_id) { int ret = OB_SUCCESS; ObShardConnector *shard_conn = NULL; ObClientSessionInfo &cs_info = client_session.get_session_info(); ObShardConnector *prev_shard_conn = cs_info.get_shard_connector(); - ObSqlParseResult &parse_result = trans_state.trans_info_.client_request_.get_parse_result(); ObShardRule *logic_tb_info = NULL; - int64_t group_id = OBPROXY_MAX_DBMESH_ID; + group_id = OBPROXY_MAX_DBMESH_ID; int64_t table_id = OBPROXY_MAX_DBMESH_ID; - int64_t es_id = OBPROXY_MAX_DBMESH_ID; + es_id = OBPROXY_MAX_DBMESH_ID; ObTestLoadType testload_type = TESTLOAD_NON; ObString hint_table; if (OB_ISNULL(prev_shard_conn)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("shard connector info is null", K(ret)); - } else if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + } else if (OB_FAIL(get_shard_hint(table_name, cs_info, logic_db_info, parse_result, group_id, table_id, es_id, hint_table, testload_type))) { LOG_WARN("fail to get shard hint", K(ret)); // get group_id @@ -1896,21 +2231,24 @@ int ObProxyShardUtils::handle_other_real_info(ObDbConfigLogicDb &logic_db_info, LOG_WARN("fail to get shard rule", K(table_name), K(ret)); } else { int64_t last_group_id = cs_info.get_group_id(); - ObString saved_database_name; cs_info.get_logic_database_name(saved_database_name); bool is_not_saved_database = saved_database_name != logic_db_info.db_name_.config_string_; - // need to re-select a shard_conn condition, and any one of the conditions can be satisfied - // 1. SQL comes with database, and it is different from the current logic library - // 2. The group id is specified in the hint, and it is different from the last time - // 3. No group_id is specified, nor did the last one (for example, switch the library) - // 4. If the last group_id is greater than the db_size of the table of this SQL - // (for example, the table of the previous SQL is group_{00-99}, the table of this SQL is group_00) - if (is_not_saved_database - || (group_id != OBPROXY_MAX_DBMESH_ID && group_id != last_group_id) - || last_group_id == OBPROXY_MAX_DBMESH_ID - || last_group_id >= logic_tb_info->db_size_) { + // If group_id is specified, check if it exceeds db_size and use it + if (group_id != OBPROXY_MAX_DBMESH_ID) { + if (group_id >= logic_tb_info->db_size_) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("sql with group hint and greater than db size", + "db_size", logic_tb_info->db_size_, K(group_id), K(ret)); + } + // If no group_id is specified, and the database accessed by the current SQL is the session database, the last_group_id is used + } else if (!is_not_saved_database && last_group_id < logic_tb_info->db_size_) { + group_id = last_group_id; + es_id = cs_info.get_es_id(); + } + + if (OB_SUCC(ret)) { ObShardTpo *shard_tpo = NULL; ObGroupCluster *gc_info = NULL; if (OB_FAIL(logic_db_info.get_shard_tpo(shard_tpo))) { @@ -1963,15 +2301,6 @@ int ObProxyShardUtils::handle_other_real_info(ObDbConfigLogicDb &logic_db_info, } } } - - //If it is the logic library on the current session, you can reuse this group_id next time - if (OB_SUCC(ret) && !is_not_saved_database) { - cs_info.set_group_id(group_id); - } - } else { - prev_shard_conn->inc_ref(); - shard_conn = prev_shard_conn; - group_id = last_group_id; } if (OB_SUCC(ret)) { @@ -1996,6 +2325,13 @@ int ObProxyShardUtils::handle_other_real_info(ObDbConfigLogicDb &logic_db_info, } } } + + //If it is a logic library on the current session, this group_id can be reused next time + if (OB_SUCC(ret) && !is_not_saved_database) { + cs_info.set_group_id(group_id); + cs_info.set_table_id(table_id); + cs_info.set_es_id(es_id); + } } if (NULL != shard_conn) { @@ -2020,11 +2356,11 @@ int ObProxyShardUtils::handle_scan_all_real_info(ObDbConfigLogicDb &logic_db_inf ObSEArray, 4> table_name_map_array; ObIAllocator *allocator = NULL; - ObProxySelectStmt *select_stmt = static_cast(parse_result.get_proxy_stmt()); - if (OB_ISNULL(select_stmt)) { + ObProxyDMLStmt *dml_stmt = static_cast(parse_result.get_proxy_stmt()); + if (OB_ISNULL(dml_stmt)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("select stmt is null, unexpected", K(ret)); - } else if (select_stmt->has_unsupport_expr_type()) { + LOG_WARN("dml stmt is null, unexpected", K(ret)); + } else if (dml_stmt->has_unsupport_expr_type()) { ret = OB_ERROR_UNSUPPORT_EXPR_TYPE; LOG_WARN("unsupport sql", K(ret)); } else if (OB_FAIL(check_topology(parse_result, logic_db_info))) { @@ -2040,17 +2376,17 @@ int ObProxyShardUtils::handle_scan_all_real_info(ObDbConfigLogicDb &logic_db_inf table_name_map_array))) { LOG_WARN("fail to handle sharding select real info", K(ret), K(table_name)); } else { - LOG_DEBUG("proxy stmt", K(select_stmt->get_stmt_type()), K(select_stmt->limit_offset_), K(select_stmt->limit_size_)); + LOG_DEBUG("proxy stmt", K(dml_stmt->get_stmt_type()), K(dml_stmt->limit_offset_), K(dml_stmt->limit_size_)); LOG_DEBUG("select expr"); - for (int64_t i = 0; i < select_stmt->select_exprs_.count(); i++) { - ObProxyExpr::print_proxy_expr(select_stmt->select_exprs_.at(i)); + for (int64_t i = 0; i < dml_stmt->select_exprs_.count(); i++) { + ObProxyExpr::print_proxy_expr(dml_stmt->select_exprs_.at(i)); } LOG_DEBUG("group by expr"); - for (int64_t i = 0; i < select_stmt->group_by_exprs_.count(); i++) { - ObProxyExpr::print_proxy_expr(select_stmt->group_by_exprs_.at(i)); + for (int64_t i = 0; i < dml_stmt->group_by_exprs_.count(); i++) { + ObProxyExpr::print_proxy_expr(dml_stmt->group_by_exprs_.at(i)); } - for (int64_t i = 0; i < select_stmt->order_by_exprs_.count(); i++) { - ObProxyOrderItem *order_expr = select_stmt->order_by_exprs_.at(i); + for (int64_t i = 0; i < dml_stmt->order_by_exprs_.count(); i++) { + ObProxyOrderItem *order_expr = dml_stmt->order_by_exprs_.at(i); LOG_DEBUG("order by expr", K(order_expr->order_direction_)); ObProxyExpr::print_proxy_expr(order_expr); } @@ -2071,11 +2407,16 @@ int ObProxyShardUtils::handle_scan_all_real_info(ObDbConfigLogicDb &logic_db_inf return ret; } -int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - const ObString &table_name, - ObIOBufferReader &client_buffer_reader) +int ObProxyShardUtils::handle_dml_real_info(ObDbConfigLogicDb &logic_db_info, + ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + const ObString &table_name, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index) { int ret = OB_SUCCESS; @@ -2083,14 +2424,12 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, ObClientSessionInfo &session_info = client_session.get_session_info(); ObShardConnector *prev_shard_conn = session_info.get_shard_connector(); - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); SqlFieldResult &sql_result = parse_result.get_sql_filed_result(); - ObProxySelectStmt *select_stmt = dynamic_cast(parse_result.get_proxy_stmt()); + ObProxyDMLStmt *dml_stmt = dynamic_cast(parse_result.get_proxy_stmt()); - int64_t group_index = OBPROXY_MAX_DBMESH_ID; + group_index = OBPROXY_MAX_DBMESH_ID; int64_t tb_index = OBPROXY_MAX_DBMESH_ID; - int64_t es_index = OBPROXY_MAX_DBMESH_ID; + es_index = OBPROXY_MAX_DBMESH_ID; ObTestLoadType testload_type = TESTLOAD_NON; ObString hint_table; ObArenaAllocator allocator; @@ -2103,22 +2442,22 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, // read request weight bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); - if (OB_ISNULL(select_stmt)) { + if (OB_ISNULL(dml_stmt)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("select stmt is null, unexpected", K(ret)); + LOG_WARN("dml stmt is null, unexpected", K(ret)); } else if (OB_FAIL(table_name_map.create(OB_ALIAS_TABLE_MAP_MAX_BUCKET_NUM, ObModIds::OB_HASH_ALIAS_TABLE_MAP))) { LOG_WARN("fail to create table name map", K(ret)); - } else if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + } else if (OB_FAIL(get_shard_hint(table_name, session_info, logic_db_info, parse_result, group_index, tb_index, es_index, hint_table, testload_type))) { LOG_WARN("fail to get shard hint", K(ret)); } if (OB_SUCC(ret)) { - ObProxySelectStmt::ExprMap &table_exprs_map = select_stmt->get_table_exprs_map(); - ObProxySelectStmt::ExprMap::iterator iter = table_exprs_map.begin(); - ObProxySelectStmt::ExprMap::iterator end = table_exprs_map.end(); + ObProxyDMLStmt::ExprMap &table_exprs_map = dml_stmt->get_table_exprs_map(); + ObProxyDMLStmt::ExprMap::iterator iter = table_exprs_map.begin(); + ObProxyDMLStmt::ExprMap::iterator end = table_exprs_map.end(); if (!hint_table.empty() && table_exprs_map.size() > 1) { ret = OB_ERR_MORE_TABLES_WITH_TABLE_HINT; @@ -2127,7 +2466,7 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, real_database_name, OB_MAX_DATABASE_NAME_LENGTH, real_table_name, OB_MAX_TABLE_NAME_LENGTH, group_index, tb_index, es_index, - hint_table, testload_type, is_read_stmt))) { + hint_table, testload_type, is_read_stmt, last_es_index))) { LOG_WARN("fail to get real info", K(table_name), K(group_index), K(tb_index), K(es_index), K(hint_table), K(testload_type), K(is_read_stmt), K(ret)); } else if (OB_ISNULL(shard_conn) || OB_ISNULL(prev_shard_conn)) { @@ -2160,8 +2499,9 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, } if (OB_SUCC(ret)) { - if (OB_FAIL(rewrite_shard_select_request(session_info, client_request, client_buffer_reader, - table_name_map, ObString::make_string(real_database_name), false))) { + if (OB_FAIL(rewrite_shard_dml_request(sql, new_sql, parse_result, + session_info.is_oracle_mode(), table_name_map, + ObString::make_string(real_database_name), false))) { LOG_WARN("fail to rewrite shard request", K(real_database_name), K(ret)); } } @@ -2179,6 +2519,8 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, bool is_not_saved_database = saved_database_name != logic_db_info.db_name_.config_string_; if (!is_not_saved_database) { session_info.set_group_id(group_index); + session_info.set_table_id(tb_index); + session_info.set_es_id(es_index); } } @@ -2189,58 +2531,8 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, return ret; } -int ObProxyShardUtils::handle_dml_real_info(ObDbConfigLogicDb &logic_db_info, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - const ObString &table_name, - char *real_database_name, int64_t db_name_len, - char *real_table_name, int64_t tb_name_len) -{ - int ret = OB_SUCCESS; - - ObShardConnector *shard_conn = NULL; - ObClientSessionInfo &session_info = client_session.get_session_info(); - ObShardConnector *prev_shard_conn = session_info.get_shard_connector(); - ObSqlParseResult &parse_result = trans_state.trans_info_.client_request_.get_parse_result(); - int64_t group_id = OBPROXY_MAX_DBMESH_ID; - - bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); - - if (OB_FAIL(get_real_info(logic_db_info, table_name, parse_result, shard_conn, - real_database_name, db_name_len, - real_table_name, tb_name_len, - &group_id, NULL, NULL, is_read_stmt))) { - LOG_WARN("fail to get real db and tb", K(table_name), K(ret)); - } else if (OB_ISNULL(shard_conn) || OB_ISNULL(prev_shard_conn)) { - ret = OB_EXPR_CALC_ERROR; - LOG_WARN("shard connector info or prev shard connector info is null", KP(shard_conn), - KP(prev_shard_conn), K(ret)); - } - - if (OB_SUCC(ret) && *prev_shard_conn != *shard_conn) { - if (OB_FAIL(change_connector(logic_db_info, client_session, trans_state, prev_shard_conn, shard_conn))) { - LOG_WARN("fail to change connector", KPC(prev_shard_conn), KPC(shard_conn), K(ret)); - } - } - - //There may be a database in SQL, only the logical library saved on the session can save the group_id, and it can be reused next time - if (OB_SUCC(ret)) { - ObString saved_database_name; - session_info.get_logic_database_name(saved_database_name); - bool is_not_saved_database = saved_database_name != logic_db_info.db_name_.config_string_; - if (!is_not_saved_database) { - session_info.set_group_id(group_id); - } - } - - if (NULL != shard_conn) { - shard_conn->dec_ref(); - shard_conn = NULL; - } - return ret; -} - -int ObProxyShardUtils::get_real_info(ObDbConfigLogicDb &logic_db_info, +int ObProxyShardUtils::get_real_info(ObClientSessionInfo &session_info, + ObDbConfigLogicDb &logic_db_info, const ObString &table_name, ObSqlParseResult &parse_result, ObShardConnector *&shard_conn, @@ -2255,7 +2547,7 @@ int ObProxyShardUtils::get_real_info(ObDbConfigLogicDb &logic_db_info, int64_t es_index = OBPROXY_MAX_DBMESH_ID; ObTestLoadType testload_type = TESTLOAD_NON; ObString hint_table; - if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + if (OB_FAIL(get_shard_hint(table_name, session_info, logic_db_info, parse_result, group_index, tb_index, es_index, hint_table, testload_type))) { LOG_WARN("fail to get shard hint", K(ret)); } else if (OB_FAIL(logic_db_info.get_real_info(table_name, parse_result, shard_conn, @@ -2286,6 +2578,7 @@ int ObProxyShardUtils::is_sharding_in_trans(ObClientSessionInfo &session_info, O { return 0 == session_info.get_cached_variables().get_autocommit() || trans_state.is_hold_start_trans_ + || trans_state.is_hold_xa_start_ || ObMysqlTransact::is_in_trans(trans_state); } @@ -2409,7 +2702,7 @@ int ObProxyShardUtils::handle_sharding_select_real_info(ObDbConfigLogicDb &logic bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); - if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + if (OB_FAIL(get_shard_hint(table_name, session_info, logic_db_info, parse_result, group_index, tb_index, es_index, hint_table, testload_type))) { LOG_WARN("fail to get shard hint", K(ret)); diff --git a/src/obproxy/proxy/shard/obproxy_shard_utils.h b/src/obproxy/proxy/shard/obproxy_shard_utils.h index 4cc3c5b4..78518138 100644 --- a/src/obproxy/proxy/shard/obproxy_shard_utils.h +++ b/src/obproxy/proxy/shard/obproxy_shard_utils.h @@ -46,12 +46,13 @@ class ObProxyShardUtils static int get_db_version(const ObString &logic_tenant_name, const ObString &logic_database_name, ObString &db_version); - static bool is_special_db(ObMysqlTransact::ObTransState &s); + static bool is_special_db(obutils::ObSqlParseResult& parse_result); static int get_logic_db_info(ObMysqlTransact::ObTransState &s, ObClientSessionInfo &session_info, dbconfig::ObDbConfigLogicDb *&logic_db_info); - static int get_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, + static int get_real_info(ObClientSessionInfo &session_info, + dbconfig::ObDbConfigLogicDb &logic_db_info, const common::ObString &table_name, obutils::ObSqlParseResult &parse_result, dbconfig::ObShardConnector *&shard_conn, @@ -64,33 +65,62 @@ class ObProxyShardUtils static bool check_shard_authority(const dbconfig::ObShardUserPrivInfo &up_info, const obutils::ObSqlParseResult &parse_result); - static int get_shard_hint(dbconfig::ObDbConfigLogicDb &logic_db_info, + static int get_shard_hint(const ObString &table_name, + ObClientSessionInfo &session_info, + dbconfig::ObDbConfigLogicDb &logic_db_info, obutils::ObSqlParseResult &parse_result, int64_t &group_index, int64_t &tb_index, - int64_t &es_index, ObString &table_name, + int64_t &es_index, ObString &hint_table_name, dbconfig::ObTestLoadType &testload_type); + static int get_shard_hint(dbconfig::ObDbConfigLogicDb &logic_db_info, + obutils::ObSqlParseResult &parse_result, + int64_t &group_index, int64_t &tb_index, + int64_t &es_index, ObString &hint_table_name, + dbconfig::ObTestLoadType &testload_type, + bool &is_sticky_session); + static int check_shard_request(ObMysqlClientSession &client_session, obutils::ObSqlParseResult &parse_result, dbconfig::ObDbConfigLogicDb &logic_db_info); - static int handle_shard_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - dbconfig::ObDbConfigLogicDb &db_info, - bool &need_wait_callback); + static int do_handle_shard_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + dbconfig::ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index, + bool& is_scan_all); + static int handle_shard_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObIOBufferReader &client_buffer_reader, + dbconfig::ObDbConfigLogicDb &db_info); + static int handle_ddl_request(ObMysqlSM *sm, + ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + dbconfig::ObDbConfigLogicDb &db_info, + bool &need_wait_callback); static int do_handle_single_shard_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - dbconfig::ObDbConfigLogicDb &logic_db_info); - static int handle_single_shard_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, + dbconfig::ObDbConfigLogicDb &logic_db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index); + static int handle_single_shard_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, ObIOBufferReader &client_buffer_reader, - dbconfig::ObDbConfigLogicDb &logic_db_info, - bool &need_wait_callback); - static int build_error_packet(int err_code, bool &need_response_for_dml, ObMysqlTransact::ObTransState &trans_state, + dbconfig::ObDbConfigLogicDb &logic_db_info); + static int build_error_packet(int err_code, bool &need_response_for_dml, + ObMysqlTransact::ObTransState &trans_state, ObMysqlClientSession *client_session); + static int handle_information_schema_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObIOBufferReader &client_buffer_reader); static int handle_sharding_select_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, ObMysqlClientSession &client_session, @@ -108,13 +138,13 @@ class ObProxyShardUtils static int check_topology(obutils::ObSqlParseResult &parse_result, dbconfig::ObDbConfigLogicDb &db_info); - static int do_rewrite_shard_select_request(const ObString &sql, - obutils::ObSqlParseResult &parse_result, - bool is_oracle_mode, - const common::hash::ObHashMap &table_name_map, - const ObString &real_database_name, - bool is_single_shard_db_table, - common::ObSqlString &new_sql); + static int rewrite_shard_dml_request(const ObString &sql, + ObSqlString &new_sql, + obutils::ObSqlParseResult &parse_result, + bool is_oracle_mode, + const common::hash::ObHashMap &table_name_map, + const ObString &real_database_name, + bool is_single_shard_db_table); static int add_table_name_to_map(ObIAllocator &allocator, hash::ObHashMap &table_name_map, const ObString &table_name, const ObString &real_table_name); @@ -123,32 +153,42 @@ class ObProxyShardUtils static bool is_read_stmt(ObClientSessionInfo &session_info, ObMysqlTransact::ObTransState &trans_state, obutils::ObSqlParseResult &parse_result); + static bool is_unsupport_type_in_multi_stmt(obutils::ObSqlParseResult& parse_result); static int change_connector(dbconfig::ObDbConfigLogicDb &logic_db_info, ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, const dbconfig::ObShardConnector *prev_shard_conn, dbconfig::ObShardConnector *shard_conn); - - static int handle_ddl_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - dbconfig::ObDbConfigLogicDb &db_info, - bool &need_wait_callback); static int handle_dml_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - const common::ObString &table_name, - dbconfig::ObDbConfigLogicDb &db_info); + const ObString &table_name, + dbconfig::ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index); static int handle_other_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - const common::ObString &table_name, - dbconfig::ObDbConfigLogicDb &db_info); + const ObString &table_name, + dbconfig::ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index); static int handle_select_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - const common::ObString &table_name, - dbconfig::ObDbConfigLogicDb &db_info); + const ObString &table_name, + dbconfig::ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index, + bool& is_scan_all); static int check_logic_database(ObMysqlTransact::ObTransState &trans_state, ObMysqlClientSession &client_session, const ObString &db_name); static void replace_oracle_table(ObSqlString &new_sql, const ObString &real_name, @@ -164,21 +204,21 @@ class ObProxyShardUtils const ObString &real_table_name, const ObString &real_database_name, bool is_oracle_mode, bool is_single_shard_db_table, ObSqlString &new_sql, int64_t ©_pos); + static int rewrite_shard_request_table_no_db(const char *sql_ptr, + int64_t table_pos, uint64_t table_len, + const ObString &real_table_name, + bool is_oracle_mode, bool is_single_shard_db_table, + ObSqlString &new_sql, int64_t ©_pos); static int rewrite_shard_request_hint_table(const char *sql_ptr, int64_t index_table_pos, uint64_t index_table_len, const ObString &real_table_name, bool is_oracle_mode, bool is_single_shard_db_table, ObSqlString &new_sql, int64_t ©_pos); static int rewrite_shard_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, + obutils::ObSqlParseResult &parse_result, const ObString &table_name, const ObString &database_name, const ObString &real_table_name, const ObString &real_database_name, - bool is_single_shard_db_table); - static int rewrite_shard_select_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, - const common::hash::ObHashMap &table_name_map, - const ObString &real_database_name, - bool is_single_shard_db_table); + bool is_single_shard_db_table, + const ObString& sql, + common::ObSqlString& new_sql); static int testload_check_obparser_node_is_valid(const ParseNode *root, const ObItemType &type); static int testload_rewrite_name_base_on_parser_node(common::ObSqlString &new_sql, const char *new_name, @@ -189,13 +229,13 @@ class ObProxyShardUtils static int testload_get_obparser_db_and_table_node(const ParseNode *root, ParseNode *&db_node, ParseNode *&table_node); - static int testload_check_and_rewrite_testload_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, + static int testload_check_and_rewrite_testload_request(obutils::ObSqlParseResult &parse_result, bool is_single_shard_db_table, const ObString &hint_table, const ObString &real_database_name, - dbconfig::ObDbConfigLogicDb &logic_db_info); + dbconfig::ObDbConfigLogicDb &logic_db_info, + const ObString& sql, + common::ObSqlString& new_sql); static int testload_check_and_rewrite_testload_hint_index(common::ObSqlString &new_sql, const char *sql_ptr, int64_t sql_len, @@ -215,27 +255,33 @@ class ObProxyShardUtils ObMysqlTransact::ObTransState &trans_state, const ObString &table_name, char *real_database_name, int64_t db_name_len, - char *real_table_name, int64_t tb_name_len); - static int handle_dml_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - const ObString &table_name, - char *real_database_name, int64_t db_name_len, - char *real_table_name, int64_t tb_name_len); + char *real_table_name, int64_t tb_name_len, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index); static int handle_scan_all_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, const ObString &table_name); - static int handle_select_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - const ObString &table_name, - ObIOBufferReader &client_buffer_reader); + static int handle_dml_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, + ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + const ObString &table_name, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index); static int handle_sys_read_consitency_prop(dbconfig::ObDbConfigLogicDb &logic_db_info, dbconfig::ObShardConnector& shard_conn, ObClientSessionInfo &session_info); static int is_sharding_in_trans(ObClientSessionInfo &session_info, ObMysqlTransact::ObTransState &trans_state); + static int build_shard_request_packet(ObClientSessionInfo &session_info, + ObProxyMysqlRequest &client_request, + ObIOBufferReader &client_buffer_reader, + const ObString& sql); }; diff --git a/src/obproxy/stat/ob_mysql_stats.cpp b/src/obproxy/stat/ob_mysql_stats.cpp index 0b096d7a..eb8161e6 100644 --- a/src/obproxy/stat/ob_mysql_stats.cpp +++ b/src/obproxy/stat/ob_mysql_stats.cpp @@ -272,6 +272,9 @@ int init_mysql_stats() MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "send_changed_session_vars_requests", RECD_INT, SEND_CHANGED_SESSION_VARS_REQUESTS, SYNC_SUM, RECP_NULL); + MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "send_changed_session_user_vars_requests", + RECD_INT, SEND_CHANGED_SESSION_USER_VARS_REQUESTS, SYNC_SUM, RECP_NULL); + MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "send_last_insert_id_requests", RECD_INT, SEND_LAST_INSERT_ID_REQUESTS, SYNC_SUM, RECP_PERSISTENT); @@ -334,6 +337,9 @@ int init_mysql_stats() MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "total_send_changed_session_vars_time", RECD_INT, TOTAL_SEND_CHANGED_SESSION_VARS_TIME, SYNC_SUM, RECP_NULL); + MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "total_send_changed_session_user_vars_time", + RECD_INT, TOTAL_SEND_CHANGED_SESSION_USER_VARS_TIME, SYNC_SUM, RECP_NULL); + MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "total_send_last_insert_id_time", RECD_INT, TOTAL_SEND_LAST_INSERT_ID_TIME, SYNC_SUM, RECP_NULL); diff --git a/src/obproxy/stat/ob_mysql_stats.h b/src/obproxy/stat/ob_mysql_stats.h index 99c6b17a..6dd86796 100644 --- a/src/obproxy/stat/ob_mysql_stats.h +++ b/src/obproxy/stat/ob_mysql_stats.h @@ -60,8 +60,10 @@ enum ObMysqlStats TOTAL_SEND_ALL_SESSION_VARS_TIME, TOTAL_SEND_USE_DATABASE_TIME, TOTAL_SEND_CHANGED_SESSION_VARS_TIME, + TOTAL_SEND_CHANGED_SESSION_USER_VARS_TIME, TOTAL_SEND_LAST_INSERT_ID_TIME, TOTAL_SEND_START_TRANS_TIME, + TOTAL_SEND_XA_START_TIME, TOTAL_PL_LOOKUP_TIME, TOTAL_CONGESTION_CONTROL_LOOKUP_TIME, @@ -132,8 +134,10 @@ enum ObMysqlStats SEND_ALL_SESSION_VARS_REQUESTS, SEND_USE_DATABASE_REQUESTS, SEND_CHANGED_SESSION_VARS_REQUESTS, + SEND_CHANGED_SESSION_USER_VARS_REQUESTS, SEND_LAST_INSERT_ID_REQUESTS, SEND_START_TRANS_REQUESTS, + SEND_XA_START_REQUESTS, VIP_TO_TENANT_CACHE_HIT, VIP_TO_TENANT_CACHE_MISS, diff --git a/src/obproxy/stat/ob_stat_processor.cpp b/src/obproxy/stat/ob_stat_processor.cpp index da5da868..f1341f36 100644 --- a/src/obproxy/stat/ob_stat_processor.cpp +++ b/src/obproxy/stat/ob_stat_processor.cpp @@ -92,7 +92,7 @@ int ObSessionStatTableSync::init(ObMysqlProxy &mysql_proxy, const char *cluster_ { int ret = OB_SUCCESS; ObAddr addr; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; ip_str[0] = '\0'; if (OB_ISNULL(cluster_name) @@ -101,7 +101,7 @@ int ObSessionStatTableSync::init(ObMysqlProxy &mysql_proxy, const char *cluster_ LOG_WARN("invalid parameter", K(cluster_name), K(stats), K(stat_names), K(ret)); } else if (OB_FAIL(ObProxyTableProcessorUtils::get_proxy_local_addr(addr))) { LOG_WARN("fail to get proxy local addr", K(addr), K(ret)); - } else if (!addr.ip_to_string(ip_str, OB_IP_STR_BUFF)) { + } else if (!addr.ip_to_string(ip_str, MAX_IP_ADDR_LENGTH)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to covert ip to string", K(addr), K(ret)); } else if (OB_FAIL(sql_.append_fmt(ObStatProcessor::INSERT_PROXY_STAT_SQL_HEAD, diff --git a/src/obproxy/stat/ob_stat_processor.h b/src/obproxy/stat/ob_stat_processor.h index 7d90c9ad..c5d39815 100644 --- a/src/obproxy/stat/ob_stat_processor.h +++ b/src/obproxy/stat/ob_stat_processor.h @@ -586,7 +586,7 @@ class ObStatProcessor ASLL(ObRecRawStatBlock, link_) all_blocks_; - char proxy_ip_[common::OB_IP_STR_BUFF]; // ip primary key + char proxy_ip_[common::MAX_IP_ADDR_LENGTH]; // ip primary key int32_t proxy_port_; // port primary key DISALLOW_COPY_AND_ASSIGN(ObStatProcessor); }; diff --git a/src/obproxy/utils/Makemodule.am b/src/obproxy/utils/Makemodule.am index 747c6051..72841d3f 100644 --- a/src/obproxy/utils/Makemodule.am +++ b/src/obproxy/utils/Makemodule.am @@ -23,6 +23,8 @@ obproxy/utils/ob_cpu_affinity.cpp\ obproxy/utils/ob_proxy_blowfish.h\ obproxy/utils/ob_proxy_blowfish.cpp\ obproxy/utils/ob_proxy_monitor_utils.h\ -obproxy/utils/ob_proxy_monitor_utils.cpp +obproxy/utils/ob_proxy_monitor_utils.cpp\ +obproxy/utils/ob_target_db_server.h\ +obproxy/utils/ob_target_db_server.cpp utils_sources:= ${utils_common_sources} diff --git a/src/obproxy/utils/ob_layout.cpp b/src/obproxy/utils/ob_layout.cpp index d022801f..a1be2ef8 100644 --- a/src/obproxy/utils/ob_layout.cpp +++ b/src/obproxy/utils/ob_layout.cpp @@ -11,8 +11,11 @@ */ #define USING_LOG_PREFIX PROXY -#include "utils/ob_layout.h" #include +#include "utils/ob_layout.h" +#include "ob_proxy_init.h" + +#define UNIX_PATH_LENGTH_MAX (sizeof(struct sockaddr_un) - sizeof(sa_family_t)) using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -22,6 +25,9 @@ namespace oceanbase namespace obproxy { +static const char* obproxy_domain = "obproxy.domain"; +static const char* obproxy_dir = "./.obproxy"; + ObLayout &get_global_layout() { static ObLayout g_layout; @@ -30,7 +36,8 @@ ObLayout &get_global_layout() ObLayout::ObLayout() : is_inited_(false), prefix_(NULL), bin_dir_(NULL), etc_dir_(NULL), - log_dir_(NULL), conf_dir_(NULL), control_config_dir_(NULL), dbconfig_dir_(NULL) + log_dir_(NULL), conf_dir_(NULL), control_config_dir_(NULL), + dbconfig_dir_(NULL), unix_domain_path_(NULL) { } @@ -60,6 +67,8 @@ int ObLayout::init(const char *start_cmd) MPRINT("fail to init proxy bin dir, ret=%d", ret); } else if (OB_FAIL(init_dir_prefix(cwd))) { MPRINT("fail to init proxy dir prefix, ret=%d", ret); + } else if (RUN_MODE_CLIENT == g_run_mode && OB_FAIL(handle_client_dirs())) { + MPRINT("fail to construct client dirs, ret=%d", ret); } else if (OB_FAIL(construct_dirs())) { MPRINT("fail to construct dirs, ret=%d", ret); } else { @@ -168,6 +177,42 @@ int ObLayout::init_bin_dir(const char *cwd, const char *start_cmd) } int ObLayout::init_dir_prefix(const char *cwd) +{ + int ret = OB_SUCCESS; + if (RUN_MODE_PROXY == g_run_mode) { + if (OB_FAIL(init_dir_prefix_proxy_mode(cwd))) { + LOG_WARN("init dir prefix proxy mode failed", K(ret)); + } + } else if (RUN_MODE_CLIENT == g_run_mode) { + if (OB_FAIL(init_dir_prefix_client_mode())) { + LOG_WARN("init_dir_prefix_client_mode", K(ret)); + } + } + + return ret; +} + +int ObLayout::init_dir_prefix_client_mode() +{ + int ret = OB_SUCCESS; + int64_t prefix_len = 0; + + prefix_len = strlen(obproxy_dir); + + if (OB_SUCC(ret)) { + if (OB_ISNULL(prefix_ = static_cast(allocator_.alloc(prefix_len + 1)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MPRINT("fail to alloc memeory, prefix_len=%ld, ret=%d", prefix_len, ret); + } else { + MEMCPY(prefix_, obproxy_dir, prefix_len); + prefix_[prefix_len] = '\0'; + } + } + + return ret; +} + +int ObLayout::init_dir_prefix_proxy_mode(const char *cwd) { int ret = OB_SUCCESS; char *env_path = NULL; @@ -290,5 +335,56 @@ int ObLayout::construct_single_dir(const char *sub_dir, char *&full_path) return ret; } +int ObLayout::handle_client_dirs() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(construct_client_obproxy_dirs())) { + LOG_WARN("construct_client_obproxy_dirs failed", K(ret)); + } else if (OB_FAIL(remove_unix_domain())) { + LOG_WARN("remove unix domain failed", K(ret)); + } + + return ret; +} + +int ObLayout::construct_client_obproxy_dirs() +{ + int ret = OB_SUCCESS; + char *actual_path = NULL; + // Create the .obproxy directory + if (OB_FAIL(extract_actual_path(prefix_, actual_path))) { + MPRINT("fail to extract_actual_path, prefix_path=%s, ret=%d", prefix_, ret); + } else if (OB_FAIL(FileDirectoryUtils::create_full_path(actual_path))) { + MPRINT("fail to create_full_path, actual_path=%s, ret=%d", actual_path, ret); + } + + if (NULL != actual_path && prefix_ != actual_path) { + allocator_.free(actual_path); + } + actual_path = NULL; + + + return ret; +} + +int ObLayout::remove_unix_domain() +{ + int ret = OB_SUCCESS; + char *actual_path = NULL; + + if (OB_FAIL(merge_file_path(prefix_, obproxy_domain, allocator_, unix_domain_path_))) { + MPRINT("fail to merge file path, sub_dir=%s, ret=%d", obproxy_domain, ret); + } else if (OB_FAIL(extract_actual_path(unix_domain_path_, actual_path))) { + MPRINT("fail to extract_actual_path, full_path=%s, ret=%d", unix_domain_path_, ret); + } else { + remove(actual_path); + if (NULL != actual_path && unix_domain_path_ != actual_path) { + allocator_.free(actual_path); + } + actual_path = NULL; + } + return ret; +} + }//end of namespace obproxy }//end of namespace oceanbase diff --git a/src/obproxy/utils/ob_layout.h b/src/obproxy/utils/ob_layout.h index beb15a3c..527a97f9 100644 --- a/src/obproxy/utils/ob_layout.h +++ b/src/obproxy/utils/ob_layout.h @@ -36,14 +36,20 @@ class ObLayout const char *get_control_config_dir() const { return control_config_dir_; } const char *get_dbconfig_dir() const { return dbconfig_dir_; } const char *get_proxy_root_dir() const { return prefix_; } + const char *get_unix_domain_path() const { return unix_domain_path_; } static int merge_file_path(const char *root, const char *file, common::ObIAllocator &allocator, char *&buf); private: int init_bin_dir(const char *cwd, const char *start_cmd); int init_dir_prefix(const char *cwd); + int init_dir_prefix_proxy_mode(const char *cwd); + int init_dir_prefix_client_mode(); int construct_dirs(); int construct_single_dir(const char *sub_dir, char *&full_path); int extract_actual_path(const char * const full_path, char *&actual_path); + int handle_client_dirs(); + int construct_client_obproxy_dirs(); + int remove_unix_domain(); private: bool is_inited_; @@ -54,6 +60,7 @@ class ObLayout char *conf_dir_; char *control_config_dir_; char *dbconfig_dir_; + char *unix_domain_path_; event::ObFixedArenaAllocator allocator_; }; diff --git a/src/obproxy/utils/ob_proxy_hot_upgrader.cpp b/src/obproxy/utils/ob_proxy_hot_upgrader.cpp index 98fb1e94..600e9751 100644 --- a/src/obproxy/utils/ob_proxy_hot_upgrader.cpp +++ b/src/obproxy/utils/ob_proxy_hot_upgrader.cpp @@ -14,6 +14,7 @@ #include "utils/ob_proxy_hot_upgrader.h" #include "iocore/eventsystem/ob_event_processor.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -28,7 +29,8 @@ ObHotUpgraderInfo g_hot_upgrade_info; void ObHotUpgraderInfo::reset() { - fd_ = OB_INVALID_INDEX; + ipv4_fd_ = OB_INVALID_INDEX; + ipv6_fd_ = OB_INVALID_INDEX; received_sig_ = OB_INVALID_INDEX; sub_pid_ = OB_INVALID_INDEX; rc_status_ = RCS_NONE; @@ -67,9 +69,9 @@ DEF_TO_STRING(ObHotUpgraderInfo) { int64_t pos = 0; J_OBJ_START(); - J_KV(K_(is_inherited), K_(upgrade_version), K_(need_conn_accept), K_(user_rejected), K_(fd), - K_(received_sig), K_(sub_pid), K_(graceful_exit_end_time), K_(graceful_exit_start_time), - K_(active_client_vc_count), K_(local_addr), + J_KV(K_(is_inherited), K_(upgrade_version), K_(need_conn_accept), K_(user_rejected), K_(ipv4_fd), + K_(ipv6_fd), K_(received_sig), K_(sub_pid), K_(graceful_exit_end_time), + K_(graceful_exit_start_time), K_(active_client_vc_count), K_(local_addr), "rc_status", get_rc_status_string(rc_status_), "hu_cmd", get_cmd_string(cmd_), "state", get_state_string(state_), diff --git a/src/obproxy/utils/ob_proxy_hot_upgrader.h b/src/obproxy/utils/ob_proxy_hot_upgrader.h index 95398a39..cbc14887 100644 --- a/src/obproxy/utils/ob_proxy_hot_upgrader.h +++ b/src/obproxy/utils/ob_proxy_hot_upgrader.h @@ -20,7 +20,8 @@ namespace oceanbase { namespace obproxy { -#define OBPROXY_INHERITED_FD "OBPROXY_INHERITED_FD" +#define OBPROXY_INHERITED_IPV4_FD "OBPROXY_INHERITED_FD" +#define OBPROXY_INHERITED_IPV6_FD "OBPROXY_INHERITED_IPV6_FD" extern volatile int g_proxy_fatal_errcode; enum ObReloadConfigStatus @@ -196,7 +197,8 @@ class ObHotUpgraderInfo static const int64_t MAX_RESTART_BUF_SIZE = 64; static const int64_t OB_MAX_INHERITED_ARGC = 4; - int fd_; // listen fd, which to be passed to sub process + int ipv4_fd_; // listen fd, which to be passed to sub process + int ipv6_fd_; int received_sig_; ObReloadConfigStatus rc_status_; // identify the current status for reload config volatile pid_t sub_pid_; // sub process pid if fork succeed diff --git a/src/obproxy/utils/ob_proxy_lib.h b/src/obproxy/utils/ob_proxy_lib.h index 01af9b92..98768673 100644 --- a/src/obproxy/utils/ob_proxy_lib.h +++ b/src/obproxy/utils/ob_proxy_lib.h @@ -200,6 +200,7 @@ static const uint64_t OBPROXY_DEFAULT_CAPABILITY_FLAG = | OB_CAP_PROXY_SESSION_SYNC | OB_CAP_PROXY_FULL_LINK_TRACING | OB_CAP_PROXY_NEW_EXTRA_INFO + | OB_CAP_PROXY_SESSION_VAR_SYNC ); #define OBPROXY_SYS_ERRNO_START -10000 diff --git a/src/obproxy/utils/ob_proxy_table_define.cpp b/src/obproxy/utils/ob_proxy_table_define.cpp index e98d559c..4cd0107f 100644 --- a/src/obproxy/utils/ob_proxy_table_define.cpp +++ b/src/obproxy/utils/ob_proxy_table_define.cpp @@ -98,11 +98,15 @@ const char *ObProxyTableInfo::PROXY_VIP_TENANT_VERSION_NAME = "o const char *ObProxyTableInfo::READ_ONLY_USERNAME_USER = "proxyro"; const char *ObProxyTableInfo::READ_ONLY_USERNAME = "proxyro@sys"; const char *ObProxyTableInfo::READ_ONLY_DATABASE = "oceanbase"; +const char *ObProxyTableInfo::OBSERVER_SYS_PASSWORD = "observer_sys_password"; +const char *ObProxyTableInfo::OBSERVER_SYS_PASSWORD1 = "observer_sys_password1"; const char *ObProxyTableInfo::TEST_MODE_USERNAME = "root@sys"; const char *ObProxyTableInfo::TEST_MODE_PASSWORD = ""; const char *ObProxyTableInfo::TEST_MODE_DATABASE = "oceanbase"; +const char *ObProxyTableInfo::DETECT_USERNAME_USER = "detect_user"; + const ObString ObProxyTableInfo::PROXY_ALL_PROXY_HEADER = ObString::make_string("all_proxy"); const ObString ObProxyTableInfo::PROXY_CONFIG_VERSION_NAME = ObString::make_string(".config_version"); const ObString ObProxyTableInfo::PROXY_UPGRADE_SWITCH_NAME = ObString::make_string(".upgrade_switch"); @@ -132,7 +136,7 @@ int ObProxyTableInfo::get_create_proxy_table_sql(char *buf, const int64_t len) } else { int64_t w_len = snprintf(buf, len, CREATE_PROXY_TABLE_SQL, PROXY_INFO_TABLE_NAME, - OB_IP_STR_BUFF, // ip + MAX_IP_ADDR_LENGTH, // ip OB_MAX_APP_NAME_LENGTH, // app_name OB_MAX_PROXY_BINARY_VERSION_LEN, // binary_version OB_MAX_UNAME_INFO_LEN, // system_info @@ -239,7 +243,7 @@ int ObProxyTableInfo::get_create_proxy_vip_tenant_table_sql(char *buf, const int } else { int64_t w_len = snprintf(buf, len, CREATE_PROXY_VIP_TENANT_TABLE_SQL, PROXY_VIP_TENANT_TABLE_NAME, // table name - OB_IP_STR_BUFF, // vip + MAX_IP_ADDR_LENGTH, // vip OB_MAX_TENANT_NAME_LENGTH, // tenant_name length OB_PROXY_MAX_CLUSTER_NAME_LENGTH, // cluster_name length OB_MAX_CONFIG_INFO_LEN // info length diff --git a/src/obproxy/utils/ob_proxy_table_define.h b/src/obproxy/utils/ob_proxy_table_define.h index f7691560..b0cfab63 100644 --- a/src/obproxy/utils/ob_proxy_table_define.h +++ b/src/obproxy/utils/ob_proxy_table_define.h @@ -67,10 +67,16 @@ class ObProxyTableInfo static const char *READ_ONLY_USERNAME_USER; static const char *READ_ONLY_USERNAME; static const char *READ_ONLY_DATABASE; + static const char *READ_ONLY_PASSWD_STAGED1; + + static const char *OBSERVER_SYS_PASSWORD; + static const char *OBSERVER_SYS_PASSWORD1; static const char *TEST_MODE_USERNAME; static const char *TEST_MODE_PASSWORD; static const char *TEST_MODE_DATABASE; + + static const char *DETECT_USERNAME_USER; }; } // end of namespace obproxy diff --git a/src/obproxy/utils/ob_proxy_utils.cpp b/src/obproxy/utils/ob_proxy_utils.cpp index b4e624e1..615bac67 100644 --- a/src/obproxy/utils/ob_proxy_utils.cpp +++ b/src/obproxy/utils/ob_proxy_utils.cpp @@ -344,5 +344,39 @@ int paste_tenant_and_cluster_name(const ObString &tenant_name, const ObString &c return ret; } +// split str like 'val0,val1;val2;val3' to +// item: val0 val1 val2 val3 +// weight: 0 0 1 2 +int split_weight_group(ObString weight_group_str, + ObIArray &items, + ObIArray &weights) { + int ret = OB_SUCCESS; + int8_t weight = 0; + bool finish = false; + while (OB_SUCC(ret) && !weight_group_str.empty() && !finish) { + ObString group = weight_group_str.split_on(';'); + if (group.empty()) { + group = weight_group_str; + finish = true; + } + // split by ',' + bool group_finish = false; + while (OB_SUCC(ret) && !group.empty() && !group_finish) { + ObString item = group.split_on(','); + if (item.empty()) { + item = group; + group_finish = true; + } + if (OB_FAIL(items.push_back(item))) { + LOG_WARN("fail to push back item", K(item), K(ret)); + } else if (OB_FAIL(weights.push_back(weight))) { + LOG_WARN("fail to push back weight", K(weight), K(ret)); + } else { /* succ */} + } + weight++; + } + return ret; +} + } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/utils/ob_proxy_utils.h b/src/obproxy/utils/ob_proxy_utils.h index 300d7c9c..62976d39 100644 --- a/src/obproxy/utils/ob_proxy_utils.h +++ b/src/obproxy/utils/ob_proxy_utils.h @@ -16,6 +16,7 @@ #include "common/ob_object.h" #include "lib/string/ob_fixed_length_string.h" #include "utils/ob_proxy_lib.h" +#include "iocore/net/ob_inet.h" namespace oceanbase { @@ -79,6 +80,12 @@ int convert_timestamp_to_version(int64_t time_us, char *buf, int64_t len); int paste_tenant_and_cluster_name(const common::ObString &tenant_name, const common::ObString &cluster_name, common::ObFixedLengthString &key_string); +// split str like val0,val1;val2;val3 into +// item: val0 val1 val2 val3 +// weight: 0 0 1 2 +int split_weight_group(common::ObString weight_group_str, + common::ObIArray &item, + common::ObIArray &weights); } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/utils/ob_target_db_server.cpp b/src/obproxy/utils/ob_target_db_server.cpp new file mode 100644 index 00000000..8a0384d0 --- /dev/null +++ b/src/obproxy/utils/ob_target_db_server.cpp @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ +#define USING_LOG_PREFIX PROXY +#include "utils/ob_target_db_server.h" + + +namespace oceanbase +{ +namespace obproxy +{ +using namespace oceanbase::common; + +int ObTargetDbServer::init(const char* target_db_server_str, uint64_t target_db_server_str_len) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_ISNULL(target_db_server_str)) { + ret = OB_INIT_FAIL; + LOG_WARN("fail to init target db server for NULL str", K(ret)); + } else if (target_db_server_str_len == 0) { + LOG_DEBUG("succ to init target db server with empty str"); + } else if (OB_ISNULL(target_db_server_buf_ = static_cast(op_fixed_mem_alloc(target_db_server_str_len + 1)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate mem for target db server", K(ret), K(target_db_server_str_len)); + } else { + target_db_server_buf_len_ = target_db_server_str_len + 1; + MEMSET(target_db_server_buf_, '\0', target_db_server_buf_len_); + MEMCPY(target_db_server_buf_, target_db_server_str, target_db_server_str_len); + + ObString target_db_server_str(target_db_server_str_len, target_db_server_buf_); + if (OB_FAIL(split_weight_group(target_db_server_str, target_db_server_, target_db_server_weight_))) { + LOG_WARN("fail to split target db server str", K(ret)); + } else { /* succ */ } + } + + if (OB_SUCC(ret)) { + is_init_ = true; + LOG_DEBUG("succ to init all target db server", K_(target_db_server), K_(target_db_server_weight)); + } else { + reset(); + } + return ret; +} + +int ObTargetDbServer::get(net::ObIpEndpoint &dest) +{ + int ret = OB_SUCCESS; + + // [weight_start, weight_end) + if (!is_init_) { + ret = OB_INIT_FAIL; + LOG_WARN("fail to get next, target db server not init", K(ret)); + } else if (last_failed_idx_ == target_db_server_.count() - 1) { + ret = OB_DATA_OUT_OF_RANGE; + LOG_WARN("fail to get next, all target db server has failed", K(ret)); + } else if (!is_rand_) { + ObTargetDbServerArray::iterator weight_begin = target_db_server_.begin(); + for (int64_t i = 0; i < target_db_server_.count(); i++) { + if (i == target_db_server_.count() - 1) { + std::random_shuffle(weight_begin, target_db_server_.end()); + } else if (target_db_server_weight_.at(i) != target_db_server_weight_.at(i + 1)) { + ObTargetDbServerArray::iterator weight_end = target_db_server_.begin() + (i + 1); + std::random_shuffle(weight_begin, weight_end); + weight_begin = weight_end; + } + } + is_rand_ = true; + } + if (OB_SUCC(ret)) { + ObString addr; + uint64_t idx = last_failed_idx_ + 1; + if (OB_FAIL(target_db_server_.at(idx, addr))) { + LOG_WARN("fail to access target db server array", K(ret), K(idx)); + } else if (OB_FAIL(ops_ip_pton(addr, dest))) { + LOG_WARN("fail to do ops_ip_pton on target db server", K(ret), K(addr)); + } else { + LOG_DEBUG("succ to get target db server", K(dest)); + } + } + return ret; +} + +int ObTargetDbServer::get_next(net::ObIpEndpoint &dest_addr) +{ + // mark previous one as failed + last_failed_idx_++; + return get(dest_addr); +} + +void ObTargetDbServer::reset() +{ + is_init_ = false; + is_rand_ = false; + last_failed_idx_ = -1; + if (OB_NOT_NULL(target_db_server_buf_)) { + op_fixed_mem_free(target_db_server_buf_, target_db_server_buf_len_); + target_db_server_buf_len_ = 0; + target_db_server_buf_ = NULL; + } + target_db_server_.reset(); + target_db_server_weight_.reset(); +} + +bool ObTargetDbServer::contains(net::ObIpEndpoint &addr) +{ + bool ret = false; + if (is_init_) { + char addr_buf[MAX_IP_ADDR_LENGTH]; + MEMSET(addr_buf, '\0', MAX_IP_ADDR_LENGTH); + // get like '{xxx.xxxx.xxx.xxx:xxxx}' + addr.to_string(addr_buf, sizeof(addr_buf)); + // remove the last '}' + addr_buf[strlen(addr_buf) - 1] = '\0'; + ObTargetDbServerArray::iterator it = target_db_server_.begin(); + while (it != target_db_server_.end()) { + // skip the first '{' + if (it->case_compare(addr_buf + 1) == 0) { + ret = true; + break; + } + it++; + } + } else { + LOG_DEBUG("target db server not init!"); + } + return ret; +} + +int64_t ObTargetDbServer::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(is_init), K_(is_rand), K_(last_failed_idx), K_(target_db_server)); + J_OBJ_END(); + return pos; +} +} // namespace obproxy +} // namespace oceanbase \ No newline at end of file diff --git a/src/obproxy/utils/ob_target_db_server.h b/src/obproxy/utils/ob_target_db_server.h new file mode 100644 index 00000000..54a3ef88 --- /dev/null +++ b/src/obproxy/utils/ob_target_db_server.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ +#ifndef OB_TARGET_DB_SERVER_H +#define OB_TARGET_DB_SERVER_H + +#include "lib/ob_define.h" +#include "lib/container/ob_se_array.h" +#include "lib/container/ob_se_array_iterator.h" +#include "lib/utility/ob_print_utils.h" +#include "iocore/net/ob_inet.h" +#include "lib/string/ob_string.h" +#include "utils/ob_proxy_utils.h" +#include "iocore/eventsystem/ob_buf_allocator.h" + +namespace oceanbase +{ +namespace obproxy +{ +typedef common::ObSEArray ObTargetDbServerArray; +class ObTargetDbServer +{ +public: + ObTargetDbServer() : + is_init_(false), is_rand_(false), last_failed_idx_(-1), + target_db_server_buf_(NULL), target_db_server_buf_len_(0) {} + + ObTargetDbServer& operator=(const ObTargetDbServer &other) { + if (this != &other) { + reset(); + // other.target_db_server_buf_len_ - 1 to minus last '\0' + init(other.target_db_server_buf_, other.target_db_server_buf_len_ - 1); + } + return *this; + } + + ~ObTargetDbServer() { + reset(); + } + + int init(const char* target_db_server_buf, uint64_t target_db_server_buf_len); + // get the server with the highest priority execpt failed servers + int get(net::ObIpEndpoint &dest_addr); + // mark the previous visit server as failed then call get() + int get_next(net::ObIpEndpoint &dest_addr); + // num of target db server + inline int64_t num() const { return is_init_? target_db_server_.count() : 0; } + void reset(); + int64_t to_string(char *buf, const int64_t buf_len) const; + bool contains(net::ObIpEndpoint &addr); + + inline bool is_init() const { return is_init_; } + inline bool is_empty() const { return is_init_? target_db_server_.empty() : true; } + inline void reuse() { is_rand_ = false; last_failed_idx_ = -1; } + +private: + bool is_init_; + bool is_rand_; + int64_t last_failed_idx_; + char* target_db_server_buf_; + uint64_t target_db_server_buf_len_; + + ObTargetDbServerArray target_db_server_; + common::ObSEArray target_db_server_weight_; +}; + +} // end of namespace obproxy +} // end of namespace oceanbase +#endif \ No newline at end of file diff --git a/src/rpc/Makemodule.am b/src/rpc/Makemodule.am index 50120c29..3b318e9f 100644 --- a/src/rpc/Makemodule.am +++ b/src/rpc/Makemodule.am @@ -20,6 +20,10 @@ rpc/obmysql/packet/ompk_handshake_response.h\ rpc/obmysql/packet/ompk_handshake_response.cpp\ rpc/obmysql/packet/ompk_prepare.h\ rpc/obmysql/packet/ompk_prepare.cpp\ +rpc/obmysql/packet/ompk_prepare_execute.h\ +rpc/obmysql/packet/ompk_prepare_execute.cpp\ +rpc/obmysql/packet/ompk_prepare_execute_req.h\ +rpc/obmysql/packet/ompk_prepare_execute_req.cpp\ rpc/obmysql/packet/ompk_ping.h\ rpc/obmysql/packet/ompk_ssl_request.h\ rpc/obmysql/packet/ompk_ssl_request.cpp diff --git a/src/rpc/ob_request.cpp b/src/rpc/ob_request.cpp index f2e4c658..4b692185 100644 --- a/src/rpc/ob_request.cpp +++ b/src/rpc/ob_request.cpp @@ -24,8 +24,11 @@ char *ObRequest::easy_alloc(int64_t size) const if (NULL == ez_req_ || NULL == ez_req_->ms) { RPC_LOG(ERROR, "ez_req_ is not corret"); } else { - buf = easy_pool_alloc( - ez_req_->ms->pool, static_cast(size)); + /* this function is defined for c driver client compile */ + UNUSED(size); + buf = NULL; + // buf = easy_pool_alloc( + // ez_req_->ms->pool, static_cast(size)); } return static_cast(buf); } diff --git a/src/rpc/obmysql/ob_mysql_field.cpp b/src/rpc/obmysql/ob_mysql_field.cpp index dfd6198b..21d30995 100644 --- a/src/rpc/obmysql/ob_mysql_field.cpp +++ b/src/rpc/obmysql/ob_mysql_field.cpp @@ -94,6 +94,15 @@ int ObMySQLField::serialize_pro41(char *buf, const int64_t len, int64_t &pos) co LOG_WARN("serialize 0 failed", K(ret)); } } + if (OB_SUCC(ret) && OB_MYSQL_TYPE_COMPLEX == type_) { + if (OB_FAIL(ObMySQLUtil::store_str_v(buf, len, type_info_.relation_name_.ptr(), type_info_.relation_name_.length(), pos))) { + LOG_WARN("serialize relation_name_ failed", K(ret)); + } else if (OB_FAIL(ObMySQLUtil::store_str_v(buf, len, type_info_.type_name_.ptr(), type_info_.type_name_.length(),pos))) { + LOG_WARN("serialize type_name_ failed", K(ret)); + } else if (OB_FAIL(ObMySQLUtil::store_length(buf, len, type_info_.version_, pos))) { + LOG_WARN("serialize type_name_ failed", K(ret)); + } else { /* succ to write complex type */ } + } return ret; } diff --git a/src/rpc/obmysql/ob_mysql_field.h b/src/rpc/obmysql/ob_mysql_field.h index 32cfc7ab..e8001a6a 100644 --- a/src/rpc/obmysql/ob_mysql_field.h +++ b/src/rpc/obmysql/ob_mysql_field.h @@ -22,6 +22,17 @@ namespace oceanbase { namespace obmysql { + +struct TypeInfo { + TypeInfo() : relation_name_(), type_name_(), version_(0), is_elem_type_(false) {} ; + common::ObString relation_name_; + common::ObString type_name_; + uint64_t version_; + ObObjType elem_type_; + bool is_elem_type_; + TO_STRING_KV(K_(relation_name), K_(type_name), K_(version), K_(elem_type), K_(is_elem_type)); +}; + class ObMySQLField { public: @@ -90,6 +101,7 @@ class ObMySQLField common::ObString org_cname_; // original column name common::ObAccuracy accuracy_; EMySQLFieldType type_; // value type + TypeInfo type_info_; // for complex type uint16_t flags_; // unsigned and so on... EMySQLFieldType default_value_; //default value, only effective when command was OB_MYSQL_COM_FIELD_LIST uint16_t charsetnr_; //character set of table diff --git a/src/rpc/obmysql/ob_mysql_global.h b/src/rpc/obmysql/ob_mysql_global.h index ff2cc80b..1acf42dc 100644 --- a/src/rpc/obmysql/ob_mysql_global.h +++ b/src/rpc/obmysql/ob_mysql_global.h @@ -100,6 +100,7 @@ enum EMySQLFieldType OB_MYSQL_TYPE_OB_TIMESTAMP_NANO = 202, OB_MYSQL_TYPE_OB_RAW = 203, OB_MYSQL_TYPE_OB_UROWID = 209, + OB_MYSQL_TYPE_JSON = 245, OB_MYSQL_TYPE_NEWDECIMAL = 246, OB_MYSQL_TYPE_ENUM = 247, OB_MYSQL_TYPE_SET = 248, @@ -219,6 +220,9 @@ inline const char *get_emysql_field_type_str(const obmysql::EMySQLFieldType &typ case obmysql::OB_MYSQL_TYPE_STRING: str = "OB_MYSQL_TYPE_STRING"; break; + case obmysql::OB_MYSQL_TYPE_JSON: + str = "OB_MYSQL_TYPE_JSON"; + break; case obmysql::OB_MYSQL_TYPE_GEOMETRY: str = "OB_MYSQL_TYPE_GEOMETRY"; break; diff --git a/src/rpc/obmysql/packet/ompk_handshake.cpp b/src/rpc/obmysql/packet/ompk_handshake.cpp index a24c89a7..e7aa4381 100644 --- a/src/rpc/obmysql/packet/ompk_handshake.cpp +++ b/src/rpc/obmysql/packet/ompk_handshake.cpp @@ -69,11 +69,11 @@ OMPKHandshake::OMPKHandshake() auth_plugin_data_len_ = 0; } - server_language_ = 83;//utf8_bin - server_status_ = 0;// no this value in mysql protocol document + server_language_ = 46; // utf8mb4_bin + server_status_ = 0; // no this value in mysql protocol document //auth_plugin_data_len_ = 0; - memset(reserved_, 0, sizeof (reserved_)); - memset(auth_plugin_data2_, 'b', sizeof (auth_plugin_data2_) - 1); + memset(reserved_, 0, sizeof(reserved_)); + memset(auth_plugin_data2_, 'b', sizeof(auth_plugin_data2_) - 1); } OMPKHandshake::~OMPKHandshake() diff --git a/src/rpc/obmysql/packet/ompk_handshake_response.h b/src/rpc/obmysql/packet/ompk_handshake_response.h index ffbeb1cc..ecb0a0c6 100644 --- a/src/rpc/obmysql/packet/ompk_handshake_response.h +++ b/src/rpc/obmysql/packet/ompk_handshake_response.h @@ -49,7 +49,7 @@ class OMPKHandshakeResponse : public ObMySQLPacket inline const ObString &get_auth_response() const { return auth_response_; } inline const ObString &get_database() const { return database_; } inline const ObString &get_auth_plugin_name() const { return auth_plugin_name_; } - inline const common::ObIArray &get_connect_attrs() const { return connect_attrs_; } + inline common::ObIArray &get_connect_attrs() { return connect_attrs_; } bool is_obproxy_client_mod() const; inline void set_capability_flags(const ObMySQLCapabilityFlags &cap) { capability_ = cap; } diff --git a/src/rpc/obmysql/packet/ompk_prepare_execute.cpp b/src/rpc/obmysql/packet/ompk_prepare_execute.cpp new file mode 100644 index 00000000..23bdf666 --- /dev/null +++ b/src/rpc/obmysql/packet/ompk_prepare_execute.cpp @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX RPC_OBMYSQL +#include "ompk_prepare_execute.h" +#include "lib/oblog/ob_log_module.h" +#include "rpc/obmysql/ob_mysql_util.h" + +using namespace oceanbase::common; +using namespace oceanbase::obmysql; + +namespace oceanbase +{ +using namespace common; +namespace obmysql +{ + +int OMPKPrepareExecute::decode() +{ + int ret = OB_SUCCESS; + const char *pos = cdata_; + if (NULL != cdata_) { + ObMySQLUtil::get_uint1(pos, status_); + ObMySQLUtil::get_uint4(pos, statement_id_); + ObMySQLUtil::get_uint2(pos, column_num_); + ObMySQLUtil::get_uint2(pos, param_num_); + ObMySQLUtil::get_uint1(pos, reserved_); + ObMySQLUtil::get_uint2(pos, warning_count_); + ObMySQLUtil::get_uint4(pos, extend_flag_); + ObMySQLUtil::get_uint1(pos, has_result_set_); + } else { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("null input", K(ret), K(cdata_)); + } + return ret; +} + +int OMPKPrepareExecute::serialize(char* buffer, int64_t length, int64_t& pos) const +{ + int ret = OB_SUCCESS; + if (NULL == buffer || 0 >= length || pos < 0 || length - pos < get_serialize_size()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(buffer), K(length), K(pos), "need_size", get_serialize_size()); + } else { + if (OB_SUCCESS != (ret = ObMySQLUtil::store_int1(buffer, length, status_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(status), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int4(buffer, length, statement_id_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(statement_id), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int2(buffer, length, column_num_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(column_num), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int2(buffer, length, param_num_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(param_num), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int1(buffer, length, reserved_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(reserved), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int2(buffer, length, warning_count_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(warning_count), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int4(buffer, length, extend_flag_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(extend_flag), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int1(buffer, length, has_result_set_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(has_result_set), K(pos)); + } + } + return ret; +} + +int64_t OMPKPrepareExecute::get_serialize_size() const +{ + int64_t len = 0; + len += 1; // status + len += 4; // statement id + len += 2; // column num + len += 2; // param num + len += 1; // reserved + len += 2; // warning count + len += 4; // extend flags + len += 1; // has result set + return len; +} + + + + +} //end of obmysql +} //end of oceanbase diff --git a/src/rpc/obmysql/packet/ompk_prepare_execute.h b/src/rpc/obmysql/packet/ompk_prepare_execute.h new file mode 100644 index 00000000..f33c6ce1 --- /dev/null +++ b/src/rpc/obmysql/packet/ompk_prepare_execute.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + + +#ifndef OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_H_ +#define OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_H_ + +#include "ompk_prepare_execute.h" +#include "rpc/obmysql/ob_mysql_packet.h" +#include "lib/utility/ob_macro_utils.h" + +namespace oceanbase +{ +namespace obmysql +{ + +/** + * This packet is response to OB_MYSQL_COM_STMT_PREPARE + * following with param desc && column desc packets + * + * status (1) -- [00] OK + * statement_id (4) -- statement-id + * num_columns (2) -- number of columns + * num_params (2) -- number of params + * reserved_ (1) -- [00] filler + * warning_count (2) -- number of warnings + */ + +class OMPKPrepareExecute: public ObMySQLPacket +{ +public: + OMPKPrepareExecute() : + status_(0), + statement_id_(0), + column_num_(0), + param_num_(0), + reserved_(0), + warning_count_(0), + extend_flag_(0), + has_result_set_(0) + {} + virtual ~OMPKPrepareExecute() {} + + int decode(); + virtual int serialize(char* buffer, int64_t length, int64_t& pos) const; + virtual int64_t get_serialize_size() const; + + inline void set_status(const uint8_t status) { status_ = status; } + inline void set_statement_id(const uint32_t id) { statement_id_ = id; } + inline void set_column_num(const uint16_t num) { column_num_ = num;} + inline void set_param_num(const uint16_t num) { param_num_ = num; } + inline void set_warning_count(const uint16_t count) { warning_count_ = count; } + inline void set_extend_flag(const uint32_t extend_flag) { extend_flag_ = extend_flag; } + inline void set_has_result_set(const uint8_t has_result_set) { has_result_set_ = has_result_set; } + + inline uint32_t get_statement_id() const { return statement_id_; } + inline uint16_t get_column_num() const { return column_num_;} + inline uint16_t get_param_num() const { return param_num_; } + inline uint16_t get_warning_count() const { return warning_count_; } + inline uint32_t get_extend_flag() const { return extend_flag_; } + inline uint8_t has_result_set() const { return has_result_set_; } + +private: + uint8_t status_; + uint32_t statement_id_; + uint16_t column_num_; + uint16_t param_num_; + uint8_t reserved_; + uint16_t warning_count_; + uint32_t extend_flag_; + uint8_t has_result_set_; + DISALLOW_COPY_AND_ASSIGN(OMPKPrepareExecute); +}; + +} //end of obmysql +} //end of oceanbase + + +#endif //OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_H_ diff --git a/src/rpc/obmysql/packet/ompk_prepare_execute_req.cpp b/src/rpc/obmysql/packet/ompk_prepare_execute_req.cpp new file mode 100644 index 00000000..533ec01e --- /dev/null +++ b/src/rpc/obmysql/packet/ompk_prepare_execute_req.cpp @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX RPC_OBMYSQL +#include "ompk_prepare_execute_req.h" + +using namespace oceanbase::common; +using namespace oceanbase::obmysql; +namespace oceanbase +{ +using namespace common; +using namespace obproxy; +using namespace proxy; + +namespace obmysql +{ + +int OMPKPrepareExecuteReq::decode() +{ + int ret = OB_SUCCESS; + const char *pos = cdata_; + int64_t data_len = hdr_.len_; + if (NULL != cdata_) { + uint64_t query_len = 0; + // skip cmd + if (OB_FAIL(ObMysqlPacketUtil::get_uint1(pos, data_len, cmd_))) { + LOG_WARN("fail to get uint1", K(data_len), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint4(pos, data_len, statement_id_))) { + LOG_WARN("fail to get uint4", K(data_len), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint1(pos, data_len, flags_))) { + LOG_WARN("fail to get uint1", K(data_len), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint4(pos, data_len, iteration_count_))) { + LOG_WARN("fail to get uint4", K(data_len), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_length(pos, data_len, query_len))) { + LOG_WARN("fail to get length", K(data_len), K(ret)); + // skip query + } else if (FALSE_IT(pos += query_len)) { + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint4(pos, data_len, param_num_))) { + LOG_WARN("fail to get uint4", K(data_len), K(ret)); + // skip null bitmap + } else if (param_num_ <= 0) { + LOG_DEBUG("skip read param related", K(param_num_)); + } else if (FALSE_IT(pos += (param_num_ + 7)/8)) { + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint1(pos, data_len, new_params_bound_flag_))) { + LOG_WARN("fail to get uint1", K(data_len), K(ret)); + } else if (new_params_bound_flag_ == 1 + && OB_FAIL(ObMysqlRequestAnalyzer::parse_param_type(param_num_, param_types_, type_infos_, pos, data_len))) { + LOG_WARN("fail to parse param type", K_(param_num), K(pos), K(data_len), K(ret)); + } else { /* do nothing */ } + // skip the rest of data + } else { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("null input", K(ret), K(cdata_)); + } + return ret; +} + +} //end of obmysql +} //end of oceanbase diff --git a/src/rpc/obmysql/packet/ompk_prepare_execute_req.h b/src/rpc/obmysql/packet/ompk_prepare_execute_req.h new file mode 100644 index 00000000..c1d148f8 --- /dev/null +++ b/src/rpc/obmysql/packet/ompk_prepare_execute_req.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + + +#ifndef OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_REQ_H_ +#define OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_REQ_H_ + +#include "rpc/obmysql/ob_mysql_util.h" +#include "lib/container/ob_se_array.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/oblog/ob_log_module.h" +#include "obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h" +#include "obproxy/packet/ob_mysql_packet_util.h" +namespace oceanbase +{ + +namespace obmysql +{ + +/** + * This packet is request to OB_MYSQL_COM_STMT_PREPARE_EXECUTE + * following with param desc && column desc packets + * + */ + +class OMPKPrepareExecuteReq: public ObMySQLPacket +{ +public: + OMPKPrepareExecuteReq() : + cmd_(OB_MYSQL_COM_STMT_PREPARE_EXECUTE), + statement_id_(0), + flags_(0), + iteration_count_(0), + query_(NULL), + param_num_(0), + null_bitmap_(NULL), + new_params_bound_flag_(0) + {} + virtual ~OMPKPrepareExecuteReq() {} + + virtual int decode(); + + inline uint32_t get_statement_id() const { return statement_id_; } + inline uint32_t get_param_num() const { return param_num_; } + inline common::ObIArray& get_param_types() { return param_types_; } + inline common::ObIArray& get_type_infos() { return type_infos_; } + +private: + uint8_t cmd_; + uint32_t statement_id_; + uint8_t flags_; + uint32_t iteration_count_; + common::ObString query_; + uint32_t param_num_; + char* null_bitmap_; + uint8_t new_params_bound_flag_; + common::ObSEArray param_types_; + common::ObSEArray type_infos_; + // ingore value of eache parameter + uint32_t execute_mode_; + uint32_t num_close_stmt_count_; + uint32_t check_sum_; + uint32_t extend_flag_; + + DISALLOW_COPY_AND_ASSIGN(OMPKPrepareExecuteReq); +}; + +} //end of obmysql +} //end of oceanbase + + +#endif //OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_REQ_H_ diff --git a/src/share/config/ob_common_config.cpp b/src/share/config/ob_common_config.cpp index f02b5d6d..7f15540a 100644 --- a/src/share/config/ob_common_config.cpp +++ b/src/share/config/ob_common_config.cpp @@ -15,6 +15,7 @@ #include "share/config/ob_server_config.h" #include "common/ob_record_header.h" +static const char *ignore_config_opt_str[] = {"target_db_server"}; namespace oceanbase { namespace common @@ -44,9 +45,26 @@ ObCommonConfig::~ObCommonConfig() { } +// tmp use for opt str +int ObCommonConfig::add_extra_config_from_opt(const char *config_str, + int64_t version /* = 0 */ , + bool check_name /* = false */) +{ + return add_config(config_str, version, check_name, ",\n", ignore_config_opt_str); +} + int ObCommonConfig::add_extra_config(const char *config_str, int64_t version /* = 0 */ , bool check_name /* = false */) +{ + return add_config(config_str, version, check_name, "\n", NULL); +} + +int ObCommonConfig::add_config(const char *config_str, + int64_t version /* = 0 */ , + bool check_name /* = false */, + const char* delim, + const char* ignore_conf[]) { int ret = OB_SUCCESS; const int64_t MAX_OPTS_LENGTH = sysconf(_SC_ARG_MAX); @@ -67,7 +85,7 @@ int ObCommonConfig::add_extra_config(const char *config_str, } else { MEMCPY(buf, config_str, config_str_length); buf[config_str_length] = '\0'; - token = STRTOK_R(buf, ",\n", &saveptr); + token = STRTOK_R(buf, delim, &saveptr); } while (OB_SUCC(ret) && OB_LIKELY(NULL != token)) { @@ -86,7 +104,21 @@ int ObCommonConfig::add_extra_config(const char *config_str, value = saveptr_one; } + bool ignore = false; + if (OB_SUCC(ret) && OB_NOT_NULL(ignore_conf)) { + int64_t ignore_conf_num = sizeof(ignore_config_opt_str)/sizeof(char*); + for (int64_t i = 0; i < ignore_conf_num; i++) { + ObString conf(ignore_conf[i]); + if (OB_NOT_NULL(ignore_conf[i]) && conf.case_compare(name) == 0) { + ignore = true; + break; + } + } + } + if (OB_FAIL(ret)) { + } else if (ignore) { + LOG_INFO("Ignore config", K(name), K(value)); } else if (OB_ISNULL(pp_item = container_.get(ObConfigStringKey(name)))) { /* make compatible with previous configuration */ ret = check_name ? OB_INVALID_CONFIG : OB_SUCCESS; @@ -101,7 +133,7 @@ int ObCommonConfig::add_extra_config(const char *config_str, (*pp_item)->set_version(version); LOG_INFO("Load config succ", K(name), K(value)); } - token = STRTOK_R(NULL, ",\n", &saveptr); + token = STRTOK_R(NULL, delim, &saveptr); } if (NULL != buf) { diff --git a/src/share/config/ob_common_config.h b/src/share/config/ob_common_config.h index d1a51b6c..a34c9df0 100644 --- a/src/share/config/ob_common_config.h +++ b/src/share/config/ob_common_config.h @@ -77,6 +77,15 @@ class ObCommonConfig : public ObInitConfigContainer virtual int add_extra_config(const char *config_str, const int64_t version = 0, const bool check_name = false); + int add_extra_config_from_opt(const char *config_str, + const int64_t version = 0, + const bool check_name = false); + int add_config(const char *config_str, + int64_t version, + bool check_name, + const char* delim, + const char* ignore_conf[]); + virtual bool is_debug_sync_enabled() const { return false; } NEED_SERIALIZE_AND_DESERIALIZE; diff --git a/src/share/config/ob_config.h b/src/share/config/ob_config.h index 77d42d93..bfe2042f 100644 --- a/src/share/config/ob_config.h +++ b/src/share/config/ob_config.h @@ -349,7 +349,7 @@ class ObConfigIntegralItem virtual bool parse_range(const char *range); virtual void set_initial_value() { initial_value_ = value_; is_initial_value_set_ = true; } -protected: +public: //use current value to do input operation bool set(const char *str); virtual int64_t parse(const char *str, bool &valid) const = 0; diff --git a/src/share/config/ob_config_helper.cpp b/src/share/config/ob_config_helper.cpp index cc4a43d5..5e9bca71 100644 --- a/src/share/config/ob_config_helper.cpp +++ b/src/share/config/ob_config_helper.cpp @@ -17,11 +17,16 @@ namespace oceanbase { namespace common { + bool ObConfigIpChecker::check(const ObConfigItem &t) const { - struct sockaddr_in sa; - int result = inet_pton(AF_INET, t.str(), &(sa.sin_addr)); - return result != 0; + struct in_addr in; + int result = inet_pton(AF_INET, t.str(), &in); + if (result != 1) { + struct in6_addr in6; + result = inet_pton(AF_INET6, t.str(), &in6); + } + return result == 1; } ObConfigConsChecker:: ~ObConfigConsChecker() diff --git a/src/share/inner_table/ob_inner_table_schema_constants.h b/src/share/inner_table/ob_inner_table_schema_constants.h index c4df4b9f..dbad5b7a 100644 --- a/src/share/inner_table/ob_inner_table_schema_constants.h +++ b/src/share/inner_table/ob_inner_table_schema_constants.h @@ -298,6 +298,7 @@ const char *const OB_HELP_KEYWORD_TNAME = "help_keyw const char *const OB_HELP_RELATION_TNAME = "help_relation"; const char *const OB_ALL_LOCAL_INDEX_STATUS_TNAME = "__all_local_index_status"; const char *const OB_ALL_DUMMY_TNAME = "__all_dummy"; +const char *const OB_ALL_BINLOG_DUMMY_TNAME = "__all_binlog_dummy"; const char *const OB_ALL_FROZEN_MAP_TNAME = "__all_frozen_map"; const char *const OB_ALL_CLOG_HISTORY_INFO_TNAME = "__all_clog_history_info"; const char *const OB_ALL_CLOG_HISTORY_INFO_V2_TNAME = "__all_clog_history_info_v2"; diff --git a/src/share/part/ob_part_desc.cpp b/src/share/part/ob_part_desc.cpp index f0efb691..58fdc09f 100644 --- a/src/share/part/ob_part_desc.cpp +++ b/src/share/part/ob_part_desc.cpp @@ -13,6 +13,7 @@ #include "share/part/ob_part_desc.h" #include "common/ob_obj_cast.h" #include "obproxy/proxy/mysqllib/ob_proxy_session_info.h" +#include "obproxy/proxy/route/obproxy_expr_calculator.h" namespace oceanbase @@ -92,9 +93,47 @@ int ObPartDesc::build_dtc_params(obproxy::proxy::ObClientSessionInfo *session_in return ret; } -void ObPartDesc::set_accuracy(const ObProxyPartKeyAccuracy &accuracy) +int ObPartDesc::cast_obj(ObObj &src_obj, + ObObj &target_obj, + ObIAllocator &allocator, + ObPartDescCtx &ctx, + ObAccuracy &accuracy) { - accuracy_ = accuracy; + return cast_obj(src_obj, target_obj.get_type(), target_obj.get_collation_type(), allocator, ctx, accuracy); +} + +int ObPartDesc::cast_obj(ObObj &src_obj, + ObObjType obj_type, + ObCollationType cs_type, + ObIAllocator &allocator, + ObPartDescCtx &ctx, + ObAccuracy &accuracy) +{ + int ret = OB_SUCCESS; + COMMON_LOG(DEBUG, "begin to cast obj", K(src_obj), K(obj_type), K(cs_type)); + + ObTimeZoneInfo tz_info; + ObDataTypeCastParams dtc_params; + + if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), + obj_type, tz_info, dtc_params))) { + COMMON_LOG(WARN, "fail to build dtc params with ctx session", K(ret), K(obj_type)); + } else { + ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, cs_type); + const ObObj *res_obj = &src_obj; + + // use src_obj as buf_obj + if (OB_FAIL(ObObjCasterV2::to_type(obj_type, cs_type, cast_ctx, src_obj, src_obj))) { + COMMON_LOG(WARN, "failed to cast obj", K(ret), K(src_obj), K(obj_type), K(cs_type)); + } else if (ctx.need_accurate() + && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, cs_type, *res_obj, src_obj, res_obj))) { + COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj)); + } else { + COMMON_LOG(DEBUG, "end to cast obj for range", K(src_obj), K(obj_type), K(cs_type)); + } + } + + return ret; } } // end of common diff --git a/src/share/part/ob_part_desc.h b/src/share/part/ob_part_desc.h index b81027cd..77e271e7 100644 --- a/src/share/part/ob_part_desc.h +++ b/src/share/part/ob_part_desc.h @@ -18,6 +18,7 @@ #include "lib/timezone/ob_time_convert.h" #include "share/part/ob_part_mgr_util.h" #include "obproxy/opsql/expr_parser/ob_expr_parse_result.h" +#include "common/ob_row.h" namespace oceanbase { @@ -82,12 +83,25 @@ class ObPartDesc int build_dtc_params(obproxy::proxy::ObClientSessionInfo *session_info, ObObjType obj_type, ObDataTypeCastParams &dtc_params); - void set_accuracy(const ObProxyPartKeyAccuracy &accuracy); - + ObIArray &get_accuracies() { return accuracies_; } + + int cast_obj(ObObj &src_obj, + ObObj &target_obj, + ObIAllocator &allocator, + ObPartDescCtx &ctx, + ObAccuracy &accuracy); + + int cast_obj(ObObj &src_obj, + ObObjType obj_type, + ObCollationType cs_type, + ObIAllocator &allocator, + ObPartDescCtx &ctx, + ObAccuracy &accuracy); + DECLARE_VIRTUAL_TO_STRING = 0; share::schema::ObPartitionLevel part_level_; share::schema::ObPartitionFuncType part_func_type_; - ObProxyPartKeyAccuracy accuracy_; + ObSEArray accuracies_; int64_t *tablet_id_array_; }; diff --git a/src/share/part/ob_part_desc_hash.cpp b/src/share/part/ob_part_desc_hash.cpp index d5101432..e90b1421 100644 --- a/src/share/part/ob_part_desc_hash.cpp +++ b/src/share/part/ob_part_desc_hash.cpp @@ -27,10 +27,15 @@ ObPartDescHash::ObPartDescHash() : is_oracle_mode_(false) { } -/* +/** GET PARTITION ID - - If input is not single int value, get all partition ids; otherwise, get the particular one. + Hash partition only route like 'by hash(c1,c2) ... where c1=xx and c2=xx', + only use range.start_key_ to calc, because when condition is like 'c1=xx', + start_key_[i] == end_key_[i] + @param range (xxx,yyy,min,min ; xxx,yyy,max,max) + @param allocator + @param part_ids[out] + @param ctx */ int ObPartDescHash::get_part(ObNewRange &range, ObIAllocator &allocator, @@ -38,30 +43,72 @@ int ObPartDescHash::get_part(ObNewRange &range, ObPartDescCtx &ctx, ObIArray &tablet_ids) { - int ret = OB_SUCCESS; - if (1 != range.get_start_key().get_obj_cnt()) { // single value - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(DEBUG, "hash part should be single key", - "obj_cnt", range.get_start_key().get_obj_cnt(), K(ret)); - } else { - int64_t part_idx = -1; - ObObj &src_obj = const_cast(range.get_start_key().get_obj_ptr()[0]); - if (is_oracle_mode_) { - ret = calc_value_for_oracle(src_obj, allocator, part_idx, ctx); + int ret = OB_SUCCESS; + // 1. Cast obj + // provide all objs are valid. + // "valid" means the obj not min or max + int64_t valid_obj_cnt = range.start_key_.get_obj_cnt(); + for (int64_t i = 0; OB_SUCC(ret) && i < range.start_key_.get_obj_cnt(); i++) { + // if obj is min or max, means all valid obj has been casted + if (range.start_key_.get_obj_ptr()[i].is_max_value() || + range.start_key_.get_obj_ptr()[i].is_min_value()) { + // minus the number of invalid obj + valid_obj_cnt = valid_obj_cnt - (range.start_key_.get_obj_cnt() - i); + // not need to cast any more and break loop + if (valid_obj_cnt == 0) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "not support hash partition calc with range", K(range)); + } + break; } else { - ret = calc_value_for_mysql(src_obj, allocator, part_idx); + ObObj *src_obj = const_cast(&range.start_key_.get_obj_ptr()[i]); + if (OB_ISNULL(src_obj)) { + // here src_obj shouldn't be null + ret = OB_ERR_NULL_VALUE; + COMMON_LOG(ERROR, "unexpected null pointer src_obj"); + } else if (src_obj->is_null()) { + // here src_obj shouldn't be null type + ret = OB_OBJ_TYPE_ERROR; + COMMON_LOG(ERROR, "unexpected null type", K(src_obj)); + // oracle mode cast all valid objs to target type + } else if (is_oracle_mode_) { + if(OB_FAIL(cast_obj(*src_obj, obj_types_[i], cs_types_[i], allocator, ctx, accuracies_.at(i)))) { + COMMON_LOG(WARN, "cast obj failed", K(src_obj), "obj_type", obj_types_[i], "cs_type", cs_types_[i]); + // TODO: handle failure + } + // mysql mode only cast first valid obj to int type then break loop + } else /*if (is_mysql_mode_) */ { + ObCastCtx cast_ctx(&allocator, NULL, CM_NULL_ON_WARN, CS_TYPE_INVALID); + if (OB_FAIL(ObObjCasterV2::to_type(ObIntType, cs_types_[i], cast_ctx, *src_obj, *src_obj))) { + COMMON_LOG(WARN, "failed to cast to ObIntType", K(src_obj), K(ret)); + } + break; + } } + } - if (OB_SUCC(ret)) { - int64_t part_id = -1; - if (OB_FAIL(get_part_hash_idx(part_idx, part_id))) { - COMMON_LOG(WARN, "fail to get part hash id", K(ret)); - } else if (OB_FAIL(part_ids.push_back(part_id))) { - COMMON_LOG(WARN, "fail to push part_id", K(ret)); - } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { - COMMON_LOG(WARN, "fail to push tablet_id", K(ret)); - } + // 2. Calc partition id + int64_t part_idx = -1; + if (OB_SUCC(ret)) { + // hash val + int64_t result = 0; + if (is_oracle_mode_) { + // oracle mode: use obj to calc hash val + ret = calc_value_for_oracle(range.start_key_.get_obj_ptr(), valid_obj_cnt, result, ctx); + } else { + // mysql mode: use single obj to calc hash val + ret = calc_value_for_mysql(range.start_key_.get_obj_ptr(), result); } + int64_t part_id = -1; + if (OB_SUCC(ret) && OB_FAIL(calc_hash_part_idx(result, part_num_, part_idx))) { + COMMON_LOG(WARN, "fail to cal hash part idx", K(ret), K(result), K(part_num_)); + } else if (OB_FAIL(get_part_hash_idx(part_idx, part_id))) { + COMMON_LOG(WARN, "fail to get part hash id", K(part_idx), K(ret)); + } else if (OB_FAIL(part_ids.push_back(part_id))) { + COMMON_LOG(WARN, "fail to push part_id", K(ret)); + } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { + COMMON_LOG(WARN, "fail to push tablet_id", K(ret)); + } else {} } return ret; @@ -152,103 +199,91 @@ uint64_t ObPartDescHash::calc_hash_value_with_seed(const ObObj &obj, const int64 return hval; } - -int ObPartDescHash::calc_value_for_oracle(ObObj &src_obj, - ObIAllocator &allocator, - int64_t &part_idx, +int ObPartDescHash::calc_value_for_oracle(const ObObj *objs, + int64_t objs_cnt, + int64_t &result, ObPartDescCtx &ctx) { int ret = OB_SUCCESS; - - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; - - if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), - obj_type_, tz_info, dtc_params))) { - COMMON_LOG(WARN, "fail to build dtc params with tz info", K(ret)); - } else { - lib::set_oracle_mode(true); - - uint64_t hash_val = 0; - ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, cs_type_); - const ObObj *res_obj = &src_obj; - - ObAccuracy accuracy(accuracy_.valid_, accuracy_.length_, accuracy_.precision_, accuracy_.scale_); - - // use src_obj as buf_obj - COMMON_LOG(DEBUG, "begin to cast value for hash oracle", K(src_obj), K(cs_type_)); - if (OB_FAIL(ObObjCasterV2::to_type(obj_type_, cs_type_, cast_ctx, src_obj, src_obj))) { - COMMON_LOG(WARN, "failed to cast obj", K(ret), K(src_obj), K(obj_type_), K(cs_type_)); - } else if (ctx.need_accurate() - && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, cs_type_, *res_obj, src_obj, res_obj))) { - COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj), K(obj_type_)); + uint64_t hash_code = 0; + if (OB_ISNULL(objs) || 0 == objs_cnt) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "objs_stack is null or number incorrect", K(objs), K(objs_cnt), K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < objs_cnt; ++i) { + const ObObj &obj = objs[i]; + const ObObjType type = obj.get_type(); + if (ObNullType == type) { + //do nothing, hash_code not changed + } else if (!is_oracle_supported_type(type)) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "type is wrong", K(ret), K(obj), K(type)); } else { - COMMON_LOG(DEBUG, "finish to cast and accuracy values for hash oracle", K(src_obj), K(obj_type_), K(cs_type_)); - // calculate hash value - const ObObjType type = src_obj.get_type(); - if (ObNullType == type) { - //do nothing, hash_code not changed - } else if (!is_oracle_supported_type(type)) { - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "type is wrong", K(ret), K(src_obj), K(type)); - } else { - hash_val = calc_hash_value_with_seed(src_obj, ctx.get_cluster_version(), hash_val); - } + hash_code = calc_hash_value_with_seed(obj, ctx.get_cluster_version(), hash_code); } + } + result = static_cast(hash_code); + result = result < 0 ? -result : result; + if (OB_SUCC(ret)) { + COMMON_LOG(TRACE, "succ to calc hash value with oracle mode", KP(objs), K(objs[0]), K(objs_cnt), K(result), K(ret)); + } else { + COMMON_LOG(WARN, "fail to calc hash value with oracle mode", KP(objs), K(objs_cnt), K(result), K(ret)); + } + return ret; +} - lib::set_oracle_mode(false); - - // calculate logic partition - if (OB_SUCC(ret)) { - int64_t N = 0; - int64_t powN = 0; - const static int64_t max_part_num_log2 = 64; - - int64_t result_num = static_cast(hash_val); - result_num = result_num < 0 ? -result_num : result_num; - - N = static_cast(std::log(part_num_) / std::log(2)); - if (N >= max_part_num_log2) { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "result is too big", K(N), K(part_num_), K(result_num)); +int ObPartDescHash::calc_value_for_mysql(const ObObj *obj, int64_t &result) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(obj)) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "unexpected null ptr", K(ret)); + } else if (OB_UNLIKELY(obj->is_null())) { + result = 0; + } else { + int64_t num = 0; + if (OB_FAIL(obj->get_int(num))) { + COMMON_LOG(WARN, "fail to get int", K(obj), K(ret)); + } else { + if (OB_UNLIKELY(INT64_MIN == num)) { + num = INT64_MAX; } else { - powN = (1ULL << N); - part_idx = result_num % powN; - if (part_idx + powN < part_num_ && (result_num & powN) == powN) { - part_idx += powN; - } + num = num < 0 ? -num : num; } - COMMON_LOG(DEBUG, "get hash part idx for oracle mode", - K(ret), K(result_num), K(part_num_), K(N), K(powN), K(part_idx)); + result = num; } } - + COMMON_LOG(TRACE, "calc hash value with mysql mode", K(ret)); return ret; } -int ObPartDescHash::calc_value_for_mysql(ObObj &src_obj, ObIAllocator &allocator, int64_t &part_idx) +int ObPartDescHash::calc_hash_part_idx(const uint64_t val, + const int64_t part_num, + int64_t &partition_idx) { int ret = OB_SUCCESS; - - ObCastCtx cast_ctx(&allocator, NULL, CM_NULL_ON_WARN, CS_TYPE_INVALID); - ObObjType target_type = ObIntType; - if (OB_FAIL(ObObjCasterV2::to_type(target_type, cs_type_, cast_ctx, src_obj, src_obj))) { - COMMON_LOG(INFO, "failed to cast to target type", K(target_type), K(src_obj), K(ret)); - } else { - int64_t val = 0; - if (OB_FAIL(src_obj.get_int(val))) { - COMMON_LOG(WARN, "fail to get int", K(src_obj), K(ret)); + int64_t N = 0; + int64_t powN = 0; + const static int64_t max_part_num_log2 = 64; + // This function is used by SQL. Should ensure SQL runs in MySQL mode when query sys table. + if (is_oracle_mode_) { + // It will not be a negative number, so use forced conversion instead of floor + N = static_cast(std::log(part_num) / std::log(2)); + if (N >= max_part_num_log2) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "result is too big", K(N), K(part_num), K(val)); } else { - if (OB_UNLIKELY(INT64_MIN == val)) { - val = INT64_MAX; - } else { - val = val < 0 ? -val : val; + powN = (1ULL << N); + partition_idx = val & (powN - 1); //pow(2, N)); + if (partition_idx + powN < part_num && (val & powN) == powN) { + partition_idx += powN; } - part_idx = val % part_num_; - COMMON_LOG(DEBUG, "get hash part idx for mysql mode", K(ret), K(val), K(part_num_), K(part_idx)); } + COMMON_LOG(DEBUG, "get hash part idx", K(lbt()), K(ret), K(val), K(part_num), K(N), K(powN), K(partition_idx)); + } else { + partition_idx = val % part_num; + COMMON_LOG(DEBUG, "get hash part idx", K(lbt()), K(ret), K(val), K(part_num), K(partition_idx)); } - return ret; } diff --git a/src/share/part/ob_part_desc_hash.h b/src/share/part/ob_part_desc_hash.h index ffe7b0a8..2d5b10ee 100644 --- a/src/share/part/ob_part_desc_hash.h +++ b/src/share/part/ob_part_desc_hash.h @@ -16,6 +16,7 @@ //#include "common/ob_object.h" #include "share/part/ob_part_desc.h" #include "share/part/ob_part_mgr_util.h" +#include "proxy/route/obproxy_part_mgr.h" namespace oceanbase { @@ -38,11 +39,12 @@ class ObPartDescHash : public ObPartDesc void set_part_space(int64_t part_space) { part_space_ = part_space; } void set_first_part_id(int64_t first_part_id) { first_part_id_ = first_part_id; } int64_t get_first_part_id() { return first_part_id_; } - void set_part_key_type(const ObObjType obj_type) { obj_type_ = obj_type; } - void set_part_key_cs_type(const ObCollationType cs_type) { cs_type_ = cs_type; } void set_part_array(int64_t *part_array) { part_array_ = part_array; } void set_oracle_mode(bool is_oracle_mode) { is_oracle_mode_ = is_oracle_mode; } + ObIArray &get_obj_types() { return obj_types_; } + ObIArray &get_cs_types() { return cs_types_; } + VIRTUAL_TO_STRING_KV("part_type", "hash", K_(is_oracle_mode), K_(part_num), @@ -52,18 +54,19 @@ class ObPartDescHash : public ObPartDesc private: uint64_t calc_hash_value_with_seed(const ObObj &obj, const int64_t cluster_version, int64_t seed); bool is_oracle_supported_type(const ObObjType type); - int calc_value_for_oracle(ObObj &src_obj, ObIAllocator &allocator, int64_t &part_idx, ObPartDescCtx &ctx); - int calc_value_for_mysql(ObObj &src_obj, ObIAllocator &allocator, int64_t &part_idx); + int calc_value_for_oracle(const ObObj *objs, int64_t objs_cnt, int64_t &result, ObPartDescCtx &ctx); + int calc_value_for_mysql(const ObObj *obj, int64_t &result); int get_part_hash_idx(const int64_t part_idx, int64_t &part_id); + int calc_hash_part_idx(const uint64_t val, const int64_t part_num, int64_t &partition_idx); private: bool is_oracle_mode_; int64_t part_num_; int64_t part_space_; int64_t first_part_id_; - // TODO: add multiple key - ObObjType obj_type_; - ObCollationType cs_type_; + // multiple key + ObSEArray obj_types_; + ObSEArray cs_types_; int64_t *part_array_; }; } diff --git a/src/share/part/ob_part_desc_key.cpp b/src/share/part/ob_part_desc_key.cpp index fa027bb7..86127731 100644 --- a/src/share/part/ob_part_desc_key.cpp +++ b/src/share/part/ob_part_desc_key.cpp @@ -22,16 +22,18 @@ namespace common ObPartDescKey::ObPartDescKey() : part_num_(0) , part_space_(0) , first_part_id_(0) - , obj_type_(ObMaxType) - , cs_type_(CS_TYPE_INVALID) , part_array_(NULL) { } - -/* +/** GET PARTITION ID - - If input is not single int value, return invalid argument; otherwise, get the particular one. + Hash partition only route like 'by key(c1,c2) ... where c1=xx and c2=xx', + only use range.start_key_ to calc, because when condition is like 'c1=xx', + start_key_[i] == end_key_[i] + @param range (xxx,yyy,min,min ; xxx,yyy,max,max) + @param allocator + @param part_ids[out] + @param ctx */ int ObPartDescKey::get_part(ObNewRange &range, ObIAllocator &allocator, @@ -40,69 +42,126 @@ int ObPartDescKey::get_part(ObNewRange &range, ObIArray &tablet_ids) { int ret = OB_SUCCESS; + // provide all objs are valid. + // "valid" means the obj not min or max + int64_t valid_obj_cnt = range.start_key_.get_obj_cnt(); + // cast objs store in range.start_key_ + for (int64_t i = 0; OB_SUCC(ret) && i < range.start_key_.get_obj_cnt(); i++) { + // if obj is min or max, means all valid obj has been casted + if (range.start_key_.get_obj_ptr()[i].is_max_value() || + range.start_key_.get_obj_ptr()[i].is_min_value()) { + // minus the number of invalid obj + valid_obj_cnt = valid_obj_cnt - (range.start_key_.get_obj_cnt() - i); + // not need to cast any more and break loop + if (valid_obj_cnt == 0) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "not support key partition calc with range", K(range)); + } + break; + } else { + ObObj *src_obj = const_cast(&range.start_key_.get_obj_ptr()[i]); + // here src_obj shouldn't be null + if (OB_ISNULL(src_obj)) { + ret = OB_ERR_NULL_VALUE; + COMMON_LOG(ERROR, "unexpected null pointer src_obj"); + break; + } else if (src_obj->is_null()) { + // here src_obj shouldn't be null type + ret = OB_OBJ_TYPE_ERROR; + COMMON_LOG(ERROR, "unexpected null type", K(src_obj)); + } else if(OB_FAIL(cast_obj(*src_obj, obj_types_[i], cs_types_[i], allocator, ctx, accuracies_.at(i)))) { + COMMON_LOG(WARN, "cast obj failed", K(src_obj), "obj_type", obj_types_[i], "cs_type", cs_types_[i]); + // TODO: handle failure + } + } - if (1 != range.get_start_key().get_obj_cnt()) { // single value - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "key part should be single key", - "obj_cnt", range.get_start_key().get_obj_cnt(), K(ret)); - } else { - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; - if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), - obj_type_, tz_info, dtc_params))) { - COMMON_LOG(WARN, "fail to build dtc params with ctx session", K(ret), K(obj_type_)); + } + + int64_t part_idx = -1; + if (OB_SUCC(ret)) { + // hash val + int64_t result = 0; + int64_t part_id = -1; + if (OB_FAIL(calc_value_for_mysql(range.start_key_.get_obj_ptr(), valid_obj_cnt, result, ctx))) { + COMMON_LOG(WARN, "fail to cal key val", K(ret), K(valid_obj_cnt)); + } else if (OB_FAIL(calc_key_part_idx(result, part_num_, part_idx))) { + COMMON_LOG(WARN, "fail to cal key part idx", K(ret), K(result), K(part_num_)); + } else if (OB_FAIL(get_part_hash_idx(part_idx, part_id))) { + COMMON_LOG(WARN, "fail to get part key id", K(part_idx), K(ret)); + } else if (OB_FAIL(part_ids.push_back(part_id))) { + COMMON_LOG(WARN, "fail to push part_id", K(ret)); + } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { + COMMON_LOG(WARN, "fail to push tablet id", K(ret)); + } else {} + } + + return ret; +} + + +int ObPartDescKey::calc_value_for_mysql(const ObObj *objs, + int64_t objs_cnt, + int64_t &result, + ObPartDescCtx &ctx) +{ + int ret = OB_SUCCESS; + uint64_t hash_code = 0; + if (OB_ISNULL(objs) || 0 == objs_cnt) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "objs_stack is null or number incorrect", K(objs), K(objs_cnt), K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < objs_cnt; ++i) { + const ObObj &obj = objs[i]; + if (ObNullType == obj.get_type()) { + //do nothing, hash_code not changed } else { - ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, cs_type_); - ObObj &src_obj = const_cast(range.get_start_key().get_obj_ptr()[0]); - const ObObj *res_obj = &src_obj; - ObAccuracy accuracy(accuracy_.valid_, accuracy_.length_, accuracy_.precision_, accuracy_.scale_); - - // use src_obj as buf_obj - if (OB_FAIL(ObObjCasterV2::to_type(obj_type_, cs_type_, cast_ctx, src_obj, src_obj))) { - COMMON_LOG(WARN, "fail to cast obj", K(ret), K(src_obj), K(obj_type_), K(cs_type_)); - } else if (ctx.need_accurate() - && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, cs_type_, *res_obj, src_obj, res_obj))) { - COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj), K(obj_type_)); - } else { - int64_t result_num = 0; - if ((IS_CLUSTER_VERSION_LESS_THAN_V4(ctx.get_cluster_version()) - && (share::schema::PARTITION_FUNC_TYPE_KEY_V3 == part_func_type_ - || share::schema::PARTITION_FUNC_TYPE_KEY_IMPLICIT_V2 == part_func_type_)) - || (!IS_CLUSTER_VERSION_LESS_THAN_V4(ctx.get_cluster_version()))) { - result_num = static_cast(src_obj.hash_murmur()); - } else { - result_num = static_cast(src_obj.hash()); - } - result_num = result_num < 0 ? -result_num : result_num; - int64_t part_idx = result_num % part_num_; - int64_t part_id = part_idx; - if (share::schema::PARTITION_LEVEL_ONE == part_level_ && NULL != part_array_) { - part_id = part_array_[part_idx]; - } - part_id = part_space_ << OB_PART_IDS_BITNUM | part_id; - if (OB_FAIL(part_ids.push_back(part_id))) { - COMMON_LOG(WARN, "fail to push part_id", K(ret)); - } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { - COMMON_LOG(WARN, "fail to push tablet id", K(ret)); - } - } + hash_code = calc_hash_value_with_seed(obj, ctx.get_cluster_version(), hash_code); } } + result = static_cast(hash_code); + result = result < 0 ? -result : result; + if (OB_SUCC(ret)) { + COMMON_LOG(TRACE, "succ to calc hash value with oracle mode", KP(objs), K(objs[0]), K(objs_cnt), K(result), K(ret)); + } else { + COMMON_LOG(WARN, "fail to calc hash value with oracle mode", KP(objs), K(objs_cnt), K(result), K(ret)); + } + return ret; +} + +uint64_t ObPartDescKey::calc_hash_value_with_seed(const ObObj &obj, const int64_t cluster_version, int64_t seed) +{ + int64_t hval = 0; + if ((IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) + && (share::schema::PARTITION_FUNC_TYPE_KEY_V3 == part_func_type_ + || share::schema::PARTITION_FUNC_TYPE_KEY_IMPLICIT_V2 == part_func_type_)) + || (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version))) { + hval = static_cast(obj.hash_murmur(seed)); + } else { + hval = static_cast(obj.hash(seed)); + } + return hval; +} + +int ObPartDescKey::calc_key_part_idx(const uint64_t val, + const int64_t part_num, + int64_t &partition_idx) +{ + int ret = OB_SUCCESS; + partition_idx = val % part_num; + COMMON_LOG(DEBUG, "get hash part idx", K(lbt()), K(ret), K(val), K(part_num), K(partition_idx)); return ret; } int ObPartDescKey::get_part_by_num(const int64_t num, common::ObIArray &part_ids, common::ObIArray &tablet_ids) { int ret = OB_SUCCESS; + int64_t part_id = -1; int64_t part_idx = num % part_num_; - int64_t part_id = part_idx; - if (share::schema::PARTITION_LEVEL_ONE == part_level_ && part_array_ != NULL) { - part_id = part_array_[part_idx]; - } - part_id = part_space_ << OB_PART_IDS_BITNUM | part_id; - if (OB_FAIL(part_ids.push_back(part_id))) { + if (OB_FAIL(get_part_hash_idx(part_idx, part_id))) { + COMMON_LOG(WARN, "fail to get part hash id", K(num), K(ret)); + } else if (OB_FAIL(part_ids.push_back(part_id))) { COMMON_LOG(WARN, "fail to push part_id", K(ret)); } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { COMMON_LOG(WARN, "fail to push tablet id", K(ret)); @@ -110,6 +169,22 @@ int ObPartDescKey::get_part_by_num(const int64_t num, common::ObIArray return ret; } +int ObPartDescKey::get_part_hash_idx(const int64_t part_idx, int64_t &part_id) +{ + int ret =OB_SUCCESS; + + part_id = part_idx; + if (share::schema::PARTITION_LEVEL_ONE == part_level_) { + if (part_idx >= 0 && NULL != part_array_) { + part_id = part_array_[part_idx]; + } + } + if (OB_SUCC(ret)) { + part_id = part_space_ << OB_PART_IDS_BITNUM | part_id; + COMMON_LOG(DEBUG, "get hash part id", K(ret), K(part_num_), K(part_id)); + } + return ret; +} } // end of common -} // end of oceanbase +} diff --git a/src/share/part/ob_part_desc_key.h b/src/share/part/ob_part_desc_key.h index ebc48a22..f1b66763 100644 --- a/src/share/part/ob_part_desc_key.h +++ b/src/share/part/ob_part_desc_key.h @@ -15,7 +15,7 @@ #include "share/part/ob_part_desc.h" #include "share/part/ob_part_mgr_util.h" - +#include "proxy/route/obproxy_part_mgr.h" namespace oceanbase { namespace common @@ -36,23 +36,30 @@ class ObPartDescKey : public ObPartDesc void set_part_space(int64_t part_space) { part_space_ = part_space; } void set_first_part_id(int64_t first_part_id) { first_part_id_ = first_part_id; } int64_t get_first_part_id() { return first_part_id_; } - void set_part_key_type(const ObObjType obj_type) { obj_type_ = obj_type; } - void set_part_key_cs_type(const ObCollationType cs_type) { cs_type_ = cs_type; } void set_part_array(int64_t *part_array) { part_array_ = part_array; } + ObIArray &get_obj_types() { return obj_types_; } + ObIArray &get_cs_types() { return cs_types_; } + VIRTUAL_TO_STRING_KV("part_type", "key", K_(part_num), K_(part_space), K_(first_part_id), K_(part_level), K_(part_func_type)); +private: + int calc_value_for_mysql(const ObObj *objs, int64_t objs_cnt, int64_t &result, ObPartDescCtx &ctx); + uint64_t calc_hash_value_with_seed(const ObObj &obj, const int64_t cluster_version, int64_t seed); + int calc_key_part_idx(const uint64_t val, const int64_t part_num, int64_t &partition_idx); + int get_part_hash_idx(const int64_t part_idx, int64_t &part_id); + private: int64_t part_num_; int64_t part_space_; int64_t first_part_id_; - // TODO: add multiple key - ObObjType obj_type_; - ObCollationType cs_type_; + // multiple key + ObSEArray obj_types_; + ObSEArray cs_types_; int64_t *part_array_; }; diff --git a/src/share/part/ob_part_desc_list.cpp b/src/share/part/ob_part_desc_list.cpp index 44552d4a..1f23817f 100644 --- a/src/share/part/ob_part_desc_list.cpp +++ b/src/share/part/ob_part_desc_list.cpp @@ -53,50 +53,54 @@ int ObPartDescList::get_part(ObNewRange &range, ObIArray &tablet_ids) { int ret = OB_SUCCESS; - + ObNewRow src_row; + // for list partition, row in start_key_ + src_row.assign(const_cast(range.start_key_.get_obj_ptr()), range.start_key_.get_obj_cnt()); if (OB_ISNULL(part_array_) || OB_UNLIKELY(part_array_size_ <= 0)) { ret = OB_INVALID_ARGUMENT; COMMON_LOG(WARN, "invalid argument, ", K_(part_array), K_(part_array_size), K(ret)); // use the fisrt range as the type to cast - } else if (1 != range.get_start_key().get_obj_cnt()) { // single value - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(DEBUG, "list part should be single key", - "obj_cnt", range.get_start_key().get_obj_cnt(), K(ret)); } else { - ObObj &src_obj = const_cast(range.get_start_key().get_obj_ptr()[0]); - // use the first row cell as target obj - ObObj &target_obj = const_cast(part_array_[0].rows_[0].get_cell(0)); - if (OB_FAIL(cast_obj(src_obj, target_obj, allocator, ctx))) { - COMMON_LOG(INFO, "fail to cast obj", K(src_obj), K(target_obj), K(ret)); - } else { - bool found = false; - for (int64_t i = 0; OB_SUCC(ret) && i < part_array_size_ && !found; ++i) { - if (i == default_part_array_idx_) { - continue; - } - for (int64_t j= 0; OB_SUCC(ret) && j < part_array_[i].rows_.count() && !found; ++j) { - if (part_array_[i].rows_[j].get_count() == 0) { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "no cells in the row", K(part_array_[i].rows_[j]), K(ret)); - } else if (src_obj == part_array_[i].rows_[j].get_cell(0)) { + bool found = false; + bool casted = false; + // cast src_row and compare with part array + for (int64_t i = 0; i < part_array_size_ && !found; i++) { + if (i == default_part_array_idx_) { + continue; + } + for (int64_t j = 0; j < part_array_[i].rows_.count() && !found; j++) { + if (part_array_[i].rows_[j].get_count() == 0) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "no cells in the row", K(part_array_[i].rows_[j]), K(ret)); + } else { + // if not cast, cast first + if (!casted && OB_FAIL(cast_row(src_row, part_array_[i].rows_.at(j), allocator, ctx))) { + COMMON_LOG(WARN, "fail to cast row"); + continue; + } else { + casted = true; + } + // if casted, then compare + if (casted && src_row == part_array_[i].rows_.at(j)) { found = true; if (OB_FAIL(part_ids.push_back(part_array_[i].part_id_))) { COMMON_LOG(WARN, "fail to push part id", K(ret)); } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[i]))) { COMMON_LOG(WARN, "fail to push tablet id", K(ret)); } - } // end found - } // end for rows - } // end for part_array - if (!found && OB_INVALID_INDEX != default_part_array_idx_) { - // if no row cell matches, use default partition - COMMON_LOG(DEBUG, "will use default partition id", K(src_obj), K(ret)); - if (OB_FAIL(part_ids.push_back(part_array_[default_part_array_idx_].part_id_))) { - COMMON_LOG(WARN, "fail to push part id", K(ret)); - } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[default_part_array_idx_]))) { - COMMON_LOG(WARN, "fail to push tablet id", K(ret)); + } else {} } + } // end for rows + } // end for part_array + + if (!found && OB_INVALID_INDEX != default_part_array_idx_) { + // if no row matches, use default partition + COMMON_LOG(DEBUG, "will use default partition id", K(src_row), K(ret)); + if (OB_FAIL(part_ids.push_back(part_array_[default_part_array_idx_].part_id_))) { + COMMON_LOG(WARN, "fail to push part id", K(ret)); + } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[default_part_array_idx_]))) { + COMMON_LOG(WARN, "fail to push tablet id", K(ret)); } } } @@ -115,34 +119,27 @@ int ObPartDescList::get_part_by_num(const int64_t num, common::ObIArray return ret; } -inline int ObPartDescList::cast_obj(ObObj &src_obj, - ObObj &target_obj, - ObIAllocator &allocator, - ObPartDescCtx &ctx) +int ObPartDescList::cast_row(ObNewRow &src_row, + ObNewRow &target_row, + ObIAllocator &allocator, + ObPartDescCtx &ctx) { int ret = OB_SUCCESS; - COMMON_LOG(DEBUG, "begin to cast obj for list", K(src_obj), K(target_obj)); - - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; - ObObjType obj_type = target_obj.get_type(); - - if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), - obj_type, tz_info, dtc_params))) { - COMMON_LOG(WARN, "fail to build dtc params with ctx session", K(ret), K(obj_type)); - } else { - ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, target_obj.get_collation_type()); - const ObObj *res_obj = &src_obj; - ObAccuracy accuracy(accuracy_.valid_, accuracy_.length_, accuracy_.precision_, accuracy_.scale_); - - // use src_obj as buf_obj - if (OB_FAIL(ObObjCasterV2::to_type(obj_type, target_obj.get_collation_type(), cast_ctx, src_obj, src_obj))) { - COMMON_LOG(WARN, "failed to cast obj", K(ret), K(src_obj), K(target_obj)); - } else if (ctx.need_accurate() - && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, target_obj.get_collation_type(), *res_obj, src_obj, res_obj))) { - COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj), K(obj_type)); + int64_t min_col_cnt = std::min(src_row.count_, target_row.count_); + for (int64_t i = 0; i < min_col_cnt && OB_SUCC(ret); ++i) { + if (src_row.get_cell(i).is_max_value() || + src_row.get_cell(i).is_min_value()) { + COMMON_LOG(DEBUG, "skip min/max obj"); + continue; + } + if (OB_FAIL(cast_obj(src_row.get_cell(i), + target_row.get_cell(i), + allocator, + ctx, + accuracies_.at(i)))) { + COMMON_LOG(INFO, "fail to cast obj", K(i), K(ret)); } else { - COMMON_LOG(DEBUG, "succ to cast obj for list", K(src_obj), K(target_obj)); + // do nothing } } diff --git a/src/share/part/ob_part_desc_list.h b/src/share/part/ob_part_desc_list.h index 13f5c314..f324a536 100644 --- a/src/share/part/ob_part_desc_list.h +++ b/src/share/part/ob_part_desc_list.h @@ -16,6 +16,7 @@ #include "share/part/ob_part_desc.h" #include "common/ob_row.h" #include "lib/container/ob_se_array.h" +#include "proxy/route/obproxy_part_mgr.h" namespace oceanbase { @@ -54,12 +55,13 @@ class ObPartDescList : public ObPartDesc return OB_SUCCESS; } - DECLARE_VIRTUAL_TO_STRING; -private: - int cast_obj(ObObj &src_obj, - ObObj &target_obj, + int cast_row(ObNewRow &src_row, + ObNewRow &target_row, ObIAllocator &allocator, ObPartDescCtx &ctx); + + DECLARE_VIRTUAL_TO_STRING; + private: ListPartition *part_array_; int64_t part_array_size_; diff --git a/src/share/part/ob_part_desc_range.cpp b/src/share/part/ob_part_desc_range.cpp index c8821ce6..120049b0 100644 --- a/src/share/part/ob_part_desc_range.cpp +++ b/src/share/part/ob_part_desc_range.cpp @@ -173,17 +173,23 @@ int ObPartDescRange::get_part_by_num(const int64_t num, common::ObIArray(src_key.get_obj_ptr()[i]), const_cast(target_key.get_obj_ptr()[i]), allocator, - ctx))) { + ctx, + accuracies_.at(i)))) { COMMON_LOG(INFO, "fail to cast obj", K(i), K(ret)); } else { // do nothing @@ -192,39 +198,5 @@ int ObPartDescRange::cast_key(ObRowkey &src_key, return ret; } -inline int ObPartDescRange::cast_obj(ObObj &src_obj, - ObObj &target_obj, - ObIAllocator &allocator, - ObPartDescCtx &ctx) -{ - int ret = OB_SUCCESS; - COMMON_LOG(DEBUG, "begin to cast obj for range", K(src_obj), K(target_obj)); - - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; - ObObjType obj_type = target_obj.get_type(); - - if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), - obj_type, tz_info, dtc_params))) { - COMMON_LOG(WARN, "fail to build dtc params with ctx session", K(ret), K(obj_type)); - } else { - ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, target_obj.get_collation_type()); - const ObObj *res_obj = &src_obj; - ObAccuracy accuracy(accuracy_.valid_, accuracy_.length_, accuracy_.precision_, accuracy_.scale_); - - // use src_obj as buf_obj - if (OB_FAIL(ObObjCasterV2::to_type(obj_type, target_obj.get_collation_type(), cast_ctx, src_obj, src_obj))) { - COMMON_LOG(WARN, "failed to cast obj", K(ret), K(src_obj), K(target_obj)); - } else if (ctx.need_accurate() - && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, target_obj.get_collation_type(), *res_obj, src_obj, res_obj))) { - COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj)); - } else { - COMMON_LOG(DEBUG, "end to cast obj for range", K(src_obj), K(target_obj)); - } - } - - return ret; -} - } // end of common } // end of oceanbase diff --git a/src/share/part/ob_part_desc_range.h b/src/share/part/ob_part_desc_range.h index 24f343c1..6baabf8a 100644 --- a/src/share/part/ob_part_desc_range.h +++ b/src/share/part/ob_part_desc_range.h @@ -15,6 +15,7 @@ #include "share/part/ob_part_desc.h" #include "lib/container/ob_se_array.h" +#include "proxy/route/obproxy_part_mgr.h" namespace oceanbase { @@ -54,6 +55,11 @@ class ObPartDescRange : public ObPartDesc return common::OB_SUCCESS; } + int cast_key(ObRowkey &src_key, + ObRowkey &target_key, + ObIAllocator &allocator, + ObPartDescCtx &ctx); + DECLARE_VIRTUAL_TO_STRING; private: int64_t get_start(const RangePartition *part_array, @@ -64,15 +70,6 @@ class ObPartDescRange : public ObPartDesc const int64_t size, const ObNewRange &range); - int cast_key(ObRowkey &src_key, - ObRowkey &target_key, - ObIAllocator &allocator, - ObPartDescCtx &ctx); - - int cast_obj(ObObj &src_obj, - ObObj &target_obj, - ObIAllocator &allocator, - ObPartDescCtx &ctx); private: RangePartition *part_array_; int64_t part_array_size_; diff --git a/unittest/obproxy/ob_expr_parser_checker.cpp b/unittest/obproxy/ob_expr_parser_checker.cpp index efe5218b..c6d61cc4 100644 --- a/unittest/obproxy/ob_expr_parser_checker.cpp +++ b/unittest/obproxy/ob_expr_parser_checker.cpp @@ -124,7 +124,6 @@ void ObExprParserChecker::build_schema(std::string &extra_str, ObExprParseResult } result.part_key_info_.key_num_ = 0; - result.target_mask_ = 0; while (true) { ObProxyParseString part_key_name = get_value(extra_str, "part_key", pos); ObProxyParseString part_key_level = get_value(extra_str, "part_level", pos); @@ -143,11 +142,6 @@ void ObExprParserChecker::build_schema(std::string &extra_str, ObExprParseResult result.part_key_info_.part_keys_[result.part_key_info_.key_num_].idx_ = part_key_idx.str_[0] - '0'; } ++result.part_key_info_.key_num_; - if (PART_KEY_LEVEL_ONE == level) { - result.target_mask_ |= BOTH_BOUND_FLAG; - } else { - result.target_mask_ |= (BOTH_BOUND_FLAG << 2); - } } } } diff --git a/unittest/obproxy/obproxy_parser_test.cpp b/unittest/obproxy/obproxy_parser_test.cpp index 4e45de08..0a8ab8d0 100755 --- a/unittest/obproxy/obproxy_parser_test.cpp +++ b/unittest/obproxy/obproxy_parser_test.cpp @@ -51,19 +51,19 @@ void show_sql_result(SqlFieldResult& sql_result) { fprintf(stdout, "========== sql_result is ===========\n"); for(int i = 0; i < sql_result.field_num_; i++) { char buf[256]; - printf("column_name:length:%d\t", sql_result.fields_[i].column_name_.string_.length()); + printf("column_name:length:%d\t", sql_result.fields_[i]->column_name_.config_string_.length()); snprintf(buf, 256, "column_name:%.*s", - sql_result.fields_[i].column_name_.string_.length(), - sql_result.fields_[i].column_name_.string_.ptr()); + sql_result.fields_[i]->column_name_.config_string_.length(), + sql_result.fields_[i]->column_name_.config_string_.ptr()); printf("%s\t", buf); //printf(" %s ", function_type_to_string(sql_result.fields_[i].type_).c_str()); - printf(" (%s) ", token_type_to_string(sql_result.fields_[i].value_type_).c_str()); - if(sql_result.fields_[i].value_type_ == TOKEN_INT_VAL) { - snprintf(buf, 256, "column_value:%ld", sql_result.fields_[i].column_int_value_); - } else if (sql_result.fields_[i].value_type_ == TOKEN_STR_VAL){ - snprintf(buf, sql_result.fields_[i].column_value_.config_string_.length()+1, "column_value:%.*s", - sql_result.fields_[i].column_value_.config_string_.length(), - sql_result.fields_[i].column_value_.config_string_.ptr()); + printf(" (%s) ", token_type_to_string(sql_result.fields_[i]->value_type_).c_str()); + if(sql_result.fields_[i]->value_type_ == TOKEN_INT_VAL) { + snprintf(buf, 256, "column_value:%ld", sql_result.fields_[i]->column_int_value_); + } else if (sql_result.fields_[i]->value_type_ == TOKEN_STR_VAL){ + snprintf(buf, sql_result.fields_[i]->column_value_.config_string_.length()+1, "column_value:%.*s", + sql_result.fields_[i]->column_value_.config_string_.length(), + sql_result.fields_[i]->column_value_.config_string_.ptr()); } printf("%s\n", buf); // fprintf(stdout, "%s %s %s\n", sql_result.fields_[i].column_name_, @@ -137,7 +137,6 @@ void build_schema(std::string &extra_str, ObExprParseResult &result) pos = 0; result.part_key_info_.key_num_ = 0; - result.target_mask_ = 0; while (true) { ObProxyParseString part_key_name = get_value(extra_str, "part_key", pos); ObProxyParseString part_key_level = get_value(extra_str, "part_level", pos); @@ -162,11 +161,6 @@ void build_schema(std::string &extra_str, ObExprParseResult &result) result.part_key_info_.part_keys_[result.part_key_info_.key_num_].idx_ = part_key_idx.str_[0] - '0'; } ++result.part_key_info_.key_num_; - if (PART_KEY_LEVEL_ONE == level) { - result.target_mask_ |= BOTH_BOUND_FLAG; - } else { - result.target_mask_ |= (BOTH_BOUND_FLAG << 2); - } } } } @@ -207,8 +201,8 @@ void extract_local_fileds(const ObExprParseResult& result, ObProxyMysqlRequest & printf("Got an empty relation_expr"); continue; } - SqlField field; - field.reset(); + SqlField *field = NULL; + SqlField::alloc_sql_field(field); //sql_result.fields_[sql_result.field_num_].type_ = relation_expr->type_; if(relation_expr->left_value_ != NULL && relation_expr->left_value_->head_ != NULL @@ -217,9 +211,9 @@ void extract_local_fileds(const ObExprParseResult& result, ObProxyMysqlRequest & ObString tmp_column(relation_expr->left_value_->head_->column_name_.str_len_, relation_expr->left_value_->head_->column_name_.str_); LOG_DEBUG("column_name is ", K(tmp_column)); - field.column_name_.set(tmp_column); + field->column_name_.set_value(tmp_column); - LOG_DEBUG("field.column", K(field.column_name_)); + LOG_DEBUG("field->column", K(field->column_name_)); // strncpy(sql_result.fields_[sql_result.field_num_].column_name_, // relation_expr->left_value_->head_->column_name_.str_, // relation_expr->left_value_->head_->column_name_.str_len_); @@ -234,19 +228,19 @@ void extract_local_fileds(const ObExprParseResult& result, ObProxyMysqlRequest & if(relation_expr->right_value_ != NULL && relation_expr->right_value_->head_ != NULL) { if(relation_expr->right_value_->head_->type_ == TOKEN_INT_VAL) { - field.value_type_ = TOKEN_INT_VAL; - field.column_int_value_ = relation_expr->right_value_->head_->int_value_; - LOG_DEBUG("field.value", K(field.column_int_value_)); + field->value_type_ = TOKEN_INT_VAL; + field->column_int_value_ = relation_expr->right_value_->head_->int_value_; + LOG_DEBUG("field->value", K(field->column_int_value_)); // snprintf(sql_result.fields_[sql_result.field_num_].column_value_, // 32, "%ld", relation_expr->right_value_->head_->int_value_); // sql_result.fields_[sql_result.field_num_].column_value_ = ""; // sql_result.fields_[sql_result.field_num_].column_value_ = std::string(buf); } else if(relation_expr->right_value_->head_->type_ == TOKEN_STR_VAL) { - field.value_type_ = TOKEN_STR_VAL; - field.column_value_.config_string_.assign_ptr( + field->value_type_ = TOKEN_STR_VAL; + field->column_value_.config_string_.assign_ptr( relation_expr->right_value_->head_->str_value_.str_, relation_expr->right_value_->head_->str_value_.str_len_); - LOG_DEBUG("field.column_value", K(field.column_value_)); + LOG_DEBUG("field->column_value", K(field->column_value_)); // strncpy(sql_result.fields_[sql_result.field_num_].column_value_, // relation_expr->right_value_->head_->str_value_.str_, diff --git a/unittest/obproxy/test_ldc_location.cpp b/unittest/obproxy/test_ldc_location.cpp index 78a2fe34..cc2c69fd 100644 --- a/unittest/obproxy/test_ldc_location.cpp +++ b/unittest/obproxy/test_ldc_location.cpp @@ -27,7 +27,7 @@ EXPECT_TRUE(is_partition_server == item->is_partition_server_);\ EXPECT_TRUE(item->is_used_);\ EXPECT_FALSE(item->is_force_congested_);\ - EXPECT_EQ(ObAddr::convert_ipv4_addr(addr), item->replica_->server_.get_ipv4());\ + EXPECT_EQ(convert_ipv4_addr_utils(addr), item->replica_->server_.get_ipv4());\ EXPECT_EQ(port, item->replica_->server_.get_port());\ EXPECT_EQ(type1, test_ldc_route.get_curr_route_type());\ EXPECT_TRUE(!test_ldc_route.is_reach_end()); @@ -41,6 +41,25 @@ namespace obproxy namespace proxy { +static uint32_t convert_ipv4_addr_utils(const char *ip) +{ + in_addr binary; + int iret = 0; + uint32_t result = 0; + + if (!OB_ISNULL(ip)) { + memset(&binary, 0, sizeof (binary)); + iret = inet_pton(AF_INET, ip, &binary); + if (iret == -1) { // no support family + binary.s_addr = 0; + } else if (iret == 0) { // invalid ip string + binary.s_addr = 0; + } + result = ntohl(binary.s_addr); + } + return result; +} + class TesLDCLocation : public ::testing::Test { @@ -182,7 +201,7 @@ void TesLDCLocation::test_get_next_item(ObLDCRoute &test_ldc_route, ASSERT_TRUE(test_ldc_route.disable_merge_status_check_ || is_merge == item->is_merging_); ASSERT_TRUE(zone_type == item->zone_type_); ASSERT_TRUE(is_partition == item->is_partition_server_); - ASSERT_EQ(ObAddr::convert_ipv4_addr(ip_str), item->replica_->server_.get_ipv4()); + ASSERT_EQ(convert_ipv4_addr_utils(ip_str), item->replica_->server_.get_ipv4()); ASSERT_EQ(port, item->replica_->server_.get_port()); ASSERT_EQ(route_type, test_ldc_route.get_curr_route_type()); ASSERT_TRUE(!test_ldc_route.is_reach_end()); @@ -206,7 +225,7 @@ void TesLDCLocation::test_get_next_item(ObLDCRoute &test_ldc_route, ASSERT_TRUE(role == item->replica_->role_); } ASSERT_TRUE(is_partition == item->is_partition_server_); - ASSERT_EQ(ObAddr::convert_ipv4_addr(ip_str), item->replica_->server_.get_ipv4()); + ASSERT_EQ(convert_ipv4_addr_utils(ip_str), item->replica_->server_.get_ipv4()); ASSERT_EQ(port, item->replica_->server_.get_port()); ASSERT_EQ(route_type, test_ldc_route.get_curr_route_type()); ASSERT_TRUE(!test_ldc_route.is_reach_end()); @@ -429,15 +448,15 @@ TEST_F(TesLDCLocation, assign) ObLDCItem *item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = 0; i < 10; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 10; i < 25; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 25; i < 40; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } //empty name treat as do not use @@ -459,15 +478,15 @@ TEST_F(TesLDCLocation, assign) item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = 0; i < 10; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 10; i < 25; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 25; i < 40; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } //right name, but congestion is not available @@ -489,19 +508,19 @@ TEST_F(TesLDCLocation, assign) item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = 0; i < 15; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 15; i < 30; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 30; i < 45; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 45; i < 60; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("4.4.4.4"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("4.4.4.4"), item_array[i].replica_->server_.get_ipv4()); } //right name @@ -522,15 +541,15 @@ TEST_F(TesLDCLocation, assign) item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_REGION]; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[SAME_REGION]; i < site_start_index_array[OTHER_REGION]; i++) { EXPECT_EQ(SAME_REGION, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[OTHER_REGION]; i < site_start_index_array[MAX_IDC_TYPE]; i++) { EXPECT_EQ(OTHER_REGION, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_IDC] + 5; i++) { @@ -646,11 +665,11 @@ TEST_F(TesLDCLocation, assign_other_region) ObLDCItem *item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_REGION]; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[OTHER_REGION]; i < site_start_index_array[MAX_IDC_TYPE]; i++) { EXPECT_EQ(OTHER_REGION, item_array[i].idc_type_); - EXPECT_NE(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_NE(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_IDC] + 5; i++) { @@ -747,15 +766,15 @@ TEST_F(TesLDCLocation, assign_non_ldc) ObLDCItem *item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = 0; i < 10; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 10; i < 25; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 25; i < 40; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 0; i < 10; i++) { @@ -836,7 +855,7 @@ TEST_F(TesLDCLocation, fill_strong_read_location) ObString proxy_primary_zone_name; bool need_skip_leader = false; bool is_random_route_mode = false; - ASSERT_EQ(OB_ERR_UNEXPECTED, ObLDCLocation::fill_strong_read_location(&pl, dummy_ldc, leader_item, target_ldc, + ASSERT_EQ(OB_ERR_UNEXPECTED, ObLDCLocation::fill_strong_read_location(&pl, dummy_ldc, leader_item, target_ldc, entry_need_update, is_only_readwrite_zone, need_use_dup_replica, need_skip_leader, is_random_route_mode, servers_info, region_names, proxy_primary_zone_name, ObString(), NULL)); @@ -1343,19 +1362,19 @@ TEST_F(TesLDCLocation, get_next_item) item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_REGION]; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); EXPECT_EQ((i < 10 ? ZONE_TYPE_READWRITE : ZONE_TYPE_READONLY), item_array[i].zone_type_); EXPECT_TRUE((i % 10 < 5) == item_array[i].is_merging_); } for (int64_t i = site_start_index_array[SAME_REGION]; i < site_start_index_array[OTHER_REGION]; i++) { EXPECT_EQ(SAME_REGION, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); EXPECT_EQ((i < (10 + site_start_index_array[SAME_REGION])? ZONE_TYPE_READWRITE : ZONE_TYPE_READONLY), item_array[i].zone_type_); EXPECT_TRUE((i % 10 < 5) == item_array[i].is_merging_); } for (int64_t i = site_start_index_array[OTHER_REGION]; i < site_start_index_array[MAX_IDC_TYPE]; i++) { EXPECT_EQ(OTHER_REGION, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); EXPECT_EQ((i < (10 + site_start_index_array[OTHER_REGION]) ? ZONE_TYPE_READWRITE : ZONE_TYPE_READONLY), item_array[i].zone_type_); EXPECT_TRUE((i % 10 < 5) == item_array[i].is_merging_); } diff --git a/unittest/obproxy/test_proxy_table_processor_utils.cpp b/unittest/obproxy/test_proxy_table_processor_utils.cpp index 02953428..4b5e0787 100644 --- a/unittest/obproxy/test_proxy_table_processor_utils.cpp +++ b/unittest/obproxy/test_proxy_table_processor_utils.cpp @@ -42,8 +42,8 @@ TEST_F(TestProxyTableProcessorUtils, test_get_proxy_local_addr) ASSERT_EQ(addr, addr_org); ObAddr my_addr; - char ip_str[OB_IP_STR_BUFF] = {'\0'}; - int ret = ObProxyTableProcessorUtils::get_one_local_addr(ip_str, OB_IP_STR_BUFF); + char ip_str[MAX_IP_ADDR_LENGTH] = {'\0'}; + int ret = ObProxyTableProcessorUtils::get_one_local_addr(ip_str, MAX_IP_ADDR_LENGTH); ASSERT_EQ(OB_SUCCESS, ret); my_addr.set_ipv4_addr(ip_str, static_cast(config.listen_port)); @@ -63,15 +63,15 @@ TEST_F(TestProxyTableProcessorUtils, test_get_proxy_local_addr_inherited) int ret = OB_SUCCESS; ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); info.is_inherited_ = true; - info.fd_ = NO_FD; + info.ipv4_fd_ = NO_FD; ObAddr addr; ret = ObProxyTableProcessorUtils::get_proxy_local_addr(addr); ASSERT_EQ(OB_ERR_UNEXPECTED, ret); - char ip_str[OB_IP_STR_BUFF] = {'\0'}; - ret = ObProxyTableProcessorUtils::get_one_local_addr(ip_str, OB_IP_STR_BUFF); + char ip_str[MAX_IP_ADDR_LENGTH] = {'\0'}; + ret = ObProxyTableProcessorUtils::get_one_local_addr(ip_str, MAX_IP_ADDR_LENGTH); ASSERT_EQ(OB_SUCCESS, ret); struct sockaddr_in s_add; @@ -87,7 +87,7 @@ TEST_F(TestProxyTableProcessorUtils, test_get_proxy_local_addr_inherited) close(test_fd); } ASSERT_TRUE(-1 != bind_ret); - info.fd_ = test_fd; + info.ipv4_fd_ = test_fd; ret = ObProxyTableProcessorUtils::get_proxy_local_addr(addr); ASSERT_EQ(OB_SUCCESS, ret); ObAddr addr2(ObAddr::IPV4, ip_str, port); @@ -107,7 +107,7 @@ TEST_F(TestProxyTableProcessorUtils, test_get_proxy_local_addr_inherited) close(test_fd); } ASSERT_TRUE(-1 != bind_ret); - info.fd_ = test_fd; + info.ipv4_fd_ = test_fd; ret = ObProxyTableProcessorUtils::get_proxy_local_addr(addr); ASSERT_EQ(OB_SUCCESS, ret); addr2.reset(); diff --git a/unittest/obproxy/test_tenant_processor.cpp b/unittest/obproxy/test_tenant_processor.cpp index fdfad609..70c48685 100644 --- a/unittest/obproxy/test_tenant_processor.cpp +++ b/unittest/obproxy/test_tenant_processor.cpp @@ -28,7 +28,6 @@ * limitations under the License. */ -//#define private public #define USING_LOG_PREFIX PROXY #include #include @@ -357,21 +356,25 @@ TEST_F(TestTenantProcessor, test_execute) SqlFieldResult sql_result; sql_result.field_num_ = 4; - SqlField sql_field; - sql_field.column_name_.set("cluster"); - sql_field.column_value_.set_value("ob_cluster"); + SqlField *sql_field = NULL; + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("cluster"); + sql_field->column_value_.set_value("ob_cluster"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("tenant"); - sql_field.column_value_.set_value("ob_tenant"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("tenant"); + sql_field->column_value_.set_value("ob_tenant"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("name"); - sql_field.column_value_.set_value("resource_max_connections"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("name"); + sql_field->column_value_.set_value("resource_max_connections"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("value"); - sql_field.column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}]"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("value"); + sql_field->column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}]"); sql_result.fields_.push_back(sql_field); ObCloudFnParams cloud_params; @@ -403,21 +406,25 @@ TEST_F(TestTenantProcessor, test_rollback) SqlFieldResult sql_result; sql_result.field_num_ = 4; - SqlField sql_field; - sql_field.column_name_.set("cluster"); - sql_field.column_value_.set_value("ob_cluster"); + SqlField *sql_field = NULL; + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("cluster"); + sql_field->column_value_.set_value("ob_cluster"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("tenant"); - sql_field.column_value_.set_value("ob_tenant"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("tenant"); + sql_field->column_value_.set_value("ob_tenant"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("name"); - sql_field.column_value_.set_value("resource_max_connections"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("name"); + sql_field->column_value_.set_value("resource_max_connections"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("value"); - sql_field.column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}]"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("value"); + sql_field->column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}]"); sql_result.fields_.push_back(sql_field); ObCloudFnParams cloud_params; @@ -452,21 +459,21 @@ TEST_F(TestTenantProcessor, test_execute_update_value) SqlFieldResult sql_result; sql_result.field_num_ = 4; SqlField sql_field[4]; - sql_field[0].column_name_.set("cluster"); + sql_field[0].column_name_.set_value("cluster"); sql_field[0].column_value_.set_value("ob_cluster"); - sql_result.fields_.push_back(sql_field[0]); + sql_result.fields_.push_back(&sql_field[0]); - sql_field[1].column_name_.set("tenant"); + sql_field[1].column_name_.set_value("tenant"); sql_field[1].column_value_.set_value("ob_tenant"); - sql_result.fields_.push_back(sql_field[1]); + sql_result.fields_.push_back(&sql_field[1]); - sql_field[2].column_name_.set("name"); + sql_field[2].column_name_.set_value("name"); sql_field[2].column_value_.set_value("resource_max_connections"); - sql_result.fields_.push_back(sql_field[2]); + sql_result.fields_.push_back(&sql_field[2]); - sql_field[3].column_name_.set("value"); - sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}, {\"vip\": \"127.0.0.2\", \"value\": 6000}]"); - sql_result.fields_.push_back(sql_field[3]); + sql_field[3].column_name_.set_value("value"); + sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}, {\"vip\": \"10.8.17.120\", \"value\": 6000}]"); + sql_result.fields_.push_back(&sql_field[3]); ObCloudFnParams cloud_params; cloud_params.stmt_type_ = OBPROXY_T_REPLACE; @@ -487,14 +494,19 @@ TEST_F(TestTenantProcessor, test_execute_update_value) ObResourceUnitTableProcessor::commit(&cloud_params, true); LOG_DEBUG("success1"); + SqlField tmp_field[4]; + tmp_field[0] = sql_field[0]; + tmp_field[1] = sql_field[1]; + tmp_field[2] = sql_field[2]; + tmp_field[3] = sql_field[3]; sql_result.reset(); sql_result.field_num_ = 4; - sql_result.fields_.push_back(sql_field[0]); - sql_result.fields_.push_back(sql_field[1]); - sql_result.fields_.push_back(sql_field[2]); - sql_field[3].column_name_.set("value"); - sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.3\", \"value\": 4000}, {\"vip\": \"127.0.0.2\", \"value\": 7777}]"); - sql_result.fields_.push_back(sql_field[3]); + sql_result.fields_.push_back(&tmp_field[0]); + sql_result.fields_.push_back(&tmp_field[1]); + sql_result.fields_.push_back(&tmp_field[2]); + sql_field[3].column_name_.set_value("value"); + sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.3\", \"value\": 4000}, {\"vip\": \"10.8.17.120\", \"value\": 7777}]"); + sql_result.fields_.push_back(&tmp_field[3]); cloud_params.fields_ = &sql_result; ASSERT_EQ(0, ObResourceUnitTableProcessor::execute(&cloud_params)); @@ -527,21 +539,21 @@ TEST_F(TestTenantProcessor, test_delete_tenant) SqlFieldResult sql_result; sql_result.field_num_ = 4; SqlField sql_field[4]; - sql_field[0].column_name_.set("cluster"); + sql_field[0].column_name_.set_value("cluster"); sql_field[0].column_value_.set_value("ob_cluster"); - sql_result.fields_.push_back(sql_field[0]); + sql_result.fields_.push_back(&sql_field[0]); - sql_field[1].column_name_.set("tenant"); + sql_field[1].column_name_.set_value("tenant"); sql_field[1].column_value_.set_value("ob_tenant"); - sql_result.fields_.push_back(sql_field[1]); + sql_result.fields_.push_back(&sql_field[1]); - sql_field[2].column_name_.set("name"); + sql_field[2].column_name_.set_value("name"); sql_field[2].column_value_.set_value("resource_max_connections"); - sql_result.fields_.push_back(sql_field[2]); + sql_result.fields_.push_back(&sql_field[2]); - sql_field[3].column_name_.set("value"); - sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}, {\"vip\": \"127.0.0.2\", \"value\": 6000}]"); - sql_result.fields_.push_back(sql_field[3]); + sql_field[3].column_name_.set_value("value"); + sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}, {\"vip\": \"10.8.17.120\", \"value\": 6000}]"); + sql_result.fields_.push_back(&sql_field[3]); ObCloudFnParams cloud_params; cloud_params.stmt_type_ = OBPROXY_T_REPLACE; @@ -561,16 +573,21 @@ TEST_F(TestTenantProcessor, test_delete_tenant) ASSERT_EQ(0, check_map_value(conn_map, 2)); LOG_DEBUG("success1"); + SqlField tmp_field[4]; + tmp_field[0] = sql_field[0]; + tmp_field[1] = sql_field[1]; + tmp_field[2] = sql_field[2]; + tmp_field[3] = sql_field[3]; sql_result.reset(); sql_result.field_num_ = 4; - sql_result.fields_.push_back(sql_field[0]); - sql_field[1].column_name_.set("tenant"); + sql_result.fields_.push_back(&tmp_field[0]); + sql_field[1].column_name_.set_value("tenant"); sql_field[1].column_value_.set_value("ob_tenant_1"); - sql_result.fields_.push_back(sql_field[1]); - sql_result.fields_.push_back(sql_field[2]); - sql_field[3].column_name_.set("value"); - sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.3\", \"value\": 4000}, {\"vip\": \"127.0.0.2\", \"value\": 7777}]"); - sql_result.fields_.push_back(sql_field[3]); + sql_result.fields_.push_back(&tmp_field[1]); + sql_result.fields_.push_back(&tmp_field[2]); + sql_field[3].column_name_.set_value("value"); + sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 4000}, {\"vip\": \"10.8.17.120\", \"value\": 7777}]"); + sql_result.fields_.push_back(&tmp_field[3]); cloud_params.fields_ = &sql_result; cloud_params.tenant_name_ = "ob_tenant_1"; diff --git a/unittest/obproxy/test_white_list_processor.cpp b/unittest/obproxy/test_white_list_processor.cpp index aec7a728..564247a3 100644 --- a/unittest/obproxy/test_white_list_processor.cpp +++ b/unittest/obproxy/test_white_list_processor.cpp @@ -53,19 +53,33 @@ TEST_F(TestWhiteListProcessor, test_ip_net) char ip2[32] = "127.0.0.3"; char ip3[32] = "127.0.0.4"; char ip4[32] = "127.0.0.5"; - ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, ip1)); - ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, ip2)); - ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, ip3)); - ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, ip4)); + ObAddr addr1(ObAddr::VER::IPV4, ip1, 0); + ObAddr addr2(ObAddr::VER::IPV4, ip2, 0); + ObAddr addr3(ObAddr::VER::IPV4, ip3, 0); + ObAddr addr4(ObAddr::VER::IPV4, ip4, 0); + struct sockaddr_storage ss = addr1.get_sockaddr(); + ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, *reinterpret_cast(&ss))); + ss = addr2.get_sockaddr(); + ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, *reinterpret_cast(&ss))); + ss = addr3.get_sockaddr(); + ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, *reinterpret_cast(&ss))); + ss = addr4.get_sockaddr(); + ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, *reinterpret_cast(&ss))); ObString cluster_name2 = "cluster2"; ObString tenant_name2 = "tenant2"; ObString user_name2 = "user2"; char ip5[32] = "127.0.0.1"; char ip6[32] = "127.0.0.2"; char ip7[32] = "127.0.0.3"; - ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, ip5)); - ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, ip6)); - ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, ip7)); + ObAddr addr5(ObAddr::VER::IPV4, ip5, 0); + ObAddr addr6(ObAddr::VER::IPV4, ip6, 0); + ObAddr addr7(ObAddr::VER::IPV4, ip7, 0); + ss = addr5.get_sockaddr(); + ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, *reinterpret_cast(&ss))); + ss = addr6.get_sockaddr(); + ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, *reinterpret_cast(&ss))); + ss = addr7.get_sockaddr(); + ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, *reinterpret_cast(&ss))); } int main(int argc, char **argv)