diff --git a/.github/workflows/check_bazel_tests.yml b/.github/workflows/check_bazel_tests.yml index 5c86089..14e0131 100644 --- a/.github/workflows/check_bazel_tests.yml +++ b/.github/workflows/check_bazel_tests.yml @@ -23,7 +23,7 @@ jobs: - name: Build run: | source "$UDF_CLIENT_ENV_FILE" - bazel build --lockfile_mode=off --config no-tty -c dbg --config python --config java --config fast-binary --verbose_failures + bazel build --lockfile_mode=off --config no-tty -c dbg --config python --config fast-binary --verbose_failures working-directory: ./exaudfclient/ tests: @@ -32,60 +32,14 @@ jobs: fail-fast: false matrix: include: - - test: "//javacontainer/test:ExaStackTraceCleanerTest" - name: "ExaStackTraceCleanerTest" - java_version: "openjdk-11-jdk" - - test: "//javacontainer/test:ExaStackTraceCleanerTest" - name: "ExaStackTraceCleanerTest" - java_version: "openjdk-17-jdk" - - test: "//javacontainer/test:javacontainer-test-extractor-legacy" - name: "javacontainer-test-extractor-legacy" - java_version: "openjdk-11-jdk" - - test: "//javacontainer/test:javacontainer-test-extractor-v2" - name: "javacontainer-test-extractor-v2" - java_version: "openjdk-11-jdk" - - test: "//javacontainer/script_options/..." - name: "javacontainer-script_options" - java_version: "" - test: "//exaudflib/test/..." name: "exaudflib" - java_version: "" - - test: "//script_options_parser/ctpg/..." - name: "script_options_parser_ctpg" - java_version: "" - - test: "//script_options_parser/legacy/..." - name: "script_options_parser_legacy" - java_version: "" - - test: "--run_under='valgrind --leak-check=yes' --config=valgrind //javacontainer/test:javacontainer-test-extractor-legacy" - name: "javacontainer-test-extractor-legacy-with-valgrind" - java_version: "openjdk-11-jdk" - - test: "--run_under='valgrind --leak-check=yes' --config=valgrind //javacontainer/test:javacontainer-test-extractor-v2" - name: "javacontainer-test-extractor-v2-with-valgrind" - java_version: "openjdk-11-jdk" - - test: "--run_under='valgrind --leak-check=yes' --config=valgrind //script_options_parser/ctpg/..." - name: "script_options_parser_ctpg_with_valgrind" - java_version: "" - - test: "--run_under='valgrind --leak-check=yes' --config=valgrind //script_options_parser/legacy/..." - name: "script_options_parser_legacy_with_valgrind" - java_version: "" - - test: "--config=asan //javacontainer/test:javacontainer-test-extractor-legacy" - name: "javacontainer-test-extractor-legacy-with-asan" - java_version: "openjdk-11-jdk" - - test: "--config=asan //javacontainer/test:javacontainer-test-extractor-v2" - name: "javacontainer-test-extractor-v2-with-asan" - java_version: "openjdk-11-jdk" - - test: "--config=asan //script_options_parser/ctpg/..." - name: "script_options_parser_ctpg_with_asan" - java_version: "" - - test: "--config=asan //script_options_parser/legacy/..." - name: "script_options_parser_legacy_with_asan" - java_version: "" steps: - uses: actions/checkout@v6 - - name: Install JDK and ZMQ + - name: Install ZMQ run: | sudo apt-get update - sudo apt-get install -y ${{ matrix.java_version }} libzmq3-dev valgrind + sudo apt-get install -y libzmq3-dev valgrind - name: Install bazel run: | BAZEL_PACKAGE_FILE="bazel_$BAZEL_PACKAGE_VERSION-linux-x86_64.deb" diff --git a/emulator/MY_TEST_JAVA b/emulator/MY_TEST_JAVA deleted file mode 100644 index 85d093a..0000000 --- a/emulator/MY_TEST_JAVA +++ /dev/null @@ -1,13 +0,0 @@ -//input_column: a,int64,INT,None,None,None -//input_column: b,string,VARCHAR(100),100,None,None -//input_type: SET - -//output_column: a,int64,INT,None,None,None -//output_column: b,string,VARCHAR(100),100,None,None -//output_type: EMITS -class MY_TEST_JAVA { - static void run(ExaMetadata exa, ExaIterator ctx) throws Exception { - String str = ctx.getString("b"); - ctx.emit(1,str); - } -} \ No newline at end of file diff --git a/emulator/exasolution.py b/emulator/exasolution.py index 609922f..d249da2 100644 --- a/emulator/exasolution.py +++ b/emulator/exasolution.py @@ -125,8 +125,7 @@ def parse_number(num): input_file = output_file_fd = output_file = script_lines = script_input_defs = script_output_defs = None if not single_call_mode: - if script_name.endswith('.java'): comment = '//' - else: comment = '#' + comment = '#' for line in script_lines: if line.startswith(comment + 'input_column:'): script_input_defs.append(line[len(comment + 'input_column:'):]) @@ -301,12 +300,6 @@ def handle_client(): #response.info.vm_type = PB_VM_EXTERNAL response.info.maximal_memory_limit = memory_limit response.info.meta_info = meta_info - #if redirector_name != None: response.info.vm_type = PB_VM_EXTERNAL - #else: - # if script_name.endswith('.py'): response.info.vm_type = PB_VM_PYTHON - # elif script_name.endswith('.R'): response.info.vm_type = PB_VM_R - # elif script_name.endswith('.java'): response.info.vm_type = PB_VM_JAVA - # else: raise RuntimeError("Unsupported VM type") send_message(response.SerializeToString()) initialized = True @@ -355,7 +348,7 @@ def handle_import(): if kind == PB_IMPORT_SCRIPT_CODE: if script_name.endswith('.py'): fname = fname + '.py' elif script_name.endswith('.R'): fname = fname + '.R' - else: fname = fname + '.java' + else: raise RuntimeError("Unsupported script language") try: getattr(response, 'import').source_code = open(fname).read() except Exception, err: response.exception_message = str(err) diff --git a/exaudfclient/.bazelrc b/exaudfclient/.bazelrc index 3744dc3..4e4676e 100644 --- a/exaudfclient/.bazelrc +++ b/exaudfclient/.bazelrc @@ -1,7 +1,6 @@ build --lockfile_mode=off --copt='-std=c++17' --force_pic --action_env=PROTOBUF_BIN --action_env=PROTOBUF_LIBRARY_PREFIX --action_env=PROTOBUF_INCLUDE_PREFIX # TODO add environment variables for R libraries build:benchmark --define benchmark=true -build:java --define java=true --action_env=JAVA_PREFIX build:python --define python=true --action_env=NUMPY_PREFIX --action_env=PYTHON3_SYSPATH --action_env=PYTHON3_PREFIX --action_env=PYTHON3_VERSION build:fast-binary --define binary_type=fast_binary //:exaudfclient build:slow-wrapper --define binary_type=slow_wrapper //:exaudfclient diff --git a/exaudfclient/.env.template b/exaudfclient/.env.template index de12eee..684c76e 100644 --- a/exaudfclient/.env.template +++ b/exaudfclient/.env.template @@ -1,4 +1,3 @@ -export JAVA_PREFIX= export PYTHON3_PREFIX= export PYTHON3_VERSION= export PROTOBUF_BIN= @@ -8,4 +7,4 @@ export OPENSSL_LIBRARY_PREFIX= export OPENSSL_INCLUDE_PREFIX= export VERBOSE_BUILD= #"--subcommands --verbose_failures" export ZMQ_LIBRARY_PREFIX= -export ZMQ_INCLUDE_PREFIX= \ No newline at end of file +export ZMQ_INCLUDE_PREFIX= diff --git a/exaudfclient/BUILD b/exaudfclient/BUILD index ef4505d..08cfedf 100644 --- a/exaudfclient/BUILD +++ b/exaudfclient/BUILD @@ -7,9 +7,6 @@ load("@rules_shell//shell:sh_library.bzl", "sh_library") VM_ENABLED_DEPS=select({ "@exaudfclient_base//:benchmark": ["@exaudfclient_base//benchmark_container:benchmark_container"], "//conditions:default": [] - }) + select({ - "@exaudfclient_base//:java": ["@exaudfclient_base//javacontainer:javacontainer"], - "//conditions:default": [] }) + select({ "@exaudfclient_base//:bash": ["@exaudfclient_base//streaming_container:streamingcontainer"], "//conditions:default": [] diff --git a/exaudfclient/MODULE.bazel b/exaudfclient/MODULE.bazel index bcc3f18..b445d66 100644 --- a/exaudfclient/MODULE.bazel +++ b/exaudfclient/MODULE.bazel @@ -5,7 +5,6 @@ bazel_dep(name = "exaudfclient_base", version = "1.0.0") #Later we might fetch it via Http or Git (after splitting up script-languages repository) local_path_override(module_name="exaudfclient_base", path="base") bazel_dep(name = "rules_cc", version = "0.2.22") -bazel_dep(name = "rules_jvm_external", version = "6.7") bazel_dep(name = "rules_shell", version = "0.8.0") numpy_local_repository = use_repo_rule("@exaudfclient_base//:python_repository.bzl", "numpy_local_repository") @@ -19,18 +18,3 @@ zmq_local_repository(name = "zmq") protobuf_local_repository = use_repo_rule("@exaudfclient_base//:protobuf_repository.bzl", "protobuf_local_repository") protobuf_local_repository(name = "protobuf") - -java_local_repository = use_repo_rule("@exaudfclient_base//:java_repository.bzl", "java_local_repository") -java_local_repository(name = "java") - - -maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") -maven.install( - artifacts = [ - "com.exasol:udf-api-java:1.0.5", - ], - repositories = [ - "https://repo1.maven.org/maven2", - ], -) -use_repo(maven, "maven") diff --git a/exaudfclient/README.md b/exaudfclient/README.md index 1f8bd30..b95fb58 100644 --- a/exaudfclient/README.md +++ b/exaudfclient/README.md @@ -1,6 +1,6 @@ # What is the exaudfclient? -The exaudfclient connects to the database via [ZeroMQ](http://zeromq.org/) and fetches the tuples which then get processed by the user-defined functions (UDFs). Currently, the exaudfclient supports UDFs in the language Python, Java and R. Further languages can be integrated via language binding between C/C++ and the desired langauge. Python 3, Java and R use [SWIG](http://www.swig.org/) for the language binding. +The exaudfclient connects to the database via [ZeroMQ](http://zeromq.org/) and fetches the tuples which then get processed by the user-defined functions (UDFs). Currently, the exaudfclient supports UDFs in Python. Further languages can be integrated via language binding between C/C++ and the desired language. Python 3 uses [SWIG](http://www.swig.org/) for the language binding. # How to build the exaudfclient? @@ -8,7 +8,6 @@ The exaudfclient connects to the database via [ZeroMQ](http://zeromq.org/) and f For the build system: -- Open JDK 11 - bazel-7.2.1 for more details see [Bazel documentation](https://docs.bazel.build/versions/master/install.html) The exaudfclient was tested with the following versions of its dependencies: @@ -23,12 +22,10 @@ For the language support: - Python 3.10 for pythoncontainer - for Python 3 the build requires [Numpy](https://www.numpy.org/) and [Pandas](https://pandas.pydata.org/) in addition for the Pandas Dataframe Support -- OpenJDK 11 for javacontainer -- R 4.4 for the rcontainer ## Start a build -The exaudfclient is a multi-language project. Therefore, we are using [Bazel](https://docs.bazel.build/versions/master/bazel-overview.html) as build system, because it provides build support for many languages and allows to mix these languages. Because the exaudfclient has language bindings to Python 2/3, Java and R, we need specify where Bazel can find the correponding library- and header-files. This is done by Environment Variables. +The exaudfclient is a multi-language project. Therefore, we are using [Bazel](https://docs.bazel.build/versions/master/bazel-overview.html) as build system, because it provides build support for many languages and allows to mix these languages. Because the exaudfclient has language bindings to Python 2/3 and R, we need specify where Bazel can find the corresponding library and header files. This is done by environment variables. For executing the build locally, you can use the script @@ -46,7 +43,6 @@ Both build script can receive parameters, such as Bazel commandline parameter, B With Bazel defines you can specify which language support is actually compiled into you exaudfclient executbale. The currently supported defines are - --define java=true --define r=true --define python=true --define benchmark=true # This language is only for test and development purpose and benchmarks the performance of the C++ Implementation @@ -70,7 +66,7 @@ The usage of multiple linker namespace requires some precautions in the build pr ## Precautions in the build process -In the build process you need to be cautious which libraries you link together and that no link leaks symbols from a library in one namespace to a library in the other namespace. Furthermore, you have to build a shared library with all dependency linked to it as output target. In our case, we have to main output targets //:exaudfclient and //:libexaudflib.so. Both get loaded into different linker namespaces. The language container live in the same namespace as //:exaudfclient. This namespace must not know anyhing about protobuf and zeromq, because it is possible that a language container may load protobuf or zeromq in a different version. Protobuf and zeromq are only known in the namespace of //:libexaudflib.so. The target //:libexaudflib.so depends on //base/exaudflib:exaudflib which contains the logic of the exaudflib. You must not depend on //base/exaudflib:exaudflib in //:exaudfclient or the langauge container, because this would leak zeromq and protobuf. If you need to depend on the other dependency of //base/exaudflib:exaudflib which not depend on protobuf or zeromq them self, such as //base/exaudflib:script_data_transfer_objects, //base/exaudflib:script_data_transfer_objects_wrapper, //base/script_options_parser:scriptoptionlines, use either their target as self, the collection of libraries //base/exaudflib:exaudflib-deps or the collection of headers //base/exaudflib:header. +In the build process you need to be cautious which libraries you link together and that no link leaks symbols from a library in one namespace to a library in the other namespace. Furthermore, you have to build a shared library with all dependency linked to it as output target. In our case, we have two main output targets: //:exaudfclient and //:libexaudflib.so. Both get loaded into different linker namespaces. The language containers live in the same namespace as //:exaudfclient. This namespace must not know anything about protobuf and zeromq, because a language container may load protobuf or zeromq in a different version. Protobuf and zeromq are only known in the namespace of //:libexaudflib.so. The target //:libexaudflib.so depends on //base/exaudflib:exaudflib which contains the logic of the exaudflib. You must not depend on //base/exaudflib:exaudflib in //:exaudfclient or a language container, because this would leak zeromq and protobuf. If you need other dependencies of //base/exaudflib:exaudflib that do not depend on protobuf or zeromq, such as //base/exaudflib:script_data_transfer_objects or //base/exaudflib:script_data_transfer_objects_wrapper, use their target directly, the collection of libraries //base/exaudflib:exaudflib-deps, or the collection of headers //base/exaudflib:header. ## Precautions in the implementations diff --git a/exaudfclient/base/.bazelrc b/exaudfclient/base/.bazelrc index 4a15be7..c6d0048 100644 --- a/exaudfclient/base/.bazelrc +++ b/exaudfclient/base/.bazelrc @@ -1,6 +1,5 @@ build --lockfile_mode=off --copt='-std=c++17' --force_pic --action_env=PROTOBUF_BIN --action_env=PROTOBUF_LIBRARY_PREFIX --action_env=PROTOBUF_INCLUDE_PREFIX build:benchmark --define benchmark=true -build:java --define java=true --action_env=JAVA_PREFIX build:python --define python=true --action_env=NUMPY_PREFIX --action_env=PYTHON3_SYSPATH --action_env=PYTHON3_PREFIX --action_env=PYTHON3_VERSION build:debug-build --sandbox_debug --config=verbose build:no-symlinks --symlink_prefix=/ diff --git a/exaudfclient/base/BUILD b/exaudfclient/base/BUILD index 55de850..5f857bf 100644 --- a/exaudfclient/base/BUILD +++ b/exaudfclient/base/BUILD @@ -1,6 +1,6 @@ package(default_visibility = ["//visibility:public"]) -exports_files(["filter_swig_code.py", "build_integrated.py", +exports_files(["build_integrated.py", "create_binary_wrapper.sh", "create_binary_wrapper_valgrind.sh", "create_binary_wrapper_valgrind_massif.sh", "exaudfclient.template.sh", "replace_swig_import_helper.py"]) @@ -18,11 +18,6 @@ config_setting( define_values = {"python": "true"}, ) -config_setting( - name = "java", - define_values = {"java": "true"}, -) - config_setting( name = "bash", define_values = {"bash": "true"}, diff --git a/exaudfclient/base/MODULE.bazel b/exaudfclient/base/MODULE.bazel index eedf459..8cb18b7 100644 --- a/exaudfclient/base/MODULE.bazel +++ b/exaudfclient/base/MODULE.bazel @@ -3,9 +3,7 @@ module(name="exaudfclient_base", version = "1.0") bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "googletest", version = "1.15.0") bazel_dep(name = "rules_cc", version = "0.2.22") -bazel_dep(name = "rules_jvm_external", version = "6.2") -# The following is necessary to build the UDF client for Java # Since Bazel >8 the Python hermetic build rules must not run as root # However, since the UDF client is built as root in a docker container # we must disable this behavior. The only way is to configure the Python hermetic toolchain @@ -27,17 +25,3 @@ zmq_local_repository(name = "zmq") protobuf_local_repository = use_repo_rule("@exaudfclient_base//:protobuf_repository.bzl", "protobuf_local_repository") protobuf_local_repository(name = "protobuf") - -java_local_repository = use_repo_rule("@exaudfclient_base//:java_repository.bzl", "java_local_repository") -java_local_repository(name = "java") - -maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") -maven.install( - artifacts = [ - "com.exasol:udf-api-java:1.0.5", - ], - repositories = [ - "https://repo1.maven.org/maven2", - ], -) -use_repo(maven, "maven") diff --git a/exaudfclient/base/benchmark_container/BUILD b/exaudfclient/base/benchmark_container/BUILD index 9aca9dd..c591e6a 100644 --- a/exaudfclient/base/benchmark_container/BUILD +++ b/exaudfclient/base/benchmark_container/BUILD @@ -6,5 +6,5 @@ cc_library( name = "benchmark_container", srcs = ["benchmark_container.cc","benchmark_container.h"], hdrs = ["benchmark_container.h"], - deps = ["//exaudflib:exaudflib-deps","//exaudflib:header", "//utils:utils"]+["//script_options_parser:scriptoptionlines"] -) \ No newline at end of file + deps = ["//exaudflib:exaudflib-deps","//exaudflib:header", "//utils:utils"] +) diff --git a/exaudfclient/base/exaudflib/swig/swig_common.h b/exaudfclient/base/exaudflib/swig/swig_common.h index 8080e59..b61b0fc 100644 --- a/exaudfclient/base/exaudflib/swig/swig_common.h +++ b/exaudfclient/base/exaudflib/swig/swig_common.h @@ -15,7 +15,6 @@ enum VMTYPE { VM_JAVASCRIPT = 3, VM_R = 4, VM_EXTERNAL = 5, - VM_JAVA = 6, VM_PLUGIN_LANGUAGE = 7, VM_BENCHMARK = 8 }; diff --git a/exaudfclient/base/exaudflib/zmqcontainer.proto b/exaudfclient/base/exaudflib/zmqcontainer.proto index 7d7e085..5cbca1d 100644 --- a/exaudfclient/base/exaudflib/zmqcontainer.proto +++ b/exaudfclient/base/exaudflib/zmqcontainer.proto @@ -83,7 +83,6 @@ enum exascript_vmtype { PB_VM_JAVASCRIPT = 3; PB_VM_R = 4; PB_VM_EXTERNAL = 5; - PB_VM_JAVA = 6; PM_VM_PLUGIN_LANGUAGE = 7; } */ diff --git a/exaudfclient/base/filter_swig_code.py b/exaudfclient/base/filter_swig_code.py deleted file mode 100644 index 34f78ab..0000000 --- a/exaudfclient/base/filter_swig_code.py +++ /dev/null @@ -1,133 +0,0 @@ -import os -import sys - -JAVA_SRC_PATH = 'java_src' - - -def filter_swig_code(target, source): - assert len(target) == 1 and len(source) == 1 - - builddir = './' - # if 'build_dir' in env: - # builddir = os.path.join( env['build_dir'], SWIGBASED_DIR ) - - # try: - # RE - # except: - # RE = env['CURRENTTOOLCHAIN'] - - target = str(target[0]) - source = str(source[0]) - print("filter_swig_code: reading file ", str(source)) - output = [] - with open(source) as rofile: - for line in rofile: - line = line.rstrip() - if source.endswith('_python_tmp.cc'): - line = line.replace('SWIG_init(void)', 'init_exascript_python(void)') - if line == ' PyObject *m, *d, *md;': - line = ' PyObject *m, *d;' - elif line == ' md = d = PyModule_GetDict(m);': - line = ' d = PyModule_GetDict(m);' - elif line == ' (void)md;': - line = '' - elif line == ' PyDict_SetItemString(md, "__all__", public_interface);': - line = ' PyDict_SetItemString(d, "__all__", public_interface);' - elif source.endswith('_r_tmp.cc') or source.endswith('_r_tmp.h'): - if line == ' const char *p = typeName;': - output.append('#if 0') - elif line == ' p = typeName + 1;': - output.append(line) - line = '#endif' - elif line == ' delete arg1;': - line = ' if (argp1 != NULL) delete arg1;' - elif line == ' {NULL, NULL, 0}': - output.append(' {"RVM_next_block", (DL_FUNC) &RVM_next_block, 4},') - output.append(' {"RVM_emit_block", (DL_FUNC) &RVM_emit_block, 2},') - elif line == 'SWIGINTERN R_CallMethodDef CallEntries[] = {': - output.append('extern "C" SEXP RVM_next_block(SEXP dataexp);') - output.append('extern "C" SEXP RVM_emit_block(SEXP dataexp);') - elif source.endswith('_java_tmp.cc'): - if line == 'SWIGEXPORT jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) {': - output.append('SWIGEXPORT jbyteArray JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getStringByteArray(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2) {') - line = next(rofile).rstrip() - if line == ' jstring jresult = 0 ;': - output.append(' jbyteArray jresult = 0 ;') - line = next(rofile).rstrip() - while line != ' if (result) jresult = jenv->NewStringUTF((const char *)result);': - output.append(line) - line = next(rofile).rstrip() - if line == ' if (result) jresult = jenv->NewStringUTF((const char *)result);': - output.append(' if (result) {') - output.append(' jsize len = strlen(result);') - output.append(' jresult = jenv->NewByteArray(len);') - output.append(' jenv->SetByteArrayRegion(jresult, 0, len, (jbyte *)result);') - output.append(' }') - output.append(' return jresult;') - while line != '}': - line = next(rofile).rstrip() - if line == 'SWIGEXPORT void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jstring jarg3, jlong jarg4) {': - output.append('SWIGEXPORT void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setStringByteArray(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jbyteArray jarg3, jlong jarg4) {') - line = next(rofile).rstrip() - while line != ' if (jarg3) {': - output.append(line) - line = next(rofile).rstrip() - if line == ' if (jarg3) {': - output.append(' arg4 = (size_t)jarg4;') - output.append(' if (jarg3) {') - output.append(' arg3 = new char[arg4 + 1];') - output.append(' if (!arg3) return;') - output.append(' jenv->GetByteArrayRegion(jarg3, 0, jarg4, (jbyte *)arg3);') - output.append(' arg3[arg4] = 0;') - output.append(' }') - output.append(' (arg1)->setString(arg2,arg3,arg4);') - output.append(' if (arg3) delete [] arg3;') - while line != '}': - line = next(rofile).rstrip() - output.append(line) - with open(str(target), 'w') as fd: - fd.write('\n'.join(output)) - fd.write('\n') - print("filter_swig_code: wrote file ", str(target)) - # piggyback on exascript_java.cc target to patch *.java files (avoids error from multiple ways to build target) - if source.endswith('_java_tmp.cc'): - filter_java_swig_code(builddir) - return 0 - - -def filter_java_swig_code(builddir=''): - files = map(lambda s: os.path.join(builddir+f'{JAVA_SRC_PATH}/com/exasol/swig', s), - ['TableIterator.java', 'ResultHandler.java', 'exascript_javaJNI.java']) - for target in files: - output = [] - with open(target) as target_file: - for line in target_file: - line = line.rstrip() - if target.endswith('TableIterator.java'): - if line == ' public String getString(long col) {': - line = ' public byte[] getString(long col) {' - elif line == ' return exascript_javaJNI.TableIterator_getString(swigCPtr, this, col);': - line = ' return exascript_javaJNI.TableIterator_getStringByteArray(swigCPtr, this, col);' - elif target.endswith('ResultHandler.java'): - if line == ' public void setString(long col, String v, long l) {': - line = ' public void setString(long col, byte[] v) {' - elif line == ' exascript_javaJNI.ResultHandler_setString(swigCPtr, this, col, v, l);': - line = ' exascript_javaJNI.ResultHandler_setStringByteArray(swigCPtr, this, col, v, v.length);' - elif target.endswith('exascript_javaJNI.java'): - if line == ' public final static native String TableIterator_getString(long jarg1, TableIterator jarg1_, long jarg2);': - line = ' public final static native byte[] TableIterator_getStringByteArray(long jarg1, TableIterator jarg1_, long jarg2);' - elif line == ' public final static native void ResultHandler_setString(long jarg1, ResultHandler jarg1_, long jarg2, String jarg3, long jarg4);': - line = ' public final static native void ResultHandler_setStringByteArray(long jarg1, ResultHandler jarg1_, long jarg2, byte[] jarg3, long jarg4);' - output.append(line) - with open(str(target), 'w') as fd: - fd.write('\n'.join(output)) - fd.write('\n') - return 0 - - -if __name__ == "__main__": - if len(sys.argv) != 3: - print('Usage: filter_swig_code.py target source') - sys.exit(1) - print("filtering swig code ", str([sys.argv[1]]), str([sys.argv[2]])) - filter_swig_code([sys.argv[1]], [sys.argv[2]]) diff --git a/exaudfclient/base/java_repository.bzl b/exaudfclient/base/java_repository.bzl deleted file mode 100644 index cceb053..0000000 --- a/exaudfclient/base/java_repository.bzl +++ /dev/null @@ -1,54 +0,0 @@ -load("@bazel_skylib//lib:paths.bzl", "paths") - -# Workaround for the problems of JNI/JVM with rpath's used by Bazel. -# Problem Description: -# - Bazel creates for all external local repositories symlinks into its build directory -# - Bazel than writes during compilation these paths to the rpath of the binary -# - JNI/JVM uses the rpath for loading additional shared libraries, -# but for a unknown reason it seems to truncate these paths. -# - We assume two possible reason, the symlink paths of bazel contain a @, or -# the paths are to long and get for that reason truncated -# - In the end, it we wasn't able to convince JNI/JVM from other paths -# for its libraries, as the original paths where apt installed the files. -# Solution: -# - We solved the problem by adding the original paths for the libraries into the rpath via the linkopts - -def _find_shared_libraries(prefix,library,p_repository_ctx): - command_result = p_repository_ctx.execute(["find", '%s'%prefix,'-name','%s'%library]) #TODO only one result - if command_result.return_code != 0: - fail("Could not acquire path of libjvm.so, got return code %s stderr: \n %s" - % (command_result.return_code, command_result.stderr)) - path_to_library = command_result.stdout.strip("\n") - print("path to %s: %s"%(library,path_to_library)) - return path_to_library - -def _java_local_repository_impl(repository_ctx): - prefix = "/usr/lib/jvm/java-11-openjdk-amd64" - if 'JAVA_PREFIX' in repository_ctx.os.environ: - prefix = repository_ctx.os.environ['JAVA_PREFIX'] - print("java prefix in environment specified; %s"%prefix) - - path_to_libjvm = paths.dirname(_find_shared_libraries(prefix,"libjvm.so",repository_ctx)) - - defines = '"ENABLE_JAVA_VM"' - build_file_content = """ -load("@rules_cc//cc:defs.bzl", "cc_library") - -cc_library( - name = "java", - srcs = glob(["{prefix}/include/*.h"], allow_empty=False), - hdrs = glob(["{prefix}/include/*.h","{prefix}/include/linux/*.h"], allow_empty=False), - includes = ["{prefix}/include","{prefix}/include/linux"], - defines = [{defines}], - linkopts = ["-ljvm","-L{rpath_libjvm}",'-Wl,-rpath','{rpath_libjvm}'], - visibility = ["//visibility:public"] -)""".format( defines=defines, prefix="java", rpath_libjvm=path_to_libjvm) - print(build_file_content) - - repository_ctx.symlink(prefix, "./java") - repository_ctx.file("BUILD", build_file_content) - -java_local_repository = repository_rule( - implementation=_java_local_repository_impl, - local = True, - environ = ["JAVA_PREFIX"]) diff --git a/exaudfclient/base/javacontainer/BUILD b/exaudfclient/base/javacontainer/BUILD deleted file mode 100644 index 15c95e5..0000000 --- a/exaudfclient/base/javacontainer/BUILD +++ /dev/null @@ -1,153 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load("@rules_cc//cc:defs.bzl", "cc_library") - -genrule( - name = "exascript_java_tmp_cc", - cmd = """ - mkdir -p java_src/com/exasol/swig - mkdir -p build_exascript_java_tmp_cc/exaudflib - cp "$(location //exaudflib:swig/script_data_transfer_objects_wrapper.h)" "$(location //exaudflib:exascript.i)" build_exascript_java_tmp_cc/exaudflib - cd build_exascript_java_tmp_cc - swig -v -O -DEXTERNAL_PROCESS -Wall -c++ -java -addextern -module exascript_java -package com.exasol.swig -outdir "../java_src/com/exasol/swig" -o "../exascript_java_tmp.cc" exaudflib/exascript.i - cd .. - cp java_src/com/exasol/swig/ConnectionInformationWrapper.java $(location ConnectionInformationWrapper.java) - cp java_src/com/exasol/swig/exascript_java.java $(location exascript_java.java) - cp java_src/com/exasol/swig/exascript_javaJNI.java $(location raw/exascript_javaJNI.java) - cp java_src/com/exasol/swig/ExportSpecificationWrapper.java $(location ExportSpecificationWrapper.java) - cp java_src/com/exasol/swig/ImportSpecificationWrapper.java $(location ImportSpecificationWrapper.java) - cp java_src/com/exasol/swig/Metadata.java $(location Metadata.java) - cp java_src/com/exasol/swig/ResultHandler.java $(location raw/ResultHandler.java) - cp java_src/com/exasol/swig/SWIGTYPE_p_ExecutionGraph__ExportSpecification.java $(location SWIGTYPE_p_ExecutionGraph__ExportSpecification.java) - cp java_src/com/exasol/swig/SWIGTYPE_p_ExecutionGraph__ImportSpecification.java $(location SWIGTYPE_p_ExecutionGraph__ImportSpecification.java) - cp java_src/com/exasol/swig/SWIGVM_datatype_e.java $(location SWIGVM_datatype_e.java) - cp java_src/com/exasol/swig/SWIGVM_itertype_e.java $(location SWIGVM_itertype_e.java) - cp java_src/com/exasol/swig/TableIterator.java $(location raw/TableIterator.java) - cp exascript_java_tmp.cc $(location exascript_java_tmp.cc) - """, - outs = ["ConnectionInformationWrapper.java", - "exascript_java.java", - "ExportSpecificationWrapper.java", - "ImportSpecificationWrapper.java", - "Metadata.java", - "SWIGTYPE_p_ExecutionGraph__ExportSpecification.java", - "SWIGTYPE_p_ExecutionGraph__ImportSpecification.java", - "SWIGVM_datatype_e.java", - "SWIGVM_itertype_e.java", - "raw/exascript_javaJNI.java", - "raw/ResultHandler.java", - "raw/TableIterator.java", - "exascript_java_tmp.cc" - ], - srcs = ["//exaudflib:exascript.i","//exaudflib:swig/script_data_transfer_objects_wrapper.h"] -) - -genrule( - name = "exascript_java_tmp_h", - cmd = """ - mkdir build_exascript_java_tmp_h - cp "$(location //exaudflib:swig/script_data_transfer_objects_wrapper.h)" "$(location //exaudflib:exascript.i)" build_exascript_java_tmp_h - cp -r "$(location exascript_java_tmp.cc)" build_exascript_java_tmp_h - cd build_exascript_java_tmp_h - swig -v -DEXTERNAL_PROCESS -c++ -java -external-runtime "../$(location exascript_java_tmp.h)" - """, - outs = ["exascript_java_tmp.h"], - srcs = ["//exaudflib:exascript.i","//exaudflib:swig/script_data_transfer_objects_wrapper.h", ":exascript_java_tmp.cc"] -) - - -genrule( - name = "filter_swig_code_exascript_java_h", - cmd = 'python3 $(location //:filter_swig_code.py) "$@" "$<"', - outs = ["exascript_java.h"], - srcs = [":exascript_java_tmp_h"], - tools = ["//:filter_swig_code.py"] -) - -genrule( - name = "filter_swig_code_exascript_java_cc", - cmd = """ - TMPDIR=`mktemp -d` - mkdir -p "$$TMPDIR"/java_src/com/exasol/swig - cp $(location :raw/TableIterator.java) "$$TMPDIR"/java_src/com/exasol/swig/ - cp $(location :raw/ResultHandler.java) "$$TMPDIR"/java_src/com/exasol/swig/ - cp $(location :raw/exascript_javaJNI.java) "$$TMPDIR"/java_src/com/exasol/swig/ - find "$$TMPDIR"/java_src/com/exasol/swig/ -name *.java -type f -exec chmod 644 {} \\; - cp -r -L $(location //:filter_swig_code.py) $(location :exascript_java_tmp.cc) "$$TMPDIR" - (cd "$$TMPDIR" - python3 filter_swig_code.py "exascript_java.cc" "exascript_java_tmp.cc") - cp "$$TMPDIR"/exascript_java.cc $(location :exascript_java.cc) - cp "$$TMPDIR"/java_src/com/exasol/swig/TableIterator.java $(location TableIterator.java) - cp "$$TMPDIR"/java_src/com/exasol/swig/ResultHandler.java $(location ResultHandler.java) - cp "$$TMPDIR"/java_src/com/exasol/swig/exascript_javaJNI.java $(location exascript_javaJNI.java) - rm -rf "$$TMPDIR" - """, - outs = [ - "exascript_java.cc", - "TableIterator.java", - "ResultHandler.java", - "exascript_javaJNI.java" - ], - srcs = [":exascript_java_tmp.cc", ":raw/TableIterator.java", - ":raw/ResultHandler.java", ":raw/exascript_javaJNI.java"], - tools = ["//:filter_swig_code.py"] -) - -cc_library( - name = "exascript_java", - srcs = [":exascript_java.cc",], - deps = ["@java//:java","//exaudflib:exaudflib-deps","//exaudflib:header"], - copts= ["-O0","-fno-lto"], - # We limit this target to -O0 (no optimization) and -fno-lto. because otherwise we get compiler warnings of the sort - # note: "code may be misoptimized unless -fno-strict-aliasing is used." - # Normally, this indicates that compiling with higher optimizations levels may break your program. Until now, we don't have enough tests - # to verify if higher levels of optimizations might work. We needed to deactivate link time optimization, too, because this delay the compilation - # until the exaudfclient binary is build and causes than there the same problem. - alwayslink=True, -) - -cc_library( - name = "javacontainer", - srcs = [":javacontainer.cc", ":javacontainer.h", ":javacontainer_impl.cc", ":javacontainer_impl.h", - ":javacontainer_builder.h", ":javacontainer_builder.cc", ":dummy"], - hdrs = [":filter_swig_code_exascript_java_h", "exascript_java_jni_decl.h"], - deps = ["@java//:java", ":exascript_java", "//exaudflib:header", - "//utils:utils","//javacontainer/script_options:java_script_option_lines", - "//swig_factory:swig_factory"], -# copts= ["-O0","-fno-lto"], - alwayslink=True, -) - -#workaround to build jars together with javacontainer c++ library -genrule( - name = "dummy", - cmd = 'touch "$@"', - outs = ["dummy.h"], - srcs = [":exaudf_deploy.jar"], -) - -java_binary( - name = "exaudf", - srcs = glob(["*.java"])+ - #The following are generated classes - [ - ":ConnectionInformationWrapper.java", - ":exascript_java.java", - ":exascript_javaJNI.java", - ":ExportSpecificationWrapper.java", - ":ImportSpecificationWrapper.java", - ":Metadata.java", - ":ResultHandler.java", - ":SWIGTYPE_p_ExecutionGraph__ExportSpecification.java", - ":SWIGTYPE_p_ExecutionGraph__ImportSpecification.java", - ":SWIGVM_datatype_e.java", - ":SWIGVM_itertype_e.java", - ":TableIterator.java" - ], - deps = ["@maven//:com_exasol_udf_api_java"], - create_executable=False, -) - -exports_files([ - "ExaStackTraceCleaner.java", - ]) diff --git a/exaudfclient/base/javacontainer/ExaCompiler.java b/exaudfclient/base/javacontainer/ExaCompiler.java deleted file mode 100644 index 947fa0e..0000000 --- a/exaudfclient/base/javacontainer/ExaCompiler.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.exasol; - -import java.util.List; -import java.util.Arrays; -import java.util.ArrayList; -import java.io.StringWriter; -import javax.tools.SimpleJavaFileObject; -import javax.tools.JavaFileObject; -import javax.tools.ToolProvider; -import javax.tools.JavaCompiler; -import javax.tools.JavaCompiler.CompilationTask; -import java.net.URI; - -class ExaCompiler { - static void compile(String classname, String code, String classpath) throws ExaCompilationException { - temporaryClasspath = classpath; - JavaFileObject file = new JavaSource(classname, code); - Iterable compilationUnits = Arrays.asList(file); - List optionList = new ArrayList(Arrays.asList("-d", temporaryClasspath)); - - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - StringWriter compilationOutput = new StringWriter(); - CompilationTask task = compiler.getTask(compilationOutput, null, null, optionList, null, compilationUnits); - - boolean success = false; - try { - success = task.call(); - } catch (Exception e) { - // ignore - } - if (!success) { - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1158: "+compilationOutput.toString()); - } - } - - static void compile(String classname, String code) throws ExaCompilationException { - compile(classname, code, temporaryClasspath); - } - - private static class JavaSource extends SimpleJavaFileObject { - final String code; - - JavaSource(String classname, String code) { - super(URI.create("string:///" + classname.replace(".","/") + Kind.SOURCE.extension), Kind.SOURCE); - this.code = code; - } - - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - return this.code; - } - } - - private static String temporaryClasspath; -} diff --git a/exaudfclient/base/javacontainer/ExaConnectionInformationImpl.java b/exaudfclient/base/javacontainer/ExaConnectionInformationImpl.java deleted file mode 100644 index 1d17c78..0000000 --- a/exaudfclient/base/javacontainer/ExaConnectionInformationImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.exasol; - - -public class ExaConnectionInformationImpl implements ExaConnectionInformation { - - private ConnectionType type; - private String address; - private String user; - private String password; - - public ExaConnectionInformationImpl(String type, String address, String user, String password) - { - if (type.equals("password")) { - this.type = ConnectionType.PASSWORD; - } else { - throw new IllegalStateException("F-UDF-CL-SL-JAVA-1157: ExaConnectionInformationImpl: received unknown connection type: "+type); - } - this.address = address; - this.user = user; - this.password = password; - } - - @Override - public ConnectionType getType() {return type;} - - @Override - public String getAddress() {return address;} - - @Override - public String getUser() {return user;} - - @Override - public String getPassword() {return password;} - -} diff --git a/exaudfclient/base/javacontainer/ExaExportSpecificationImpl.java b/exaudfclient/base/javacontainer/ExaExportSpecificationImpl.java deleted file mode 100644 index fe3f1d5..0000000 --- a/exaudfclient/base/javacontainer/ExaExportSpecificationImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.exasol; - - -import java.util.List; -import java.util.Map; - - -public class ExaExportSpecificationImpl implements ExaExportSpecification { - - - private String connectionName; - private ExaConnectionInformation connectionInformation; - private Map parameters; - private boolean hasTruncate; - private boolean hasReplace; - private String createdBy; - private List sourceColumnNames; - - public ExaExportSpecificationImpl(String connectionName, ExaConnectionInformation connectionInformation, Map parameters, - boolean hasTruncate, boolean hasReplace, String createdBy, - List sourceColumnNames) { - this.connectionName = connectionName; - this.connectionInformation = connectionInformation; - this.parameters = parameters; - this.hasTruncate = hasTruncate; - this.hasReplace = hasReplace; - this.createdBy = createdBy; - this.sourceColumnNames = sourceColumnNames; - } - - @Override - public boolean hasConnectionName() { - return connectionName != null; - } - - @Override - public String getConnectionName() { - return connectionName; - } - - @Override - public boolean hasConnectionInformation() { - return connectionInformation != null; - } - - // same class as used for getConnection() - @Override - public ExaConnectionInformation getConnectionInformation() { - return connectionInformation; - } - - @Override - public Map getParameters() { - return parameters; - } - - @Override - public boolean hasTruncate() { - return hasTruncate; - } - - @Override - public boolean hasReplace() { - return hasReplace; - } - - @Override - public boolean hasCreatedBy() { - return createdBy != null; - } - - @Override - public String getCreatedBy() { - return createdBy; - } - - @Override - public List getSourceColumnNames() { - return sourceColumnNames; - } - -} diff --git a/exaudfclient/base/javacontainer/ExaImportSpecificationImpl.java b/exaudfclient/base/javacontainer/ExaImportSpecificationImpl.java deleted file mode 100644 index 11e9c73..0000000 --- a/exaudfclient/base/javacontainer/ExaImportSpecificationImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.exasol; - - -import java.util.List; -import java.util.Map; - - -public class ExaImportSpecificationImpl implements ExaImportSpecification { - - - private boolean isSubselect; - private List subselectColumnNames; - private List subselectColumnTypes; - private String connectionName; - private ExaConnectionInformation connectionInformation; - private Map parameters; - - public ExaImportSpecificationImpl(boolean isSubselect, List subselectColumnNames, List subselectColumnTypes, String connectionName, ExaConnectionInformation connectionInformation, Map parameters) { - this.isSubselect = isSubselect; - this.subselectColumnNames = subselectColumnNames; - this.subselectColumnTypes = subselectColumnTypes; - this.connectionName = connectionName; - this.connectionInformation = connectionInformation; - this.parameters = parameters; - } - - @Override - public boolean isSubselect() { - return isSubselect; - } - - @Override - public List getSubselectColumnNames() { - return subselectColumnNames; - } - - // returns a string like "VARCHAR(100)" - @Override - public List getSubselectColumnSqlTypes() { - return subselectColumnTypes; - } - - @Override - public boolean hasConnectionName() { - return connectionName != null; - } - - @Override - public String getConnectionName() { - return connectionName; - } - - @Override - public boolean hasConnectionInformation() { - return connectionInformation != null; - } - - // same class as used for getConnection() - @Override - public ExaConnectionInformation getConnectionInformation() { - return connectionInformation; - } - - @Override - public Map getParameters() { - return parameters; - } -} diff --git a/exaudfclient/base/javacontainer/ExaIteratorImpl.java b/exaudfclient/base/javacontainer/ExaIteratorImpl.java deleted file mode 100644 index 567c10d..0000000 --- a/exaudfclient/base/javacontainer/ExaIteratorImpl.java +++ /dev/null @@ -1,679 +0,0 @@ -package com.exasol; - -import java.util.ArrayList; -import java.io.PrintWriter; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.Timestamp; -import java.io.IOError; -import com.exasol.swig.ResultHandler; -import com.exasol.swig.TableIterator; -import com.exasol.swig.Metadata; - -class ExaIteratorImpl implements ExaIterator { - private ExaMetadata exaMetadata; - private TableIterator tableIterator; - private ResultHandler resultHandler; - private boolean finished; - private boolean singleInput; - private boolean singleOutput; - private boolean insideRun; - private Object[] cache; - private String[] inputColumnTypes; - private String[] outputColumnTypes; - private ArrayList columnNames; - - @Override - public long size() throws ExaIterationException { - long size = tableIterator.rowsInGroup(); - String exMsg = tableIterator.checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaIterationException("F-UDF-CL-SL-JAVA-1101: "+exMsg); - } - return size; - } - - @Override - public boolean next() throws ExaIterationException { - if (insideRun && singleInput) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1102: next() function is not allowed in scalar context"); - clearCache(); - if (finished) - return false; - boolean next = tableIterator.next(); - String exMsg = tableIterator.checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaIterationException("F-UDF-CL-SL-JAVA-1103: "+exMsg); - } - if (!next) - finished = true; - return next; - } - - @Override - public void reset() throws ExaIterationException { - if (singleInput) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1104: reset() function is not allowed in scalar context"); - clearCache(); - tableIterator.reset(); - String exMsg = tableIterator.checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaIterationException("F-UDF-CL-SL-JAVA-1105: "+exMsg); - } - finished = false; - } - - @Override - public void emit(Object... values) throws ExaIterationException, ExaDataTypeException { - if (insideRun && singleOutput) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1106: emit() function is not allowed in scalar context"); - - if(values != null){ - if (values.length != exaMetadata.getOutputColumnCount()) { - String errorText = "E-UDF-CL-SL-JAVA-1107: emit() takes exactly " + exaMetadata.getOutputColumnCount(); - errorText += (exaMetadata.getOutputColumnCount() > 1) ? " arguments" : " argument"; - errorText += " (" + values.length + " given)"; - throw new ExaIterationException(errorText); - } - - for (int i = 0; i < values.length; i++) { - if (values[i] == null) { - resultHandler.setNull(i); - } - else if (values[i] instanceof Byte || values[i] instanceof Short || values[i] instanceof Integer) { - Number val = (Number) values[i]; - if (outputColumnTypes[i].equals("INT32")) - resultHandler.setInt32(i, val.intValue()); - else if (outputColumnTypes[i].equals("INT64")) - resultHandler.setInt64(i, val.longValue()); - else if (outputColumnTypes[i].equals("NUMERIC")) - resultHandler.setNumeric(i, val.toString()); - else if (outputColumnTypes[i].equals("DOUBLE")) - resultHandler.setDouble(i, val.doubleValue()); - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1108: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of type " + - outputColumnTypes[i] + - " but data given have type " + - values[i].getClass().getCanonicalName() - ); - } - else if (values[i] instanceof Long) { - Long val = (Long) values[i]; - if (outputColumnTypes[i].equals("INT32")) { - if (isConversionToIntegerSafe(val, exaMetadata.getOutputColumnName(i))) - resultHandler.setInt32(i, val.intValue()); - } - else if (outputColumnTypes[i].equals("INT64")) - resultHandler.setInt64(i, val.longValue()); - else if (outputColumnTypes[i].equals("NUMERIC")) - resultHandler.setNumeric(i, val.toString()); - else if (outputColumnTypes[i].equals("DOUBLE")) - resultHandler.setDouble(i, val.doubleValue()); - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1109: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of type " + - outputColumnTypes[i] + - " but data given have type " + - values[i].getClass().getCanonicalName() - ); - } - else if (values[i] instanceof Float || values[i] instanceof Double) { - Number val = (Number) values[i]; - if (outputColumnTypes[i].equals("INT32")) { - if (isConversionToIntegerSafe(val, exaMetadata.getOutputColumnName(i))) - resultHandler.setInt32(i, val.intValue()); - } - else if (outputColumnTypes[i].equals("INT64")) { - if (isConversionToLongSafe(val, exaMetadata.getOutputColumnName(i))) - resultHandler.setInt64(i, val.longValue()); - } - else if (outputColumnTypes[i].equals("NUMERIC")) - resultHandler.setNumeric(i, val.toString()); - else if (outputColumnTypes[i].equals("DOUBLE")) - resultHandler.setDouble(i, val.doubleValue()); - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1110: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of type "+ - outputColumnTypes[i] + - " but data given have type " + - values[i].getClass().getCanonicalName() - ); - } - else if (values[i] instanceof BigDecimal) { - BigDecimal val = (BigDecimal) values[i]; - if (outputColumnTypes[i].equals("INT32")) - resultHandler.setInt32(i, val.intValueExact()); - else if (outputColumnTypes[i].equals("INT64")) - resultHandler.setInt64(i, val.longValueExact()); - else if (outputColumnTypes[i].equals("NUMERIC")) - resultHandler.setNumeric(i, val.toString()); - else if (outputColumnTypes[i].equals("DOUBLE")) - resultHandler.setDouble(i, val.doubleValue()); - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1111: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of type " + - outputColumnTypes[i] + - " but data given have type " + - values[i].getClass().getCanonicalName() - ); - } - else if (values[i] instanceof Boolean) { - Boolean val = (Boolean) values[i]; - if (outputColumnTypes[i].equals("BOOLEAN")) - resultHandler.setBoolean(i, val.booleanValue()); - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1112: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of type " + - outputColumnTypes[i] + - " but data given have type " + - values[i].getClass().getCanonicalName() - ); - } - else if (values[i] instanceof String) { - String val = (String) values[i]; - if (outputColumnTypes[i].equals("STRING")) { - byte[] utf8Bytes = null; - try { - utf8Bytes = val.getBytes("UTF-8"); - } catch (java.io.UnsupportedEncodingException ex) { - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1113: Column with name '" + - exaMetadata.getOutputColumnName(i) + - "' contains invalid UTF-8 data" - ); - } - resultHandler.setString(i, utf8Bytes); - } - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1114: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of type " + - outputColumnTypes[i] + - " but data given have type " + - values[i].getClass().getCanonicalName() - ); - } - else if (values[i] instanceof Date) { - Date val = (Date) values[i]; - if (outputColumnTypes[i].equals("DATE")) - resultHandler.setDate(i, val.toString()); - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1115: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of type " + - outputColumnTypes[i] + - " but data given have type " + - values[i].getClass().getCanonicalName() - ); - } - else if (values[i] instanceof Timestamp) { - Timestamp val = (Timestamp) values[i]; - if (outputColumnTypes[i].equals("TIMESTAMP")) - resultHandler.setTimestamp(i, val.toString()); - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1116: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of type " + - outputColumnTypes[i] + - " but data given have type " + - values[i].getClass().getCanonicalName() - ); - } - else { - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1117: emit column '" + - exaMetadata.getOutputColumnName(i) + - "' is of unsupported type " + - values[i].getClass().getCanonicalName() - ); - } - - String exMsg = resultHandler.checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1118: "+exMsg); - } - } - }else{ - if(exaMetadata.getOutputColumnCount()==1){ - resultHandler.setNull(0); - }else{ - String errorText = "E-UDF-CL-SL-JAVA-1119: emit() takes exactly " + exaMetadata.getOutputColumnCount(); - errorText += (exaMetadata.getOutputColumnCount() > 1) ? " arguments" : " argument"; - errorText += " (" + 1 + " given)"; - throw new ExaIterationException(errorText); - } - } - - boolean next = resultHandler.next(); - String exMsg = resultHandler.checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaIterationException("F-UDF-CL-SL-JAVA-1120: "+exMsg); - } - if (!next) { - throw new ExaIterationException("F-UDF-CL-SL-JAVA-1121: Internal error while emiting row"); - } - } - - @Override - public Integer getInteger(int column) throws ExaIterationException, ExaDataTypeException { - Object object = getObject(column); - if (object == null) - return null; - if (!isConversionToIntegerSafe(object, columnNames.get(column))) - return null; - if (object instanceof Integer) - return (Integer) object; - else if (object instanceof Long) - return new Integer(((Long) object).intValue()); - else if (object instanceof BigDecimal) - return new Integer(((BigDecimal) object).intValueExact()); - else if (object instanceof Double) - return new Integer(((Double) object).intValue()); - else - throw - new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1122: getInteger cannot convert column '" + - columnNames.get(column) + - "' of type " + - exaMetadata.getInputColumnSqlType(column) + - " to an Integer" - ); - } - - @Override - public Integer getInteger(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1123: Column with name '" + name + "' does not exist"); - return getInteger(col); - } - - @Override - public Long getLong(int column) throws ExaIterationException, ExaDataTypeException { - Object object = getObject(column); - if (object == null) - return null; - if (!isConversionToLongSafe(object, columnNames.get(column))) - return null; - if (object instanceof Integer) - return new Long(((Integer) object).longValue()); - else if (object instanceof Long) - return (Long) object; - else if (object instanceof BigDecimal) - return new Long(((BigDecimal) object).longValueExact()); - else if (object instanceof Double) - return new Long(((Double) object).longValue()); - else - throw - new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1124: getLong cannot convert column '" + - columnNames.get(column) + - "' of type " + - exaMetadata.getInputColumnSqlType(column) + - " to a Long" - ); - } - - @Override - public Long getLong(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1125: Column with name '" + name + "' does not exist"); - return getLong(col); - } - - @Override - public BigDecimal getBigDecimal(int column) throws ExaIterationException, ExaDataTypeException { - Object object = getObject(column); - if (object == null) - return null; - if (object instanceof Integer) - return new BigDecimal(((Integer) object).intValue()); - else if (object instanceof Long) - return new BigDecimal(((Long) object).longValue()); - else if (object instanceof BigDecimal) - return (BigDecimal) object; - else if (object instanceof Double) - return new BigDecimal(((Double) object).doubleValue()); - else - throw - new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1126: getBigDecimal cannot convert column '" + - columnNames.get(column) + - "' of type " + - exaMetadata.getInputColumnSqlType(column) + - " to a BigDecimal" - ); - } - - @Override - public BigDecimal getBigDecimal(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1127: Column with name '" + name + "' does not exist"); - return getBigDecimal(col); - } - - @Override - public Double getDouble(int column) throws ExaIterationException, ExaDataTypeException { - Object object = getObject(column); - if (object == null) - return null; - if (object instanceof Integer) - return new Double(((Integer)object).doubleValue()); - else if (object instanceof Long) - return new Double(((Long)object).doubleValue()); - else if (object instanceof BigDecimal) - return new Double(((BigDecimal)object).doubleValue()); - else if (object instanceof Double) - return (Double) object; - else - throw - new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1128: getDouble cannot convert column '" + - columnNames.get(column) + - "' of type " + - exaMetadata.getInputColumnSqlType(column) + - " to a Double" - ); - } - - @Override - public Double getDouble(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1129: Column with name '" + name + "' does not exist"); - return getDouble(col); - } - - @Override - public String getString(int column) throws ExaIterationException, ExaDataTypeException { - Object object = getObject(column); - if (object == null) - return null; - if (object instanceof String) - return (String) object; - else if (object instanceof Integer || object instanceof Long || object instanceof BigDecimal || object instanceof Double || - object instanceof Boolean || object instanceof Date || object instanceof Timestamp) - return object.toString(); - else - throw - new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1130: getString cannot convert column '" + - columnNames.get(column) + - "' of type " + - exaMetadata.getInputColumnSqlType(column) + - " to a String" - ); - } - - @Override - public String getString(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1131: Column with name '" + name + "' does not exist"); - return getString(col); - } - - @Override - public Boolean getBoolean(int column) throws ExaIterationException, ExaDataTypeException { - Object object = getObject(column); - if (object == null) - return null; - if (object instanceof Boolean) - return (Boolean) object; - else - throw new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1132: getBoolean cannot convert column '" + - columnNames.get(column) + - "' of type " + - exaMetadata.getInputColumnSqlType(column) + - " to a Boolean" - ); - } - - @Override - public Boolean getBoolean(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1133: Column with name '" + name + "' does not exist"); - return getBoolean(col); - } - - @Override - public Date getDate(int column) throws ExaIterationException, ExaDataTypeException { - Object object = getObject(column); - if (object == null) - return null; - if (object instanceof Date) - return (Date) object; - else - throw - new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1134: getDate cannot convert column '" + - columnNames.get(column) + - "' of type " + - exaMetadata.getInputColumnSqlType(column) + - " to a Date"); - } - - @Override - public Date getDate(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1135: Column with name '" + name + "' does not exist"); - return getDate(col); - } - - @Override - public Timestamp getTimestamp(int column) throws ExaIterationException, ExaDataTypeException { - Object object = getObject(column); - if (object == null) - return null; - if (object instanceof Timestamp) - return (Timestamp) object; - else - throw - new ExaDataTypeException( - "E-UDF-CL-SL-JAVA-1136: getTimestamp cannot convert column '" + - columnNames.get(column) + - "' of type " + - exaMetadata.getInputColumnSqlType(column) + - " to a Timestamp" - ); - } - - @Override - public Timestamp getTimestamp(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1137: Column with name '" + name + "' does not exist"); - return getTimestamp(col); - } - - @Override - public Object getObject(int column) throws ExaIterationException, ExaDataTypeException { - if (column < 0 || column >= exaMetadata.getInputColumnCount()) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1138: Column number " + column + " does not exist"); - - if (finished) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1139: Iteration finished"); - - if (cache[column] != null) - return cache[column]; - - Object val = null; - switch (inputColumnTypes[column]) { - case "INT32": - val = new Integer(tableIterator.getInt32(column)); - break; - case "INT64": - val = new Long(tableIterator.getInt64(column)); - break; - case "NUMERIC": - String numeric = tableIterator.getNumeric(column); - if (!tableIterator.wasNull()) - val = new BigDecimal(numeric); - break; - case "DOUBLE": - val = new Double(tableIterator.getDouble(column)); - break; - case "STRING": - byte[] utf8Bytes = tableIterator.getString(column); - try { - val = new String(utf8Bytes, "UTF-8"); - } catch (java.io.UnsupportedEncodingException ex) { - throw new ExaDataTypeException("F-UDF-CL-SL-JAVA-1140: Column with name '" + columnNames.get(column) + "' contains invalid UTF-8 data"); - } - break; - case "BOOLEAN": - val = new Boolean(tableIterator.getBoolean(column)); - break; - case "DATE": - String date = tableIterator.getDate(column); - if (!tableIterator.wasNull()) - val = Date.valueOf(date); - break; - case "TIMESTAMP": - String timestamp = tableIterator.getTimestamp(column); - if (!tableIterator.wasNull()) - val = Timestamp.valueOf(timestamp); - break; - default: - throw new ExaDataTypeException("F-UDF-CL-SL-JAVA-1141: Column with name '" + columnNames.get(column) + "' has an invalid data type"); - } - if (tableIterator.wasNull()) - val = null; - cache[column] = val; - return val; - } - - @Override - public Object getObject(String name) throws ExaIterationException, ExaDataTypeException { - int col = columnNames.indexOf(name); - if (col == -1) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1142: Column with name '" + name + "' does not exist"); - return getObject(col); - } - - private boolean isConversionToIntegerSafe(Object from, String name) throws ExaDataTypeException { - if (from == null) - return false; - - if (from instanceof Long) { - long val = (Long) from; - if (val > Integer.MAX_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1143: emit column '" + name + "' has value of " - + val + " but column can only have maximum value of " + Integer.MAX_VALUE); - if (val < Integer.MIN_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1144: emit column '" + name + "' has value of " - + val + " but column can only have minimum value of " + Integer.MIN_VALUE); - } - else if (from instanceof Float) { - float val = (Float) from; - if (val > Integer.MAX_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1145: emit column '" + name + "' has value of " - + val + " but column can only have maximum value of " + Integer.MAX_VALUE); - if (val < Integer.MIN_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1146: emit column '" + name + "' has value of " - + val + " but column can only have minimum value of " + Integer.MIN_VALUE); - if (val != Math.floor(val)) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1147: emit column '" + name + "' has a non-integer value of " + val); - } - else if (from instanceof Double) { - double val = (Double) from; - if (val > Integer.MAX_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1148: emit column '" + name + "' has value of " - + val + " but column can only have maximum value of " + Integer.MAX_VALUE); - if (val < Integer.MIN_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1149: emit column '" + name + "' has value of " - + val + " but column can only have minimum value of " + Integer.MIN_VALUE); - if (val != Math.floor(val)) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1150: emit column '" + name + "' has a non-integer value of " + val); - } - - return true; - } - - private boolean isConversionToLongSafe(Object from, String name) throws ExaDataTypeException { - if (from == null) - return false; - - if (from instanceof Float) { - float val = (Float) from; - if (val > Long.MAX_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1151: emit column '" + name + "' has value of " - + val + " but column can only have maximum value of " + Long.MAX_VALUE); - if (val < Long.MIN_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1152: emit column '" + name + "' has value of " - + val + " but column can only have minimum value of " + Long.MIN_VALUE); - if (val != Math.floor(val)) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1153: emit column '" + name + "' has a non-integer value of " + val); - } - else if (from instanceof Double) { - double val = (Double) from; - if (val > Long.MAX_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1154: emit column '" + name + "' has value of " - + val + " but column can only have maximum value of " + Long.MAX_VALUE); - if (val < Long.MIN_VALUE) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1155: emit column '" + name + "' has value of " - + val + " but column can only have minimum value of " + Long.MIN_VALUE); - if (val != Math.floor(val)) - throw new ExaDataTypeException("E-UDF-CL-SL-JAVA-1156: emit column '" + name + "' has a non-integer value of " + val); - } - - return true; - } - - private void clearCache() { - for (int i = 0; i < cache.length; i++) - cache[i] = null; - } - - void setInsideRun(boolean inside) { - insideRun = inside; - } - - ExaIteratorImpl(ExaMetadata exaMetadata, TableIterator tableIterator, ResultHandler resultHandler) throws ExaIterationException { - this.exaMetadata = exaMetadata; - this.tableIterator = tableIterator; - this.resultHandler = resultHandler; - - finished = false; - singleInput = this.exaMetadata.getInputType().equals("SCALAR") ? true : false; - singleOutput = this.exaMetadata.getOutputType().equals("RETURN") ? true : false; - insideRun = false; - cache = new Object[(int) this.exaMetadata.getInputColumnCount()]; - - Metadata tmp = new Metadata(); - inputColumnTypes = new String[(int) this.exaMetadata.getInputColumnCount()]; - for (int i = 0; i < inputColumnTypes.length; i++) { - inputColumnTypes[i] = tmp.inputColumnType(i).toString(); - } - outputColumnTypes = new String[(int) this.exaMetadata.getOutputColumnCount()]; - for (int i = 0; i < outputColumnTypes.length; i++) { - outputColumnTypes[i] = tmp.outputColumnType(i).toString(); - } - - columnNames = new ArrayList(); - for(int i = 0; i < this.exaMetadata.getInputColumnCount(); i++) { - columnNames.add(this.exaMetadata.getInputColumnName(i)); - } - } -} diff --git a/exaudfclient/base/javacontainer/ExaMetadataImpl.java b/exaudfclient/base/javacontainer/ExaMetadataImpl.java deleted file mode 100644 index 0681112..0000000 --- a/exaudfclient/base/javacontainer/ExaMetadataImpl.java +++ /dev/null @@ -1,305 +0,0 @@ -package com.exasol; - -import java.math.BigInteger; -import java.util.ArrayList; -import com.exasol.swig.Metadata; -import com.exasol.swig.ConnectionInformationWrapper; - -class ExaMetadataImpl implements ExaMetadata { - private Metadata metadata; - - private String databaseName; - private String databaseVersion; - private String scriptLanguage; - private String scriptName; - private String currentUser; - private String scopeUser; - private String currentSchema; - private String scriptSchema; - private String scriptCode; - private String sessionId; - private long statementId; - private long nodeCount; - private long nodeId; - private String vmId; - private BigInteger memoryLimit; - private String inputType; - private long inputColumnCount; - private ColumnInfo[] inputColumns; - private String outputType; - private long outputColumnCount; - private ColumnInfo[] outputColumns; - private ArrayList importedScripts; - - @Override - public String getDatabaseName() { return databaseName; } - @Override - public String getDatabaseVersion() { return databaseVersion; } - @Override - public String getScriptLanguage() { return scriptLanguage; } - @Override - public String getScriptName() { return scriptName; } - @Override - public String getCurrentUser() { return currentUser; } - @Override - public String getScopeUser() { return scopeUser; } - @Override - public String getCurrentSchema() { return currentSchema; } - @Override - public String getScriptSchema() { return scriptSchema; } - @Override - public String getScriptCode() { return scriptCode; } - @Override - public String getSessionId() { return sessionId; } - @Override - public long getStatementId() { return statementId; } - @Override - public long getNodeCount() { return nodeCount; } - @Override - public long getNodeId() { return nodeId; } - @Override - public String getVmId() { return vmId; } - @Override - public BigInteger getMemoryLimit() { return memoryLimit; } - @Override - public String getInputType() { return inputType; } - @Override - public long getInputColumnCount() {return inputColumnCount; } - @Override - public String getInputColumnName(int column) throws ExaIterationException { - if (column < 0 || column >= inputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1083: Column number " + column + " does not exist"); - return inputColumns[column].name; - } - @Override - public Class getInputColumnType(int column) throws ExaIterationException { - if (column < 0 || column >= inputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1084: Column number " + column + " does not exist"); - return inputColumns[column].type; - } - @Override - public String getInputColumnSqlType(int column) throws ExaIterationException { - if (column < 0 || column >= inputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1085: Column number " + column + " does not exist"); - return inputColumns[column].sqlType; - } - @Override - public long getInputColumnPrecision(int column) throws ExaIterationException { - if (column < 0 || column >= inputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1086: Column number " + column + " does not exist"); - return inputColumns[column].precision; - } - @Override - public long getInputColumnScale(int column) throws ExaIterationException { - if (column < 0 || column >= inputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1087: Column number " + column + " does not exist"); - return inputColumns[column].scale; - } - @Override - public long getInputColumnLength(int column) throws ExaIterationException { - if (column < 0 || column >= inputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1088: Column number " + column + " does not exist"); - return inputColumns[column].length; - } - @Override - public String getOutputType() { return outputType; } - @Override - public long getOutputColumnCount() { return outputColumnCount; } - @Override - public String getOutputColumnName(int column) throws ExaIterationException { - if (column < 0 || column >= outputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1089: Column number " + column + " does not exist"); - return outputColumns[column].name; - } - @Override - public Class getOutputColumnType(int column) throws ExaIterationException { - if (column < 0 || column >= outputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1090: Column number " + column + " does not exist"); - return outputColumns[column].type; - } - @Override - public String getOutputColumnSqlType(int column) throws ExaIterationException { - if (column < 0 || column >= outputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1091: Column number " + column + " does not exist"); - return outputColumns[column].sqlType; - } - @Override - public long getOutputColumnPrecision(int column) throws ExaIterationException { - if (column < 0 || column >= outputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1092: Column number " + column + " does not exist"); - return outputColumns[column].precision; - } - @Override - public long getOutputColumnScale(int column) throws ExaIterationException { - if (column < 0 || column >= outputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1093: Column number " + column + " does not exist"); - return outputColumns[column].scale; - } - @Override - public long getOutputColumnLength(int column) throws ExaIterationException { - if (column < 0 || column >= outputColumns.length) - throw new ExaIterationException("E-UDF-CL-SL-JAVA-1094: Column number " + column + " does not exist"); - return outputColumns[column].length; - } - - @Override - public Class importScript(String name) throws ExaCompilationException, ClassNotFoundException { - if (name == null) - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1095: Script name is null"); - boolean isQuoted = (name.charAt(0) == '"' && name.charAt(name.length() - 1) == '"'); - String scriptName = isQuoted ? name.substring(1, name.length() - 1) : name.toUpperCase(); - if (!importedScripts.contains(scriptName)) { - String code = metadata.moduleContent(name); - code = "package com.exasol;\r\n" + code; - String exMsg = checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1096: "+exMsg); - } - try{ - ExaCompiler.compile("com.exasol." + scriptName, code); - }catch(ExaCompilationException ex){ - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1097: "+ex.toString()); - } - importedScripts.add(scriptName); - } - return Class.forName("com.exasol." + scriptName); - } - - @Override - public ExaConnectionInformation getConnection(String name) throws ExaConnectionAccessException { - if (name == null) { - throw new ExaConnectionAccessException("E-UDF-CL-SL-JAVA-1098: Connection name is null"); - } - boolean isQuoted = (name.charAt(0) == '"' && name.charAt(name.length() - 1) == '"'); - String connectionName = isQuoted ? name.substring(1, name.length() - 1) : name.toUpperCase(); - ConnectionInformationWrapper w = metadata.connectionInformation(connectionName); - String exMsg = checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaConnectionAccessException("E-UDF-CL-SL-JAVA-1099: "+exMsg); - } - return new ExaConnectionInformationImpl(w.copyKind(), w.copyAddress(), w.copyUser(), w.copyPassword()); - } - - public String checkException() { - return metadata.checkException(); - } - - ExaMetadataImpl() throws ClassNotFoundException, ExaDataTypeException { - metadata = new Metadata(); - - databaseName = metadata.databaseName(); - databaseVersion = metadata.databaseVersion(); - scriptLanguage = "Java " + System.getProperty("java.version"); - scriptName = metadata.scriptName(); - scriptSchema = metadata.scriptSchema(); - currentUser = metadata.currentUser(); - scopeUser = metadata.scopeUser(); - currentSchema = metadata.currentSchema(); - scriptCode = metadata.scriptCode(); - sessionId = metadata.sessionID_S(); - statementId = metadata.statementID(); - nodeCount = metadata.nodeCount(); - nodeId = metadata.nodeID(); - vmId = metadata.vmID_S(); - memoryLimit = metadata.memoryLimit(); - - inputType = (metadata.inputType().toString().equals("EXACTLY_ONCE")) ? "SCALAR" : "SET"; - inputColumnCount = metadata.inputColumnCount(); - inputColumns = new ColumnInfo[(int) inputColumnCount]; - for (int i = 0; i < inputColumns.length; i++) { - inputColumns[i] = new ColumnInfo(); - inputColumns[i].initInputColumnInfo(i); - } - - outputType = (metadata.outputType().toString().equals("EXACTLY_ONCE")) ? "RETURN" : "EMIT"; - outputColumnCount = metadata.outputColumnCount(); - outputColumns = new ColumnInfo[(int) outputColumnCount]; - for (int i = 0; i < outputColumns.length; i++) { - outputColumns[i] = new ColumnInfo(); - outputColumns[i].initOutputColumnInfo(i); - } - - importedScripts = new ArrayList(); - } - - private class ColumnInfo { - private String name; - private String exaType; - private Class type; - private String sqlType; - private long precision; - private long scale; - private long length; - - private void initInputColumnInfo(long column) throws ClassNotFoundException, ExaDataTypeException { - name = metadata.inputColumnName(column); - exaType = metadata.inputColumnType(column).toString(); - sqlType = metadata.inputColumnTypeName(column); - precision = metadata.inputColumnPrecision(column); - scale = metadata.inputColumnScale(column); - length = metadata.inputColumnSize(column); - setColumnInfo(); - } - - private void initOutputColumnInfo(long column) throws ClassNotFoundException, ExaDataTypeException { - name = metadata.outputColumnName(column); - exaType = metadata.outputColumnType(column).toString(); - sqlType = metadata.outputColumnTypeName(column); - precision = metadata.outputColumnPrecision(column); - scale = metadata.outputColumnScale(column); - length = metadata.outputColumnSize(column); - setColumnInfo(); - - } - - private void setColumnInfo() throws ClassNotFoundException, ExaDataTypeException { - switch(exaType) { - case "INT32": - type = Class.forName("java.lang.Integer"); - scale = 0; - length = 0; - break; - case "INT64": - type = Class.forName("java.lang.Long"); - scale = 0; - length = 0; - break; - case "NUMERIC": - type = Class.forName("java.math.BigDecimal"); - length = 0; - break; - case "DOUBLE": - type = Class.forName("java.lang.Double"); - precision = 0; - scale = 0; - length = 0; - break; - case "STRING": - type = Class.forName("java.lang.String"); - precision = 0; - scale = 0; - break; - case "BOOLEAN": - type = Class.forName("java.lang.Boolean"); - precision = 0; - scale = 0; - length = 0; - break; - case "DATE": - type = Class.forName("java.sql.Date"); - precision = 0; - scale = 0; - length = 0; - break; - case "TIMESTAMP": - type = Class.forName("java.sql.Timestamp"); - precision = 0; - scale = 0; - length = 0; - break; - default: - throw new ExaDataTypeException("F-UDF-CL-SL-JAVA-1100: data type " + exaType + " is not supported"); - } - } - } -} diff --git a/exaudfclient/base/javacontainer/ExaStackTraceCleaner.java b/exaudfclient/base/javacontainer/ExaStackTraceCleaner.java deleted file mode 100644 index 58559c3..0000000 --- a/exaudfclient/base/javacontainer/ExaStackTraceCleaner.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.exasol; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.MalformedParameterizedTypeException; -import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; -import java.io.StringWriter; -import java.io.PrintWriter; -import java.util.LinkedList; -import java.util.ListIterator; -import java.util.Arrays; - -class ExaStackTraceCleaner { - - public ExaStackTraceCleaner(final String triggerClassName) { - mTriggerClassName = triggerClassName; - } - - public String cleanStackTrace(final Throwable src) { - final Throwable th = unpack(src); - cleanExceptionChain(th); - return format(th); - } - - private Throwable unpack(final Throwable src) { - Throwable exc = src; - while (exc != null && (exc instanceof InvocationTargetException || - exc instanceof MalformedParameterizedTypeException || - exc instanceof UndeclaredThrowableException)) { - Throwable cause = exc.getCause(); - if (cause == null) - break; - else - exc = cause; - } - return exc; - } - - private String format(final Throwable src) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - src.printStackTrace(pw); - String stacktrace = sw.toString(); - LinkedList stacktrace_lines = new LinkedList(Arrays.asList(stacktrace.split("\\r?\\n"))); - - ListIterator list_Iter = stacktrace_lines.listIterator(0); - StringWriter stringWriter = new StringWriter(); - PrintWriter writer = new PrintWriter(stringWriter, true); - while (list_Iter.hasNext()) { - String line = (String) list_Iter.next(); - writer.println(line.replaceFirst("^\tat ", "")); - } - String cleanedStacktrace = stringWriter.toString(); - return cleanedStacktrace; - } - - private void cleanExceptionChain(final Throwable src) { - StackTraceElement[] stackTraceElements = src.getStackTrace(); - Integer start_index = null; - LinkedList newStackTrace = new LinkedList<>(); - - if (stackTraceElements.length > 0) { - for (int idxStackTraceElement = (stackTraceElements.length - 1); idxStackTraceElement >= 0; idxStackTraceElement--) { - StackTraceElement stackTraceElement = stackTraceElements[idxStackTraceElement]; - boolean addStackTrace = true; - if (stackTraceElement.getClassName().equals(mTriggerClassName)) { - if (start_index == null) { - start_index = idxStackTraceElement; - } - } else if ("java.base".equals(stackTraceElement.getModuleName())) { - if (start_index != null && - (stackTraceElement.getClassName().startsWith("jdk.internal.reflect") || - stackTraceElement.getClassName().startsWith("java.lang.reflect"))) { - addStackTrace = false; - } - } else { - start_index = null; - } - if (addStackTrace) { - newStackTrace.add(0, stackTraceElement); - } - } - StackTraceElement[] newArr = new StackTraceElement[newStackTrace.size()]; - newArr = newStackTrace.toArray(newArr); - src.setStackTrace(newArr); - } - if (src.getCause() != null) { - cleanExceptionChain(src.getCause()); - } - } - - private final String mTriggerClassName; -} \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/ExaUndefinedSingleCallException.java b/exaudfclient/base/javacontainer/ExaUndefinedSingleCallException.java deleted file mode 100644 index 5bdab65..0000000 --- a/exaudfclient/base/javacontainer/ExaUndefinedSingleCallException.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.exasol; - -/** - * This class is not part of the public Java UDF API - */ -public class ExaUndefinedSingleCallException extends Exception { - private static final long serialVersionUID = 1L; - public ExaUndefinedSingleCallException(String undefinedRemoteFn) { - super("Undefined single call fn: "+undefinedRemoteFn); - this.undefinedRemoteFn = undefinedRemoteFn; - } - public String getUndefinedRemoteFn() { - return undefinedRemoteFn; - } - private String undefinedRemoteFn; -} diff --git a/exaudfclient/base/javacontainer/ExaWrapper.java b/exaudfclient/base/javacontainer/ExaWrapper.java deleted file mode 100644 index c881fdd..0000000 --- a/exaudfclient/base/javacontainer/ExaWrapper.java +++ /dev/null @@ -1,273 +0,0 @@ -package com.exasol; - -import java.io.IOError; -import java.io.StringWriter; -import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.MalformedParameterizedTypeException; -import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.ListIterator; -import java.util.List; -import java.util.Map; -import java.util.ArrayList; -import java.util.HashMap; -import com.exasol.swig.ResultHandler; -import com.exasol.swig.TableIterator; -import com.exasol.swig.ImportSpecificationWrapper; -import com.exasol.swig.ExportSpecificationWrapper; -import com.exasol.swig.ConnectionInformationWrapper; -import com.exasol.ExaStackTraceCleaner; - -class ExaWrapper { - static byte[] runSingleCall(String fn, Object args) throws Throwable { - Class argClass = Object.class; - if (args != null) { - if (args instanceof ImportSpecificationWrapper) { - ImportSpecificationWrapper is = (ImportSpecificationWrapper)args; - List columnNames = new ArrayList(); - List columnTypes = new ArrayList(); - if (is.isSubselect()) { - for (int i=0; i parameters = new HashMap(); - for (int i=0; i parameters = new HashMap(); - for (int i=0; i sourceColumnNames = new ArrayList(); - for (int i=0; i 0) { - throw new ExaIterationException("UDF.CL.SL.JAVA-1161: "+exMsg); - } - // Take the scriptClass name specified by user in the script, or the name of the script as fallback - boolean userDefinedScriptName = true; - String scriptClassName = System.getProperty("exasol.scriptclass", ""); - if (scriptClassName.trim().isEmpty()) { - userDefinedScriptName = false; - scriptClassName = exaMetadata.getScriptName(); - scriptClassName = scriptClassName.replace('.', '_'); // ** see comment in run() method - scriptClassName = "com.exasol." + scriptClassName; - } - try { - Class scriptClass = Class.forName(scriptClassName); - if (args == null) { - Class[] params = {ExaMetadata.class}; - Method method = scriptClass.getDeclaredMethod(fn, params); - String resS = String.valueOf(method.invoke(null, exaMetadata)); - return resS.getBytes("UTF-8"); - } else { - Class[] params = {ExaMetadata.class,argClass}; - Method method = scriptClass.getDeclaredMethod(fn, params); - String resS = String.valueOf(method.invoke(null, exaMetadata, args)); - return resS.getBytes("UTF-8"); - } - } catch (java.lang.ClassNotFoundException ex) { - if (userDefinedScriptName) { - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1066: The main script class defined via %scriptclass cannot be found: " + scriptClassName); - } else { - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1067: The main script class (same name as the script) cannot be found: " + scriptClassName + ". Please create the class or specify the class via %scriptclass."); - } - } catch (InvocationTargetException ex) { - throw convertReflectiveExceptionToCause("F-UDF-CL-SL-JAVA-1068","Exception during singleCall "+fn,ex); - } catch (NoSuchMethodException ex) { - throw new ExaUndefinedSingleCallException(fn); - } - } - - static Class getScriptClass(ExaMetadataImpl exaMetadata) throws Throwable { - boolean userDefinedScriptName = true; - String scriptClassName = System.getProperty("exasol.scriptclass", ""); - if (scriptClassName.trim().isEmpty()) { - userDefinedScriptName = false; - scriptClassName = exaMetadata.getScriptName(); - // Only for test simulator (e.g., script.java -> script_java) - scriptClassName = scriptClassName.replace('.', '_'); - scriptClassName = "com.exasol." + scriptClassName; - } - try{ - // Take the scriptClass name specified by user in the script, or the name of the script as fallback - Class scriptClass = Class.forName(scriptClassName); - return scriptClass; - } catch (java.lang.ClassNotFoundException ex) { - if (userDefinedScriptName) { - throw new ExaCompilationException("F-UDF.CL.SL.JAVA-1072: The main script class defined via %scriptclass cannot be found: " + scriptClassName); - } else { - throw new ExaCompilationException("F-UDF.CL.SL.JAVA-1073: The main script class (same name as the script) cannot be found: " + scriptClassName + ". Please create the class or specify the class via %scriptclass."); - } - } - } - - - static ExaMetadataImpl getMetaData() throws Throwable { - ExaMetadataImpl exaMetadata = new ExaMetadataImpl(); - String exMsg = exaMetadata.checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaIterationException("UDF.CL.SL.JAVA-1165: "+exMsg); - } - return exaMetadata; - } - - static void run() throws Throwable { - ExaMetadataImpl exaMetadata = null; - try{ - exaMetadata = getMetaData(); - }catch(ExaIterationException ex){ - throw new ExaIterationException("F-UDF.CL.SL.JAVA-1069: "+ex.getMessage()); - } - TableIterator tableIterator = new TableIterator(); - String exMsg = tableIterator.checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaIterationException("F-UDF-CL-SL-JAVA-1070: "+exMsg); - } - ResultHandler resultHandler = new ResultHandler(tableIterator); - exMsg = resultHandler.checkException(); - if (exMsg != null && exMsg.length() > 0) { - throw new ExaIterationException("F-UDF-CL-SL-JAVA-1071: "+exMsg); - } - - ExaIteratorImpl exaIter = new ExaIteratorImpl(exaMetadata, tableIterator, resultHandler); - - Class scriptClass = null; - try { - scriptClass = getScriptClass(exaMetadata); - } catch (ExaCompilationException ex){ - throw new ExaCompilationException("F-UDF.CL.SL.JAVA-1165: "+ex.getMessage()); - } - // init() - try { - Class[] initParams = {ExaMetadata.class}; - Method initMethod = scriptClass.getDeclaredMethod("init", initParams); - initMethod.invoke(null, exaMetadata); - } catch (InvocationTargetException ex) { - throw convertReflectiveExceptionToCause("F-UDF-CL-SL-JAVA-1074","Exception during init",ex); - } catch (NoSuchMethodException ex) { - System.err.println("W-UDF-CL-SL-JAVA-1075: Skipping init, because init method cannot be found."); - } - - // run() - Class[] runParams = {ExaMetadata.class, ExaIterator.class}; - Method runMethod = scriptClass.getDeclaredMethod("run", runParams); - - try { - if (exaMetadata.getInputType().equals("SET")) { // MULTIPLE INPUT - if (exaMetadata.getOutputType().equals("EMIT")) { // MULTIPLE OUTPUT - if (!runMethod.getReturnType().equals(Void.TYPE)) - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1076: EMITS requires a void return type for run()"); - exaIter.setInsideRun(true); - Object returnValue = runMethod.invoke(null, exaMetadata, exaIter); - exaIter.setInsideRun(false); - } - else { // EXACTLY_ONCE OUTPUT - if (runMethod.getReturnType().equals(Void.TYPE)) - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1077: RETURNS requires a non-void return type for run()"); - exaIter.setInsideRun(true); - Object returnValue = runMethod.invoke(null, exaMetadata, exaIter); - exaIter.setInsideRun(false); - exaIter.emit(returnValue); - } - } - else { // EXACTLY_ONCE INPUT - if (exaMetadata.getOutputType().equals("EMIT")) { // MULTIPLE OUTPUT - if (!runMethod.getReturnType().equals(Void.TYPE)) - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1078: EMITS requires a void return type for run()"); - do { - exaIter.setInsideRun(true); - Object returnValue = runMethod.invoke(null, exaMetadata, exaIter); - exaIter.setInsideRun(false); - } while (exaIter.next()); - } - else { // EXACTLY_ONCE OUTPUT - if (runMethod.getReturnType().equals(Void.TYPE)) - throw new ExaCompilationException("F-UDF-CL-SL-JAVA-1079: RETURNS requires a non-void return type for run()"); - do { - exaIter.setInsideRun(true); - Object returnValue = runMethod.invoke(null, exaMetadata, exaIter); - exaIter.setInsideRun(false); - exaIter.emit(returnValue); - } while (exaIter.next()); - } - } - } - catch (InvocationTargetException ex) { - throw convertReflectiveExceptionToCause("F-UDF-CL-SL-JAVA-1080","Exception during run",ex); - } - - resultHandler.flush(); - } - - static void cleanup() throws Throwable { - // FIXME cleanup gets only called if run is successful - // cleanup() - ExaMetadataImpl exaMetadata = null; - try{ - exaMetadata = getMetaData(); - }catch(ExaIterationException ex){ - throw new ExaIterationException("F-UDF.CL.SL.JAVA-1166: "+ex.getMessage()); - } - Class scriptClass = null; - try { - scriptClass = getScriptClass(exaMetadata); - } catch (ExaCompilationException ex){ - throw new ExaCompilationException("F-UDF.CL.SL.JAVA-1167: "+ex.getMessage()); - } - try { - Class[] cleanupParams = {ExaMetadata.class}; - Method cleanupMethod = scriptClass.getDeclaredMethod("cleanup", cleanupParams); - cleanupMethod.invoke(null, exaMetadata); - } - catch (InvocationTargetException ex) { - throw convertReflectiveExceptionToCause("F-UDF-CL-SL-JAVA-1081","Exception during cleanup",ex); - } - catch (NoSuchMethodException ex) { - System.err.println("W-UDF.CL.SL.JAVA-1082: Skipping cleanup, because cleanup method cannot be found."); - } - } - - private static Throwable convertReflectiveExceptionToCause(String error_code, String errorMessage, Throwable ex) { - ExaStackTraceCleaner exaStackTraceCleaner = new ExaStackTraceCleaner(ExaWrapper.class.getName()); - String cleanedStacktrace = exaStackTraceCleaner.cleanStackTrace(ex); - String error_message=error_code+": "+errorMessage+" \n"+cleanedStacktrace; - System.out.println(error_message); - return new ExaUDFException(error_message); - } -} diff --git a/exaudfclient/base/javacontainer/exascript_java_jni_decl.h b/exaudfclient/base/javacontainer/exascript_java_jni_decl.h deleted file mode 100644 index 022e4c9..0000000 --- a/exaudfclient/base/javacontainer/exascript_java_jni_decl.h +++ /dev/null @@ -1,261 +0,0 @@ -#ifndef EXASCRIPT_JAVA_JNI_DECL_H -#define EXASCRIPT_JAVA_JNI_DECL_H - -#ifdef __cplusplus -extern "C" { -#endif - - -// the signature definitions can be printed with 'javah -classpath . com.exasol.swig.exascript_javaJNI' -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ConnectionInformationWrapper_1copyKind(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ConnectionInformationWrapper_1copyAddress(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ConnectionInformationWrapper_1copyUser(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ConnectionInformationWrapper_1copyPassword(JNIEnv *, jclass, jlong, jobject); - -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_new_1ImportSpecificationWrapper(JNIEnv *jenv, jclass, jlong); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1isSubselect(JNIEnv *, jclass, jlong, jobject); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1numSubselectColumns(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copySubselectColumnName(JNIEnv *, jclass, jlong, jobject, jlong); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copySubselectColumnType(JNIEnv *, jclass, jlong, jobject, jlong); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1hasConnectionName(JNIEnv *, jclass, jlong, jobject); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1hasConnectionInformation(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copyConnectionName(JNIEnv *, jclass, jlong, jobject); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1getConnectionInformation(JNIEnv *, jclass, jlong, jobject); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1getNumberOfParameters(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copyKey(JNIEnv *, jclass, jlong, jobject, jlong); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copyValue(JNIEnv *, jclass, jlong, jobject, jlong); - -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_new_1ExportSpecificationWrapper(JNIEnv *, jclass, jlong); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasConnectionName(JNIEnv *, jclass, jlong, jobject); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasConnectionInformation(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copyConnectionName(JNIEnv *, jclass, jlong, jobject); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1getConnectionInformation(JNIEnv *, jclass, jlong, jobject); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1getNumberOfParameters(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copyKey(JNIEnv *, jclass, jlong, jobject, jlong); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copyValue(JNIEnv *, jclass, jlong, jobject, jlong); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasTruncate(JNIEnv *, jclass, jlong, jobject); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasReplace(JNIEnv *, jclass, jlong, jobject); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasCreatedBy(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copyCreatedBy(JNIEnv *, jclass, jlong, jobject); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1numSourceColumns(JNIEnv *, jclass, jlong, jobject); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copySourceColumnName(JNIEnv *, jclass, jlong, jobject, jlong); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_delete_1ExportSpecificationWrapper(JNIEnv *, jclass, jlong); - -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_UNSUPPORTED_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_DOUBLE_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_INT32_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_INT64_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_NUMERIC_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_TIMESTAMP_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_DATE_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_STRING_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_BOOLEAN_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_EXACTLY_1ONCE_1get(JNIEnv *jenv, jclass jcls); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_MULTIPLE_1get(JNIEnv *jenv, jclass jcls); - -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_new_1Metadata(JNIEnv *jenv, jclass jcls); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1databaseName(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1databaseVersion(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1scriptName(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1scriptSchema(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1currentUser(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1scopeUser(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1currentSchema(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1scriptCode(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1moduleContent(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2); -jobject JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1connectionInformation(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2); -jobject JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1sessionID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1sessionID_1S(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1statementID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1nodeCount(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1nodeID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jobject JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1vmID(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1vmID_1S(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jobject JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1memoryLimit(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnCount(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnName(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnTypeName(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnPrecision(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnScale(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnCount(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnName(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnTypeName(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnPrecision(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnScale(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputType(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_Metadata_1checkException(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_delete_1Metadata(JNIEnv *jenv, jclass jcls, jlong jarg1); - -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_new_1TableIterator(JNIEnv *jenv, jclass jcls); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1checkException(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1reinitialize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1next(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1eot(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1reset(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1restBufferSize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1rowsInGroup(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1rowsCompleted(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jdouble JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getDouble(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jbyteArray JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getStringByteArray(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jint JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getInt32(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getInt64(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getNumeric(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getDate(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getTimestamp(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getBoolean(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1wasNull(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_delete_1TableIterator(JNIEnv *jenv, jclass jcls, jlong jarg1); - -jlong JNICALL Java_com_exasol_swig_exascript_1javaJNI_new_1ResultHandler(JNIEnv *jenv, jclass jcls); -jstring JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1checkException(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1reinitialize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -jboolean JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1next(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1flush(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setDouble(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jdouble jarg3); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setStringByteArray(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jbyteArray jarg3, jlong jarg4); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setInt32(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jint jarg3); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setInt64(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jlong jarg3); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setNumeric(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jstring jarg3); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setDate(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jstring jarg3); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setTimestamp(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jstring jarg3); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setBoolean(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jboolean jarg3); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setNull(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2); -void JNICALL Java_com_exasol_swig_exascript_1javaJNI_delete_1ResultHandler(JNIEnv *jenv, jclass jcls, jlong jarg1); - -// This array is a mapping from the native java methods in exascript_javaJNI class to -// The signature syntax can be printed via "javap -s -p exascript_javaJNI" in the folder containing the exascript_javaJNI.class -JNINativeMethod methods[] = { - {(char *)"UNSUPPORTED_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_UNSUPPORTED_1get}, - {(char *)"DOUBLE_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_DOUBLE_1get}, - {(char *)"INT32_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_INT32_1get}, - {(char *)"INT64_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_INT64_1get}, - {(char *)"NUMERIC_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_NUMERIC_1get}, - {(char *)"TIMESTAMP_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TIMESTAMP_1get}, - {(char *)"DATE_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_DATE_1get}, - {(char *)"STRING_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_STRING_1get}, - {(char *)"BOOLEAN_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_BOOLEAN_1get}, - {(char *)"EXACTLY_ONCE_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_EXACTLY_1ONCE_1get}, - {(char *)"MULTIPLE_get", (char *)"()I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_MULTIPLE_1get}, - {(char *)"new_Metadata", (char *)"()J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_new_1Metadata}, - {(char *)"Metadata_databaseName", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1databaseName}, - {(char *)"Metadata_databaseVersion", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1databaseVersion}, - {(char *)"Metadata_scriptName", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1scriptName}, - {(char *)"Metadata_scriptSchema", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1scriptSchema}, - {(char *)"Metadata_currentUser", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1currentUser}, - {(char *)"Metadata_scopeUser", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1scopeUser}, - {(char *)"Metadata_currentSchema", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1currentSchema}, - {(char *)"Metadata_scriptCode", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1scriptCode}, - {(char *)"Metadata_moduleContent", (char *)"(JLcom/exasol/swig/Metadata;Ljava/lang/String;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1moduleContent}, - {(char *)"Metadata_connectionInformation", (char *)"(JLcom/exasol/swig/Metadata;Ljava/lang/String;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1connectionInformation}, - {(char *)"Metadata_sessionID", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/math/BigInteger;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1sessionID}, - {(char *)"Metadata_sessionID_S", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1sessionID_1S}, - {(char *)"Metadata_statementID", (char *)"(JLcom/exasol/swig/Metadata;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1statementID}, - {(char *)"Metadata_nodeCount", (char *)"(JLcom/exasol/swig/Metadata;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1nodeCount}, - {(char *)"Metadata_nodeID", (char *)"(JLcom/exasol/swig/Metadata;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1nodeID}, - {(char *)"Metadata_vmID", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/math/BigInteger;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1vmID}, - {(char *)"Metadata_vmID_S", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1vmID_1S}, - {(char *)"Metadata_memoryLimit", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/math/BigInteger;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1memoryLimit}, - {(char *)"Metadata_inputColumnCount", (char *)"(JLcom/exasol/swig/Metadata;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnCount}, - {(char *)"Metadata_inputColumnName", (char *)"(JLcom/exasol/swig/Metadata;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnName}, - {(char *)"Metadata_inputColumnType", (char *)"(JLcom/exasol/swig/Metadata;J)I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnType}, - {(char *)"Metadata_inputColumnTypeName", (char *)"(JLcom/exasol/swig/Metadata;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnTypeName}, - {(char *)"Metadata_inputColumnSize", (char *)"(JLcom/exasol/swig/Metadata;J)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnSize}, - {(char *)"Metadata_inputColumnPrecision", (char *)"(JLcom/exasol/swig/Metadata;J)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnPrecision}, - {(char *)"Metadata_inputColumnScale", (char *)"(JLcom/exasol/swig/Metadata;J)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputColumnScale}, - {(char *)"Metadata_inputType", (char *)"(JLcom/exasol/swig/Metadata;)I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1inputType}, - {(char *)"Metadata_outputColumnCount", (char *)"(JLcom/exasol/swig/Metadata;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnCount}, - {(char *)"Metadata_outputColumnName", (char *)"(JLcom/exasol/swig/Metadata;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnName}, - {(char *)"Metadata_outputColumnType", (char *)"(JLcom/exasol/swig/Metadata;J)I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnType}, - {(char *)"Metadata_outputColumnTypeName", (char *)"(JLcom/exasol/swig/Metadata;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnTypeName}, - {(char *)"Metadata_outputColumnSize", (char *)"(JLcom/exasol/swig/Metadata;J)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnSize}, - {(char *)"Metadata_outputColumnPrecision", (char *)"(JLcom/exasol/swig/Metadata;J)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnPrecision}, - {(char *)"Metadata_outputColumnScale", (char *)"(JLcom/exasol/swig/Metadata;J)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputColumnScale}, - {(char *)"Metadata_outputType", (char *)"(JLcom/exasol/swig/Metadata;)I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1outputType}, - {(char *)"Metadata_checkException", (char *)"(JLcom/exasol/swig/Metadata;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_Metadata_1checkException}, - {(char *)"delete_Metadata", (char *)"(J)V", (void *)&JNICALL Java_com_exasol_swig_exascript_1javaJNI_delete_1Metadata}, - - {(char *)"new_TableIterator", (char *)"()J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_new_1TableIterator}, - {(char *)"TableIterator_checkException", (char *)"(JLcom/exasol/swig/TableIterator;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1checkException}, - {(char *)"TableIterator_reinitialize", (char *)"(JLcom/exasol/swig/TableIterator;)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1reinitialize}, - {(char *)"TableIterator_next", (char *)"(JLcom/exasol/swig/TableIterator;)Z", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1next}, - {(char *)"TableIterator_eot", (char *)"(JLcom/exasol/swig/TableIterator;)Z", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1eot}, - {(char *)"TableIterator_reset", (char *)"(JLcom/exasol/swig/TableIterator;)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1reset}, - {(char *)"TableIterator_restBufferSize", (char *)"(JLcom/exasol/swig/TableIterator;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1restBufferSize}, - {(char *)"TableIterator_rowsInGroup", (char *)"(JLcom/exasol/swig/TableIterator;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1rowsInGroup}, - {(char *)"TableIterator_rowsCompleted", (char *)"(JLcom/exasol/swig/TableIterator;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1rowsCompleted}, - {(char *)"TableIterator_getDouble", (char *)"(JLcom/exasol/swig/TableIterator;J)D", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getDouble}, - {(char *)"TableIterator_getStringByteArray", (char *)"(JLcom/exasol/swig/TableIterator;J)[B", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getStringByteArray}, - {(char *)"TableIterator_getInt32", (char *)"(JLcom/exasol/swig/TableIterator;J)I", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getInt32}, - {(char *)"TableIterator_getInt64", (char *)"(JLcom/exasol/swig/TableIterator;J)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getInt64}, - {(char *)"TableIterator_getNumeric", (char *)"(JLcom/exasol/swig/TableIterator;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getNumeric}, - {(char *)"TableIterator_getDate", (char *)"(JLcom/exasol/swig/TableIterator;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getDate}, - {(char *)"TableIterator_getTimestamp", (char *)"(JLcom/exasol/swig/TableIterator;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getTimestamp}, - {(char *)"TableIterator_getBoolean", (char *)"(JLcom/exasol/swig/TableIterator;J)Z", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1getBoolean}, - {(char *)"TableIterator_wasNull", (char *)"(JLcom/exasol/swig/TableIterator;)Z", (void *)&Java_com_exasol_swig_exascript_1javaJNI_TableIterator_1wasNull}, - {(char *)"delete_TableIterator", (char *)"(J)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_delete_1TableIterator}, - - {(char *)"new_ResultHandler", (char *)"(JLcom/exasol/swig/TableIterator;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_new_1ResultHandler}, - {(char *)"ResultHandler_checkException", (char *)"(JLcom/exasol/swig/ResultHandler;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1checkException}, - {(char *)"ResultHandler_reinitialize", (char *)"(JLcom/exasol/swig/ResultHandler;)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1reinitialize}, - {(char *)"ResultHandler_next", (char *)"(JLcom/exasol/swig/ResultHandler;)Z", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1next}, - {(char *)"ResultHandler_flush", (char *)"(JLcom/exasol/swig/ResultHandler;)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1flush}, - {(char *)"ResultHandler_setDouble", (char *)"(JLcom/exasol/swig/ResultHandler;JD)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setDouble}, - {(char *)"ResultHandler_setStringByteArray", (char *)"(JLcom/exasol/swig/ResultHandler;J[BJ)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setStringByteArray}, - {(char *)"ResultHandler_setInt32", (char *)"(JLcom/exasol/swig/ResultHandler;JI)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setInt32}, - {(char *)"ResultHandler_setInt64", (char *)"(JLcom/exasol/swig/ResultHandler;JJ)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setInt64}, - {(char *)"ResultHandler_setNumeric", (char *)"(JLcom/exasol/swig/ResultHandler;JLjava/lang/String;)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setNumeric}, - {(char *)"ResultHandler_setDate", (char *)"(JLcom/exasol/swig/ResultHandler;JLjava/lang/String;)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setDate}, - {(char *)"ResultHandler_setTimestamp", (char *)"(JLcom/exasol/swig/ResultHandler;JLjava/lang/String;)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setTimestamp}, - {(char *)"ResultHandler_setBoolean", (char *)"(JLcom/exasol/swig/ResultHandler;JZ)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setBoolean}, - {(char *)"ResultHandler_setNull", (char *)"(JLcom/exasol/swig/ResultHandler;J)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ResultHandler_1setNull}, - {(char *)"delete_ResultHandler", (char *)"(J)V", (void *)&Java_com_exasol_swig_exascript_1javaJNI_delete_1ResultHandler}, - - - {(char *)"ConnectionInformationWrapper_copyKind",(char *)"(JLcom/exasol/swig/ConnectionInformationWrapper;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ConnectionInformationWrapper_1copyKind}, - {(char *)"ConnectionInformationWrapper_copyAddress",(char *)"(JLcom/exasol/swig/ConnectionInformationWrapper;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ConnectionInformationWrapper_1copyAddress}, - {(char *)"ConnectionInformationWrapper_copyUser",(char *)"(JLcom/exasol/swig/ConnectionInformationWrapper;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ConnectionInformationWrapper_1copyUser}, - {(char *)"ConnectionInformationWrapper_copyPassword",(char *)"(JLcom/exasol/swig/ConnectionInformationWrapper;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ConnectionInformationWrapper_1copyPassword}, - - - {(char *)"new_ImportSpecificationWrapper",(char*)"(J)J",(void*)&Java_com_exasol_swig_exascript_1javaJNI_new_1ImportSpecificationWrapper}, - {(char *)"ImportSpecificationWrapper_isSubselect",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;)Z", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1isSubselect}, - {(char *)"ImportSpecificationWrapper_numSubselectColumns",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1numSubselectColumns}, - {(char *)"ImportSpecificationWrapper_copySubselectColumnName",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copySubselectColumnName}, - {(char *)"ImportSpecificationWrapper_copySubselectColumnType",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copySubselectColumnType}, - {(char *)"ImportSpecificationWrapper_hasConnectionName",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;)Z", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1hasConnectionName}, - {(char *)"ImportSpecificationWrapper_hasConnectionInformation",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;)Z", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1hasConnectionInformation}, - {(char *)"ImportSpecificationWrapper_copyConnectionName",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copyConnectionName}, - {(char *)"ImportSpecificationWrapper_getConnectionInformation",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1getConnectionInformation}, - {(char *)"ImportSpecificationWrapper_getNumberOfParameters",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;)J", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1getNumberOfParameters}, - {(char *)"ImportSpecificationWrapper_copyKey",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copyKey}, - {(char *)"ImportSpecificationWrapper_copyValue",(char *)"(JLcom/exasol/swig/ImportSpecificationWrapper;J)Ljava/lang/String;", (void *)&Java_com_exasol_swig_exascript_1javaJNI_ImportSpecificationWrapper_1copyValue}, - - - {(char *)"new_ExportSpecificationWrapper",(char *)"(J)J",(void *)&Java_com_exasol_swig_exascript_1javaJNI_new_1ExportSpecificationWrapper}, - {(char *)"ExportSpecificationWrapper_hasConnectionName",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)Z",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasConnectionName}, - {(char *)"ExportSpecificationWrapper_hasConnectionInformation",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)Z",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasConnectionInformation}, - {(char *)"ExportSpecificationWrapper_copyConnectionName",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)Ljava/lang/String;",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copyConnectionName}, - {(char *)"ExportSpecificationWrapper_getConnectionInformation",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)J",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1getConnectionInformation}, - {(char *)"ExportSpecificationWrapper_getNumberOfParameters",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)J",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1getNumberOfParameters}, - {(char *)"ExportSpecificationWrapper_copyKey",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;J)Ljava/lang/String;",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copyKey}, - {(char *)"ExportSpecificationWrapper_copyValue",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;J)Ljava/lang/String;",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copyValue}, - {(char *)"ExportSpecificationWrapper_hasTruncate",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)Z",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasTruncate}, - {(char *)"ExportSpecificationWrapper_hasReplace",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)Z",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasReplace}, - {(char *)"ExportSpecificationWrapper_hasCreatedBy",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)Z",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1hasCreatedBy}, - {(char *)"ExportSpecificationWrapper_copyCreatedBy",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)Ljava/lang/String;",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copyCreatedBy}, - {(char *)"ExportSpecificationWrapper_numSourceColumns",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;)J",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1numSourceColumns}, - {(char *)"ExportSpecificationWrapper_copySourceColumnName",(char *)"(JLcom/exasol/swig/ExportSpecificationWrapper;J)Ljava/lang/String;",(void *)&Java_com_exasol_swig_exascript_1javaJNI_ExportSpecificationWrapper_1copySourceColumnName}, - {(char *)"delete_ExportSpecificationWrapper",(char *)"(J)V",(void *)&Java_com_exasol_swig_exascript_1javaJNI_delete_1ExportSpecificationWrapper}, - -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/exaudfclient/base/javacontainer/javacontainer.cc b/exaudfclient/base/javacontainer/javacontainer.cc deleted file mode 100644 index d0e8556..0000000 --- a/exaudfclient/base/javacontainer/javacontainer.cc +++ /dev/null @@ -1,57 +0,0 @@ -#include "javacontainer/javacontainer.h" -#include "javacontainer/javacontainer_impl.h" -#include "javacontainer/script_options/extractor.h" - -using namespace SWIGVMContainers; -using namespace std; - -JavaVMach::JavaVMach(bool checkOnly,std::unique_ptr extractor) { - try { - m_impl = new JavaVMImpl(checkOnly, false, std::move(extractor)); - } catch (std::exception& err) { - lock_guard lock(exception_msg_mtx); - exception_msg = "F-UDF-CL-SL-JAVA-1000: "+std::string(err.what()); - } catch (...) { - lock_guard lock(exception_msg_mtx); - exception_msg = "F-UDF-CL-SL-JAVA-1001: JVM crashed for unknown reason"; - } -} - - -bool JavaVMach::run() { - try { - return m_impl->run(); - } catch (std::exception& err) { - lock_guard lock(exception_msg_mtx); - exception_msg = "F-UDF-CL-SL-JAVA-1002: "+std::string(err.what()); - } catch (...) { - lock_guard lock(exception_msg_mtx); - exception_msg = "F-UDF-CL-SL-JAVA-1003: JVM crashed for unknown reason"; - } - return false; -} - -void JavaVMach::shutdown() { - try { - m_impl->shutdown(); - } catch (std::exception& err) { - lock_guard lock(exception_msg_mtx); - exception_msg = "F-UDF-CL-SL-JAVA-1004: "+std::string(err.what()); - } catch (...) { - lock_guard lock(exception_msg_mtx); - exception_msg = "F-UDF-CL-SL-JAVA-1005: JVM crashed for unknown reason"; - } -} - -const char* JavaVMach::singleCall(single_call_function_id_e fn, const ExecutionGraph::ScriptDTO& args) { - try { - return m_impl->singleCall(fn, args, calledUndefinedSingleCall); - } catch (std::exception& err) { - lock_guard lock(exception_msg_mtx); - exception_msg = "F-UDF-CL-SL-JAVA-1006: "+std::string(err.what()); - } catch (...) { - lock_guard lock(exception_msg_mtx); - exception_msg = "F-UDF-CL-SL-JAVA-1007: JVM crashed for unknown reason"; - } - return strdup(""); -} diff --git a/exaudfclient/base/javacontainer/javacontainer.h b/exaudfclient/base/javacontainer/javacontainer.h deleted file mode 100644 index fca3d33..0000000 --- a/exaudfclient/base/javacontainer/javacontainer.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef JAVACONTAINER_H -#define JAVACONTAINER_H - - -#include "exaudflib/vm/swig_vm.h" -#include -#include - -#ifdef ENABLE_JAVA_VM - -namespace SWIGVMContainers { - -class JavaVMImpl; - -namespace JavaScriptOptions { - -struct Extractor; - -} - -class JavaVMach: public SWIGVM { - public: - /* - * scriptOptionsParser: JavaVMach takes ownership of ScriptOptionsParser pointer. - */ - JavaVMach(bool checkOnly, std::unique_ptr extractor); - virtual ~JavaVMach() {} - virtual void shutdown(); - virtual bool run(); - virtual const char* singleCall(single_call_function_id_e fn, const ExecutionGraph::ScriptDTO& args); - private: - JavaVMImpl *m_impl; -}; - -} //namespace SWIGVMContainers - - -#endif //ENABLE_JAVA_VM - - -#endif //JAVACONTAINER_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/javacontainer_builder.cc b/exaudfclient/base/javacontainer/javacontainer_builder.cc deleted file mode 100644 index f44b9ef..0000000 --- a/exaudfclient/base/javacontainer/javacontainer_builder.cc +++ /dev/null @@ -1,31 +0,0 @@ -#include "javacontainer/javacontainer_builder.h" -#include "javacontainer/script_options/extractor_impl.h" -#include "swig_factory/swig_factory_impl.h" - -#ifdef ENABLE_JAVA_VM - -namespace SWIGVMContainers { - -JavaContainerBuilder::JavaContainerBuilder() -: m_useCtpgParser(false) {} - -JavaContainerBuilder& JavaContainerBuilder::useCtpgParser() { - m_useCtpgParser = true; - return *this; -} - -JavaVMach* JavaContainerBuilder::build() { - std::unique_ptr extractor; - if (m_useCtpgParser) { - extractor = std::make_unique(std::make_unique()); - } else { - extractor = std::make_unique(std::make_unique()); - } - return new JavaVMach(false, std::move(extractor)); -} - - -} //namespace SWIGVMContainers - - -#endif //ENABLE_JAVA_VM diff --git a/exaudfclient/base/javacontainer/javacontainer_builder.h b/exaudfclient/base/javacontainer/javacontainer_builder.h deleted file mode 100644 index 9a7113d..0000000 --- a/exaudfclient/base/javacontainer/javacontainer_builder.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef JAVACONTAINER_BUILDER_H -#define JAVACONTAINER_BUILDER_H - -#include -#include "javacontainer/javacontainer.h" - -#ifdef ENABLE_JAVA_VM - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -struct ScriptOptionsParser; - -} - -class JavaContainerBuilder { - public: - JavaContainerBuilder(); - - JavaContainerBuilder& useCtpgParser(); - - JavaVMach* build(); - - private: - bool m_useCtpgParser; -}; - -} //namespace SWIGVMContainers - - -#endif //ENABLE_JAVA_VM - - -#endif //JAVACONTAINER_BUILDER_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/javacontainer_impl.cc b/exaudfclient/base/javacontainer/javacontainer_impl.cc deleted file mode 100644 index 5820bb2..0000000 --- a/exaudfclient/base/javacontainer/javacontainer_impl.cc +++ /dev/null @@ -1,454 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "exascript_java_jni_decl.h" - -#include "utils/debug_message.h" -#include "javacontainer/javacontainer.h" -#include "javacontainer/javacontainer_impl.h" -#include "javacontainer/script_options/extractor.h" - - -using namespace SWIGVMContainers; -using namespace std; - -JavaVMImpl::JavaVMImpl(bool checkOnly, bool noJNI, - std::unique_ptr extractor) -: m_checkOnly(checkOnly) -, m_exaJavaPath("") -, m_localClasspath("/tmp") // **IMPORTANT**: /tmp needs to be in the classpath, otherwise ExaCompiler crashe with com.exasol.ExaCompilationException: /DATE_STRING.java:3: error: error while writing DATE_STRING: could not create parent directories -, m_scriptCode(SWIGVM_params->script_code) -, m_jvm(NULL) -, m_env(NULL) -, m_needsCompilation(true) -{ - - stringstream ss; - //Path "external/exaudfclient_base+/" comes from external module "exaudfclient_base" - m_exaJavaPath = "/exaudf/external/exaudfclient_base+/javacontainer"; // TODO hardcoded path - - parseScriptOptions(std::move(extractor)); - - m_needsCompilation = checkNeedsCompilation(); - if (m_needsCompilation) { - DBG_FUNC_CALL(cerr,addPackageToScript()); - DBG_FUNC_CALL(cerr,addLocalClasspath()); - } - DBG_FUNC_CALL(cerr,setJvmOptions()); - if(false == noJNI) { - DBG_FUNC_CALL(cerr,createJvm()); - DBG_FUNC_CALL(cerr,registerFunctions()); - if (m_needsCompilation) { - DBG_FUNC_CALL(cerr,compileScript()); - } - } -} - -void JavaVMImpl::parseScriptOptions(std::unique_ptr extractor) { - - DBG_FUNC_CALL(cerr,extractor->extract(m_scriptCode)); - - DBG_FUNC_CALL(cerr,setClasspath()); - - m_jvmOptions = std::move(extractor->moveJvmOptions()); - - extractor->iterateJarPaths([&](const std::string& s) { addJarToClasspath(s);}); -} - -void JavaVMImpl::shutdown() { - if (m_checkOnly) - throw JavaVMach::exception("F-UDF.CL.SL.JAVA-1159: Java VM in check only mode"); - jclass cls = m_env->FindClass("com/exasol/ExaWrapper"); - string calledUndefinedSingleCall; - check("F-UDF.CL.SL.JAVA-1160",calledUndefinedSingleCall); - if (!cls) - throw JavaVMach::exception("F-UDF.CL.SL.JAVA-1161: FindClass for ExaWrapper failed"); - jmethodID mid = m_env->GetStaticMethodID(cls, "cleanup", "()V"); - check("F-UDF.CL.SL.JAVA-1162",calledUndefinedSingleCall); - if (!mid) - throw JavaVMach::exception("F-UDF.CL.SL.JAVA-1163: GetStaticMethodID for run failed"); - m_env->CallStaticVoidMethod(cls, mid); - check("F-UDF.CL.SL.JAVA-1164",calledUndefinedSingleCall); - try { - m_jvm->DestroyJavaVM(); - } catch(...) { - - } -} - -bool JavaVMImpl::run() { - if (m_checkOnly) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1008: Java VM in check only mode"); - jclass cls = m_env->FindClass("com/exasol/ExaWrapper"); - string calledUndefinedSingleCall; - check("F-UDF-CL-SL-JAVA-1009",calledUndefinedSingleCall); - if (!cls) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1010: FindClass for ExaWrapper failed"); - jmethodID mid = m_env->GetStaticMethodID(cls, "run", "()V"); - check("F-UDF-CL-SL-JAVA-1011",calledUndefinedSingleCall); - if (!mid) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1012: GetStaticMethodID for run failed"); - m_env->CallStaticVoidMethod(cls, mid); - check("F-UDF-CL-SL-JAVA-1013",calledUndefinedSingleCall); - return true; -} - -static string singleCallResult; - -const char* JavaVMImpl::singleCall(single_call_function_id_e fn, const ExecutionGraph::ScriptDTO& args, string& calledUndefinedSingleCall) { - - if (m_checkOnly) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1014: Java VM in check only mode"); - - const char* func = NULL; - switch (fn) { - case SC_FN_NIL: break; - case SC_FN_DEFAULT_OUTPUT_COLUMNS: func = "getDefaultOutputColumns"; break; - case SC_FN_VIRTUAL_SCHEMA_ADAPTER_CALL: func = "adapterCall"; break; - case SC_FN_GENERATE_SQL_FOR_IMPORT_SPEC: func = "generateSqlForImportSpec"; break; - case SC_FN_GENERATE_SQL_FOR_EXPORT_SPEC: func = "generateSqlForExportSpec"; break; - } - if (func == NULL) { - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1015: Unknown single call "+std::to_string(fn)); - } - jclass cls = m_env->FindClass("com/exasol/ExaWrapper"); - check("F-UDF-CL-SL-JAVA-1016",calledUndefinedSingleCall); - if (!cls) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1017: FindClass for ExaWrapper failed"); - jmethodID mid = m_env->GetStaticMethodID(cls, "runSingleCall", "(Ljava/lang/String;Ljava/lang/Object;)[B"); - check("F-UDF-CL-SL-JAVA-1018",calledUndefinedSingleCall); - if (!mid) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1019: GetStaticMethodID for run failed"); - jstring fn_js = m_env->NewStringUTF(func); - check("F-UDF-CL-SL-JAVA-1020",calledUndefinedSingleCall); - - - // Prepare arg - // TODO VS This will be refactored completely - // We intentionally define these variables outside so that they are not destroyed too early - jobject args_js = NULL; - ExecutionGraph::ImportSpecification* imp_spec; - ExecutionGraph::ImportSpecificationWrapper imp_spec_wrapper(NULL); - ExecutionGraph::ExportSpecification* exp_spec; - ExecutionGraph::ExportSpecificationWrapper exp_spec_wrapper(NULL); - if (fn == SC_FN_GENERATE_SQL_FOR_IMPORT_SPEC) { - imp_spec = const_cast(dynamic_cast(&args)); - imp_spec_wrapper = ExecutionGraph::ImportSpecificationWrapper(imp_spec); - if (imp_spec) - { - jclass import_spec_wrapper_cls = m_env->FindClass("com/exasol/swig/ImportSpecificationWrapper"); - check("F-UDF-CL-SL-JAVA-1021",calledUndefinedSingleCall); - jmethodID import_spec_wrapper_constructor = m_env->GetMethodID(import_spec_wrapper_cls, "", "(JZ)V"); - check("F-UDF-CL-SL-JAVA-1022",calledUndefinedSingleCall); - args_js = m_env->NewObject(import_spec_wrapper_cls, import_spec_wrapper_constructor, &imp_spec_wrapper, false); - } - } else if (fn == SC_FN_GENERATE_SQL_FOR_EXPORT_SPEC) { - exp_spec = const_cast(dynamic_cast(&args)); - exp_spec_wrapper = ExecutionGraph::ExportSpecificationWrapper(exp_spec); - if (exp_spec) - { - jclass export_spec_wrapper_cls = m_env->FindClass("com/exasol/swig/ExportSpecificationWrapper"); - check("F-UDF-CL-SL-JAVA-1023",calledUndefinedSingleCall); - jmethodID export_spec_wrapper_constructor = m_env->GetMethodID(export_spec_wrapper_cls, "", "(JZ)V"); - check("F-UDF-CL-SL-JAVA-1024",calledUndefinedSingleCall); - args_js = m_env->NewObject(export_spec_wrapper_cls, export_spec_wrapper_constructor, &exp_spec_wrapper, false); - } - } else if (fn == SC_FN_VIRTUAL_SCHEMA_ADAPTER_CALL) { - const ExecutionGraph::StringDTO* argDto = dynamic_cast(&args); - string string_arg = argDto->getArg(); - args_js = m_env->NewStringUTF(string_arg.c_str()); - } - - check("F-UDF-CL-SL-JAVA-1025",calledUndefinedSingleCall); - jbyteArray resJ = (jbyteArray)m_env->CallStaticObjectMethod(cls, mid, fn_js, args_js); - if (check("F-UDF-CL-SL-JAVA-1026",calledUndefinedSingleCall) == 0) return strdup(""); - jsize resLen = m_env->GetArrayLength(resJ); - check("F-UDF-CL-SL-JAVA-1027",calledUndefinedSingleCall); - char* buffer = new char[resLen + 1]; - m_env->GetByteArrayRegion(resJ, 0, resLen, reinterpret_cast(buffer)); - buffer[resLen] = '\0'; - singleCallResult = string(buffer); - delete buffer; - m_env->DeleteLocalRef(args_js); - m_env->DeleteLocalRef(resJ); - - - return singleCallResult.c_str(); -} - -void JavaVMImpl::addPackageToScript() { - // Each script is generated in the com.exasol package, not in the default - // package. Scripts classes may not be in the default package because - // com.exasol.ExaWrapper requires to call run() on them (accessing default - // package from a non-default package is not allowed). Furthermore, only if - // the script is in the same package as ExaWrapper the script can be - // defined as package-private. - m_scriptCode = "package com.exasol;\r\n" + m_scriptCode; -} - -void JavaVMImpl::createJvm() { - unsigned int numJvmOptions = m_jvmOptions.size(); - JavaVMOption *options = new JavaVMOption[numJvmOptions]; - for (size_t i = 0; i < numJvmOptions; ++i) { - options[i].optionString = strdup((char*)(m_jvmOptions[i].c_str())); - DBGVAR(cerr,options[i].optionString); - options[i].extraInfo = NULL; - } - - JavaVMInitArgs vm_args; - vm_args.version = JNI_VERSION_1_2; - vm_args.nOptions = numJvmOptions; - vm_args.options = options; - vm_args.ignoreUnrecognized = JNI_FALSE; - //vm_args.ignoreUnrecognized = JNI_TRUE; - DBGVAR(cerr,m_env); - - DBG_FUNC_CALL(cerr,int rc = JNI_CreateJavaVM(&m_jvm, (void**)&m_env, &vm_args)); - if (rc != JNI_OK) { - stringstream ss; - ss << "F-UDF-CL-SL-JAVA-1028: Cannot start the JVM: "; - switch (rc) { - case JNI_ERR: ss << "unknown error"; break; - case JNI_EDETACHED: ss << "thread is detached from VM"; break; - case JNI_EVERSION: ss << "version error"; break; - case JNI_ENOMEM: ss << "out of memory"; break; - case JNI_EEXIST: ss << "VM already exists"; break; - case JNI_EINVAL: ss << "invalid arguments"; break; - default: ss << "unknown"; break; - } - ss << " (" << rc << ")"; - delete [] options; - throw JavaVMach::exception(ss.str()); - } - delete [] options; -} - -void JavaVMImpl::compileScript() { - string calledUndefinedSingleCall; - jstring classnameStr = m_env->NewStringUTF(SWIGVM_params->script_name); - check("F-UDF-CL-SL-JAVA-1029",calledUndefinedSingleCall); - jstring codeStr = m_env->NewStringUTF(m_scriptCode.c_str()); - check("F-UDF-CL-SL-JAVA-1030",calledUndefinedSingleCall); - jstring classpathStr = m_env->NewStringUTF(m_localClasspath.c_str()); - check("F-UDF-CL-SL-JAVA-1031",calledUndefinedSingleCall); - if (!classnameStr || !codeStr || !classpathStr) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1032: NewStringUTF for compile failed"); - jclass cls = m_env->FindClass("com/exasol/ExaCompiler"); - check("F-UDF-CL-SL-JAVA-1033",calledUndefinedSingleCall); - if (!cls) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1034: FindClass for ExaCompiler failed"); - jmethodID mid = m_env->GetStaticMethodID(cls, "compile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - check("F-UDF-CL-SL-JAVA-1035",calledUndefinedSingleCall); - if (!mid) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1036: GetStaticMethodID for compile failed"); - m_env->CallStaticVoidMethod(cls, mid, classnameStr, codeStr, classpathStr); - check("F-UDF-CL-SL-JAVA-1037",calledUndefinedSingleCall); -} - - -bool JavaVMImpl::check(const string& errorCode, string& calledUndefinedSingleCall) { - jthrowable ex = m_env->ExceptionOccurred(); - if (ex) { - m_env->ExceptionClear(); - - jclass undefinedSingleCallExceptionClass = m_env->FindClass("com/exasol/ExaUndefinedSingleCallException"); - if (!undefinedSingleCallExceptionClass) { - throw JavaVMach::exception(errorCode+": F-UDF-CL-SL-JAVA-1042: FindClass for com.exasol.ExaUndefinedSingleCallException failed"); - } - if (m_env->IsInstanceOf(ex, undefinedSingleCallExceptionClass)) { - jmethodID undefinedRemoteFn = m_env->GetMethodID(undefinedSingleCallExceptionClass, "getUndefinedRemoteFn", "()Ljava/lang/String;"); - check("F-UDF-CL-SL-JAVA-1043",calledUndefinedSingleCall); - if (!undefinedRemoteFn) - throw JavaVMach::exception(errorCode+": F-UDF-CL-SL-JAVA-1044: com.exasol.ExaUndefinedSingleCallException.getUndefinedRemoteFn() could not be found"); - jobject undefinedRemoteFnString = m_env->CallObjectMethod(ex,undefinedRemoteFn); - if (undefinedRemoteFnString) { - jstring fn = static_cast(undefinedRemoteFnString); - const char *fn_str = m_env->GetStringUTFChars(fn,0); - std::string fn_string = fn_str; - m_env->ReleaseStringUTFChars(fn,fn_str); - calledUndefinedSingleCall = fn_string; - return 0; - //swig_undefined_single_call_exception ex(fn_string); - //throwException(ex); - } else { - throw JavaVMach::exception(errorCode+": F-UDF-CL-SL-JAVA-1045: Internal error: getUndefinedRemoteFn() returned no result"); - } - } - - string exceptionMessage = ""; - jclass exClass = m_env->GetObjectClass(ex); - if (!exClass) - throw JavaVMach::exception(errorCode+": F-UDF-CL-SL-JAVA-1046: FindClass for Throwable failed"); - // Throwable.toString() - jmethodID toString = m_env->GetMethodID(exClass, "toString", "()Ljava/lang/String;"); - check("F-UDF-CL-SL-JAVA-1047",calledUndefinedSingleCall); - if (!toString) - throw JavaVMach::exception(errorCode+": F-UDF-CL-SL-JAVA-1048: Throwable.toString() could not be found"); - jobject object = m_env->CallObjectMethod(ex, toString); - if (object) { - jstring message = static_cast(object); - char const *utfMessage = m_env->GetStringUTFChars(message, 0); - exceptionMessage.append("\n"); - exceptionMessage.append(utfMessage); - m_env->ReleaseStringUTFChars(message, utfMessage); - } - else { - exceptionMessage.append(errorCode+": F-UDF-CL-SL-JAVA-1049: Throwable.toString(): result is null"); - } - -// // Build Stacktrace -// -// // Throwable.getStackTrace() -// jmethodID getStackTrace = m_env->GetMethodID(exClass, "getStackTrace", "()[Ljava/lang/StackTraceElement;"); -// check("F-UDF-CL-SL-JAVA-1050",calledUndefinedSingleCall); -// if (!getStackTrace) -// throwException(errorCode+": F-UDF-CL-SL-JAVA-1051: Throwable.getStackTrace() could not be found"); -// jobjectArray frames = (jobjectArray)m_env->CallObjectMethod(ex, getStackTrace); -// if (frames) { -// jclass frameClass = m_env->FindClass("java/lang/StackTraceElement"); -// check("F-UDF-CL-SL-JAVA-1052",calledUndefinedSingleCall); -// if (!frameClass) -// throwException(errorCode+": F-UDF-CL-SL-JAVA-1053: FindClass for StackTraceElement failed"); -// jmethodID frameToString = m_env->GetMethodID(frameClass, "toString", "()Ljava/lang/String;"); -// check("F-UDF-CL-SL-JAVA-1054",calledUndefinedSingleCall); -// if (!frameToString) -// throwException(errorCode+": F-UDF-CL-SL-JAVA-1055: StackTraceElement.toString() could not be found"); -// jsize framesLength = m_env->GetArrayLength(frames); -// for (int i = 0; i < framesLength; i++) { -// jobject frame = m_env->GetObjectArrayElement(frames, i); -// check("F-UDF-CL-SL-JAVA-1056",calledUndefinedSingleCall); -// jobject frameMsgObj = m_env->CallObjectMethod(frame, frameToString); -// if (frameMsgObj) { -// jstring message = static_cast(frameMsgObj); -// const char *utfMessage = m_env->GetStringUTFChars(message, 0); -// string line = utfMessage; -// // If stack trace lines are wrapper or reflection entries, stop -// if ((line.find("ExaWrapper.") == 0) || (line.find("ExaCompiler.") == 0) || (line.find("sun.reflect.") == 0)) { -// if (i != 0) -// exceptionMessage.append("\n"); -// m_env->ReleaseStringUTFChars(message, utfMessage); -// break; -// } -// else { -// if (i == 0) -// exceptionMessage.append("\nStack trace:"); -// exceptionMessage.append("\n"); -// exceptionMessage.append(utfMessage); -// m_env->ReleaseStringUTFChars(message, utfMessage); -// } -// } -// } -// } - throw JavaVMach::exception(errorCode+": "+exceptionMessage); - } - return 1; -} - -void JavaVMImpl::registerFunctions() { - string calledUndefinedSingleCall; - jclass cls = m_env->FindClass("com/exasol/swig/exascript_javaJNI"); - check("F-UDF-CL-SL-JAVA-1057",calledUndefinedSingleCall); - if (!cls) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1058: FindClass for exascript_javaJNI failed"); - int rc = m_env->RegisterNatives(cls, methods, sizeof(methods) / sizeof(methods[0])); - check("F-UDF-CL-SL-JAVA-1059",calledUndefinedSingleCall); - if (rc) - throw JavaVMach::exception("F-UDF-CL-SL-JAVA-1060: RegisterNatives failed"); -} - -void JavaVMImpl::setClasspath() { - m_exaJarPath = m_exaJavaPath + "/exaudf_deploy.jar"; - m_classpath = m_exaJarPath; -} - -void JavaVMImpl::addLocalClasspath() { - m_classpath = m_localClasspath + ":" + m_classpath; -} - -bool JavaVMImpl::checkNeedsCompilation() { - std::string trimmedScriptCode = m_scriptCode; - trimmedScriptCode.erase(0, trimmedScriptCode.find_first_not_of("\t\n\r ")); // left trim - trimmedScriptCode.erase(trimmedScriptCode.find_last_not_of("\t\n\r ") + 1); // right trim - return false == trimmedScriptCode.empty(); -} - -void JavaVMImpl::addJarToClasspath(const string& path) { - string jarPath = path; // m_exaJavaPath + "/jars/" + path; - - struct stat st; - int rc = stat(jarPath.c_str(), &st); - if (rc && errno == ENOENT) { - // Not found in HOME, try path directly - jarPath = path; - rc = stat(jarPath.c_str(), &st); - if (rc) { - stringstream errorMsg; - errorMsg << "F-UDF-CL-SL-JAVA-1061: Java VM cannot find '" << jarPath.c_str() << "': " << strerror(errno); - throw JavaVMach::exception(errorMsg.str()); - } - } - else if (rc) { - stringstream errorMsg; - errorMsg << "F-UDF-CL-SL-JAVA-1062: Java VM cannot find '" << jarPath.c_str() << "': " << strerror(errno); - throw JavaVMach::exception(errorMsg.str()); - } - - if (!S_ISREG(st.st_mode)) { - stringstream errorMsg; - errorMsg << "F-UDF-CL-SL-JAVA-1063: '" << jarPath.c_str() << "' is not a regular file"; - throw JavaVMach::exception(errorMsg.str()); - } - - // Add file to classpath - m_classpath += ":" + jarPath; -} - - -void JavaVMImpl::setJvmOptions() { - bool minHeap = false; - bool maxHeap = false; - bool maxStack = false; - for (vector::iterator it = m_jvmOptions.begin(); it != m_jvmOptions.end(); ++it) { - if ((*it).find("-Xms") != string::npos) { - minHeap = true; - } - else if ((*it).find("-Xmx") != string::npos) { - maxHeap = true; - } - else if ((*it).find("-Xss") != string::npos) { - maxStack = true; - } - } - - // Initial heap size - unsigned long minHeapSize = 128; - unsigned long maxHeapSize = 1024; - if (!minHeap) { - stringstream ss; - ss << "-Xms" << minHeapSize << "m"; - m_jvmOptions.push_back(ss.str()); - } - // Max heap size - if (!maxHeap) { - unsigned long maxHeapSizeMb = static_cast(0.625 * (SWIGVM_params->maximal_memory_limit / (1024 * 1024))); - maxHeapSizeMb = (maxHeapSizeMb < minHeapSize) ? minHeapSize : maxHeapSizeMb; - maxHeapSizeMb = (maxHeapSizeMb > maxHeapSize) ? maxHeapSize : maxHeapSizeMb; - stringstream ss; - ss << "-Xmx" << maxHeapSizeMb << "m"; - m_jvmOptions.push_back(ss.str()); - } - // Max thread stack size - if (!maxStack) - m_jvmOptions.push_back("-Xss512k"); - // Error file path - m_jvmOptions.push_back("-XX:ErrorFile=" + m_localClasspath + "/hs_err_pid%p.log"); - // Classpath - m_jvmOptions.push_back("-Djava.class.path=" + m_classpath); - // Serial garbage collection - m_jvmOptions.push_back("-XX:+UseSerialGC"); // TODO allow different Garbage Collectors, multiple options are not allowed, so we need to check if options was specified by the user or otherwise use -XX:+UseSerialGC as default -} diff --git a/exaudfclient/base/javacontainer/javacontainer_impl.h b/exaudfclient/base/javacontainer/javacontainer_impl.h deleted file mode 100644 index 0423b21..0000000 --- a/exaudfclient/base/javacontainer/javacontainer_impl.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef JAVACONTAINER_IMPL_H -#define JAVACONTAINER_IMPL_H - -#include -#include -#include -#include - -#include "exaudflib/vm/swig_vm.h" -#include - -#ifdef ENABLE_JAVA_VM - -class JavaVMTest; - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - struct Extractor; -} - -class JavaVMImpl { - public: - friend class ::JavaVMTest; - /* - * scriptOptionsParser: JavaVMImpl takes ownership of ScriptOptionsParser pointer. - */ - JavaVMImpl(bool checkOnly, bool noJNI, std::unique_ptr extractor); - ~JavaVMImpl() {} - void shutdown(); - bool run(); - const char* singleCall(single_call_function_id_e fn, const ExecutionGraph::ScriptDTO& args, - std::string& calledUndefinedSingleCall); - private: - void createJvm(); - void addPackageToScript(); - void compileScript(); - bool check(const std::string& errorCode, std::string& calledUndefinedSingleCall); // returns 0 if the check failed - void registerFunctions(); - void addLocalClasspath(); - bool checkNeedsCompilation(); - void setClasspath(); - void setJvmOptions(); - void addJarToClasspath(const std::string& path); - void parseScriptOptions(std::unique_ptr extractor); - bool m_checkOnly; - std::string m_exaJavaPath; - std::string m_localClasspath; - std::string m_scriptCode; - std::string m_exaJarPath; - std::string m_classpath; - std::vector m_jvmOptions; - JavaVM *m_jvm; - JNIEnv *m_env; - bool m_needsCompilation; -}; - -} //namespace SWIGVMContainers - - -#endif //ENABLE_JAVA_VM - - -#endif //JAVACONTAINER_IMPL_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/BUILD b/exaudfclient/base/javacontainer/script_options/BUILD deleted file mode 100644 index 3bf350f..0000000 --- a/exaudfclient/base/javacontainer/script_options/BUILD +++ /dev/null @@ -1,19 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load("@rules_cc//cc:defs.bzl", "cc_library") - -cc_library( - name = "java_script_option_lines", - hdrs = [":extractor.h", ":extractor_impl.h", ":parser_legacy.h", ":parser_ctpg.h", - ":converter_v2.h", ":converter_legacy.h"], - srcs = [":parser.h", ":converter.h", ":converter.cc", ":parser_legacy.cc", ":extractor_impl.h", - ":extractor_impl.cc", ":converter_legacy.cc", ":converter_legacy.h", - ":converter_v2.cc", ":converter_v2.h", - ":keywords.h", ":keywords.cc", ":distinct_script_set.h", ":distinct_script_set.cc", ":parser_ctpg.cc", - ":parser_ctpg_script_importer.cc", ":parser_ctpg_script_importer.h", - ":parser_ctpg_jvm_options_parser.cc", ":parser_ctpg_jvm_options_parser.h", ":string_ops.h", ":string_ops.cc"], - deps = ["//script_options_parser/legacy:script_option_lines_parser_legacy", - "//script_options_parser/ctpg:script_option_lines_parser_ctpg", "//utils:utils", - "//exaudflib:header", "//exaudflib:exaudflib-deps", "//swig_factory:swig_factory_if", - "//script_options_parser:exception"], -) diff --git a/exaudfclient/base/javacontainer/script_options/converter.cc b/exaudfclient/base/javacontainer/script_options/converter.cc deleted file mode 100644 index d2f7103..0000000 --- a/exaudfclient/base/javacontainer/script_options/converter.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "javacontainer/script_options/converter.h" - -#include - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -Converter::Converter() -: m_jvmOptions() -, m_whitespace(" \t\f\v") {} - -void Converter::convertScriptClassName(const std::string & value) { - - if (value.empty()) { - return; - } - m_jvmOptions.push_back("-Dexasol.scriptclass=" + value); -} - - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/converter.h b/exaudfclient/base/javacontainer/script_options/converter.h deleted file mode 100644 index ec7516e..0000000 --- a/exaudfclient/base/javacontainer/script_options/converter.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERCONVERTER_H -#define SCRIPTOPTIONLINEPARSERCONVERTER_H 1 - -#include -#include -#include - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -/** - * This class retrieves the raw Java script option values (scriptclass, jvmoption, jar) - * and converts them to the proper format expected by the JvmContainerImpl class. - * Besides the converter functions it provides methods to access the converted values. - */ -class Converter { - - public: - typedef std::function tJarIteratorCallback; - - Converter(); - - void convertScriptClassName(const std::string & value); - - virtual void convertJvmOption(const std::string & value) = 0; - - std::vector&& moveJvmOptions() { - return std::move(m_jvmOptions); - } - - virtual void convertExternalJar(const std::string & value) = 0; - - virtual void iterateJarPaths(tJarIteratorCallback callback) const = 0; - - protected: - - std::vector m_jvmOptions; - - const std::string m_whitespace; -}; - - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPARSERCONVERTER_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/converter_legacy.cc b/exaudfclient/base/javacontainer/script_options/converter_legacy.cc deleted file mode 100644 index ddf4276..0000000 --- a/exaudfclient/base/javacontainer/script_options/converter_legacy.cc +++ /dev/null @@ -1,42 +0,0 @@ -#include "javacontainer/script_options/converter_legacy.h" -#include "javacontainer/script_options/string_ops.h" -#include -#include -#include - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -ConverterLegacy::ConverterLegacy() -: Converter() -, m_jarPaths() {} - -void ConverterLegacy::convertExternalJar(const std::string& value) { - std::istringstream stream(value); - std::string jar; - - while (std::getline(stream, jar, ':')) { - m_jarPaths.insert(jar); - } -} - -void ConverterLegacy::convertJvmOption(const std::string& value) { - std::string::size_type start = 0, delim = 0; - while ((start = value.find_first_not_of(m_whitespace, delim)) != std::string::npos) { - delim = value.find_first_of(m_whitespace, start); - const std::string::size_type len = (std::string::npos == delim) ? std::string::npos : delim - start; - m_jvmOptions.push_back(value.substr(start, len)); - } -} - - -void ConverterLegacy::iterateJarPaths(Converter::tJarIteratorCallback callback) const { - std::for_each(m_jarPaths.begin(), m_jarPaths.end(), callback); -} - - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/converter_legacy.h b/exaudfclient/base/javacontainer/script_options/converter_legacy.h deleted file mode 100644 index 6fb8abd..0000000 --- a/exaudfclient/base/javacontainer/script_options/converter_legacy.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERCONVERTERLEGACY_H -#define SCRIPTOPTIONLINEPARSERCONVERTERLEGACY_H 1 - -#include -#include -#include -#include - -#include "javacontainer/script_options/converter.h" - - - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -/** - * This class is a specialization for the generic converter class. - * It implements conversion of the jar option according to the requirements in the old - * parser implementation. - */ -class ConverterLegacy : public Converter { - - public: - ConverterLegacy(); - - void convertExternalJar(const std::string & value) override; - - void convertJvmOption(const std::string & value) override; - - void iterateJarPaths(tJarIteratorCallback callback) const override; - - private: - - std::set m_jarPaths; - -}; - - - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPARSERCONVERTER_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/converter_v2.cc b/exaudfclient/base/javacontainer/script_options/converter_v2.cc deleted file mode 100644 index 9f279f4..0000000 --- a/exaudfclient/base/javacontainer/script_options/converter_v2.cc +++ /dev/null @@ -1,37 +0,0 @@ -#include "javacontainer/script_options/converter_v2.h" -#include "javacontainer/script_options/string_ops.h" -#include "javacontainer/script_options/parser_ctpg_jvm_options_parser.h" -#include -#include -#include - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -ConverterV2::ConverterV2() -: Converter() -, m_jarPaths() {} - -void ConverterV2::convertExternalJar(const std::string & value) { - std::istringstream stream(value); - std::string jar; - - while (std::getline(stream, jar, ':')) { - m_jarPaths.push_back(jar); - } -} - - -void ConverterV2::convertJvmOption(const std::string & value) { - JvmOptionsCTPG::parseJvmOptions(value, m_jvmOptions); -} - -void ConverterV2::iterateJarPaths(Converter::tJarIteratorCallback callback) const { - std::for_each(m_jarPaths.begin(), m_jarPaths.end(), callback); -} - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/converter_v2.h b/exaudfclient/base/javacontainer/script_options/converter_v2.h deleted file mode 100644 index 8807d90..0000000 --- a/exaudfclient/base/javacontainer/script_options/converter_v2.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERCONVERTERV2_H -#define SCRIPTOPTIONLINEPARSERCONVERTERV2_H 1 - -#include -#include -#include - -#include "javacontainer/script_options/converter.h" - - - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -/** - * This class is a specialization for the generic converter class. - * It implements conversion of the jar option according to the requirements in the new - * parser implementation. - */ -class ConverterV2 : public Converter { - - public: - ConverterV2(); - - void convertExternalJar(const std::string & value) override; - - void convertJvmOption(const std::string & value) override; - - void iterateJarPaths(tJarIteratorCallback callback) const override; - - private: - - std::vector m_jarPaths; - -}; - - - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPARSERCONVERTER_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/distinct_script_set.cc b/exaudfclient/base/javacontainer/script_options/distinct_script_set.cc deleted file mode 100644 index 34898ec..0000000 --- a/exaudfclient/base/javacontainer/script_options/distinct_script_set.cc +++ /dev/null @@ -1,17 +0,0 @@ -#include "javacontainer/script_options/distinct_script_set.h" -#include - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - - -bool DistinctScriptSet::addScript(const char *script) { - std::string strScript = std::string(script); - return m_importedScripts.insert(strScript).second; -} - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/distinct_script_set.h b/exaudfclient/base/javacontainer/script_options/distinct_script_set.h deleted file mode 100644 index 081681b..0000000 --- a/exaudfclient/base/javacontainer/script_options/distinct_script_set.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERCHECKSUM_H -#define SCRIPTOPTIONLINEPARSERCHECKSUM_H 1 - -#include -#include -#include - - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -class DistinctScriptSet { - -public: - DistinctScriptSet() = default; - - bool addScript(const char *script); - -private: - std::unordered_set m_importedScripts; -}; - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPARSERCHECKSUM_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/extractor.h b/exaudfclient/base/javacontainer/script_options/extractor.h deleted file mode 100644 index 8d1f669..0000000 --- a/exaudfclient/base/javacontainer/script_options/extractor.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPEXTRACTOR_H -#define SCRIPTOPTIONLINEPEXTRACTOR_H 1 - -#include -#include -#include - - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -/** - * Abstract interface for the Extractor class. - * Defines methods to extract the Java options from the script code. - * The extraction process searches for the known Java Options and handles them appropriatly. - * The script code is then modified, where the found options are removed. - * The interface defines methods to access the found Jar- and JvmOption options. - * The scriptclass and import options are processed internally by the respective extractor implementation. - */ -struct Extractor { - - typedef std::function tJarIteratorCallback; - - virtual ~Extractor() {} - - /** - * Access the found Jar paths. For each found jar path the given callback function is called with the jar option as argument. - */ - virtual void iterateJarPaths(tJarIteratorCallback callback) const = 0; - - /** - * Access the Jvm option options. The extractor implementations must store the found Jvm Options in a std::vector. - * The vector is returned as rvalue. - */ - virtual std::vector&& moveJvmOptions() = 0; - - /** - * Run the extraction. This will: - * 1. Add the first `scriptclass` option to the list of Jvm options. - * 2. Replace and (nested) reference of an `import` script - * 3. Find and store all Jar options - * 4. Find and store all `jvmoption` options - * 5. Remove `scriptclass`, `jar`, `import` and `jvmoption` from the script code. The behavior is implementation specific. - */ - virtual void extract(std::string & scriptCode) = 0; -}; - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPEXTRACTOR_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/extractor_impl.cc b/exaudfclient/base/javacontainer/script_options/extractor_impl.cc deleted file mode 100644 index b156d44..0000000 --- a/exaudfclient/base/javacontainer/script_options/extractor_impl.cc +++ /dev/null @@ -1,54 +0,0 @@ -#include "javacontainer/script_options/extractor_impl.h" -#include "javacontainer/script_options/parser.h" - -#include "utils/debug_message.h" -#include - -#define EXTR_DBG_FUNC_CALL(f) DBG_FUNC_CALL(std::cerr, f) - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -template -ExtractorImpl::ExtractorImpl(std::unique_ptr swigFactory) -: m_parser(std::move(swigFactory)) -, m_converter() {} - -template -void ExtractorImpl::iterateJarPaths(Extractor::tJarIteratorCallback callback) const { - return m_converter.iterateJarPaths(callback); -} - -template -std::vector&& ExtractorImpl::moveJvmOptions() { - return std::move(m_converter.moveJvmOptions()); -} - -template -void ExtractorImpl::extract(std::string & scriptCode) { - m_parser.prepareScriptCode(scriptCode); - EXTR_DBG_FUNC_CALL(m_parser.parseForScriptClass( [&](const std::string& value){ - EXTR_DBG_FUNC_CALL(m_converter.convertScriptClassName(value)); // To be called before scripts are imported. Otherwise, the script classname from an imported script could be used - })); - EXTR_DBG_FUNC_CALL(m_parser.extractImportScripts()); - EXTR_DBG_FUNC_CALL(m_parser.parseForJvmOptions( [&](const std::string& value){ - EXTR_DBG_FUNC_CALL(m_converter.convertJvmOption(value)); - })); - - EXTR_DBG_FUNC_CALL(m_parser.parseForExternalJars( [&](const std::string& value){ - EXTR_DBG_FUNC_CALL(m_converter.convertExternalJar(value)); - })); - - scriptCode = std::move(m_parser.getScriptCode()); -} - - -// Explict class template instantiations -template class ExtractorImpl; -template class ExtractorImpl; - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/extractor_impl.h b/exaudfclient/base/javacontainer/script_options/extractor_impl.h deleted file mode 100644 index e65fe5a..0000000 --- a/exaudfclient/base/javacontainer/script_options/extractor_impl.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPEXTRACTORIMPL_H -#define SCRIPTOPTIONLINEPEXTRACTORIMPL_H 1 - -#include -#include -#include - - -#include "javacontainer/script_options/extractor.h" -#include "javacontainer/script_options/converter_legacy.h" -#include "javacontainer/script_options/converter_v2.h" -#include "javacontainer/script_options/parser_ctpg.h" -#include "javacontainer/script_options/parser_legacy.h" -#include "swig_factory/swig_factory.h" - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -/** - * Concrete implementation for the Extractor class. - * Given template parameter TParser and TConverter define concrete behavior. - */ -template -class ExtractorImpl : public Extractor { - - public: - - ExtractorImpl(std::unique_ptr swigFactory); - - virtual void iterateJarPaths(tJarIteratorCallback callback) const override; - std::vector&& moveJvmOptions() override; - - void extract(std::string & scriptCode); - - private: - TParser m_parser; - TConverter m_converter; -}; - -typedef ExtractorImpl tExtractorLegacy; -typedef ExtractorImpl tExtractorV2; - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPEXTRACTORIMPL_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/keywords.cc b/exaudfclient/base/javacontainer/script_options/keywords.cc deleted file mode 100644 index 4ac2aff..0000000 --- a/exaudfclient/base/javacontainer/script_options/keywords.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include "javacontainer/script_options/keywords.h" -#include - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -Keywords::Keywords(bool withScriptOptionsPrefix) -: m_jarKeyword() -, m_scriptClassKeyword() -, m_importKeyword() -, m_jvmKeyword() { - const std::string_view jar{"%jar"}; - const std::string_view scriptClass{"%scriptclass"}; - const std::string_view import{"%import"}; - const std::string_view jvm{"%jvmoption"}; - if (withScriptOptionsPrefix) { - m_jarKeyword = jar; - m_scriptClassKeyword = scriptClass; - m_importKeyword = import; - m_jvmKeyword = jvm; - } else { - m_jarKeyword.assign(jar.substr(1)); - m_scriptClassKeyword.assign(scriptClass.substr(1)); - m_importKeyword.assign(import.substr(1)); - m_jvmKeyword.assign(jvm.substr(1)); - } -} - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - diff --git a/exaudfclient/base/javacontainer/script_options/keywords.h b/exaudfclient/base/javacontainer/script_options/keywords.h deleted file mode 100644 index 314bf5b..0000000 --- a/exaudfclient/base/javacontainer/script_options/keywords.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef SCRIPTOPTIONLINEKEYWORDS_H -#define SCRIPTOPTIONLINEKEYWORDS_H 1 - -#include - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -class Keywords { - public: - Keywords(bool withScriptOptionsPrefix); - const std::string & scriptClassKeyword() { return m_scriptClassKeyword; } - const std::string & importKeyword() { return m_importKeyword; } - const std::string & jvmKeyword() { return m_jvmKeyword; } - const std::string & jarKeyword() { return m_jarKeyword; } - private: - std::string m_jarKeyword; - std::string m_scriptClassKeyword; - std::string m_importKeyword; - std::string m_jvmKeyword; -}; - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - - -#endif // SCRIPTOPTIONLINEKEYWORDS_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/parser.h b/exaudfclient/base/javacontainer/script_options/parser.h deleted file mode 100644 index abb497f..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSER_H -#define SCRIPTOPTIONLINEPARSER_H 1 - -#include -#include -#include - - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -struct ScriptOptionsParser { - virtual ~ScriptOptionsParser() {}; - /* - Passes the script code for parsing to the parser. The parser might modify the script code, because it will remove - known options. - */ - virtual void prepareScriptCode(const std::string & scriptCode) = 0; - /* - Searches for script class option. - If the option is found, the function removes the option from "scriptCode" and calls "callback" with the option value and position - within "scriptCode". - */ - virtual void parseForScriptClass(std::function callback) = 0; - /* - Searches for JVM options. - If an option is found, the function removes the option from "scriptCode" and calls "callback" with the option value and position - within "scriptCode". - */ - virtual void parseForJvmOptions(std::function callback) = 0; - - /* - Searches for External Jar. - If an option is found, the function removes the option from "scriptCode" and calls "callback" with the option value and position - within "scriptCode". - */ - virtual void parseForExternalJars(std::function callback) = 0; - - /* - Searches for the "%import" options and embeds the respective imported script code at the same location as - the option in the script code. - */ - virtual void extractImportScripts() = 0; - - /* - Returns the (eventually modified) script code. - */ - virtual std::string && getScriptCode() = 0; -}; - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - - -#endif //SCRIPTOPTIONLINEPARSER_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc b/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc deleted file mode 100644 index 6209a78..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg.cc +++ /dev/null @@ -1,162 +0,0 @@ -#include "javacontainer/script_options/parser_ctpg.h" -#include "javacontainer/script_options/parser_ctpg_script_importer.h" -#include "utils/exceptions.h" -#include "script_options_parser/exception.h" -#include "swig_factory/swig_factory.h" -#include "javacontainer/script_options/string_ops.h" -#include -#include - - -namespace ctpg_parser = ExecutionGraph::OptionsLineParser::CTPG; - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -ScriptOptionLinesParserCTPG::ScriptOptionLinesParserCTPG(std::unique_ptr swigFactory) -: m_scriptCode() -, m_keywords(false) -, m_needParsing(true) -, m_swigFactory(std::move(swigFactory)) {} - -void ScriptOptionLinesParserCTPG::prepareScriptCode(const std::string & scriptCode) { - m_scriptCode = scriptCode; -} - -void ScriptOptionLinesParserCTPG::parseForScriptClass(std::function callback) { - try { - parseForSingleOption(m_keywords.scriptClassKeyword(), [&](const std::string &option) { - std::string trimmedValue(option); - StringOps::trim(trimmedValue); - callback(trimmedValue); - }); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1623"); - } -} - -void ScriptOptionLinesParserCTPG::parseForJvmOptions(std::function callback) { - try { - parseForMultipleOption(m_keywords.jvmKeyword(), callback); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1624"); - } -} - -void ScriptOptionLinesParserCTPG::parseForExternalJars(std::function callback) { - try { - parseForMultipleOption(m_keywords.jarKeyword(), [callback] (const std::string &option) { - std::string formattedValue(option); - StringOps::replaceTrailingEscapeWhitespaces(formattedValue); - callback(formattedValue); - }); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1625"); - } -} - -void ScriptOptionLinesParserCTPG::extractImportScripts() { - - try { - parse(); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1626"); - } - - const auto optionIt = m_foundOptions.find(m_keywords.importKeyword()); - if (optionIt != m_foundOptions.end()) { - CTPG::ScriptImporter scriptImporter(*m_swigFactory, m_keywords); - scriptImporter.importScript(m_scriptCode, m_foundOptions); - //The imported scripts will change the location of the other options in m_foundOptions - //Also there might be new JVM / External Jar options - //=> We need to clear the option map and reset the parser. - m_foundOptions.clear(); - m_needParsing = true; - } -} - -std::string && ScriptOptionLinesParserCTPG::getScriptCode() { - try { - parse(); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1627"); - } - //Remove all options from script code in reverse order - struct option_location { - size_t pos; - size_t len; - }; - struct comp { - bool operator()(option_location a, option_location b) const { - return a.pos > b.pos; - } - }; - std::set option_locations; - for (const auto & option: m_foundOptions) { - for (const auto & option_loc: option.second) { - option_location loc = { .pos = option_loc.idx_in_source, .len = option_loc.size}; - option_locations.insert(loc); - } - } - for (const auto option_loc: option_locations) { - m_scriptCode.erase(option_loc.pos, option_loc.len); - } - return std::move(m_scriptCode); -} - -void ScriptOptionLinesParserCTPG::parse() { - if (m_needParsing) { - if(!m_foundOptions.empty()) { - throw std::logic_error( - "F-UDF-CL-SL-JAVA-1620 Internal error. Parser result is not empty. " - "Please open a bug ticket at https://github.com/exasol/script-languages-release/issues/new."); - } - try { - ExecutionGraph::OptionsLineParser::CTPG::parseOptions(m_scriptCode, m_foundOptions); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1621"); - } - - m_needParsing = false; - - //Check for unknown options - for (const auto & option: m_foundOptions) { - if (m_keywords.jarKeyword() != option.first && - m_keywords.scriptClassKeyword() != option.first && - m_keywords.importKeyword() != option.first && - m_keywords.jvmKeyword() != option.first) { - std::stringstream ss; - ss << "F-UDF-CL-SL-JAVA-1622 " << "Unexpected option: " << option.first; - throw std::invalid_argument(ss.str()); - } - } - } -} - -void ScriptOptionLinesParserCTPG::parseForSingleOption(const std::string key, std::function callback) { - parse(); - const auto optionIt = m_foundOptions.find(key); - if (optionIt != m_foundOptions.end()) { - if (optionIt->second.size() != 1) { - std::stringstream ss; - ss << "F-UDF-CL-SL-JAVA-1628 found " << optionIt->second.size() << " instances for script option key '" << key << "' but expected at most one." << std::endl; - throw std::invalid_argument(ss.str()); - } - callback(optionIt->second[0].value); - } -} - -void ScriptOptionLinesParserCTPG::parseForMultipleOption(const std::string key, std::function callback) { - parse(); - const auto optionIt = m_foundOptions.find(key); - if (optionIt != m_foundOptions.end()) { - for (const auto & option : optionIt->second) { - callback(option.value); - } - } -} - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg.h b/exaudfclient/base/javacontainer/script_options/parser_ctpg.h deleted file mode 100644 index 1f7bad8..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERCTPGY_H -#define SCRIPTOPTIONLINEPARSERCTPGY_H 1 - -#include "javacontainer/script_options/parser.h" -#include "javacontainer/script_options/keywords.h" -#include "script_options_parser/ctpg/script_option_lines_ctpg.h" -#include - -namespace SWIGVMContainers { - -struct SwigFactory; - -namespace JavaScriptOptions { - -class ScriptOptionLinesParserCTPG : public ScriptOptionsParser { - - public: - ScriptOptionLinesParserCTPG(std::unique_ptr swigFactory); - - virtual ~ScriptOptionLinesParserCTPG() {}; - - void prepareScriptCode(const std::string & scriptCode) override; - - void parseForScriptClass(std::function callback) override; - - void parseForJvmOptions(std::function callback) override; - - void parseForExternalJars(std::function callback) override; - - void extractImportScripts() override; - - std::string && getScriptCode() override; - - private: - void parse(); - - void parseForSingleOption(const std::string key, std::function callback); - void parseForMultipleOption(const std::string key, std::function callback); - - void importScripts(SwigFactory & swigFactory); - - private: - std::string m_scriptCode; - Keywords m_keywords; - ExecutionGraph::OptionsLineParser::CTPG::options_map_t m_foundOptions; - bool m_needParsing; - std::unique_ptr m_swigFactory; -}; - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPARSERCTPGY_H diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg_jvm_options_parser.cc b/exaudfclient/base/javacontainer/script_options/parser_ctpg_jvm_options_parser.cc deleted file mode 100644 index 826af38..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg_jvm_options_parser.cc +++ /dev/null @@ -1,98 +0,0 @@ -#include "javacontainer/script_options/parser_ctpg_jvm_options_parser.h" -#include "script_options_parser/ctpg/ctpg.hpp" -#include - -using namespace exaudf_ctpg; -using namespace exaudf_ctpg::ftors; - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -namespace JvmOptionsCTPG { - - -const auto to_options(std::string&& e) -{ - tJvmOptions options{e}; - return options; -} - -auto&& add_option(std::string&& e, tJvmOptions&& ob) -{ - ob.push_back(std::move(e)); - return std::move(ob); -} - -auto convert_escape_sequence(std::string_view escape_seq) -{ - if (escape_seq == R"_(\ )_") { - return std::string_view(" "); - } else if (escape_seq == R"_(\t)_") { - return std::string_view("\t"); - } else if (escape_seq == R"_(\f)_") { - return std::string_view("\f"); - } else if (escape_seq == R"_(\v)_") { - return std::string_view("\v"); - } else if (escape_seq == R"_(\\)_") { - return std::string_view("\\"); - } else { - throw std::invalid_argument(std::string("Internal parser error: Unexpected escape sequence " + std::string(escape_seq))); - } -} - - -constexpr char not_separator_pattern[] = R"_([^ \x09\x0c\x0b])_"; -constexpr char whitespaces_pattern[] = R"_([ \x09\x0c\x0b]+)_"; -constexpr char escape_pattern[] = R"_(\\\\|\\t|\\ |\\f|\\v)_"; - -constexpr regex_term not_separator("not_separator"); -constexpr regex_term whitespaces("whitespace"); -constexpr regex_term escape_seq("escape_seq"); - -constexpr nterm text("text"); -constexpr nterm option_element("option_element"); - - -constexpr parser jvm_option_parser( - text, - terms(escape_seq, not_separator, whitespaces), - nterms(text, option_element), - rules( - text() - >= [] () {return tJvmOptions();}, - text(option_element) - >= [](auto&& e) { return to_options(std::move(e)); }, - text(text, whitespaces) - >= [](auto&& ob, skip) { return std::move(ob); }, - text(text, whitespaces, option_element) - >= [](auto&& ob, skip, auto&& e) { return add_option(std::move(e), std::move(ob)); }, - option_element(not_separator) - >= [](auto ns) { return std::string(ns); }, - option_element(option_element, not_separator) - >= [](auto &&ob, auto c) { return std::move(ob.append(c)); }, - option_element(option_element, escape_seq) - >= [](auto &&ob, auto es) { return std::move(ob.append(convert_escape_sequence(es))); } - ) -); - - -void parseJvmOptions(const std::string & jvmOptions, tJvmOptions& result) { - std::stringstream error_buffer; - auto && res = jvm_option_parser.parse( - parse_options{}.set_skip_whitespace(false), - buffers::string_buffer(jvmOptions.c_str()), - error_buffer); - if (res.has_value()) { - result.insert(result.end(), res.value().begin(), res.value().end()); - } - else { - throw std::invalid_argument(error_buffer.str()); - } -} - -} //namespace JvmOptionsCTPG - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg_jvm_options_parser.h b/exaudfclient/base/javacontainer/script_options/parser_ctpg_jvm_options_parser.h deleted file mode 100644 index 84ee8dd..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg_jvm_options_parser.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERCTPGJVMOPTIONSPARSER_H -#define SCRIPTOPTIONLINEPARSERCTPGJVMOPTIONSPARSER_H 1 - -#include -#include - - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -namespace JvmOptionsCTPG { - -typedef std::vector tJvmOptions; - -void parseJvmOptions(const std::string & jvmOptions, tJvmOptions& result); - - - -} //namespace CTPG - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPARSERCTPGSCRIPTIMPORTER_H diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.cc b/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.cc deleted file mode 100644 index d5daeba..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.cc +++ /dev/null @@ -1,111 +0,0 @@ -#include "javacontainer/script_options/parser_ctpg_script_importer.h" -#include "swig_factory/swig_factory.h" -#include "utils/debug_message.h" -#include "utils/exceptions.h" -#include "script_options_parser/exception.h" -#include "javacontainer/script_options/string_ops.h" - -#include -#include -#include - -namespace ctpg_parser = ExecutionGraph::OptionsLineParser::CTPG; - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -namespace CTPG { - -ScriptImporter::ScriptImporter(SwigFactory & swigFactory, Keywords & keywords) -: m_importedScripts() -, m_swigFactory(swigFactory) -, m_metaData() -, m_keywords(keywords) {} - -void ScriptImporter::importScript(std::string & scriptCode, - ctpg_parser::options_map_t & options) { - importScript(scriptCode, options, 0); -} - -void ScriptImporter::collectImportScripts(const ScriptImporter::OptionValues_t & option_values, - const size_t recursionDepth, - std::vector &result) { - for (const auto & option: option_values) { - const char *importScriptCode = findImportScript(option.value); - std::string importScriptCodeStr; - if (m_importedScripts.addScript(importScriptCode) ) { - // Script has not been imported yet - // If this imported script contains %import statements - // they will be resolved in the next recursion. - ctpg_parser::options_map_t newOptions; - try { - ExecutionGraph::OptionsLineParser::CTPG::parseOptions(importScriptCode, newOptions); - } catch(const ExecutionGraph::OptionParserException & ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1630"); - } - importScriptCodeStr.assign(importScriptCode); - importScript(importScriptCodeStr, newOptions, recursionDepth + 1); - } - CollectedScript replacedScript = {.script = std::move(importScriptCodeStr), .origPos = option.idx_in_source, .origLen = option.size }; - result.push_back(std::move(replacedScript)); - } -} - -void ScriptImporter::replaceImportScripts(std::string & scriptCode, - const std::vector &collectedImportScripts) { - //Replace the imported script bodies from end to start. - //Doing it in forward order would invalidate the offsets of later import scripts. - for (auto optionIt = collectedImportScripts.crbegin(); optionIt != collectedImportScripts.crend(); optionIt++) { - scriptCode.replace(optionIt->origPos, optionIt->origLen, optionIt->script); - } -} - - -void ScriptImporter::importScript(std::string & scriptCode, - ctpg_parser::options_map_t & options, - const size_t recursionDepth) { - const auto optionIt = options.find(std::string(m_keywords.importKeyword())); - - if (recursionDepth >= cMaxRecursionDepth) { - throw std::runtime_error("F-UDF-CL-SL-JAVA-1633: Maximal recursion depth for importing scripts reached."); - } - if (optionIt != options.end()) { - m_importedScripts.addScript(scriptCode.c_str()); - //Sort options from first in script to last in script - std::sort(optionIt->second.begin(), optionIt->second.end(), - [](const ctpg_parser::ScriptOption& first, const ctpg_parser::ScriptOption& second) - { - return first.idx_in_source < second.idx_in_source; - }); - std::vector collectedScripts; - collectedScripts.reserve(optionIt->second.size()); - //In order to continue compatibility with legacy implementation - //we must collect import scripts in forward direction but then replace in reverse direction. - collectImportScripts(optionIt->second, recursionDepth, collectedScripts); - replaceImportScripts(scriptCode, collectedScripts); - } -} - -const char* ScriptImporter::findImportScript(const std::string & scriptKey) { - std::string trimmedScriptKey(scriptKey); - StringOps::trim(trimmedScriptKey); - if (!m_metaData) { - m_metaData.reset(m_swigFactory.makeSwigMetadata()); - if (!m_metaData) { - throw std::runtime_error("F-UDF-CL-SL-JAVA-1631: Failure while importing scripts"); - } - } - const char *importScriptCode = m_metaData->moduleContent(trimmedScriptKey.c_str()); - const char *exception = m_metaData->checkException(); - if (exception) { - throw std::runtime_error("F-UDF-CL-SL-JAVA-1632: " + std::string(exception)); - } - return importScriptCode; -} - -} //namespace CTPG - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.h b/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.h deleted file mode 100644 index 284a406..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser_ctpg_script_importer.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERCTPGSCRIPTIMPORTER_H -#define SCRIPTOPTIONLINEPARSERCTPGSCRIPTIMPORTER_H 1 - -#include "javacontainer/script_options/distinct_script_set.h" -#include "javacontainer/script_options/keywords.h" -#include "exaudflib/swig/swig_meta_data.h" -#include "script_options_parser/ctpg/script_option_lines_ctpg.h" -#include - - -namespace SWIGVMContainers { - - struct SwigFactory; - -namespace JavaScriptOptions { - -namespace CTPG { - - - -class ScriptImporter { - - public: - ScriptImporter(SwigFactory & swigFactory, Keywords & keywords); - - void importScript(std::string & scriptCode, ExecutionGraph::OptionsLineParser::CTPG::options_map_t & options); - - private: - struct CollectedScript { - CollectedScript(CollectedScript&&) = default; - std::string script; - size_t origPos; - size_t origLen; - }; - - typedef ExecutionGraph::OptionsLineParser::CTPG::options_map_t::mapped_type OptionValues_t; - - void importScript(std::string & scriptCode, - ExecutionGraph::OptionsLineParser::CTPG::options_map_t & options, - const size_t recursionDepth); - const char* findImportScript(const std::string & scriptKey); - - void collectImportScripts(const OptionValues_t & option_values, - const size_t recursionDepth, - std::vector &result); - - void replaceImportScripts(std::string & scriptCode, - const std::vector &collectedImportScripts); - - DistinctScriptSet m_importedScripts; - SwigFactory & m_swigFactory; - std::unique_ptr m_metaData; - Keywords & m_keywords; - //The empirical maximal value for recursion depth is ~18000. So we add a little bit extra to have some buffer. - const size_t cMaxRecursionDepth = 10000U; -}; - -} //namespace CTPG - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPARSERCTPGSCRIPTIMPORTER_H diff --git a/exaudfclient/base/javacontainer/script_options/parser_legacy.cc b/exaudfclient/base/javacontainer/script_options/parser_legacy.cc deleted file mode 100644 index 3da5b93..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser_legacy.cc +++ /dev/null @@ -1,198 +0,0 @@ -#include "javacontainer/script_options/parser_legacy.h" -#include "javacontainer/script_options/distinct_script_set.h" -#include "script_options_parser/legacy/script_option_lines.h" -#include "exaudflib/swig/swig_meta_data.h" -#include "swig_factory/swig_factory.h" -#include "utils/exceptions.h" -#include "script_options_parser/exception.h" - -#include - - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -ScriptOptionLinesParserLegacy::ScriptOptionLinesParserLegacy(std::unique_ptr swigFactory) -: m_whitespace(" \t\f\v") -, m_lineend(";") -, m_scriptCode() -, m_keywords(true) -, m_swigFactory(std::move(swigFactory)) {} - -void ScriptOptionLinesParserLegacy::prepareScriptCode(const std::string & scriptCode) { - m_scriptCode = scriptCode; -} - -void ScriptOptionLinesParserLegacy::extractImportScripts() { - std::unique_ptr metaData; - // Attention: We must hash the parent script before modifying it (adding the - // package definition). Otherwise we don't recognize if the script imports its self - DistinctScriptSet importedScripts; - importedScripts.addScript(m_scriptCode.c_str()); - /* - The following while loop iteratively replaces import scripts in the script code. Each replacement is done in two steps: - 1. Remove the "%import ..." option in the script code - 2. Insert the new script code at the same location - It can happen that the imported scripts have again an "%import ..." option. - Those cases will be handled in the next iteration of the while loop, because the parser searches the options in - each iteration from the beginning of the (then modified) script code. - For example, lets assume the following Jave UDF, stored in member variable 'm_scriptCode': - %import other_script_A; - class MyJavaUdf { - static void run(ExaMetadata exa, ExaIterator ctx) throws Exception { - ctx.emit(\"Success!\");\n" - } - }; - and 'other_script_A' is defined as (which will be retrieved over SWIGMetadata.moduleContent()): - %import other_script_B; - class OtherClassA { - static void doSomething() { - } - }; - and other_script_B as: - %import other_script_A; - class OtherClassB { - static void doSomething() { - } - }; - The first iteration of the while loop would modify the member variable m_scriptCode to: - %import other_script_B; - class OtherClassA { - static void doSomething() { - } - }; - class MyJavaUdf { - static void run(ExaMetadata exa, ExaIterator ctx) throws Exception { - ctx.emit(\"Success!\");\n" - } - }; - The second iteration of the while loop would modify the member variable m_scriptCode to: - The first iteration of the while loop would modify the member variable m_scriptCode to: - %import other_script_A; - class OtherClassB { - static void doSomething() { - } - }; - class OtherClassA { - static void doSomething() { - } - }; - class MyJavaUdf { - static void run(ExaMetadata exa, ExaIterator ctx) throws Exception { - ctx.emit(\"Success!\");\n" - } - }; - The third iteration of the while loop would modify the member variable m_scriptCode to: - class OtherClassB { - static void doSomething() { - } - }; - class OtherClassA { - static void doSomething() { - } - }; - class MyJavaUdf { - static void run(ExaMetadata exa, ExaIterator ctx) throws Exception { - ctx.emit(\"Success!\");\n" - } - }; - because the content of "other_script_A" is already stored in the DistinctScriptSet, - and the parser only removes the script options keyword, but does not insert again the code of other_script_A. - The fourth iteration of the while loop would detect no further import option keywords and would break the loop. - */ - while (true) { - std::string newScript; - size_t scriptPos; - try { - parseForSingleOption(m_keywords.importKeyword(), - [&](const std::string& value, size_t pos){scriptPos = pos; newScript = value;}); - } catch (const ExecutionGraph::OptionParserException & ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1614"); - } - if (!newScript.empty()) { - if (!metaData) { - metaData.reset(m_swigFactory->makeSwigMetadata()); - if (!metaData) - throw std::runtime_error("F-UDF-CL-SL-JAVA-1615: Failure while importing scripts"); - } - const char *importScriptCode = metaData->moduleContent(newScript.c_str()); - const char *exception = metaData->checkException(); - if (exception) - throw std::runtime_error("F-UDF-CL-SL-JAVA-1616: " + std::string(exception)); - if (importedScripts.addScript(importScriptCode)) { - // Script has not been imported yet - // If this imported script contains %import statements - // they will be resolved in the next iteration of the while loop. - m_scriptCode.insert(scriptPos, importScriptCode); - } - } else { - break; - } - } -} - -void ScriptOptionLinesParserLegacy::parseForScriptClass(std::function callback) { - try { - parseForSingleOption(m_keywords.scriptClassKeyword(), - [&](const std::string& value, size_t pos){callback(value);}); - } catch (const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1610"); - } -} - -void ScriptOptionLinesParserLegacy::parseForJvmOptions(std::function callback) { - try { - parseForMultipleOptions(m_keywords.jvmKeyword(), - [&](const std::string& value, size_t pos){callback(value);}); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1612"); - } -} - -void ScriptOptionLinesParserLegacy::parseForExternalJars(std::function callback) { - try { - parseForMultipleOptions(m_keywords.jarKeyword(), - [&](const std::string& value, size_t pos){callback(value);}); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1613"); - } -} - -std::string && ScriptOptionLinesParserLegacy::getScriptCode() { - return std::move(m_scriptCode); -} - -void ScriptOptionLinesParserLegacy::parseForSingleOption(const std::string & keyword, - std::function callback) { - size_t pos; - try { - const std::string option = - ExecutionGraph::extractOptionLine(m_scriptCode, keyword, m_whitespace, m_lineend, pos); - if (option != "") { - callback(option, pos); - } - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1606"); - } -} - -void ScriptOptionLinesParserLegacy::parseForMultipleOptions(const std::string & keyword, - std::function callback) { - size_t pos; - while (true) { - try { - const std::string option = - ExecutionGraph::extractOptionLine(m_scriptCode, keyword, m_whitespace, m_lineend, pos); - if (option == "") - break; - callback(option, pos); - } catch(const ExecutionGraph::OptionParserException& ex) { - Utils::rethrow(ex, "F-UDF-CL-SL-JAVA-1607"); - } - } -} - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/parser_legacy.h b/exaudfclient/base/javacontainer/script_options/parser_legacy.h deleted file mode 100644 index 6159cff..0000000 --- a/exaudfclient/base/javacontainer/script_options/parser_legacy.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERLEGACY_H -#define SCRIPTOPTIONLINEPARSERLEGACY_H 1 - - -#include "javacontainer/script_options/parser.h" -#include "javacontainer/script_options/keywords.h" - -#include - -namespace SWIGVMContainers { - -struct SwigFactory; - -namespace JavaScriptOptions { - -class ScriptOptionLinesParserLegacy : public ScriptOptionsParser { - - public: - ScriptOptionLinesParserLegacy(std::unique_ptr swigFactory); - - virtual ~ScriptOptionLinesParserLegacy() {}; - - void prepareScriptCode(const std::string & scriptCode) override; - - void parseForScriptClass(std::function callback) override; - - void parseForJvmOptions(std::function callback) override; - - void parseForExternalJars(std::function callback) override; - - void extractImportScripts() override; - - std::string && getScriptCode() override; - - private: - void parseForSingleOption(const std::string& key, - std::function callback); - void parseForMultipleOptions(const std::string& key, - std::function callback); - - private: - const std::string m_whitespace; - const std::string m_lineend; - std::string m_scriptCode; - Keywords m_keywords; - std::unique_ptr m_swigFactory; -}; - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - - -#endif //SCRIPTOPTIONLINEPARSERLEGACY_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/string_ops.cc b/exaudfclient/base/javacontainer/script_options/string_ops.cc deleted file mode 100644 index d6d6d89..0000000 --- a/exaudfclient/base/javacontainer/script_options/string_ops.cc +++ /dev/null @@ -1,79 +0,0 @@ -#include "javacontainer/script_options/string_ops.h" -#include -#include -#include - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -namespace StringOps { - -inline uint32_t countBackslashesBackwards(const std::string & s, size_t pos) { - uint32_t retVal(0); - while (pos >= 0 && s.at(pos--) == '\\') retVal++; - return retVal; -} - -inline size_t replaceOnlyBackslashSequencesButKeepChar(std::string & s, size_t backslashStartIdx, size_t nBackslashes) { - const uint32_t nHalfBackslashes = (nBackslashes>>1); - if (nHalfBackslashes > 0) { - s = s.erase(backslashStartIdx, nHalfBackslashes ); - } - const size_t newBackslashEndIdx = backslashStartIdx + nHalfBackslashes; - return newBackslashEndIdx + 1; //+1 because of the last None-Whitespace character we need to keep -} - -inline size_t replaceBackslashSequencesAndWhitespaceSequence(std::string & s, size_t backslashStartIdx, - size_t nBackslashes, const char* replacement) { - const uint32_t nHalfBackslashes = (nBackslashes>>1); - s = s.erase(backslashStartIdx, nHalfBackslashes+1 ); //Delete also backslash of whitespace escape sequence - const size_t newBackslashEndIdx = backslashStartIdx + nHalfBackslashes; - s = s.replace(newBackslashEndIdx, 1, replacement); - return newBackslashEndIdx + 1; //+1 because of the replaced whitespace character -} - -inline size_t replaceCharAtPositionAndBackslashes(std::string & s, size_t pos, const char* replacement) { - const size_t nBackslashes = (pos > 0) ? countBackslashesBackwards(s, pos-1) : 0; - - const size_t backslashStartIdx = pos-nBackslashes; - if(nBackslashes % 2 == 0) { - return replaceOnlyBackslashSequencesButKeepChar(s, backslashStartIdx, nBackslashes); - } - else { - return replaceBackslashSequencesAndWhitespaceSequence(s, backslashStartIdx, nBackslashes, replacement); - } -} - -void replaceTrailingEscapeWhitespaces(std::string & s) { - if (s.size() > 0) { - const size_t lastNoneWhitespaceIdx = s.find_last_not_of(" \t\v\f"); - if (lastNoneWhitespaceIdx != std::string::npos) { - size_t firstWhitespaceAfterNoneWhitespaceIdx = lastNoneWhitespaceIdx + 1; - if (s.size() > 1) { - if(s[lastNoneWhitespaceIdx] == 't') { - firstWhitespaceAfterNoneWhitespaceIdx = replaceCharAtPositionAndBackslashes(s, lastNoneWhitespaceIdx, "\t"); - } else if (s[lastNoneWhitespaceIdx] == '\\' && lastNoneWhitespaceIdx < (s.size() - 1) && s.at(lastNoneWhitespaceIdx+1) == ' ') { - firstWhitespaceAfterNoneWhitespaceIdx = replaceCharAtPositionAndBackslashes(s, lastNoneWhitespaceIdx+1, " "); - } else if (s[lastNoneWhitespaceIdx] == 'f') { - firstWhitespaceAfterNoneWhitespaceIdx = replaceCharAtPositionAndBackslashes(s, lastNoneWhitespaceIdx, "\f"); - } else if (s[lastNoneWhitespaceIdx] == 'v') { - firstWhitespaceAfterNoneWhitespaceIdx = replaceCharAtPositionAndBackslashes(s, lastNoneWhitespaceIdx, "\v"); - } - } - if (firstWhitespaceAfterNoneWhitespaceIdx != std::string::npos && - firstWhitespaceAfterNoneWhitespaceIdx < s.size()) { - s = s.substr(0, firstWhitespaceAfterNoneWhitespaceIdx); //Right Trim the string - } - } else { - s = ""; - } - } -} - -} //namespace StringOps - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers diff --git a/exaudfclient/base/javacontainer/script_options/string_ops.h b/exaudfclient/base/javacontainer/script_options/string_ops.h deleted file mode 100644 index 7da1e53..0000000 --- a/exaudfclient/base/javacontainer/script_options/string_ops.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef SCRIPTOPTIONLINEPARSERSTRINGOPS_H -#define SCRIPTOPTIONLINEPARSERSTRINGOPS_H 1 - -#include -#include - - - -namespace SWIGVMContainers { - -namespace JavaScriptOptions { - -namespace StringOps { - -//Following code is based on https://stackoverflow.com/a/217605 - -inline void ltrim(std::string &s) { - s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { - return !std::isspace(ch); - })); -} - -inline void rtrim(std::string &s) { - s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { - return !std::isspace(ch); - }).base(), s.end()); -} - -inline void trim(std::string &s) { - ltrim(s); - rtrim(s); -} - -void replaceTrailingEscapeWhitespaces(std::string & s); - -} //namespace StringOps - - -} //namespace JavaScriptOptions - -} //namespace SWIGVMContainers - -#endif //SCRIPTOPTIONLINEPARSERSTRINGOPS_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/test/BUILD b/exaudfclient/base/javacontainer/script_options/test/BUILD deleted file mode 100644 index 76f9bf6..0000000 --- a/exaudfclient/base/javacontainer/script_options/test/BUILD +++ /dev/null @@ -1,10 +0,0 @@ - -cc_test( - name = "java-script-options-tests", - srcs = ["ctpg_script_importer_test.cc", "swig_factory_test.cc", - "swig_factory_test.h", "string_ops_tests.cc", "converter_test.cc"], - deps = [ - "//javacontainer/script_options:java_script_option_lines", - "@googletest//:gtest_main", - ], -) diff --git a/exaudfclient/base/javacontainer/script_options/test/converter_test.cc b/exaudfclient/base/javacontainer/script_options/test/converter_test.cc deleted file mode 100644 index ba640e7..0000000 --- a/exaudfclient/base/javacontainer/script_options/test/converter_test.cc +++ /dev/null @@ -1,92 +0,0 @@ - -#include "include/gtest/gtest.h" -#include "gmock/gmock.h" -#include "javacontainer/script_options/converter_legacy.h" -#include "javacontainer/script_options/converter_v2.h" - -using namespace SWIGVMContainers::JavaScriptOptions; - - -class LegacyConverterJarTest : public ::testing::TestWithParam>> {}; - -TEST_P(LegacyConverterJarTest, jar) { - const std::pair> option_value = GetParam(); - const std::string jar_option_value = option_value.first; - - ConverterLegacy converter; - converter.convertExternalJar(option_value.first); - std::vector result; - converter.iterateJarPaths([&](auto jar) {result.push_back(jar);}); - ASSERT_EQ(result, option_value.second); -} - -const std::vector>> jar_strings = - { - std::make_pair("test.jar:test2.jar", std::vector({"test.jar", "test2.jar"})), //basic splitting - std::make_pair("test.jar:test.jar", std::vector({"test.jar"})), //filter duplicates - std::make_pair("testDEF.jar:testABC.jar", std::vector({"testABC.jar", "testDEF.jar"})), //alphabetical order - }; - -INSTANTIATE_TEST_SUITE_P( - Converter, - LegacyConverterJarTest, - ::testing::ValuesIn(jar_strings) -); - - - -class ConverterV2JarTest : public ::testing::TestWithParam>> {}; - -TEST_P(ConverterV2JarTest, jar) { - const std::pair> option_value = GetParam(); - const std::string jar_option_value = option_value.first; - - ConverterV2 converter; - converter.convertExternalJar(option_value.first); - std::vector result; - converter.iterateJarPaths([&](auto jar) {result.push_back(jar);}); - ASSERT_EQ(result, option_value.second); -} - -const std::vector>> jar_strings_v2 = - { - std::make_pair("test.jar:test2.jar", std::vector({"test.jar", "test2.jar"})), //basic splitting - std::make_pair("test.jar:test.jar", std::vector({"test.jar", "test.jar"})), //keep duplicates - std::make_pair("testDEF.jar:testABC.jar", std::vector({"testDEF.jar", "testABC.jar"})), //maintain order - }; - -INSTANTIATE_TEST_SUITE_P( - Converter, - ConverterV2JarTest, - ::testing::ValuesIn(jar_strings_v2) -); - -class ConverterV2JvmOptionsTest : public ::testing::TestWithParam>> {}; - -TEST_P(ConverterV2JvmOptionsTest, jvm_option) { - const std::pair> option_value = GetParam(); - const std::string jvm_option_value = option_value.first; - - ConverterV2 converter; - converter.convertJvmOption(option_value.first); - std::vector result = std::move(converter.moveJvmOptions()); - ASSERT_EQ(result, option_value.second); -} - -const std::vector>> jvm_options_strings_v2 = - { - std::make_pair("optionA=abc optionB=def", std::vector({"optionA=abc", "optionB=def"})), - std::make_pair("optionA=abc\\ def optionB=ghi", std::vector({"optionA=abc def", "optionB=ghi"})), - std::make_pair("optionA=abc\\tdef optionB=ghi", std::vector({"optionA=abc\tdef", "optionB=ghi"})), - std::make_pair(" optionA=abc\\tdef optionB=ghi", std::vector({"optionA=abc\tdef", "optionB=ghi"})), - std::make_pair(" optionA=abc\\tdef\\\\\t\t optionB=ghi", std::vector({"optionA=abc\tdef\\", "optionB=ghi"})), - std::make_pair(" optionA=abc\\tdef\\\\\\t\\t optionB=ghi", std::vector({"optionA=abc\tdef\\\t\t", "optionB=ghi"})), - std::make_pair(" optionA=abc\\tdef\\\\\\t\\t optionB=ghi ", std::vector({"optionA=abc\tdef\\\t\t", "optionB=ghi"})), - std::make_pair(" optionA=abc\\tdef\\\\\\t\\t optionB=ghi\\ \\t ", std::vector({"optionA=abc\tdef\\\t\t", "optionB=ghi \t"})) - }; - -INSTANTIATE_TEST_SUITE_P( - Converter, - ConverterV2JvmOptionsTest, - ::testing::ValuesIn(jvm_options_strings_v2) -); diff --git a/exaudfclient/base/javacontainer/script_options/test/ctpg_script_importer_test.cc b/exaudfclient/base/javacontainer/script_options/test/ctpg_script_importer_test.cc deleted file mode 100644 index 1efbadc..0000000 --- a/exaudfclient/base/javacontainer/script_options/test/ctpg_script_importer_test.cc +++ /dev/null @@ -1,66 +0,0 @@ - -#include "include/gtest/gtest.h" -#include "gmock/gmock.h" -#include "javacontainer/script_options/parser_ctpg.h" - -#include "javacontainer/script_options/test/swig_factory_test.h" -#include - -using namespace SWIGVMContainers::JavaScriptOptions; - - -static const char* sc_scriptName = "script"; - - -void checkIndex(size_t currentIdx, const char* scriptKey) { - std::stringstream ss; - ss << sc_scriptName << currentIdx; - if (ss.str() != scriptKey) { - throw std::logic_error(std::string("Script Key does not match: '") + ss.str() + " != '" + scriptKey + "'"); - } -} - -const char* buildNewScriptCode(size_t currentIdx) { - std::stringstream ss; - ss << "%import " << sc_scriptName << currentIdx << ";something"; - static std::string ret; - ret = ss.str(); - return ret.c_str(); -} - -TEST(ScriptImporterTest, max_recursion_depth) { - /** - This test checks that running an infinite recursion of the script import will result in the expected exception. - For that, the test creates new "import scripts" on the fly: - Whenever the parser finds a new 'import script' option, - it calls SWIGVMContainers::SWIGMetadataIf::moduleContent(). - The mocked implementation redirects this request to `buildNewScriptCode()` which creates a - new dummy import script with another '%import ...` option. - */ - - size_t currentIdx = 0; - std::unique_ptr swigFactory = - std::make_unique([&](const char* scriptKey) { - checkIndex(currentIdx, scriptKey); - return buildNewScriptCode(++currentIdx); - }); - ScriptOptionLinesParserCTPG parser(std::move(swigFactory)); - - const std::string code = buildNewScriptCode(currentIdx); - parser.prepareScriptCode(code); - EXPECT_THROW({ - try - { - parser.extractImportScripts(); - } - catch( const std::runtime_error& e ) - { - //We need to deceive "find_duplicate_error_codes.sh" here - const std::string expectedError = - std::string("F-UDF-CL-SL-JAVA-") + "1633: Maximal recursion depth for importing scripts reached."; - EXPECT_STREQ( expectedError.c_str(), e.what()); - throw; - } - }, std::runtime_error ); -} - diff --git a/exaudfclient/base/javacontainer/script_options/test/string_ops_tests.cc b/exaudfclient/base/javacontainer/script_options/test/string_ops_tests.cc deleted file mode 100644 index 9615212..0000000 --- a/exaudfclient/base/javacontainer/script_options/test/string_ops_tests.cc +++ /dev/null @@ -1,59 +0,0 @@ - -#include "include/gtest/gtest.h" -#include "gmock/gmock.h" -#include "javacontainer/script_options/string_ops.h" - -using namespace SWIGVMContainers::JavaScriptOptions; - - - - -TEST(StringOpsTest, trim) { - std::string sample = " \tHello World \t"; - StringOps::trim(sample); - EXPECT_EQ(sample, "Hello World"); -} - -TEST(StringOpsTest, trimWithNoneASCII) { - /* - Test that trim works correctly with None-ASCII characters - \xa0's bit sequence is '1010 0000', while space bit sequence '0010 0000'. - If StringOps::trim() would not work correctly with characters where MSB is set, it would interpret \xa0 as space. - */ - std::string sample = " \t\xa0Hello World\xa0 \t"; - StringOps::trim(sample); - EXPECT_EQ(sample, "\xa0Hello World\xa0"); -} - -class ReplaceTrailingEscapeWhitespacesTest : public ::testing::TestWithParam> {}; - -TEST_P(ReplaceTrailingEscapeWhitespacesTest, s) { - const std::pair underTest = GetParam(); - - std::string str = underTest.first; - StringOps::replaceTrailingEscapeWhitespaces(str); - ASSERT_EQ(str, underTest.second); -} - -const std::vector> replace_trailing_escape_whitespaces_strings = - { - std::make_pair("hello world", std::string("hello world")), - std::make_pair("hello world ", std::string("hello world")), - std::make_pair("hello world\\t", std::string("hello world\t")), - std::make_pair("hello world\\f", std::string("hello world\f")), - std::make_pair("hello world\\v", std::string("hello world\v")), - std::make_pair("hello world\\\\t", std::string("hello world\\t")), - std::make_pair("hello world\\\\t\t", std::string("hello world\\t")), - std::make_pair("hello world\\\\\\t\t", std::string("hello world\\\t")), - std::make_pair("hello world\\\\\\\\t\t", std::string("hello world\\\\t")), - std::make_pair("hello worl\td\\\\\\\\t\t", std::string("hello worl\td\\\\t")), - std::make_pair("t\t ", std::string("t")), - std::make_pair("hello worl\td\\\\\\\\", std::string("hello worl\td\\\\\\\\")), //If no whitespace escape sequence, backslashes are not interpreted as backslash escape sequence - }; - - -INSTANTIATE_TEST_SUITE_P( - StringOpsTest, - ReplaceTrailingEscapeWhitespacesTest, - ::testing::ValuesIn(replace_trailing_escape_whitespaces_strings) -); \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/script_options/test/swig_factory_test.cc b/exaudfclient/base/javacontainer/script_options/test/swig_factory_test.cc deleted file mode 100644 index adca665..0000000 --- a/exaudfclient/base/javacontainer/script_options/test/swig_factory_test.cc +++ /dev/null @@ -1,105 +0,0 @@ -#include "javacontainer/script_options/test/swig_factory_test.h" -#include "exaudflib/swig/swig_meta_data.h" - -#include - -class NotImplemented : public std::logic_error -{ -public: - NotImplemented() : std::logic_error("Function not yet implemented") { }; - NotImplemented(const std::string funcName) : std::logic_error("Function " + funcName + " not yet implemented") { }; -}; - -class SWIGMetadataTest : public SWIGVMContainers::SWIGMetadataIf { - -public: - SWIGMetadataTest(std::function callback): m_callback(callback) {} - virtual const char* databaseName() { throw NotImplemented("databaseName"); return nullptr;} - virtual const char* databaseVersion() { throw NotImplemented("databaseVersion"); return nullptr;} - virtual const char* scriptName() { throw NotImplemented("scriptName"); return nullptr;} - virtual const char* scriptSchema() { throw NotImplemented("scriptSchema"); return nullptr;} - virtual const char* currentUser() { throw NotImplemented("currentUser"); return nullptr;} - virtual const char* scopeUser() { throw NotImplemented("scopeUser"); return nullptr;} - virtual const char* currentSchema() { throw NotImplemented("currentSchema"); return nullptr;} - virtual const char* scriptCode() { throw NotImplemented("scriptCode"); return nullptr;} - virtual const unsigned long long sessionID() { throw NotImplemented("sessionID"); return 0;} - virtual const char *sessionID_S() { throw NotImplemented("sessionID_S"); return nullptr;} - virtual const unsigned long statementID() { throw NotImplemented("statementID"); return 0;} - virtual const unsigned int nodeCount() { throw NotImplemented("nodeCount"); return 0;} - virtual const unsigned int nodeID() { throw NotImplemented("nodeID"); return 0;} - virtual const unsigned long long vmID() { throw NotImplemented("vmID"); return 0;} - virtual const unsigned long long memoryLimit() { throw NotImplemented("memoryLimit"); return 0;} - virtual const SWIGVMContainers::VMTYPE vmType() { - throw NotImplemented("vmType"); - return SWIGVMContainers::VM_UNSUPPORTED; - } - virtual const char *vmID_S() { throw NotImplemented("vmID_S"); return nullptr;} - virtual const ExecutionGraph::ConnectionInformationWrapper* connectionInformation(const char* connection_name) { - throw NotImplemented("connectionInformation"); return nullptr; - } - virtual const char* moduleContent(const char* name) { - return m_callback(name); - } - virtual const unsigned int inputColumnCount() { throw NotImplemented("inputColumnCount"); return 0;} - virtual const char *inputColumnName(unsigned int col) { - throw NotImplemented("inputColumnName"); - return nullptr; - } - virtual const SWIGVMContainers::SWIGVM_datatype_e inputColumnType(unsigned int col) { - throw NotImplemented("inputColumnType"); - return SWIGVMContainers::UNSUPPORTED; - } - virtual const char *inputColumnTypeName(unsigned int col) { - throw NotImplemented("inputColumnTypeName"); return nullptr; - } - virtual const unsigned int inputColumnSize(unsigned int col) { - throw NotImplemented("inputColumnSize"); return 0; - } - virtual const unsigned int inputColumnPrecision(unsigned int col) { - throw NotImplemented("inputColumnPrecision"); return 0; - } - virtual const unsigned int inputColumnScale(unsigned int col) { - throw NotImplemented("inputColumnScale"); return 0; - } - virtual const SWIGVMContainers::SWIGVM_itertype_e inputType() { - throw NotImplemented("inputType"); - return SWIGVMContainers::EXACTLY_ONCE; - } - virtual const unsigned int outputColumnCount() { throw NotImplemented("outputColumnCount"); return 0;} - virtual const char *outputColumnName(unsigned int col) { throw NotImplemented("outputColumnName"); return nullptr;} - virtual const SWIGVMContainers::SWIGVM_datatype_e outputColumnType(unsigned int col) { - throw NotImplemented("outputColumnType"); - return SWIGVMContainers::UNSUPPORTED; - } - virtual const char *outputColumnTypeName(unsigned int col) { - throw NotImplemented("outputColumnTypeName"); return nullptr; - } - virtual const unsigned int outputColumnSize(unsigned int col) { - throw NotImplemented("outputColumnSize"); return 0; - } - virtual const unsigned int outputColumnPrecision(unsigned int col) { - throw NotImplemented("outputColumnPrecision"); return 0; - } - virtual const unsigned int outputColumnScale(unsigned int col) { - throw NotImplemented("outputColumnScale"); return 0; - } - virtual const SWIGVMContainers::SWIGVM_itertype_e outputType() { - throw NotImplemented("outputType"); - return SWIGVMContainers::EXACTLY_ONCE; - } - virtual const bool isEmittedColumn(unsigned int col) { throw NotImplemented("isEmittedColumn"); return false;} - virtual const char* checkException() { return nullptr;} - virtual const char* pluginLanguageName() { throw NotImplemented("pluginLanguageName"); return nullptr;} - virtual const char* pluginURI() { throw NotImplemented("pluginURI"); return nullptr;} - virtual const char* outputAddress() { throw NotImplemented("outputAddress"); return nullptr;} - -private: - std::function m_callback; -}; - -SwigFactoryTestImpl::SwigFactoryTestImpl(std::function callback) -: m_callback(callback) {} - -SWIGVMContainers::SWIGMetadataIf* SwigFactoryTestImpl::makeSwigMetadata() { - return new SWIGMetadataTest(m_callback); -} diff --git a/exaudfclient/base/javacontainer/script_options/test/swig_factory_test.h b/exaudfclient/base/javacontainer/script_options/test/swig_factory_test.h deleted file mode 100644 index b98f144..0000000 --- a/exaudfclient/base/javacontainer/script_options/test/swig_factory_test.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef SWIG_FACTORY_TEST_H -#define SWIG_FACTORY_TEST_H 1 - -#include -#include -#include "swig_factory/swig_factory.h" -#include - -struct SwigFactoryTestImpl : public SWIGVMContainers::SwigFactory { - - SwigFactoryTestImpl(std::function callback); - - virtual SWIGVMContainers::SWIGMetadataIf* makeSwigMetadata() override; - -private: - std::function m_callback; -}; - - -#endif //namespace SWIG_FACTORY_TEST_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/test/BUILD b/exaudfclient/base/javacontainer/test/BUILD deleted file mode 100644 index 69ff84f..0000000 --- a/exaudfclient/base/javacontainer/test/BUILD +++ /dev/null @@ -1,60 +0,0 @@ -java_library( - name = "ExaStackTraceCleaner", - srcs = ["//javacontainer:ExaStackTraceCleaner.java"] -) - -java_test( - name = "ExaStackTraceCleanerTest", - srcs = ["java/com/exasol/ExaStackTraceCleanerTest.java"], - size = "small", - deps = [":ExaStackTraceCleaner"] -) - -JAVACONTAINER_TEST_SRCS = ["cpp/javacontainer_test.cc", "cpp/exaudf_wrapper.cc", "cpp/javavm_test.cc", "cpp/javavm_test.h", - "cpp/swig_factory_test.h", "cpp/swig_factory_test.cc"] - -JAVACONTAINER_PERF_TEST_SRCS = ["cpp/javacontainer_perf_test.cc", "cpp/exaudf_wrapper.cc", "cpp/javavm_test.cc", "cpp/javavm_test.h", - "cpp/swig_factory_test.h", "cpp/swig_factory_test.cc"] - -cc_test( - name = "javacontainer-test-extractor-legacy", - srcs = JAVACONTAINER_TEST_SRCS, - deps = [ - "//javacontainer:javacontainer", - "@googletest//:gtest_main", - ], - data = ["test.jar", "other_test.jar"] -) - -cc_test( - name = "javacontainer-test-extractor-v2", - srcs = JAVACONTAINER_TEST_SRCS + ["cpp/javacontainer_extractor_v2_test.cc"], - deps = [ - "//javacontainer:javacontainer", - "@googletest//:gtest_main", - ], - defines = ["USE_EXTRACTOR_V2"], - data = ["test.jar", "other_test.jar"] -) - - -cc_test( - name = "javacontainer-perf-test-legacy-parser", - srcs = JAVACONTAINER_PERF_TEST_SRCS, - deps = [ - "//javacontainer:javacontainer", - "@googletest//:gtest_main", - ], - data = ["test.jar", "other_test.jar"] -) - -cc_test( - name = "javacontainer-perf-test-ctpg-parser", - srcs = JAVACONTAINER_PERF_TEST_SRCS, - deps = [ - "//javacontainer:javacontainer", - "@googletest//:gtest_main", - ], - defines = ["USE_EXTRACTOR_V2"], - data = ["test.jar", "other_test.jar"] -) diff --git a/exaudfclient/base/javacontainer/test/cpp/exaudf_wrapper.cc b/exaudfclient/base/javacontainer/test/cpp/exaudf_wrapper.cc deleted file mode 100644 index 274c19b..0000000 --- a/exaudfclient/base/javacontainer/test/cpp/exaudf_wrapper.cc +++ /dev/null @@ -1,12 +0,0 @@ -#include "exaudflib/swig/swig_common.h" - -//Dummy implementation to calm down the linker -void* load_dynamic(const char* name) { - return nullptr; -} - -//Globalinstance of the SWIGVM_params which we used to communicate with JavaVMImpl; -namespace SWIGVMContainers { -SWIGVM_params_t gSWIGVM_params_t; -__thread SWIGVM_params_t * SWIGVM_params = &gSWIGVM_params_t; -} \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/test/cpp/javacontainer_extractor_v2_test.cc b/exaudfclient/base/javacontainer/test/cpp/javacontainer_extractor_v2_test.cc deleted file mode 100644 index 3f5308e..0000000 --- a/exaudfclient/base/javacontainer/test/cpp/javacontainer_extractor_v2_test.cc +++ /dev/null @@ -1,133 +0,0 @@ - -#include "include/gtest/gtest.h" -#include "gmock/gmock.h" -#include "javacontainer/test/cpp/javavm_test.h" -#include "javacontainer/test/cpp/swig_factory_test.h" -#include "javacontainer/javacontainer.h" -#include -#include - -using ::testing::MatchesRegex; - -class JavaContainerEscapeSequenceTest : public ::testing::TestWithParam> {}; - -TEST_P(JavaContainerEscapeSequenceTest, quoted_jvm_option) { -const std::pair option_value = GetParam(); - const std::string script_code = - "%jvmoption " + option_value.first + ";\n\n" - "class JVMOPTION_TEST_WITH_SPACE {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - JavaVMTest vm(script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n\n\n" - "class JVMOPTION_TEST_WITH_SPACE {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(expected_script_code, vm.getJavaVMInternalStatus().m_scriptCode); - EXPECT_EQ("/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", vm.getJavaVMInternalStatus().m_exaJarPath); - EXPECT_EQ("/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", vm.getJavaVMInternalStatus().m_classpath); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - - const std::vector expectedJVMOptions = { option_value.second, "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(expectedJVMOptions, vm.getJavaVMInternalStatus().m_jvmOptions); -} - -const std::vector> escape_sequences = - { - std::make_pair("-Dhttp.agent=ABC\\nDEF", "-Dhttp.agent=ABC\nDEF"), - std::make_pair("-Dhttp.agent=ABC\\rDEF", "-Dhttp.agent=ABC\rDEF"), - std::make_pair("-Dhttp.agent=ABC\\;DEF", "-Dhttp.agent=ABC;DEF"), - std::make_pair("-Dhttp.agent=ABC\\aDEF", "-Dhttp.agent=ABC\\aDEF"), //any other escape sequence must stay as is - std::make_pair("\\n-Dhttp.agent=ABCDEF", "\n-Dhttp.agent=ABCDEF"), - std::make_pair("\\r-Dhttp.agent=ABCDEF", "\r-Dhttp.agent=ABCDEF"), - std::make_pair("\\;-Dhttp.agent=ABCDEF", ";-Dhttp.agent=ABCDEF"), - std::make_pair("-Dhttp.agent=ABCDEF\\n", "-Dhttp.agent=ABCDEF\n"), - std::make_pair("-Dhttp.agent=ABCDEF\\r", "-Dhttp.agent=ABCDEF\r"), - std::make_pair("-Dhttp.agent=ABCDEF\\;", "-Dhttp.agent=ABCDEF;"), - std::make_pair("\\ -Dhttp.agent=ABCDEF", "-Dhttp.agent=ABCDEF"), - std::make_pair("\\t-Dhttp.agent=ABCDEF", "-Dhttp.agent=ABCDEF"), - std::make_pair("\\f-Dhttp.agent=ABCDEF", "-Dhttp.agent=ABCDEF"), - std::make_pair("\\v-Dhttp.agent=ABCDEF", "-Dhttp.agent=ABCDEF"), - std::make_pair("\\v-Dhttp.agent=ABC\\tDEF", "-Dhttp.agent=ABC\tDEF"), - std::make_pair("\\v-Dhttp.agent=ABC\\ DEF", "-Dhttp.agent=ABC DEF"), - std::make_pair("\\v-Dhttp.agent=ABC\\fDEF", "-Dhttp.agent=ABC\fDEF"), - std::make_pair("\\v-Dhttp.agent=ABC\\vDEF", "-Dhttp.agent=ABC\vDEF"), - std::make_pair("\\v-Dhttp.agent=\"ABC\\tDEF\"", "-Dhttp.agent=\"ABC\tDEF\"") - }; - -INSTANTIATE_TEST_SUITE_P( - JavaContainer, - JavaContainerEscapeSequenceTest, - ::testing::ValuesIn(escape_sequences) -); - -TEST(JavaContainer, import_script_with_escaped_options) { - const std::string script_code = - "%import other_script;\n\n" - "%jvmoption -Dsomeoption=\"ABC\";\n\n" - "%scriptclass com.exasol.udf_profiling.UdfProfiler;\n" - "%jar javacontainer/test/test.jar;" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - std::unique_ptr swigFactory = std::make_unique(); - - const std::string other_script_code = - "%jvmoption -Dsomeotheroption=\"DE\\nF\";\n\n" - "%jar javacontainer/test/other_test.jar;" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script", other_script_code); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n\n\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/other_test.jar:javacontainer/test/test.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dexasol.scriptclass=com.exasol.udf_profiling.UdfProfiler", - "-Dsomeotheroption=\"DE\nF\"", "-Dsomeoption=\"ABC\"", "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/other_test.jar:javacontainer/test/test.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, basic_jar_with_trailing_escape) { - const std::string script_code = "%scriptclass com.exasol.udf_profiling.UdfProfiler;\n" - "%jar javacontainer/test/test.jar\\t\t;"; - EXPECT_THROW({ - try - { - JavaVMTest vm(script_code); - } - catch( const SWIGVMContainers::JavaVMach::exception& e ) - { - EXPECT_THAT( e.what(), MatchesRegex("^.*Java VM cannot find 'javacontainer/test/test\\.jar\t': No such file or directory$")); - throw; - } - }, SWIGVMContainers::JavaVMach::exception ); -} diff --git a/exaudfclient/base/javacontainer/test/cpp/javacontainer_perf_test.cc b/exaudfclient/base/javacontainer/test/cpp/javacontainer_perf_test.cc deleted file mode 100644 index b116241..0000000 --- a/exaudfclient/base/javacontainer/test/cpp/javacontainer_perf_test.cc +++ /dev/null @@ -1,58 +0,0 @@ -#include "include/gtest/gtest.h" -#include "gmock/gmock.h" -#include "javacontainer/test/cpp/javavm_test.h" -#include "javacontainer/test/cpp/swig_factory_test.h" -#include - -const uint32_t NumInlineJavaLines = 500000; -const uint32_t NumInlineJavaWordsPerLine = 100; - - -TEST(JavaContainerPerformance, large_inline_java_udf_test) { - std::string script_code = - "%jvmoption option1=abc;\n" - "%jvmoption option2=def;\n" - "class JVMOPTION_TEST_WITH_SPACE {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n"; - - for (uint32_t idxLine(0); idxLine < NumInlineJavaLines; ++idxLine) { - for (uint32_t idxWord(0); idxWord < NumInlineJavaWordsPerLine; ++idxWord) - script_code.append("somecode "); - script_code.append("\n"); - } - script_code.append(" }\n}\n"); - JavaVMTest vm(script_code); -} - -TEST(JavaContainerPerformance, large_inline_single_line_full_java_udf_test) { - std::string script_code = - "%jvmoption option1=abc;" - "%jvmoption option2=def;" - "class JVMOPTION_TEST_WITH_SPACE {" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {"; - - for (uint32_t idxLine(0); idxLine < NumInlineJavaLines; ++idxLine) { - for (uint32_t idxWord(0); idxWord < NumInlineJavaWordsPerLine; ++idxWord) - script_code.append("somecode "); - - } - script_code.append(" }}"); - JavaVMTest vm(script_code); -} - -TEST(JavaContainerPerformance, large_inline_single_line_slim_java_udf_test) { - std::string script_code = - "%jvmoption option1=abc;" - "%jvmoption option2=def;" - "class JVMOPTION_TEST_WITH_SPACE {" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {"; - - for (uint32_t idxLine(0); idxLine < NumInlineJavaLines / 10; ++idxLine) { - for (uint32_t idxWord(0); idxWord < NumInlineJavaWordsPerLine / 10; ++idxWord) - script_code.append("someco%de ; \\t"); - - } - script_code.append(" }}"); - JavaVMTest vm(script_code); -} - diff --git a/exaudfclient/base/javacontainer/test/cpp/javacontainer_test.cc b/exaudfclient/base/javacontainer/test/cpp/javacontainer_test.cc deleted file mode 100644 index aad470e..0000000 --- a/exaudfclient/base/javacontainer/test/cpp/javacontainer_test.cc +++ /dev/null @@ -1,609 +0,0 @@ - -#include "include/gtest/gtest.h" -#include "gmock/gmock.h" -#include "javacontainer/test/cpp/javavm_test.h" -#include "javacontainer/javacontainer.h" -#include "javacontainer/test/cpp/swig_factory_test.h" -#include - -using ::testing::MatchesRegex; - - -TEST(JavaContainer, basic_jar) { - const std::string script_code = "%scriptclass com.exasol.udf_profiling.UdfProfiler;\n" - "%jar javacontainer/test/test.jar;"; - JavaVMTest vm(script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, "\n"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/test.jar"); - EXPECT_FALSE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dexasol.scriptclass=com.exasol.udf_profiling.UdfProfiler", - "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/test.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, basic_jar_script_class_with_white_spaces) { - const std::string script_code = "%scriptclass com.exasol.udf_profiling.UdfProfiler\t ;\n" - "%jar javacontainer/test/test.jar;"; - JavaVMTest vm(script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, "\n"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/test.jar"); - EXPECT_FALSE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dexasol.scriptclass=com.exasol.udf_profiling.UdfProfiler", - "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/test.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - - -TEST(JavaContainer, basic_jar_with_white_spaces) { - const std::string script_code = "%jar javacontainer/test/test.jar \t ;"; - - JavaVMTest vm(script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/test.jar"); -} - -TEST(JavaContainer, basic_jars_ordering) { - /* - * This test validates correct behavior of collecting the %jar options in Extractor V1/V2. - * Both jar files referenced in `script_code` do not exist. - * The JavaVM will throw an exception with the first JAR file it gets from Extractor. - * For extractor V1: Our assumption is that the exception will be for `base/javacontainer/test/abc.jar` - * as this is alphabetically the first JAR file. (re-ordering) - * For extractor V2: Our assumption is that the exception will be for `base/javacontainer/test/test1.jar` - * as this is the first JAR file. (no re-ordering) - */ - const std::string script_code = "%jar javacontainer/test/test1.jar:javacontainer/test/abc.jar;"; - -#ifndef USE_EXTRACTOR_V2 - const char* regexExpectedException = "^.*Java VM cannot find 'javacontainer/test/abc\\.jar': No such file or directory$"; -#else - const char* regexExpectedException = "^.*Java VM cannot find 'javacontainer/test/test1\\.jar': No such file or directory$"; -#endif - EXPECT_THROW({ - try - { - JavaVMTest vm(script_code); - } - catch( const SWIGVMContainers::JavaVMach::exception& e ) - { - EXPECT_THAT( e.what(), MatchesRegex(regexExpectedException)); - throw; - } - }, SWIGVMContainers::JavaVMach::exception ); -} - -TEST(JavaContainer, basic_inline) { - const std::string script_code = "import java.time.LocalDateTime;" - "import java.time.ZoneOffset;" - "import java.time.format.DateTimeFormatter;" - "class SIMPLE {" - "static void main(String[] args) {" - "int i = 0;" - "}" - "static int run(ExaMetadata exa, ExaIterator ctx) {" - "return 0;" - "}" - "}"; - JavaVMTest vm(script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = std::string("package com.exasol;\r\n") + script_code; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - - - -TEST(JavaContainer, combined_inline_jar) { - const std::string script_code = "import java.time.LocalDateTime;" - "import java.time.ZoneOffset;" - "import java.time.format.DateTimeFormatter;" - "class SIMPLE {" - "static void main(String[] args) {" - "int i = 0;" - "}" - "static int run(ExaMetadata exa, ExaIterator ctx) {" - "return 0;" - "}" - "}"; - const std::string script_code_with_jar = std::string("%jar javacontainer/test/test.jar;") + script_code; - JavaVMTest vm(script_code_with_jar); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = std::string("package com.exasol;\r\n") + script_code; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/test.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/test.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - - -TEST(JavaContainer, quoted_jvm_option) { - const std::string script_code = - "%jvmoption -Dhttp.agent=\"ABC DEF\";\n\n" - "class JVMOPTION_TEST_WITH_SPACE {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - JavaVMTest vm(script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n\n\n" - "class JVMOPTION_TEST_WITH_SPACE {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - /* - * Note: The option "DEF" is wrong and causes UDF's to crash! - * The correct option would be '-Dhttp.agent=\"ABC DEF\"' - */ - const std::vector expectedJVMOptions = { "-Dhttp.agent=\"ABC", "DEF\"", "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, simple_import_script) { - const std::string script_code = - "%import other_script;\n\n" - "%jvmoption -Dhttp.agent=\"ABC\";\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_script_code = - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script", other_script_code); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dhttp.agent=\"ABC\"", "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, simple_import_script_with_white_space) { - const std::string script_code = - "%import other_script\t ;\n\n" - "%jvmoption -Dhttp.agent=\"ABC\";\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_script_code = - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script", other_script_code); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dhttp.agent=\"ABC\"", "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, simple_import_script_with_quotes) { - const std::string script_code = - "%import \"other_script\t \";\n\n" - "%jvmoption -Dhttp.agent=\"ABC\";\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_script_code = - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("\"other_script\t \"", other_script_code); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dhttp.agent=\"ABC\"", "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, import_script_with_recursion) { - const std::string script_code = - "%import other_script;\n\n" - "%jvmoption -Dhttp.agent=\"ABC\";\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_script_code = - "%import other_script;\n\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script", other_script_code); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n\n\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dhttp.agent=\"ABC\"", "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, import_script_with_jvmoption) { - const std::string script_code = - "%import other_script;\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_script_code = - "%jvmoption -Dhttp.agent=\"ABC\";\n\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script", other_script_code); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n\n\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dhttp.agent=\"ABC\"", "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, multiple_import_scripts) { - const std::string script_code = - "%import other_script_A;\n\n" - "%import other_script_C;\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_scipt_code_A = - "%import other_script_B;\n\n" - "class OtherClassA {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - const std::string other_scipt_code_B = - "class OtherClassB {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - const std::string other_scipt_code_C = - "%import other_script_B;\n\n" - "class OtherClassC {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script_A", other_scipt_code_A); - swigFactory->addModule("other_script_B", other_scipt_code_B); - swigFactory->addModule("other_script_C", other_scipt_code_C); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n" - "class OtherClassB {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n" - "class OtherClassA {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n\n\n" - "class OtherClassC {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, import_script_with_mixed_options) { - const std::string script_code = - "%import other_script;\n\n" - "%jvmoption -Dsomeoption=\"ABC\";\n\n" - "%scriptclass com.exasol.udf_profiling.UdfProfiler;\n" - "%jar javacontainer/test/test.jar;" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_script_code = - "%jvmoption -Dsomeotheroption=\"DEF\";\n\n" - "%jar javacontainer/test/other_test.jar;" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script", other_script_code); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n\n\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/other_test.jar:javacontainer/test/test.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Dexasol.scriptclass=com.exasol.udf_profiling.UdfProfiler", - "-Dsomeotheroption=\"DEF\"", "-Dsomeoption=\"ABC\"", "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar:javacontainer/test/other_test.jar:javacontainer/test/test.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - -TEST(JavaContainer, import_script_script_class_option_ignored) { - const std::string script_code = - "%import other_script;\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_script_code = - "%scriptclass com.exasol.udf_profiling.UdfProfiler;\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script", other_script_code); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n" -#ifndef USE_EXTRACTOR_V2 //The parsers behave differently: The legacy parser incorrectly keeps imported scriptclass options - "%scriptclass com.exasol.udf_profiling.UdfProfiler;" -#endif - "\n" - "class OtherClass {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} - - -TEST(JavaContainer, import_scripts_deep_recursion) { - const std::string script_code = - "%import other_script_A;\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - " ctx.emit(\"Success!\");\n" - " }\n" - "}\n"; - auto swigFactory = std::make_unique(); - - const std::string other_scipt_code_A = - "%import other_script_B;\n\n" - "class OtherClassA {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - const std::string other_scipt_code_B = - "%import other_script_C;\n\n" - "class OtherClassB {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - const std::string other_scipt_code_C = - "%import other_script_D;\n\n" - "class OtherClassC {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - const std::string other_scipt_code_D = - "%import other_script_A;\n\n" - "class OtherClassD {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n"; - swigFactory->addModule("other_script_A", other_scipt_code_A); - swigFactory->addModule("other_script_B", other_scipt_code_B); - swigFactory->addModule("other_script_C", other_scipt_code_C); - swigFactory->addModule("other_script_D", other_scipt_code_D); - JavaVMTest vm(script_code, std::move(swigFactory)); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJavaPath, "/exaudf/external/exaudfclient_base+/javacontainer"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_localClasspath, "/tmp"); - const std::string expected_script_code = - "package com.exasol;\r\n\n\n" - "class OtherClassD {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n" - "class OtherClassC {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n" - "class OtherClassB {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n" - "class OtherClassA {\n" - "static void doSomething() {\n\n" - " }\n" - "}\n\n\n" - "class JVMOPTION_TEST {\n" - "static void run(ExaMetadata exa, ExaIterator ctx) throws Exception {\n\n" - "\tctx.emit(\"Success!\");\n" - " }\n}\n"; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_scriptCode, expected_script_code); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_exaJarPath, "/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_EQ(vm.getJavaVMInternalStatus().m_classpath, "/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar"); - EXPECT_TRUE(vm.getJavaVMInternalStatus().m_needsCompilation); - const std::vector expectedJVMOptions = { "-Xms128m", "-Xmx128m", "-Xss512k", - "-XX:ErrorFile=/tmp/hs_err_pid%p.log", - "-Djava.class.path=/tmp:/exaudf/external/exaudfclient_base+/javacontainer/exaudf_deploy.jar", - "-XX:+UseSerialGC" }; - EXPECT_EQ(vm.getJavaVMInternalStatus().m_jvmOptions, expectedJVMOptions); -} diff --git a/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc b/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc deleted file mode 100644 index fe73a89..0000000 --- a/exaudfclient/base/javacontainer/test/cpp/javavm_test.cc +++ /dev/null @@ -1,37 +0,0 @@ -#include "javacontainer/test/cpp/javavm_test.h" -#include "javacontainer/test/cpp/swig_factory_test.h" -#include "javacontainer/javacontainer_impl.h" -#include "javacontainer/script_options/extractor_impl.h" -#include - -std::unique_ptr makeDefaultSwigFactory() { - return std::make_unique(); -} - -JavaVMTest::JavaVMTest(std::string scriptCode) : javaVMInternalStatus() { - run(scriptCode, std::move(makeDefaultSwigFactory())); -} - -JavaVMTest::JavaVMTest(std::string scriptCode, std::unique_ptr swigFactory) : javaVMInternalStatus() { - run(scriptCode, std::move(swigFactory)); -} - -void JavaVMTest::run(std::string scriptCode, std::unique_ptr swigFactory) { - SWIGVMContainers::SWIGVM_params->script_code = scriptCode.data(); -#ifndef USE_EXTRACTOR_V2 - std::unique_ptr extractor = - std::make_unique(std::move(swigFactory)); -#else - std::unique_ptr extractor = - std::make_unique(std::move(swigFactory)); -#endif - SWIGVMContainers::JavaVMImpl javaVMImpl(false, true, std::move(extractor)); - javaVMInternalStatus.m_exaJavaPath = javaVMImpl.m_exaJavaPath; - javaVMInternalStatus.m_localClasspath = javaVMImpl.m_localClasspath; - javaVMInternalStatus.m_scriptCode = javaVMImpl.m_scriptCode; - javaVMInternalStatus.m_exaJarPath = javaVMImpl.m_exaJarPath; - javaVMInternalStatus.m_classpath = javaVMImpl.m_classpath; - javaVMInternalStatus.m_jvmOptions = javaVMImpl.m_jvmOptions; - javaVMInternalStatus.m_needsCompilation = javaVMImpl.m_needsCompilation; -} - diff --git a/exaudfclient/base/javacontainer/test/cpp/javavm_test.h b/exaudfclient/base/javacontainer/test/cpp/javavm_test.h deleted file mode 100644 index a0e8e0b..0000000 --- a/exaudfclient/base/javacontainer/test/cpp/javavm_test.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef JAVA_VM_TEST -#define JAVA_VM_TEST - -#include -#include -#include -#include - -struct JavaVMInternalStatus { - std::string m_exaJavaPath; - std::string m_localClasspath; - std::string m_scriptCode; - std::string m_exaJarPath; - std::string m_classpath; - bool m_needsCompilation; - std::vector m_jvmOptions; -}; - -class SwigFactoryTestImpl; - -class JavaVMTest { - public: - JavaVMTest(std::string scriptCode); - - JavaVMTest(std::string scriptCode, std::unique_ptr swigFactory); - - const JavaVMInternalStatus& getJavaVMInternalStatus() {return javaVMInternalStatus;} - - private: - void run(std::string scriptCode, std::unique_ptr swigFactory); - private: - JavaVMInternalStatus javaVMInternalStatus; -}; - -#endif \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.cc b/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.cc deleted file mode 100644 index 750789f..0000000 --- a/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.cc +++ /dev/null @@ -1,128 +0,0 @@ -#include "javacontainer/test/cpp/swig_factory_test.h" -#include "exaudflib/swig/swig_meta_data.h" - -#include - -class NotImplemented : public std::logic_error -{ -public: - NotImplemented() : std::logic_error("Function not yet implemented") { }; - NotImplemented(const std::string funcName) : std::logic_error("Function " + funcName + " not yet implemented") { }; -}; - -class SWIGMetadataTest : public SWIGVMContainers::SWIGMetadataIf { - -public: - SWIGMetadataTest(const std::map & moduleContent, const std::string & exceptionMsg) - : m_exceptionMsg(exceptionMsg) - , m_moduleContent(moduleContent) {} - virtual const char* databaseName() { throw NotImplemented("databaseName"); return nullptr;} - virtual const char* databaseVersion() { throw NotImplemented("databaseVersion"); return nullptr;} - virtual const char* scriptName() { throw NotImplemented("scriptName"); return nullptr;} - virtual const char* scriptSchema() { throw NotImplemented("scriptSchema"); return nullptr;} - virtual const char* currentUser() { throw NotImplemented("currentUser"); return nullptr;} - virtual const char* scopeUser() { throw NotImplemented("scopeUser"); return nullptr;} - virtual const char* currentSchema() { throw NotImplemented("currentSchema"); return nullptr;} - virtual const char* scriptCode() { throw NotImplemented("scriptCode"); return nullptr;} - virtual const unsigned long long sessionID() { throw NotImplemented("sessionID"); return 0;} - virtual const char *sessionID_S() { throw NotImplemented("sessionID_S"); return nullptr;} - virtual const unsigned long statementID() { throw NotImplemented("statementID"); return 0;} - virtual const unsigned int nodeCount() { throw NotImplemented("nodeCount"); return 0;} - virtual const unsigned int nodeID() { throw NotImplemented("nodeID"); return 0;} - virtual const unsigned long long vmID() { throw NotImplemented("vmID"); return 0;} - virtual const unsigned long long memoryLimit() { throw NotImplemented("memoryLimit"); return 0;} - virtual const SWIGVMContainers::VMTYPE vmType() { - throw NotImplemented("vmType"); - return SWIGVMContainers::VM_UNSUPPORTED; - } - virtual const char *vmID_S() { throw NotImplemented("vmID_S"); return nullptr;} - virtual const ExecutionGraph::ConnectionInformationWrapper* connectionInformation(const char* connection_name) { - throw NotImplemented("connectionInformation"); return nullptr; - } - virtual const char* moduleContent(const char* name) { - auto it = m_moduleContent.find(std::string(name)); - if (m_moduleContent.end() == it) { - throw std::invalid_argument("Script not found."); - } - return it->second.c_str(); - } - virtual const unsigned int inputColumnCount() { throw NotImplemented("inputColumnCount"); return 0;} - virtual const char *inputColumnName(unsigned int col) { - throw NotImplemented("inputColumnName"); - return nullptr; - } - virtual const SWIGVMContainers::SWIGVM_datatype_e inputColumnType(unsigned int col) { - throw NotImplemented("inputColumnType"); - return SWIGVMContainers::UNSUPPORTED; - } - virtual const char *inputColumnTypeName(unsigned int col) { - throw NotImplemented("inputColumnTypeName"); return nullptr; - } - virtual const unsigned int inputColumnSize(unsigned int col) { - throw NotImplemented("inputColumnSize"); return 0; - } - virtual const unsigned int inputColumnPrecision(unsigned int col) { - throw NotImplemented("inputColumnPrecision"); return 0; - } - virtual const unsigned int inputColumnScale(unsigned int col) { - throw NotImplemented("inputColumnScale"); return 0; - } - virtual const SWIGVMContainers::SWIGVM_itertype_e inputType() { - throw NotImplemented("inputType"); - return SWIGVMContainers::EXACTLY_ONCE; - } - virtual const unsigned int outputColumnCount() { throw NotImplemented("outputColumnCount"); return 0;} - virtual const char *outputColumnName(unsigned int col) { throw NotImplemented("outputColumnName"); return nullptr;} - virtual const SWIGVMContainers::SWIGVM_datatype_e outputColumnType(unsigned int col) { - throw NotImplemented("outputColumnType"); - return SWIGVMContainers::UNSUPPORTED; - } - virtual const char *outputColumnTypeName(unsigned int col) { - throw NotImplemented("outputColumnTypeName"); return nullptr; - } - virtual const unsigned int outputColumnSize(unsigned int col) { - throw NotImplemented("outputColumnSize"); return 0; - } - virtual const unsigned int outputColumnPrecision(unsigned int col) { - throw NotImplemented("outputColumnPrecision"); return 0; - } - virtual const unsigned int outputColumnScale(unsigned int col) { - throw NotImplemented("outputColumnScale"); return 0; - } - virtual const SWIGVMContainers::SWIGVM_itertype_e outputType() { - throw NotImplemented("outputType"); - return SWIGVMContainers::EXACTLY_ONCE; - } - virtual const bool isEmittedColumn(unsigned int col) { throw NotImplemented("isEmittedColumn"); return false;} - virtual const char* checkException() { - if (m_exceptionMsg.empty()) { - return nullptr; - } - return m_exceptionMsg.c_str(); - } - virtual const char* pluginLanguageName() { throw NotImplemented("pluginLanguageName"); return nullptr;} - virtual const char* pluginURI() { throw NotImplemented("pluginURI"); return nullptr;} - virtual const char* outputAddress() { throw NotImplemented("outputAddress"); return nullptr;} - -private: - std::string m_exceptionMsg; - - std::map m_moduleContent; -}; - - - -SwigFactoryTestImpl::SwigFactoryTestImpl() {} - - -void SwigFactoryTestImpl::addModule(const std::string key, const std::string script) { - m_moduleContent.insert(std::make_pair(key, script)); -} - -void SwigFactoryTestImpl::setException(const std::string msg) { - m_exceptionMsg = msg; -} - -SWIGVMContainers::SWIGMetadataIf* SwigFactoryTestImpl::makeSwigMetadata() { - return new SWIGMetadataTest(m_moduleContent, m_exceptionMsg); -} diff --git a/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.h b/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.h deleted file mode 100644 index fedd1a4..0000000 --- a/exaudfclient/base/javacontainer/test/cpp/swig_factory_test.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef SWIG_FACTORY_TEST_H -#define SWIG_FACTORY_TEST_H 1 - -#include -#include -#include "swig_factory/swig_factory.h" - -struct SwigFactoryTestImpl : public SWIGVMContainers::SwigFactory { - - SwigFactoryTestImpl(); - - void addModule(const std::string key, const std::string script); - - void setException(const std::string msg); - - virtual SWIGVMContainers::SWIGMetadataIf* makeSwigMetadata() override; - -private: - std::map m_moduleContent; - std::string m_exceptionMsg; -}; - - -#endif //namespace SWIG_FACTORY_TEST_H \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/test/java/com/exasol/ExaStackTraceCleanerTest.java b/exaudfclient/base/javacontainer/test/java/com/exasol/ExaStackTraceCleanerTest.java deleted file mode 100644 index d522aca..0000000 --- a/exaudfclient/base/javacontainer/test/java/com/exasol/ExaStackTraceCleanerTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.exasol; - -import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import com.exasol.ExaStackTraceCleaner; -import java.lang.Exception; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.CoreMatchers.containsString; - -//First build some artificial exception chain - -final class CustomTestException extends Exception { - public CustomTestException(final String msg, final Throwable th) { - super(msg, th); - } -} - - -final class CustomTestClass { - public CustomTestClass() {} - - public void throwEx() throws CustomTestException { - try { - try { - throw new RuntimeException("ex1"); - } catch (final RuntimeException ex) { - throw new RuntimeException("ex2", ex); - } - } catch(final RuntimeException ex) { - throw new CustomTestException("ex3", ex); - } - } -} - -class ExaWrapper { - public static void wrap_custom_test_class() throws ClassNotFoundException, NoSuchMethodException, - InstantiationException, IllegalAccessException, - InvocationTargetException { - Class a = Class.forName("com.exasol.CustomTestClass"); - Constructor constructor = a.getConstructor(); - Object obj = constructor.newInstance(); - Method m = a.getMethod("throwEx"); - m.invoke(obj); - } -} - -public class ExaStackTraceCleanerTest { - - - @Test - public void runSimpleTest() { - Throwable th = null; - try { - ExaWrapper.wrap_custom_test_class(); - } catch(final Exception ex) { - th = ex; - } - ExaStackTraceCleaner exaStackTraceCleaner = new ExaStackTraceCleaner(ExaWrapper.class.getName()); - final String result = exaStackTraceCleaner.cleanStackTrace(th); - String[] resultLines = result.split("\n"); - //Check that the - assertTrue(resultLines.length > 4); - assertEquals(resultLines[0], "com.exasol.CustomTestException: ex3"); - assertThat(resultLines[1], containsString("com.exasol.CustomTestClass.throwEx(ExaStackTraceCleanerTest.java")); - assertThat(resultLines[2], containsString("com.exasol.ExaWrapper.wrap_custom_test_class(ExaStackTraceCleanerTest.java:47)")); - assertThat(resultLines[3], containsString("com.exasol.ExaStackTraceCleanerTest.runSimpleTest(ExaStackTraceCleanerTest.java")); - } - -} \ No newline at end of file diff --git a/exaudfclient/base/javacontainer/test/other_test.jar b/exaudfclient/base/javacontainer/test/other_test.jar deleted file mode 100644 index e69de29..0000000 diff --git a/exaudfclient/base/javacontainer/test/test.jar b/exaudfclient/base/javacontainer/test/test.jar deleted file mode 100644 index e69de29..0000000 diff --git a/exaudfclient/base/script_options_parser/BUILD b/exaudfclient/base/script_options_parser/BUILD deleted file mode 100644 index 907a7d2..0000000 --- a/exaudfclient/base/script_options_parser/BUILD +++ /dev/null @@ -1,8 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load("@rules_cc//cc:defs.bzl", "cc_library") - -cc_library( - name = "exception", - hdrs = ["exception.h"] -) diff --git a/exaudfclient/base/script_options_parser/ctpg/BUILD b/exaudfclient/base/script_options_parser/ctpg/BUILD deleted file mode 100644 index 07a551f..0000000 --- a/exaudfclient/base/script_options_parser/ctpg/BUILD +++ /dev/null @@ -1,11 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load("@rules_cc//cc:defs.bzl", "cc_library") - -cc_library( - name = "script_option_lines_parser_ctpg", - hdrs = ["script_option_lines_ctpg.h"], - srcs = ["script_option_lines_ctpg.cc","ctpg.hpp"], - deps = ["//script_options_parser:exception"], - copts= ["-fno-lto"], -) diff --git a/exaudfclient/base/script_options_parser/ctpg/ctpg.hpp b/exaudfclient/base/script_options_parser/ctpg/ctpg.hpp deleted file mode 100644 index fc6a123..0000000 --- a/exaudfclient/base/script_options_parser/ctpg/ctpg.hpp +++ /dev/null @@ -1,3434 +0,0 @@ -/** - -CTPG Library https://github.com/peter-winter/ctpg - -MIT License - -Copyright (c) 2021 peter-winter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -**/ - -#ifndef CTPG_H -#define CTPG_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace exaudf_ctpg -{ - -using size_t = std::size_t; -using size8_t = std::uint8_t; -using size16_t = std::uint16_t; -using size32_t = std::uint32_t; - -template -using str_table = const char* [N]; - -constexpr size_t uninitialized = size_t(-1); -constexpr size16_t uninitialized16 = size16_t(-1); -constexpr size32_t uninitialized32 = size32_t(-1); - -namespace meta -{ - template - struct contains_type - {}; - - template - struct unique_type_list : contains_type... - { - using variant_type = std::variant; - - template - struct insert - { - static unique_type_list foo(contains_type*); - static unique_type_list foo(...); - - using type = decltype(foo(std::declval*>())); - }; - - template - typename insert::type operator + (New); - }; - - template - struct unique_types_variant - { - using unique_list = decltype((std::declval>() + ... + std::declval())); - using type = typename unique_list::variant_type; - }; - - template - using unique_types_variant_t = typename unique_types_variant::type; - - template - constexpr int sum_size = (0 + ... + sizeof(T)); - - template - constexpr size_t distinct_values_count = 1 << (sizeof(T) * 8); - - constexpr size_t distinct_chars_count = distinct_values_count; - - template - struct max - { - static const size_t value = std::max(First, max::value); - }; - - template - struct max - { - static const size_t value = X; - }; - - template - constexpr size_t max_v = max::value; - - template - constexpr size_t count_zeros = (0 + ... + (X == 0 ? 1 : 0)); -} - -namespace stdex -{ - template - struct is_cvector_compatible : std::bool_constant && std::is_trivially_destructible_v> - {}; - - template - class cvector - {}; - - template - class cvector::value>> - { - public: - using size_type = std::size_t; - - constexpr cvector() : - the_data{}, current_size(0) - {} - - constexpr cvector(const T& arg, size_t count): - the_data{}, current_size(0) - { - for (size_t i = 0; i < count; ++i) - push_back(arg); - } - - private: - template - struct iterator_base - { - using it_type = Derived; - constexpr it_type* cast() { return static_cast(this); } - constexpr const it_type* cast() const { return static_cast(this); } - - constexpr bool operator == (const it_type& other) const { return cast()->ptr == other.ptr; } - constexpr bool operator != (const it_type& other) const { return cast()->ptr != other.ptr; } - constexpr it_type operator - (size_type amount) const { return it_type{ cast()->ptr - amount }; } - constexpr size_type operator - (const it_type& other) const { return size_type(cast()->ptr - other.ptr); } - constexpr it_type operator + (size_type amount) const { return it_type{ cast()->ptr + amount }; } - constexpr it_type operator ++(int) { it_type it{ cast()->ptr }; ++(cast()->ptr); return it; } - constexpr it_type& operator ++() { ++(cast()->ptr); return *cast(); } - constexpr bool operator > (const it_type& other) const { return cast()->ptr > other.ptr; } - constexpr bool operator < (const it_type& other) const { return cast()->ptr < other.ptr; } - }; - - public: - struct iterator : iterator_base - { - T* ptr; - constexpr iterator(T* ptr) : ptr(ptr) {} - constexpr T& operator *() const { return *ptr; } - }; - - struct const_iterator : iterator_base - { - const T* ptr; - constexpr const_iterator(const T* ptr) : ptr(ptr) {} - constexpr const T& operator *() const { return *ptr; } - }; - - constexpr const T* data() const { return the_data; } - constexpr T* data() { return the_data; } - constexpr size_type size() const { return current_size; } - constexpr bool empty() const { return current_size == 0; } - constexpr void reserve(size_type) const {}; - constexpr const T& operator[](size_type idx) const { return the_data[idx]; } - constexpr T& operator[](size_type idx) { return the_data[idx]; } - constexpr void push_back(const T& v) { the_data[current_size++] = v; } - constexpr void emplace_back(T&& v) { the_data[current_size++] = std::move(v); } - constexpr const T& front() const { return the_data[0]; } - constexpr T& front() { return the_data[0]; } - constexpr T& back() { return the_data[current_size - 1]; } - constexpr const T& back() const { return the_data[current_size - 1]; } - constexpr const_iterator begin() const { return const_iterator(the_data); } - constexpr const_iterator end() const { return const_iterator(the_data + current_size); } - constexpr iterator begin() { return iterator(the_data); } - constexpr iterator end() { return iterator(the_data + current_size); } - constexpr void clear() { current_size = 0; } - constexpr void pop_back() { current_size--; } - constexpr iterator erase(iterator first, iterator last) - { - if (!(first < last)) - return end(); - auto from = first < begin() ? begin() : first; - auto to = last > end() ? end() : last; - size_type diff = to - from; - iterator it = to; - while (!(it == end())) - { - *from = std::move(*it); - ++from; ++it; - } - current_size -= diff; - - return end(); - } - - private: - T the_data[N]; - size_type current_size; - }; - - template - class cbitset - { - public: - using size_type = std::size_t; - using underlying_type = std::uint64_t; - - constexpr cbitset& set(size_type idx) - { - check_idx(idx); - data[idx / underlying_size] |= (underlying_type(1) << (idx % underlying_size)); - return *this; - } - - constexpr cbitset& set(size_type idx, bool value) - { - check_idx(idx); - data[idx / underlying_size] ^= (-!!value ^ data[idx / underlying_size]) & (underlying_type(1) << (idx % underlying_size)); - return *this; - } - - constexpr cbitset& reset(size_type idx) - { - check_idx(idx); - data[idx / underlying_size] &= ~(underlying_type(1) << (idx % underlying_size)); - return *this; - } - - constexpr cbitset& flip(size_type idx) - { - check_idx(idx); - data[idx / underlying_size] ^= (underlying_type(1) << (idx % underlying_size)); - return *this; - } - - constexpr bool test(size_type idx) const - { - check_idx(idx); - return (data[idx / underlying_size] >> (idx % underlying_size)) & underlying_type(1); - } - - constexpr cbitset& flip() - { - for (auto& d : data) - d = ~d; - return *this; - } - - constexpr cbitset& set() - { - for (auto& d : data) - d = underlying_type(-1); - return *this; - } - - constexpr cbitset& reset() - { - for (auto& d : data) - d = underlying_type(0); - return *this; - } - - constexpr size_type size() const - { - return N; - } - - private: - constexpr void check_idx(size_type idx) const - { - if (idx >= N) - throw std::runtime_error("Index access out of range"); - } - - static const size_type underlying_size = sizeof(underlying_type) * 8; - static const size_type underlying_count = (N / underlying_size) + ((N % underlying_size) ? 1 : 0); - underlying_type data[underlying_count] = {}; - }; - - template - struct is_cqueue_compatible : std::bool_constant && std::is_trivially_destructible_v> - {}; - - template - class cqueue - {}; - - template - class cqueue::value>> - { - public: - constexpr cqueue(): - data{}, start{0}, end{0}, size_{0} - {} - - constexpr void push(const T& v) - { - if (size_ >= N) - throw std::runtime_error("Pushing out of range"); - - data[end++] = v; - if (end == N) - end = 0; - size_++; - } - - constexpr void pop() - { - if (empty()) - throw std::runtime_error("Pop on empty"); - - start++; - if (start == N) - start = 0; - size_--; - } - - constexpr T& top() - { - if (empty()) - throw std::runtime_error("Top on empty"); - return data[start]; - } - - constexpr const T& top() const - { - return std::as_const(*this).top(); - } - - constexpr bool empty() const - { - return size_ == 0; - } - - constexpr std::size_t size() const - { - return size_; - } - - private: - T data[N]; - std::size_t start; - std::size_t end; - std::size_t size_; - }; - - template - constexpr Container& sort(Container& c, Pred p) - { - bool swap = true; - while (swap) - { - swap = false; - for (auto i = 0u; i < std::size(c) - 1; i++) - { - if (p(c[i + 1], c[i])) - { - auto x = c[i]; - c[i] = c[i + 1]; - c[i + 1] = x; - swap = true; - } - } - } - return c; - } -} - -namespace utils -{ - template - constexpr T construct_default(Args...) - { - return T(); - } - - template - constexpr void copy_array(T *a1, const T* a2, std::index_sequence) - { - (void(a1[I] = a2[I]), ...); - } - - constexpr size_t char_to_idx(char c) - { - return static_cast(static_cast(c)) & 0xff; - } - - constexpr char idx_to_char(size_t idx) - { - return static_cast(static_cast(idx & 0xff)); - } - - constexpr bool is_printable(char c) - { - return c >= 0x20 && c <= 0x7e; - } - - constexpr bool is_hex_digit(char c) - { - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); - } - - constexpr bool is_dec_digit(char c) - { - return c >= '0' && c <= '9'; - } - - class char_names - { - public: - const static size_t name_size = 5; - - constexpr char_names() - { - for (size_t i = 0; i < meta::distinct_chars_count; ++i) - { - char d[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - if (idx_to_char(i) > 32 && idx_to_char(i) < 127) - { - arr[i][0] = idx_to_char(i); - arr[i][1] = 0; - } - else - { - arr[i][0] = '\\'; - arr[i][1] = 'x'; - arr[i][2] = d[i / 16]; - arr[i][3] = d[i % 16]; - arr[i][4] = 0; - } - } - } - - constexpr const char* name(char c) const { return arr[char_to_idx(c)]; } - - private: - char arr[meta::distinct_chars_count][name_size] = {}; - }; - - constexpr char_names c_names = {}; - - constexpr bool str_equal(const char* str1, const char* str2) - { - if ((str1 == nullptr) || (str2 == nullptr)) - throw std::runtime_error("null pointers not allowed here"); - while (*str1 == *str2) - { - if (*str1 == 0) - return true; - str1++; str2++; - } - return false; - } - - template - constexpr size_t find_str(const str_table& table, const char* str) - { - size_t res = 0; - for (const auto& n : table) - { - if (str_equal(n, str)) - return res; - res++; - } - if (res == N) - throw std::runtime_error("string not found"); - return uninitialized; - } - - constexpr size_t find_char(char c, const char* str) - { - size_t i = 0; - while (*str) - { - if (*str == c) - return i; - str++; i++; - } - return uninitialized; - } - - constexpr std::size_t str_len(const char* str) - { - std::size_t i = 0; - const char* p = str; - while (*p) { ++i; ++p; } - return i; - } - - struct slice - { - size32_t start; - size32_t n; - }; - - template - struct fake_table - { - T operator[](size_t) const { return val; } - T val; - }; -} - -namespace ftors -{ - template - struct ignore - { - template - constexpr ignore(T&&){} - }; - - template> - class element - {}; - - template - class element> - { - public: - template - constexpr decltype(auto) operator ()(ignore..., First&& arg, Rest&&...) const - { - return std::forward(arg); - } - }; - - constexpr element<1> _e1; - constexpr element<2> _e2; - constexpr element<3> _e3; - constexpr element<4> _e4; - constexpr element<5> _e5; - constexpr element<6> _e6; - constexpr element<7> _e7; - constexpr element<8> _e8; - constexpr element<9> _e9; - - template - class val - { - public: - constexpr val(T&& v): - v(std::forward(v)) - {} - - template - constexpr auto operator ()(Args&&...) const - { - return v; - } - - private: - T v; - }; - - template - val(T&&) -> val>; - - template - class create - { - public: - template - constexpr auto operator ()(Args&&...) const - { - return T{}; - } - }; - - template> - struct construct - {}; - - template< - typename T, - std::size_t FromIdx, - std::size_t... Skip - > - struct construct< - T, - FromIdx, - std::index_sequence> - { - template - constexpr auto operator()(ignore..., Arg&& arg, Rest&&...) const - { - return T{std::forward(arg)}; - } - }; - - template< - std::size_t ContIdx = 1, - std::size_t ArgIdx = 2, - typename = std::make_index_sequence, - typename = std::make_index_sequence, - bool container_first = ContIdx < ArgIdx - > - struct emplace_back - {}; - - template< - std::size_t ContIdx, - std::size_t ArgIdx, - std::size_t... Skip1, - std::size_t... Skip2 - > - struct emplace_back< - ContIdx, - ArgIdx, - std::index_sequence, - std::index_sequence, - true> - { - template - constexpr decltype(auto) operator()(ignore..., Container &&container, ignore..., Arg&& arg, Rest&&...) const - { - container.emplace_back(std::move(arg)); - return std::move(container); - } - }; - - template< - std::size_t ContIdx, - std::size_t ArgIdx, - std::size_t... Skip1, - std::size_t... Skip2 - > - struct emplace_back< - ContIdx, - ArgIdx, - std::index_sequence, - std::index_sequence, - false> - { - template - constexpr decltype(auto) operator()(ignore..., Arg&& arg, ignore..., Container &&container, Rest&&...) const - { - container.emplace_back(std::move(arg)); - return std::move(container); - } - }; - - template< - std::size_t ContIdx = 1, - std::size_t ArgIdx = 2, - typename = std::make_index_sequence, - typename = std::make_index_sequence, - bool container_first = ContIdx < ArgIdx - > - struct push_back - {}; - - template< - std::size_t ContIdx, - std::size_t ArgIdx, - std::size_t... Skip1, - std::size_t... Skip2 - > - struct push_back< - ContIdx, - ArgIdx, - std::index_sequence, - std::index_sequence, - true> - { - template - constexpr decltype(auto) operator()(ignore..., Container &&container, ignore..., const Arg& arg, Rest&&...) const - { - container.push_back(arg); - return std::move(container); - } - }; - - template< - std::size_t ContIdx, - std::size_t ArgIdx, - std::size_t... Skip1, - std::size_t... Skip2 - > - struct push_back< - ContIdx, - ArgIdx, - std::index_sequence, - std::index_sequence, - false> - { - template - constexpr decltype(auto) operator()(ignore..., const Arg& arg, ignore..., Container &&container, Rest&&...) const - { - container.push_back(arg); - return std::move(container); - } - }; -} - -namespace buffers -{ - template - class cstring_buffer - { - public: - template - constexpr cstring_buffer(const char(&source)[N1]) - { - utils::copy_array(data, source, std::make_index_sequence{}); - } - - struct iterator - { - const char* ptr; - - constexpr char operator *() const { return *ptr; } - constexpr iterator& operator ++() { ++ptr; return *this; } - constexpr iterator operator ++(int) { iterator i(*this); ++ptr; return i; } - constexpr bool operator == (const iterator& other) const { return ptr == other.ptr; } - constexpr bool operator != (const iterator& other) const { return ptr != other.ptr; } - constexpr iterator& operator += (size_t len) { ptr += len; return *this; } - }; - - constexpr iterator begin() const { return iterator{ data }; } - constexpr iterator end() const { return iterator{ data + N - 1 }; } - constexpr std::string_view get_view(iterator start, iterator end) const { return std::string_view(start.ptr, end.ptr - start.ptr); } - - private: - char data[N] = { 0 }; - }; - - template - cstring_buffer(const char(&)[N])->cstring_buffer; - - class string_buffer - { - public: - string_buffer(std::string&& str): - str(std::move(str)) - {} - - string_buffer(const char* str): - str(str) - {} - - auto begin() const { return str.cbegin(); } - auto end() const { return str.cend(); } - - using iterator = std::string::const_iterator; - - std::string_view get_view(iterator start, iterator end) const - { - return std::string_view(str.data() + (start - str.begin()), end - start); - } - - private: - std::string str; - }; - - template - using iterator_t = typename Buffer::iterator; -} - -template -class nterm -{ -public: - using value_type = ValueType; - - constexpr nterm(const char* name) : - name(name) - { - if (name[0] == 0) - throw std::runtime_error("empty name not allowed"); - } - - constexpr const char* get_name() const { return name; } - - template - constexpr auto operator()(Args&&... args) const; - -private: - const char* name; -}; - -enum class associativity { no_assoc, ltor, rtol }; - -struct source_point -{ - size32_t line = 1; - size32_t column = 1; - size_t global = 0; - - template - constexpr void update(Iterator start, Iterator end) - { - while (!(start == end)) - { - if (*start == '\n') - { - ++line; - column = 1; - } - else - ++column; - ++global; - ++start; - } - } - - friend std::ostream& operator << (std::ostream& o, const source_point& sp); -}; - -inline std::ostream& operator << (std::ostream& o, const source_point& sp) -{ - o << "[" << sp.line << ":" << sp.column << "]"; - return o; -} - -template -class term_value -{ -public: - constexpr term_value(VT v, source_point sp): - value(v), sp{ sp } - {} - - constexpr operator VT() const { return value; } - constexpr size32_t get_line() const { return sp.line; } - constexpr size32_t get_column() const { return sp.column; } - constexpr const VT& get_value() const { return value; } - constexpr source_point get_sp() const { return sp; } - -private: - VT value; - source_point sp; -}; - -class term -{ -public: - constexpr term(int precedence = 0, associativity a = associativity::no_assoc) : - precedence(precedence), ass(a) - {} - - constexpr associativity get_associativity() const { return ass; } - constexpr int get_precedence() const { return precedence; } - -protected: - int precedence; - associativity ass; -}; - -namespace detail -{ - constexpr std::string_view pass_sv(const std::string_view& sv) { return sv; } - constexpr char first_sv_char(const std::string_view& sv) { return sv[0]; } -} - -class char_term : public term -{ -public: - using internal_value_type = char; - - static const size_t dfa_size = 2; - static const bool is_trivial = true; - - constexpr char_term(char c, int precedence = 0, associativity a = associativity::no_assoc): - term(precedence, a), c(c) - { - utils::copy_array(id, utils::c_names.name(c), std::make_index_sequence{}); - } - - constexpr const char* get_id() const { return id; } - constexpr const char* get_name() const { return get_id(); } - constexpr char get_char() const { return c; } - constexpr char get_data() const { return c; } - - constexpr const auto& get_ftor() const { return detail::first_sv_char; } - -private: - char c; - char id[utils::char_names::name_size] = {}; -}; - -template -class string_term : public term -{ -public: - using internal_value_type = std::string_view; - static const size_t dfa_size = (DataSize - 1) * 2; - static const bool is_trivial = true; - - constexpr string_term(const char (&str)[DataSize], int precedence = 0, associativity a = associativity::no_assoc): - term(precedence, a) - { - utils::copy_array(data, str, std::make_index_sequence{}); - } - - constexpr const char* get_id() const { return data; } - constexpr const char* get_name() const { return get_id(); } - constexpr const auto& get_data() const { return data; } - - constexpr const auto& get_ftor() const { return detail::pass_sv; } - -private: - char data[DataSize] = {}; -}; - -template -class typed_term -{ -public: - using internal_value_type = std::invoke_result_t; - static const size_t dfa_size = Term::dfa_size; - static const bool is_trivial = Term::is_trivial; - - constexpr typed_term(Term t, Ftor f): - term(t), ftor(f) - {} - - constexpr const char* get_id() const { return term.get_id(); } - constexpr const char* get_name() const { return term.get_name(); } - constexpr decltype(auto) get_data() const { return term.get_data(); } - - constexpr associativity get_associativity() const { return term.get_associativity(); } - constexpr int get_precedence() const { return term.get_precedence(); } - - using ftor_type = Ftor; - - constexpr const ftor_type& get_ftor() const { return ftor; } - -private: - Term term; - ftor_type ftor; -}; - -template -class custom_term : public term -{ -public: - using internal_value_type = std::invoke_result_t; - static const size_t dfa_size = 0; - static const bool is_trivial = false; - - constexpr custom_term(const char* custom_name, Ftor ftor, int precedence = 0, associativity a = associativity::no_assoc): - term(precedence, a), custom_name(custom_name), ftor(ftor) - {} - - constexpr const char* get_id() const { return get_name(); } - constexpr const char* get_name() const { return custom_name; } - - using ftor_type = Ftor; - - constexpr const ftor_type& get_ftor() const { return ftor; } - -private: - const char* custom_name; - Ftor ftor; -}; - -struct error_recovery_token -{ - constexpr static const char* get_name() { return ""; } - constexpr static const char* get_id() { return get_name(); } -}; - -constexpr error_recovery_token error; - -template -struct value_type -{}; - -template -struct value_type>> -{ - using type = term_value; -}; - -template -struct value_type> -{ - using type = ValueType; -}; - -template -struct value_type> -{ - using type = term_value::internal_value_type>; -}; - -struct no_type {}; - -template<> -struct value_type -{ - using type = no_type; -}; - -template -using value_type_t = typename value_type::type; - -struct parse_options -{ - constexpr parse_options& set_verbose(bool val = true) { verbose = val; return *this; } - constexpr parse_options& set_skip_whitespace(bool val = true) { skip_whitespace = val; return *this; } - constexpr parse_options& set_skip_newline(bool val = true) { skip_newline = val; return *this; } - - bool verbose = false; - bool skip_whitespace = true; - bool skip_newline = true; -}; - -struct match_options -{ - bool verbose = false; - constexpr match_options& set_verbose(bool val = true) { verbose = val; return *this; } -}; - -namespace detail -{ - struct no_stream - { - template - constexpr const no_stream& operator <<(T&&) const { return *this; } - }; -} - -template -struct recognized_term -{ - Iterator it; - size16_t term_idx; -}; - -namespace regex -{ - using conflicted_terms = size16_t[4]; - - constexpr void add_conflicted_term(conflicted_terms& ts, size16_t t) - { - for (size_t i = 0; i < 4; ++i) - if (ts[i] == uninitialized16) - { - ts[i] = t; - break; - } - } - - struct dfa_state - { - constexpr dfa_state() - { - for (auto& t : transitions) - t = uninitialized16; - } - - size8_t start_state = 0; - size8_t end_state = 0; - size8_t unreachable = 0; - conflicted_terms conflicted_recognition = { uninitialized16, uninitialized16, uninitialized16, uninitialized16 }; - static const size_t transitions_size = meta::distinct_values_count; - size16_t transitions[transitions_size] = {}; - }; - - struct char_range - { - constexpr char_range(char c): - start(c), end(c) - {} - - constexpr char_range(char c1, char c2): - start(c1), end(c2) - {} - char start; - char end; - }; - - constexpr char hex_digits_to_char(char d1, char d2) - { - auto dd = [](char d) -> char - { - if (d >= 'A' && d <= 'F') - return char(10) + d - 'A'; - else if (d >= 'a' && d <= 'f') - return char(10) + d - 'a'; - else - return d - '0'; - }; - return dd(d1) * 16 + dd(d2); - } - - class char_subset - { - public: - constexpr char_subset() = default; - - template - constexpr char_subset(const char (&str)[N]) - { - for (size_t i = 0; i < N - 1; ++i) // ignore trailing 0, so N - 1 - data.set(utils::char_to_idx(str[i])); - } - - constexpr char_subset(char_range r) - { - add_range(r); - } - - constexpr char_subset& add_range(char_range r) - { - for (size_t i = utils::char_to_idx(r.start); i <= utils::char_to_idx(r.end); ++i) - data.set(i); - return *this; - } - - constexpr bool test(size_t idx) const { return data.test(idx); } - constexpr size_t size() const { return data.size(); } - constexpr char_subset& set() { data.set(); return *this; } - constexpr char_subset& flip() { data.flip(); return *this; } - constexpr char_subset& set(size_t idx) { data.set(idx); return *this; } - - private: - stdex::cbitset> data = {}; - }; - - template - using dfa = stdex::cvector; - - class dfa_size_analyzer - { - public: - using slice = utils::slice; - - constexpr slice primary_char(char) { return prim(); } - constexpr slice primary_subset(char_subset&&) { return prim(); } - - constexpr slice star(slice s) { return s; } - constexpr slice plus(slice s) { return s; } - constexpr slice opt(slice s) { return s; } - constexpr slice cat(slice s1, slice s2) { return add(s1, s2); } - constexpr slice alt(slice s1, slice s2) { return add(s1, s2); } - - constexpr slice rep(slice s, size32_t n) - { - if (n == 0) - return s; - size += (s.n * (n - 1)); - return slice{ s.start, s.n * n }; - } - - private: - constexpr slice prim() { auto old = size; size += 2; return slice{ old, 2 }; } - constexpr slice add(slice s1, slice s2) { return slice{ s1.start, s1.n + s2.n }; } - - size32_t size = 0; - }; - - template - class dfa_builder - { - public: - constexpr dfa_builder(dfa& sm): - sm(sm) - {} - - using slice = utils::slice; - - constexpr dfa_state& transition(dfa_state& from, const char_subset& s) - { - for (size_t i = 0; i < s.size(); ++i) - if (s.test(i)) - { - from.transitions[i] = size16_t(sm.size()); - } - sm.push_back(dfa_state()); - return sm.back(); - } - - constexpr dfa_state& transition(dfa_state& from, char c) - { - from.transitions[utils::char_to_idx(c)] = size16_t(sm.size()); - sm.push_back(dfa_state()); - return sm.back(); - } - - constexpr slice primary_char(char c) - { - return primary_subset(char_subset(char_range(c))); - } - - constexpr slice primary_subset(const char_subset& s) - { - size_t old_size = sm.size(); - sm.push_back(dfa_state()); - sm.back().start_state = 1; - dfa_state& to = transition(sm.back(), s); - to.end_state = 1; - return slice{ size32_t(old_size), 2 }; - } - - constexpr slice star(slice s) - { - size_t b = s.start; - sm[b].end_state = 1; - for (size_t i = s.start; i < s.start + s.n; ++i) - { - if (sm[i].end_state) - merge(i, b); - } - return s; - } - - constexpr slice plus(slice s) - { - size_t b = s.start; - for (size_t i = s.start; i < s.start + s.n; ++i) - { - if (sm[i].end_state) - merge(i, b, true); - } - return s; - } - - constexpr slice opt(slice s) - { - sm[s.start].end_state = 1; - return s; - } - - constexpr slice rep(slice s, size32_t n) - { - if (n == 0) - { - for (size_t j = s.start; j < s.start + s.n; ++j) - { - if (sm[j].start_state) - { - for (auto& t : sm[j].transitions) - t = uninitialized16; - sm[j].end_state = 1; - sm[j].start_state = 0; - } - else - sm[j].unreachable = 1; - } - return s; - } - - for (size_t i = 0; i < n - 1; ++i) - { - for (size_t j = s.start; j < s.start + s.n; ++j) - { - sm.push_back(sm[j]); - auto& st = sm.back(); - for (auto& t : st.transitions) - { - if (t != uninitialized16) - t += size16_t(s.n * (i + 1)); - } - } - } - slice whole = s; - for (size_t i = 0; i < n - 1; ++i) - { - cat(whole, slice{ whole.start + whole.n, s.n }); - whole = slice{ whole.start, whole.n + s.n}; - } - return whole; - } - - constexpr slice cat(slice s1, slice s2) - { - size_t b = s2.start; - for (size_t i = s1.start; i < s1.start + s1.n; ++i) - { - if (sm[i].end_state) - merge(i, b, false, true); - } - return slice{ s1.start, s1.n + s2.n }; - } - - constexpr slice alt(slice s1, slice s2) - { - size_t b1 = s1.start; - size_t b2 = s2.start; - merge(b1, b2, true, true); - return slice{ s1.start, s1.n + s2.n }; - } - - constexpr void mark_end_states(slice s, size16_t idx) - { - for (size_t i = s.start; i < s.start + s.n; ++i) - { - mark_end_state(sm[i], idx); - } - } - - constexpr size_t size() const { return sm.size(); } - private: - constexpr void merge(size_t to, size_t from, bool keep_end_state = false, bool mark_from_as_unreachable = false) - { - if (to == from) - return; - dfa_state& s_from = sm[from]; - dfa_state& s_to = sm[to]; - s_from.start_state = 0; - if (keep_end_state) - s_to.end_state = s_to.end_state || s_from.end_state; - else - s_to.end_state = s_from.end_state; - - s_from.unreachable = mark_from_as_unreachable ? 1 : 0; - - for (size_t i = 0; i < dfa_state::transitions_size; ++i) - { - size16_t& tr_from = s_from.transitions[i]; - if (tr_from == uninitialized16) - continue; - size16_t& tr_to = s_to.transitions[i]; - if (tr_to == uninitialized16) - { - tr_to = tr_from; - sm[tr_to].unreachable = 0; - } - else - merge(tr_to, tr_from, keep_end_state, mark_from_as_unreachable); - } - - auto& cr = s_from.conflicted_recognition; - for (size_t j = 0; j < 4; ++j) - { - size16_t term_idx = cr[j]; - if (term_idx != uninitialized16) - mark_end_state(s_to, term_idx); - else - break; - } - } - - constexpr void mark_end_state(dfa_state& s, size16_t idx) - { - if (!s.end_state) - return; - add_conflicted_term(s.conflicted_recognition, idx); - } - - dfa& sm; - }; - - template - struct regex_pattern_data - { - const char (&pattern)[N]; - }; - - template - constexpr void add_term_data_to_dfa(char c, dfa_builder& b, const Parser&, size16_t idx) - { - using slice = utils::slice; - - slice prev{0, size32_t(b.size())}; - slice new_sl = b.primary_char(c); - b.mark_end_states(new_sl, idx); - b.alt(prev, new_sl); - } - - template - constexpr void add_term_data_to_dfa(const char (&str)[DataSize], dfa_builder& b, const Parser&, size16_t idx) - { - using slice = utils::slice; - slice prev{0, size32_t(b.size())}; - - slice whole = b.primary_char(str[0]); - for (size_t i = 1; i < DataSize - 1; ++i) - { - slice char_sl = b.primary_char(str[i]); - whole = b.cat(whole, char_sl); - } - - b.mark_end_states(whole, idx); - b.alt(prev, whole); - } - - template - constexpr void add_term_data_to_dfa( - const regex_pattern_data& pattern_data, - dfa_builder& b, - const Parser& p, - size16_t idx) - { - using slice = utils::slice; - detail::no_stream s{}; - std::optional res = p.parse( - parse_options{}.set_skip_whitespace(false), - buffers::cstring_buffer(pattern_data.pattern), - s - ); - - if (res.has_value()) - { - slice prev{0, size32_t(b.size())}; - b.mark_end_states(res.value(), idx); - b.alt(prev, res.value()); - } - else - throw std::runtime_error("Regex parse error"); - } - - template - constexpr auto dfa_match( - const dfa& sm, - match_options options, - source_point sp, - Iterator start, - Iterator end, - ErrorStream& error_stream) - { - size16_t state_idx = 0; - Iterator it_prev = start; - recognized_term rt{ start, uninitialized16 }; - while (true) - { - const dfa_state& state = sm[state_idx]; - size16_t rec_idx = state.conflicted_recognition[0]; - if (rec_idx != uninitialized16) - { - rt.it = start; - rt.term_idx = rec_idx; - - if (options.verbose) - { - error_stream << sp << " REGEX MATCH: Recognized " << rec_idx << "\n"; - } - } - sp.update(it_prev, start); - - if (start == end) - break; - - size16_t tr = state.transitions[utils::char_to_idx(*start)]; - if (tr == uninitialized16) - { - if (rt.term_idx == uninitialized16) - rt.it = start; - break; - } - - state_idx = tr; - - if (options.verbose) - { - error_stream << sp << " REGEX MATCH: Current char " << utils::c_names.name(*start) << "\n"; - error_stream << sp << " REGEX MATCH: New state " << state_idx << "\n"; - } - it_prev = start; - ++start; - } - return rt; - } - - template - constexpr void write_dfa_state_diag_str(const dfa_state& st, Stream& s, size16_t idx, const StrTable& term_names) - { - s << "STATE " << idx; - if (st.unreachable) - { - s << " (unreachable) \n"; - return; - } - - if (st.end_state) - s << " recognized "; - size16_t term_idx = st.conflicted_recognition[0]; - if (term_idx != uninitialized16) - s << term_names[term_idx]; - s << " "; - - auto f_range = [&s](const auto& r, size16_t state_idx) - { - if (r.size() > 2) - { - s << "["; - s << utils::c_names.name(r.front()); - s << " - "; - s << utils::c_names.name(r.back()); - s << "] -> " << state_idx << " "; - } - else - { - for (char c : r) - { - s << utils::c_names.name(c); - s << " -> " << state_idx << " "; - } - } - }; - - stdex::cvector tmp; - size16_t prev = uninitialized16; - for (size_t i = 0; i < dfa_state::transitions_size + 1; ++i) - { - size16_t to = (i == dfa_state::transitions_size ? uninitialized16 : st.transitions[i]); - if (to == prev && to != uninitialized16) - tmp.push_back(utils::idx_to_char(i)); - else - { - if (prev != uninitialized16) - { - f_range(tmp, prev); - tmp.clear(); - } - if (to != uninitialized16) - tmp.push_back(utils::idx_to_char(i)); - } - prev = to; - } - s << "\n"; - } - - template - constexpr void write_dfa_diag_str(const dfa& sm, Stream& stream, const StrTable& term_names) - { - for (size16_t i = 0; i < sm.size(); ++i) - write_dfa_state_diag_str(sm[i], stream, i, term_names); - } - - template - constexpr void write_dfa_diag_str(const dfa& sm, Stream& stream) - { - write_dfa_diag_str(sm, stream, utils::fake_table{""}); - } - - template - constexpr auto create_regex_parser(Builder& b); -} - -namespace detail -{ - template - constexpr decltype(auto) make_term(Arg&& arg) - { - return std::forward(arg); - } - - constexpr auto make_term(char c) - { - return char_term(c); - } - - template - constexpr auto make_term(const char (&str)[N]) - { - return string_term(str); - } - - template - struct fake_root - { - using value_type = ValueType; - - constexpr auto operator()(const nterm& nt) const; - - constexpr static const char* get_name() { return "##"; }; - }; - - struct eof - { - constexpr static const char* get_name() { return ""; } - }; - - template - class rule - { - public: - using f_type = F; - static const size_t n = sizeof...(R); - - constexpr rule(L l, std::tuple r) : - f(nullptr), l(l), r(r), precedence(0) - {} - - template - constexpr rule(F1&& f, L l, std::tuple r) : - f(std::move(f)), l(l), r(r), precedence(0) - {} - - template - constexpr rule(F1&& f, L l, std::tuple r, int precedence) : - f(std::move(f)), l(l), r(r), precedence(precedence) - {} - - constexpr auto operator[](int prec) - { - return rule(std::move(f), l, r, prec); - } - - template - constexpr auto operator >= (F1&& f) - { - return rule, L, R...>(std::move(f), l, r, precedence); - } - - template - constexpr auto operator >>= (F1&& f) - { - return rule, L, R...>(std::move(f), l, r, precedence); - } - - constexpr const F& get_f() const { return f; } - constexpr const L& get_l() const { return l; } - constexpr const auto& get_r() const { return r; } - constexpr int get_precedence() const { return precedence; } - - private: - F f; - L l; - std::tuple r; - int precedence; - }; - - template - rule(L l, std::tuple r) -> rule; - - template - constexpr auto make_rule_item(Arg&& arg) - { - return make_term(arg); - } - - template - constexpr auto make_rule_item(const nterm& nt) - { - return nt; - } - - template - constexpr auto fake_root::operator()(const nterm& nt) const - { - return rule(*this, std::make_tuple(nt)); - } -} - -template -template -constexpr auto nterm::operator()(Args&&... args) const -{ - return detail::rule( - *this, - std::make_tuple(detail::make_rule_item(args)...) - ); -} - -namespace detail -{ - constexpr size_t value_stack_initial_capacity = 1 << 10; - constexpr size_t cursor_stack_initial_capacity = 1 << 10; - - template - struct value_reductors - { - constexpr value_reductors(const RuleTupleType& rule_tuple): rule_tuple(rule_tuple) { - init_reductors(rule_tuple, std::make_index_sequence>{}); - } - - constexpr ValueVariantType invoke(Context&& context, size_t i, ValueVariantType* args) const { - return reductors[i](std::forward(context), rule_tuple, args); - } - - private: - template - constexpr void init_reductors(const RuleTupleType& rule_tuple, std::index_sequence) - { - (void(init_nth_reductor(std::get(rule_tuple))), ...); - } - - template - constexpr void init_nth_reductor(const detail::rule&) - { - reductors[Nr] = &reduce_value, value_type_t...>; - } - - template - constexpr static LValueType reduce_value_impl([[maybe_unused]] Context&& ctx, [[maybe_unused]] const F& f, ValueVariantType* start, std::index_sequence) - { - if constexpr (std::is_same_v) - return LValueType(std::get(std::move(*(start + I)))...); - else - { - if constexpr (RequiresContext) - return LValueType(f(std::forward(ctx), std::get(std::move(*(start + I)))...)); - else - return LValueType(f(std::get(std::move(*(start + I)))...)); - } - } - - template - constexpr static ValueVariantType reduce_value(Context&& ctx, const RuleTupleType& rules, ValueVariantType* start) - { - return ValueVariantType( - reduce_value_impl( - std::forward(ctx), std::get(rules).get_f(), start, std::index_sequence_for{}) - ); - } - - const RuleTupleType& rule_tuple; - - using value_reductor = ValueVariantType(*)(Context&&, const RuleTupleType&, ValueVariantType*); - value_reductor reductors[RuleCount] = {}; - }; - - template - struct parse_state - { - constexpr parse_state( - CursorStack& cursor_stack, - ValueStack& value_stack, - ErrorStream& error_stream, - parse_options options, - Iterator buffer_begin, - Iterator buffer_end, - const ValueReductors& reductors): - cursor_stack(cursor_stack), - value_stack(value_stack), - error_stream(error_stream), - options(options), - current_sp{1, 1}, - current_it(buffer_begin), - current_term_end_it(buffer_begin), - buffer_end(buffer_end), - reductors(reductors), - current_term_idx(uninitialized16), - recovery_mode(false), - consume_mode(false) - { - cursor_stack.reserve(cursor_stack_initial_capacity); - value_stack.reserve(value_stack_initial_capacity); - } - - constexpr void enter_recovery_mode() { recovery_mode = true; } - constexpr void leave_recovery_mode() { recovery_mode = false; } - constexpr void enter_consume_mode() { consume_mode = true; } - constexpr void leave_consume_mode() { consume_mode = false; } - constexpr bool in_recovery_mode() const { return recovery_mode; } - constexpr bool in_consume_mode() const { return consume_mode; } - - using iterator = Iterator; - - CursorStack& cursor_stack; - ValueStack& value_stack; - ErrorStream& error_stream; - parse_options options; - source_point current_sp; - iterator current_it; - iterator current_term_end_it; - iterator buffer_end; - const ValueReductors& reductors; - size16_t current_term_idx; - bool recovery_mode; - bool consume_mode; - }; - - template - struct parse_table_cursor_stack_type - { - using type = std::vector; - }; - - template - struct parse_table_cursor_stack_type, EmptyRulesCount> - { - using type = stdex::cvector; - }; - - template - using parse_table_cursor_stack_type_t = typename parse_table_cursor_stack_type::type; - - template - struct parser_value_stack_type - { - using type = std::vector; - }; - - template - struct parser_value_stack_type< - buffers::cstring_buffer, - EmptyRulesCount, - ValueVariantType, - std::enable_if_t::value> - > - { - using type = std::vector; - }; - - template - struct parser_value_stack_type< - buffers::cstring_buffer, - EmptyRulesCount, - ValueVariantType, - std::enable_if_t::value> - > - { - using type = stdex::cvector; - }; - - template - using parser_value_stack_type_t = typename parser_value_stack_type::type; -} - - -namespace detail -{ - struct deduce_max_states - { - template - static const size_t value = (0 + ... + (RuleSizes + 1)) * TermCount; - }; -} - -template -struct use_lexer -{ - using type = Lexer; -}; - -struct use_generated_lexer -{ - using type = no_type; -}; - -template -class parser -{}; - -template -class parser< - nterm, - std::tuple, - std::tuple, - std::tuple, - LexerUsage -> -{ - using term_tuple_type = std::tuple; - using nterm_tuple_type = std::tuple; - using rule_tuple_type = std::tuple; - using root_nterm_type = nterm; - using root_value_type = RootValueType; - - static const bool generate_lexer = std::is_same_v; - using lexer_type = typename LexerUsage::type; - -public: - constexpr parser( - root_nterm_type grammar_root, - term_tuple_type terms, - nterm_tuple_type nterms, - rule_tuple_type&& rules, - LexerUsage): - parser(grammar_root, terms, nterms, std::move(rules)) - {} - - constexpr parser( - root_nterm_type grammar_root, - term_tuple_type terms, - nterm_tuple_type nterms, - rule_tuple_type&& rules): - term_tuple(terms), - nterm_tuple(nterms), - rule_tuple(std::move(rules)) - { - auto seq_for_terms = std::make_index_sequence>{}; - analyze_nterms(std::make_index_sequence>{}); - analyze_nterm(detail::fake_root>{}); - analyze_terms(seq_for_terms); - analyze_eof(); - analyze_error_recovery_token(); - analyze_rules(std::make_index_sequence>{}, grammar_root); - analyze_states(); - - create_lexer(seq_for_terms); - } - - template - constexpr std::optional parse(const Buffer& buffer) const - { - detail::no_stream error_stream; - return parse(buffer, error_stream); - } - - template - constexpr std::optional context_parse(Context&& ctx, const Buffer& buffer) const - { - detail::no_stream error_stream; - return context_parse(std::forward(ctx), buffer, error_stream); - } - - template - constexpr std::optional parse(const Buffer& buffer, ErrorStream& error_stream) const - { - return parse(parse_options{}, buffer, error_stream); - } - - template - constexpr std::optional context_parse(Context&& ctx, const Buffer& buffer, ErrorStream& error_stream) const - { - return context_parse(std::forward(ctx), parse_options{}, buffer, error_stream); - } - - template - constexpr std::optional parse(parse_options options, const Buffer& buffer, ErrorStream& error_stream) const - { - return context_parse(no_type{}, options, buffer, error_stream); - } - - template - constexpr std::optional context_parse(Context&& ctx, parse_options options, const Buffer& buffer, ErrorStream& error_stream) const - { - detail::parser_value_stack_type_t value_stack{}; - detail::parse_table_cursor_stack_type_t cursor_stack{}; - - detail::value_reductors reductors(rule_tuple); - detail::parse_state ps(cursor_stack, value_stack, error_stream, options, buffer.begin(), buffer.end(), reductors); - - ps.cursor_stack.push_back(0); - - std::optional root_value; - - while (true) - { - size16_t cursor = ps.cursor_stack.back(); - - auto t_idx = get_current_term(ps); - if (t_idx == uninitialized16) - break; - - const auto& entry = parse_table[cursor][get_parse_table_idx(true, t_idx)]; - - if (entry.kind == parse_table_entry_kind::error) - { - if (ps.in_consume_mode()) - { - if (!consume_term_recovering(ps)) - break; - continue; - } - if (!ps.in_recovery_mode()) - { - syntax_error(ps); - enter_recovery_mode(ps); - } - if (!pop_stacks(ps)) - break; - continue; - } - else - { - if (ps.in_consume_mode()) - leave_consume_mode(ps); - } - - if (entry.kind == parse_table_entry_kind::shift) - { - shift(ps, buffer.get_view(ps.current_it, ps.current_term_end_it), t_idx, entry.shift); - consume_term(ps); - } - else if (entry.kind == parse_table_entry_kind::shift_error_recovery_token) - { - shift_recovery_token(ps, entry.shift); - leave_recovery_mode(ps); - enter_consume_mode(ps); - } - else if (entry.kind == parse_table_entry_kind::reduce) - reduce(std::forward(ctx), ps, entry.reduce); - else if (entry.kind == parse_table_entry_kind::rr_conflict) - rr_conflict(std::forward(ctx), ps, entry.reduce); - else if (entry.kind == parse_table_entry_kind::success) - { - root_value = std::optional(std::move(success(ps))); - break; - } - } - - return root_value; - } - - template - constexpr void write_diag_str(Stream& s) const - { - s << "PARSER" << "\n" << "\n"; - - s << "Parser Object size: " << sizeof(*this) << "\n\nRULES\n\n"; - - for (size16_t i = 0; i < rule_count; ++i) - { - s << i << " "; - write_rule_diag_str(s, i); - s << "\n"; - } - - s << "\nSTATES\n\n"; - for (size16_t i = 0; i < state_count; ++i) - { - write_state_diag_str(s, i); - s << "\n"; - } - - if constexpr (generate_lexer) - { - s << "\n" << "LEXICAL ANALYZER" << "\n" << "\n"; - regex::write_dfa_diag_str(lexer_sm, s, term_names); - } - } - -private: - static const size_t max_rule_element_count = meta::max_v<1, Rules::n...>; - static const size16_t eof_idx = sizeof...(Terms); - static const size16_t error_recovery_token_idx = sizeof...(Terms) + 1; - static const size_t term_count = sizeof...(Terms) + 2; - static const size16_t fake_root_idx = sizeof...(NTerms); - static const size_t nterm_count = sizeof...(NTerms) + 1; - static const size_t root_rule_idx = sizeof...(Rules); - static const size_t rule_count = sizeof...(Rules) + 1; - static const size_t empty_rules_count = meta::count_zeros; - static const size_t situation_size = max_rule_element_count + 1; - static const size_t situation_address_space_size = rule_count * situation_size * term_count; - static const size_t max_states = detail::deduce_max_states::template value; - static const size_t lexer_dfa_size = generate_lexer ? (0 + ... + Terms::dfa_size) : 1; - - using value_variant_type = meta::unique_types_variant_t< - std::nullptr_t, - no_type, - value_type_t..., - value_type_t... - >; - - using term_subset = stdex::cbitset; - using nterm_subset = stdex::cbitset; - using right_side_slice_subset = stdex::cbitset; - using state = stdex::cbitset; - using situation_set = stdex::cbitset; - - struct situation_queue_entry - { - size16_t state_idx; - size32_t idx; - }; - - using situation_queue_t = stdex::cqueue< - situation_queue_entry, - max_states * max_states - >; - - struct symbol - { - constexpr symbol() : - term(false), idx(uninitialized16) - {} - - constexpr symbol(bool term, size16_t idx) : - term(term), idx(idx) - {} - - constexpr size16_t get_parse_table_idx() const - { - return parser::get_parse_table_idx(term, idx); - } - - bool term; - size16_t idx; - }; - - struct situation_info - { - size16_t rule_info_idx; - size16_t after; - size16_t t; - }; - - struct rule_info - { - size16_t l_idx; - size16_t r_idx; - size16_t r_elements; - }; - - enum class parse_table_entry_kind : size16_t { error, success, shift, shift_error_recovery_token, reduce, rr_conflict }; - - constexpr static bool is_shift(parse_table_entry_kind kind) - { - return kind == parse_table_entry_kind::shift || kind == parse_table_entry_kind::shift_error_recovery_token; - } - - struct parse_table_entry - { - parse_table_entry_kind kind = parse_table_entry_kind::error; - size16_t shift = uninitialized16; - size16_t reduce = uninitialized16; - - bool has_shift = false; - bool has_reduce = false; - - constexpr void set_shift(size16_t value) { shift = value; has_shift = true; } - constexpr void set_reduce(size16_t value) { reduce = value; has_reduce = true; } - }; - - constexpr static size16_t get_parse_table_idx(bool term, size16_t idx) - { - return term ? nterm_count + idx : idx; - } - - constexpr void analyze_eof() - { - term_names[eof_idx] = detail::eof::get_name(); - term_ids[eof_idx] = detail::eof::get_name(); - term_precedences[eof_idx] = 0; - term_associativities[eof_idx] = associativity::no_assoc; - } - - constexpr void analyze_error_recovery_token() - { - term_names[error_recovery_token_idx] = error_recovery_token::get_name(); - term_ids[error_recovery_token_idx] = error_recovery_token::get_name(); - term_precedences[error_recovery_token_idx] = 0; - term_associativities[error_recovery_token_idx] = associativity::no_assoc; - } - - template - constexpr void analyze_term(const Term& t) - { - term_precedences[TermIdx] = t.get_precedence(); - term_associativities[TermIdx] = t.get_associativity(); - term_names[TermIdx] = t.get_name(); - term_ids[TermIdx] = t.get_id(); - term_ftors[TermIdx] = string_view_to_term_value; - } - - template - constexpr void analyze_nterm(const nterm& nt, size16_t idx) - { - nterm_names[idx] = nt.get_name(); - } - - template - constexpr void analyze_nterm(detail::fake_root) - { - nterm_names[fake_root_idx] = detail::fake_root::get_name(); - } - - template - constexpr auto make_symbol(const Term& t) const - { - return symbol{ true, size16_t(utils::find_str(term_ids, t.get_id())) }; - } - - template - constexpr auto make_symbol(const nterm& nt) const - { - return symbol{ false, size16_t(utils::find_str(nterm_names, nt.get_name())) }; - } - - template - constexpr void analyze_terms(std::index_sequence) - { - (void(analyze_term(std::get(term_tuple))), ...); - } - - template - constexpr void analyze_nterms(std::index_sequence) - { - (void(analyze_nterm(std::get(nterm_tuple), I)), ...); - } - - template - constexpr void analyze_rules(std::index_sequence, const root_nterm_type& root) - { - (void(analyze_rule(std::get(rule_tuple), std::make_index_sequence{})), ...); - analyze_rule(detail::fake_root>{}(root), std::index_sequence<0>{}); - stdex::sort(rule_infos, [](const auto& ri1, const auto& ri2) { return ri1.l_idx < ri2.l_idx; }); - make_nterm_rule_slices(); - } - - constexpr void make_nterm_rule_slices() - { - size16_t nt = 0; - for (size16_t i = 0u; i < rule_count; ++i) - { - if (nt != rule_infos[i].l_idx) - { - nt = rule_infos[i].l_idx; - nterm_rule_slices[nt].start = i; - nterm_rule_slices[nt].n = 1; - } - else - nterm_rule_slices[nt].n++; - } - } - - constexpr size16_t calculate_rule_last_term(size16_t rule_idx, size16_t rule_size) const - { - for (int i = int(rule_size - 1); i >= 0; --i) - { - const auto& s = right_sides[rule_idx][i]; - if (!s.term) - continue; - return s.idx; - } - return uninitialized16; - } - - constexpr int calculate_rule_precedence(int precedence, size16_t rule_idx) const - { - if (precedence != 0) - return precedence; - size16_t last_term_idx = rule_last_terms[rule_idx]; - if (last_term_idx != uninitialized16) - return term_precedences[last_term_idx]; - return 0; - } - - constexpr associativity calculate_rule_associativity(size16_t rule_idx) const - { - size16_t last_term_idx = rule_last_terms[rule_idx]; - if (last_term_idx != uninitialized16) - return term_associativities[last_term_idx]; - return associativity::no_assoc; - } - - template - constexpr void analyze_rule(const detail::rule& r, std::index_sequence) - { - size16_t l_idx = size16_t(utils::find_str(nterm_names, r.get_l().get_name())); - (void(right_sides[Nr][I] = make_symbol(std::get(r.get_r()))), ...); - constexpr size16_t rule_elements_count = size16_t(sizeof...(R)); - rule_infos[Nr] = { l_idx, size16_t(Nr), rule_elements_count }; - rule_last_terms[Nr] = calculate_rule_last_term(Nr, rule_elements_count); - rule_precedences[Nr] = calculate_rule_precedence(r.get_precedence(), Nr); - rule_associativities[Nr] = calculate_rule_associativity(Nr); - } - - struct state_analyze_info - { - situation_queue_t situation_queue = { }; - stdex::cvector closures[situation_address_space_size] = {}; - stdex::cbitset done_closures = {}; - term_subset situation_first_after[situation_address_space_size] = { }; - situation_set situation_first_after_analyzed = {}; - term_subset right_side_slice_first[situation_size * rule_count] = {}; - right_side_slice_subset right_side_slice_first_analyzed = {}; - nterm_subset nterm_empty = { }; - term_subset nterm_first[nterm_count] = { }; - nterm_subset nterm_empty_analyzed = { }; - nterm_subset nterm_first_analyzed = { }; - }; - - constexpr size32_t make_situation_idx(situation_info a) const - { - return a.rule_info_idx * situation_size * term_count + a.after * term_count + a.t; - } - - constexpr situation_info make_situation_info(size32_t idx) const - { - size16_t t = size16_t(idx % term_count); - idx /= term_count; - size16_t after = size16_t(idx % situation_size); - size16_t rule_info_idx = size16_t(idx / situation_size); - return situation_info{ rule_info_idx, after, t }; - } - - constexpr void add_term_subset(term_subset& dest, const term_subset& source) - { - for (size_t i = 0u; i < term_count; ++i) - dest.set(i, dest.test(i) || source.test(i)); - } - - constexpr const term_subset& make_right_side_slice_first(const rule_info& ri, size_t start, state_analyze_info& sai) - { - size_t right_side_slice_idx = max_rule_element_count * ri.r_idx + start; - auto& res = sai.right_side_slice_first[right_side_slice_idx]; - - if (sai.right_side_slice_first_analyzed.test(right_side_slice_idx)) - return res; - sai.right_side_slice_first_analyzed.set(right_side_slice_idx); - - for (size_t i = start; i < ri.r_elements; ++i) - { - const symbol& s = right_sides[ri.r_idx][i]; - if (s.term) - { - res.set(s.idx); - break; - } - add_term_subset(res, make_nterm_first(s.idx, sai)); - if (!make_nterm_empty(s.idx, sai)) - break; - } - return res; - } - - constexpr const term_subset& make_nterm_first(size16_t nt, state_analyze_info& sai) - { - if (sai.nterm_first_analyzed.test(nt)) - return sai.nterm_first[nt]; - sai.nterm_first_analyzed.set(nt); - - const utils::slice& s = nterm_rule_slices[nt]; - for (size_t i = 0u; i < s.n; ++i) - { - const rule_info& ri = rule_infos[s.start + i]; - add_term_subset(sai.nterm_first[nt], make_right_side_slice_first(ri, 0, sai)); - } - return sai.nterm_first[nt]; - } - - constexpr bool is_right_side_slice_empty(const rule_info& ri, size_t start, state_analyze_info& sai) - { - for (size_t i = start; i < ri.r_elements; ++i) - { - const symbol& s = right_sides[ri.r_idx][i]; - if (s.term) - return false; - if (!make_nterm_empty(s.idx, sai)) - return false; - } - return true; - } - - constexpr bool is_right_side_empty(const rule_info& ri, state_analyze_info& sai) - { - return is_right_side_slice_empty(ri, 0, sai); - } - - constexpr bool make_nterm_empty(size16_t nt, state_analyze_info& sai) - { - if (sai.nterm_empty_analyzed.test(nt)) - return sai.nterm_empty.test(nt); - sai.nterm_empty_analyzed.set(nt); - - const utils::slice& s = nterm_rule_slices[nt]; - for (size_t i = 0u; i < s.n; ++i) - { - if (is_right_side_empty(rule_infos[s.start + i], sai)) - { - return (sai.nterm_empty.set(nt), true); - } - } - return (sai.nterm_empty.reset(nt), false); - } - - constexpr const term_subset& make_situation_first_after(const situation_info& addr, size32_t idx, state_analyze_info& sai) - { - if (sai.situation_first_after_analyzed.test(idx)) - return sai.situation_first_after[idx]; - sai.situation_first_after_analyzed.set(idx); - - const rule_info& ri = rule_infos[addr.rule_info_idx]; - add_term_subset(sai.situation_first_after[idx], make_right_side_slice_first(ri, addr.after + 1, sai)); - if (is_right_side_slice_empty(ri, addr.after + 1, sai)) - sai.situation_first_after[idx].set(addr.t); - return sai.situation_first_after[idx]; - } - - constexpr void analyze_states() - { - situation_info root_situation_info{ root_rule_idx, 0, eof_idx }; - size32_t idx = make_situation_idx(root_situation_info); - state_count = 1; - - state_analyze_info sai; - - add_situation_to_state(0, idx, sai); - - while (!sai.situation_queue.empty()) - { - const auto& entry = sai.situation_queue.top(); - sai.situation_queue.pop(); - - situation_closure(entry.state_idx, entry.idx, sai); - situation_transition(entry.state_idx, entry.idx, sai); - } - } - - constexpr void add_situation_to_state(size16_t state_idx, size32_t idx, state_analyze_info& sai) - { - state& s = states[state_idx]; - if (!s.test(idx)) - { - s.set(idx); - sai.situation_queue.push({ state_idx, idx }); - } - } - - constexpr void situation_closure(size16_t state_idx, size32_t idx, state_analyze_info& sai) - { - if (sai.done_closures.test(idx)) - { - for(auto i = 0u; i < sai.closures[idx].size(); ++i) - { - add_situation_to_state(state_idx, sai.closures[idx][i], sai); - } - return; - } - - sai.done_closures.set(idx); - - situation_info addr = make_situation_info(idx); - const rule_info& ri = rule_infos[addr.rule_info_idx]; - if (addr.after >= ri.r_elements) - return; - - const symbol& s = right_sides[ri.r_idx][addr.after]; - if (!s.term) - { - size16_t nt = s.idx; - const term_subset& first = make_situation_first_after(addr, idx, sai); - const utils::slice& sl = nterm_rule_slices[nt]; - for (auto i = 0u; i < sl.n; ++i) - { - for (size16_t t = 0; t < term_count; ++t) - { - if (first.test(t)) - { - size32_t new_s_idx = make_situation_idx(situation_info{ size16_t(sl.start + i), 0, t }); - add_situation_to_state(state_idx, new_s_idx, sai); - sai.closures[idx].push_back(new_s_idx); - } - } - } - } - } - - constexpr auto solve_conflict(size16_t rule_info_idx, size16_t term_idx) const - { - size16_t rule_idx = rule_infos[rule_info_idx].r_idx; - int r_p = rule_precedences[rule_idx]; - int t_p = term_precedences[term_idx]; - if (r_p > t_p) - return parse_table_entry_kind::reduce; - - if (r_p == t_p) - { - if (rule_associativities[rule_idx] == associativity::ltor) - return parse_table_entry_kind::reduce; - } - return parse_table_entry_kind::shift; - } - - constexpr void situation_transition(size16_t state_idx, size32_t idx, state_analyze_info& sai) - { - situation_info addr = make_situation_info(idx); - const rule_info& ri = rule_infos[addr.rule_info_idx]; - bool reduction = addr.after >= ri.r_elements; - - const auto& s = right_sides[ri.r_idx][addr.after]; - size16_t symbol_idx = reduction ? get_parse_table_idx(true, addr.t) : s.get_parse_table_idx(); - auto& entry = parse_table[state_idx][symbol_idx]; - if (reduction) - { - if (ri.r_idx == root_rule_idx) - { - entry.kind = parse_table_entry_kind::success; - } - else if (entry.has_shift) - { - entry.kind = solve_conflict(addr.rule_info_idx, addr.t); - } - else if (entry.has_reduce) - { - entry.kind = parse_table_entry_kind::rr_conflict; - } - else - { - entry.kind = parse_table_entry_kind::reduce; - } - entry.set_reduce(size16_t(addr.rule_info_idx)); - return; - } - - situation_info new_addr = situation_info{ addr.rule_info_idx, size16_t(addr.after + 1), addr.t }; - size32_t new_idx = make_situation_idx(new_addr); - - if (entry.has_shift) - { - add_situation_to_state(entry.shift, new_idx, sai); - return; - } - - size16_t new_state_idx = uninitialized16; - for (size16_t i = 0; i < state_count; ++i) - { - if (states[i].test(new_idx)) - { - new_state_idx = i; - break; - } - } - if (new_state_idx == uninitialized16) - { - new_state_idx = state_count; - ++state_count; - } - - if (entry.has_reduce) - { - entry.kind = solve_conflict(entry.reduce, s.idx); - } - else - { - entry.kind = parse_table_entry_kind::shift; - }; - entry.set_shift(new_state_idx); - - if (entry.kind == parse_table_entry_kind::shift && s.idx == error_recovery_token_idx) - entry.kind = parse_table_entry_kind::shift_error_recovery_token; - - add_situation_to_state(new_state_idx, new_idx, sai); - } - - constexpr const char* get_symbol_name(const symbol& s) const - { - return s.term ? term_names[s.idx] : nterm_names[s.idx]; - } - - template - constexpr void write_rule_diag_str(Stream& s, size16_t rule_info_idx) const - { - const rule_info& ri = rule_infos[rule_info_idx]; - s << nterm_names[ri.l_idx] << " <- "; - if (ri.r_elements > 0) - s << get_symbol_name(right_sides[ri.r_idx][0]); - for (size_t i = 1u; i < ri.r_elements; ++i) - { - s << " " << get_symbol_name(right_sides[ri.r_idx][i]); - } - } - - template - constexpr void write_situation_diag_str(Stream& s, size32_t idx) const - { - const situation_info addr = make_situation_info(idx); - const rule_info& ri = rule_infos[addr.rule_info_idx]; - s << nterm_names[ri.l_idx] << " <- "; - for (size_t i = 0u; i < addr.after; ++i) - { - s << get_symbol_name(right_sides[ri.r_idx][i]) << " "; - } - s << ". "; - for (size_t i = addr.after; i < ri.r_elements; ++i) - { - s << get_symbol_name(right_sides[ri.r_idx][i]) << " "; - } - s << "==> " << term_names[addr.t]; - } - - template - constexpr void write_state_diag_str(Stream& s, size16_t idx) const - { - s << "STATE " << idx << "\n"; - - for (size32_t i = 0u; i < situation_address_space_size; ++i) - { - if (states[idx].test(i)) - { - write_situation_diag_str(s, i); - s << "\n"; - } - } - - s << "\n"; - - for (size_t i = 0; i < nterm_count; ++i) - { - const auto& entry = parse_table[idx][i]; - if (is_shift(entry.kind)) - s << "On " << nterm_names[i] << " go to " << entry.shift << "\n"; - } - for (size_t i = nterm_count; i < nterm_count + term_count; ++i) - { - const auto& entry = parse_table[idx][i]; - if (entry.kind == parse_table_entry_kind::error) - continue; - - size_t term_idx = i - nterm_count; - s << "On " << term_names[term_idx]; - if (entry.kind == parse_table_entry_kind::success) - s << " success \n"; - else if (entry.kind == parse_table_entry_kind::reduce && entry.has_shift) - s << " shift to " << entry.shift << " S/R CONFLICT, prefer reduce(" << rule_infos[entry.reduce].r_idx << ") over shift\n"; - else if (is_shift(entry.kind) && entry.has_reduce) - s << " shift to " << entry.shift << " S/R CONFLICT, prefer shift over reduce(" << rule_infos[entry.reduce].r_idx << ")\n"; - else if (is_shift(entry.kind)) - s << " shift to " << entry.shift << "\n"; - else if (entry.kind == parse_table_entry_kind::reduce) - s << " reduce using (" << rule_infos[entry.reduce].r_idx << ")\n"; - else if (entry.kind == parse_table_entry_kind::rr_conflict) - s << " R/R CONFLICT - !!! FIX IT !!! \n"; - } - } - - template - constexpr static value_variant_type string_view_to_term_value(const term_tuple_type& term_tuple, const std::string_view& sv, source_point sp) - { - const auto &t = std::get(term_tuple); - using term_value_type = value_type_t>; - return value_variant_type(term_value_type(t.get_ftor()(sv), sp)); - } - - template - constexpr void shift_recovery_token(ParseState& ps, size16_t new_cursor_value) const - { - if (ps.options.verbose) - ps.error_stream << ps.current_sp << " PARSE: Shift to " << new_cursor_value << ", term: " << term_names[error_recovery_token_idx] << "\n"; - ps.cursor_stack.push_back(new_cursor_value); - - ps.value_stack.emplace_back(term_value(no_type{}, ps.current_sp)); - } - - template - constexpr void shift(ParseState& ps, const std::string_view& sv, size16_t term_idx, size16_t new_cursor_value) const - { - if (ps.options.verbose) - ps.error_stream << ps.current_sp << " PARSE: Shift to " << new_cursor_value << ", term: " << sv << "\n"; - ps.cursor_stack.push_back(new_cursor_value); - - const auto& ftor = term_ftors[term_idx]; - ps.value_stack.emplace_back(ftor(term_tuple, sv, ps.current_sp)); - } - - template - constexpr void reduce(Context&& ctx, ParseState& ps, size16_t rule_info_idx) const - { - const auto& ri = rule_infos[rule_info_idx]; - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Reduced using rule " << ri.r_idx << " "; - write_rule_diag_str(ps.error_stream, rule_info_idx); - ps.error_stream << "\n"; - } - - ps.cursor_stack.erase(ps.cursor_stack.end() - ri.r_elements, ps.cursor_stack.end()); - size16_t new_cursor_value = parse_table[ps.cursor_stack.back()][ri.l_idx].shift; - - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Go to " << new_cursor_value << "\n"; - } - - ps.cursor_stack.push_back(new_cursor_value); - value_variant_type* start = ps.value_stack.data() + ps.value_stack.size() - ri.r_elements; - value_variant_type lvalue(ps.reductors.invoke(std::forward(ctx), ri.r_idx, start)); - ps.value_stack.erase(ps.value_stack.end() - ri.r_elements, ps.value_stack.end()); - ps.value_stack.emplace_back(std::move(lvalue)); - } - - template - constexpr void rr_conflict(Context&& ctx, ParseState& ps, size16_t rule_idx) const - { - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: R/R conflict encountered \n"; - } - reduce(std::forward(ctx), ps, rule_idx); - } - - template - constexpr bool pop_stacks(ParseState& ps) const - { - ps.cursor_stack.pop_back(); - if (ps.value_stack.size() != 0) - ps.value_stack.pop_back(); - - if (ps.cursor_stack.size() == 0) - { - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Could not recover from error \n"; - } - return false; - } - - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Recovering to state " << ps.cursor_stack.back() << "\n"; - } - - return true; - } - - template - constexpr void syntax_error(ParseState& ps) const - { - ps.error_stream << ps.current_sp << " PARSE: Syntax error: " << - "Unexpected '" << term_names[ps.current_term_idx] << "'" << "\n"; - } - - template - constexpr root_value_type& success(ParseState& ps) const - { - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Success \n"; - } - return std::get(ps.value_stack.front()); - } - - template - constexpr void consume_term(ParseState& ps) const - { - ps.current_sp.update(ps.current_it, ps.current_term_end_it); - ps.current_it = ps.current_term_end_it; - } - - template - constexpr void enter_recovery_mode(ParseState& ps) const - { - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Entering recovery mode \n"; - } - ps.enter_recovery_mode(); - } - - template - constexpr void leave_recovery_mode(ParseState& ps) const - { - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Leaving recovery mode \n"; - } - ps.leave_recovery_mode(); - } - - template - constexpr void enter_consume_mode(ParseState& ps) const - { - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Entering consume mode \n"; - } - ps.enter_consume_mode(); - } - - template - constexpr void leave_consume_mode(ParseState& ps) const - { - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Leaving consume mode \n"; - } - ps.leave_consume_mode(); - } - - template - constexpr bool consume_term_recovering(ParseState& ps) const - { - if (ps.current_term_idx == eof_idx) - return false; - if (ps.options.verbose) - { - ps.error_stream << ps.current_sp << " PARSE: Recovery, consuming term " << term_names[ps.current_term_idx] << " \n"; - } - consume_term(ps); - return true; - } - - template - constexpr size16_t get_current_term(ParseState& ps) const - { - if (ps.in_recovery_mode()) - return error_recovery_token_idx; - - if (ps.current_it != ps.current_term_end_it) - return ps.current_term_idx; - - if (ps.options.skip_whitespace) - { - auto after_ws = skip_whitespace(ps); - ps.current_sp.update(ps.current_it, after_ws); - ps.current_it = after_ws; - } - - using res_type = recognized_term; - - if (ps.current_it == ps.buffer_end) - { - ps.current_term_idx = eof_idx; - trace_recognized_term(ps); - return eof_idx; - } - - res_type res{}; - match_options opts; - opts.set_verbose(ps.options.verbose); - - if constexpr (generate_lexer) - { - res = regex::dfa_match(lexer_sm, opts, ps.current_sp, ps.current_it, ps.buffer_end, ps.error_stream); - } - else - { - lexer_type custom_lexer; - res = custom_lexer.match(opts, ps.current_sp, ps.current_it, ps.buffer_end, ps.error_stream); - } - - ps.current_term_end_it = res.it; - ps.current_term_idx = res.term_idx; - - if (ps.current_term_idx == uninitialized16) - { - unexpected_char(ps); - return uninitialized16; - } - else - { - trace_recognized_term(ps); - } - - return ps.current_term_idx; - } - - template - constexpr auto skip_whitespace(ParseState& ps) const - { - constexpr char space_chars_newline[] = { 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x20, 0x00 }; - constexpr char space_chars_no_newline[] = { 0x09, 0x0b, 0x0c, 0x0d, 0x20, 0x00 }; - - const auto space_chars = ps.options.skip_newline - ? space_chars_newline - : space_chars_no_newline; - - auto start = ps.current_it; - while (true) - { - if (start == ps.buffer_end) - break; - if (utils::find_char(*start, space_chars) == uninitialized) - break; - ++start; - } - return start; - } - - template - constexpr void unexpected_char(ParseState& ps) const - { - ps.error_stream << ps.current_sp << " PARSE: Unexpected character: " << *ps.current_it << "\n"; - } - - template - constexpr void trace_recognized_term(ParseState& ps) const - { - if (ps.options.verbose) - ps.error_stream << ps.current_sp << " PARSE: Recognized " << term_names[ps.current_term_idx] << " \n"; - } - - struct no_parser{}; - - template - constexpr void create_lexer(std::index_sequence) - { - if constexpr (generate_lexer) - { - regex::dfa_builder b(lexer_sm); - constexpr bool trivial_lexer = (true && ... && std::tuple_element_t::is_trivial); - if constexpr (trivial_lexer) - (void(regex::add_term_data_to_dfa(std::get(term_tuple).get_data(), b, no_parser{}, size16_t(I))), ...); - else - { - auto p = regex::create_regex_parser(b); - (void(regex::add_term_data_to_dfa(std::get(term_tuple).get_data(), b, p, size16_t(I))), ...); - } - } - } - - str_table term_names = { }; - str_table term_ids = { }; - str_table nterm_names = { }; - symbol right_sides[rule_count][max_rule_element_count] = { }; - rule_info rule_infos[rule_count] = { }; - utils::slice nterm_rule_slices[nterm_count] = { }; - state states[max_states] = { }; - parse_table_entry parse_table[max_states][term_count + nterm_count] = {}; - size16_t state_count = 0; - int term_precedences[term_count] = { }; - associativity term_associativities[term_count] = { }; - int rule_precedences[rule_count] = { }; - associativity rule_associativities[rule_count] = { }; - size16_t rule_last_terms[rule_count] = { }; - term_tuple_type term_tuple; - nterm_tuple_type nterm_tuple; - rule_tuple_type rule_tuple; - - using string_view_to_term_value_t = value_variant_type(*)(const term_tuple_type&, const std::string_view&, source_point); - string_view_to_term_value_t term_ftors[term_count] = {}; - - using dfa_type = regex::dfa; - dfa_type lexer_sm = {}; -}; - -template -parser(Root, Terms, NTerms, Rules&&) -> parser; - -template -parser(Root, Terms, NTerms, Rules&&, LexerUsage) -> parser; - -template -constexpr auto terms(const Terms&... terms) -{ - return std::make_tuple(detail::make_term(terms)...); -} - -template -constexpr auto nterms(NTerms... nterms) -{ - return std::make_tuple(nterms...); -} - -template -constexpr auto rules(Rules&&... rules) -{ - return std::make_tuple(std::move(rules)...); -} - -struct skip -{ - template - constexpr skip(T&&) {} -}; - -namespace regex -{ - class regex_lexer - { - public: - constexpr regex_lexer() - { - //0 1 2 3 4 5 6 7 8 9 - //regex_digit_09 regex_primary * + ? | ( ) { } - - specials[utils::char_to_idx('*')] = 2; - specials[utils::char_to_idx('+')] = 3; - specials[utils::char_to_idx('?')] = 4; - specials[utils::char_to_idx('|')] = 5; - specials[utils::char_to_idx('(')] = 6; - specials[utils::char_to_idx(')')] = 7; - specials[utils::char_to_idx('{')] = 8; - specials[utils::char_to_idx('}')] = 9; - } - - template - constexpr auto match( - match_options options, - source_point sp, - Iterator start, - Iterator end, - ErrorStream& error_stream) - { - if (start == end) - return not_recognized(start); - - char c = *start; - - auto res = [&](size16_t idx, size_t len) - { return recognized(idx, len, options, sp, start, error_stream); }; - - if (specials[utils::char_to_idx(c)] != 0) - return res(specials[utils::char_to_idx(c)], 1); - - if (utils::is_dec_digit(c)) - return res(0, 1); - - size_t len = 0; - bool ok = match_primary(start, end, len); - if (ok) - return res(1, len); - - return not_recognized(start); - } - - private: - size16_t specials[meta::distinct_chars_count] = {}; - - template - constexpr bool match_primary(Iterator start, Iterator end, size_t& len) - { - len = 0; - bool ok = match_escaped(start, end, len); - if (!ok) - return false; - if (len != 0) - return true; - - ok = match_range(start, end, len); - if (!ok) - return false; - if (len != 0) - return true; - - ok = utils::is_printable(*start); - if (ok) - len = 1; - return ok; - } - - template - constexpr bool match_range(Iterator start, Iterator end, size_t& len) - { - char c = *start; - if (c == '[') - { - len = 1; - ++start; - if (start == end) - { - len = 0; - return false; - } - c = *start; - if (c == '^') - { - len = 2; - ++start; - } - if (start == end) - { - len = 0; - return false; - } - while (start != end && *start != ']') - { - size_t item_len = 0; - bool ok = match_range_item(start, end, item_len); - if (!ok) - { - len = 0; - return false; - } - len += item_len; - start += item_len; - } - if (start == end) - { - len = 0; - return false; - } - len++; - } - return true; - } - - template - constexpr bool match_range_item(Iterator start, Iterator end, size_t& len) - { - len = 0; - bool ok = match_escaped(start, end, len); - if (!ok) - return false; - - if (len == 0) - { - ok = utils::is_printable(*start); - if (!ok) - return false; - len = 1; - } - - start += len; - - if (*start == '-') - { - len++; - - ++start; - if (start == end || *start == ']') - return false; - - size_t range_end_len = 0; - bool escaped_ok = match_escaped(start, end, range_end_len); - if (!escaped_ok) - return false; - - if (range_end_len == 0) - { - ok = utils::is_printable(*start); - if (!ok) - return false; - len += 1; - } - else - len += range_end_len; - } - - return ok; - } - - template - constexpr bool match_escaped(Iterator start, Iterator end, size_t& len) - { - char c = *start; - - if (c == '\\') - { - ++start; - if (start == end) - return false; - c = *start; - len = 2; - if (c == 'x') - { - ++start; - if (start == end) - return true; - c = *start; - if (!utils::is_hex_digit(c)) - return true; - ++start; - len = 3; - if (start == end) - return true; - c = *start; - if (!utils::is_hex_digit(c)) - return true; - len = 4; - return true; - } - return utils::is_printable(c); - } - return true; - } - - template - constexpr auto recognized( - size16_t idx, - size_t len, - match_options options, - source_point sp, - Iterator start, - ErrorStream& error_stream) - { - Iterator term_end = start; - if (options.verbose) - error_stream << sp << " LEXER MATCH: Recognized " << idx << " \n"; - term_end += len; - sp.update(start, term_end); - return recognized_term{term_end, idx}; - } - - template - constexpr auto not_recognized(Iterator start) const - { - return recognized_term{start, uninitialized16}; - } - }; - - constexpr char regex_char(std::string_view sv, size_t& len) - { - if (sv[0] == '\\') - { - if (sv[1] == 'x') - { - if (sv.size() == 2 || !utils::is_hex_digit(sv[2])) - { - len = 2; - return 0; - } - else if (sv.size() == 3 || !utils::is_hex_digit(sv[3])) - { - len = 3; - return hex_digits_to_char('0', sv[2]); - } - else - { - len = 4; - return hex_digits_to_char(sv[2], sv[3]); - } - } - else - { - len = 2; - return sv[1]; - } - } - else - { - len = 1; - return sv[0]; - } - } - - constexpr char_subset string_view_to_subset(std::string_view sv) - { - char_subset cs; - - if (sv[0] == '.') - cs.flip(); - else if (sv[0] == '[') - { - bool flip = false; - size_t i = 1; - if (sv[1] == '^') - { - i++; - flip = true; - } - while (sv[i] != ']') - { - size_t len = 0; - char c1 = regex_char(sv.substr(i), len); - i += len; - if (sv[i] == '-') - { - ++i; - char c2 = regex_char(sv.substr(i), len); - cs.add_range(char_range{c1, c2}); - } - else - cs.set(utils::char_to_idx(c1)); - } - if (flip) - cs.flip(); - } - else - { - size_t len = 0; - cs.set(utils::char_to_idx(regex_char(sv, len))); - } - - return cs; - } - - template - constexpr auto create_regex_parser(Builder& b) - { - using slice = utils::slice; - using namespace ftors; - - constexpr nterm expr("expr"); - constexpr nterm alt("alt"); - constexpr nterm concat("concat"); - constexpr nterm q_expr("q_expr"); - constexpr nterm primary("primary"); - constexpr nterm number("number"); - - constexpr custom_term regex_digit_09("regex_digit_09", [](auto sv) { return size32_t(sv[0]) - '0'; }); - constexpr custom_term regex_primary("regex_primary", string_view_to_subset); - - return parser( - expr, - terms(regex_digit_09, regex_primary, '*', '+', '?', '|', '(', ')', '{', '}'), - nterms(expr, alt, concat, q_expr, primary, number), - rules( - number(regex_digit_09), - number(number, regex_digit_09) >= [](size32_t n, size32_t x){ return n * 10 + x; }, - primary(regex_digit_09) >= [&b](size32_t number){ return b.primary_char(char(number + '0')); }, - primary(regex_primary) >= [&b](const auto& s){ return b.primary_subset(s); }, - primary('(', expr, ')') >= _e2, - q_expr(primary), - q_expr(primary, '*') >= [&b](slice s, skip) { return b.star(s); }, - q_expr(primary, '+') >= [&b](slice s, skip) { return b.plus(s); }, - q_expr(primary, '?') >= [&b](slice s, skip) { return b.opt(s); }, - q_expr(primary, '{', number, '}') >= [&b](slice s, skip, size32_t n, skip) { return b.rep(s, n); }, - concat(q_expr), - concat(concat, q_expr) >= [&b](slice s1, slice s2) { return b.cat(s1, s2); }, - alt(concat), - alt(alt, '|', alt) >= [&b](slice s1, skip, slice s2) { return b.alt(s1, s2); }, - expr(alt) - ), - use_lexer{} - ); - } - - template - constexpr size32_t analyze_dfa_size(const char (&pattern)[N]) - { - dfa_size_analyzer a; - auto p = create_regex_parser(a); - buffers::cstring_buffer buffer(pattern); - detail::no_stream s{}; - auto res = p.parse( - parse_options{}.set_skip_whitespace(false), - buffer, - s); - if (!res.has_value()) - throw std::runtime_error("invalid regex"); - return res.value().n; - } - - template - constexpr void write_regex_parser_diag_msg(Stream& s) - { - regex::dfa_size_analyzer a; - auto p = regex::create_regex_parser(a); - p.write_diag_str(s); - } - - template - class expr - { - public: - static const size32_t dfa_size = analyze_dfa_size(Pattern); - - constexpr expr() - { - dfa_builder b(sm); - auto p = create_regex_parser(b); - detail::no_stream stream{}; - auto s = p.parse( - parse_options{}.set_skip_whitespace(false), - buffers::cstring_buffer(Pattern), - stream - ); - if (!s.has_value()) - throw std::runtime_error("invalid regex"); - b.mark_end_states(s.value(), 0); - } - - template - constexpr void debug_parse(Stream& s) const - { - regex::dfa_size_analyzer a; - auto p = regex::create_regex_parser(a); - p.parse( - parse_options{}.set_skip_whitespace(false).set_verbose(), - buffers::cstring_buffer(Pattern), - s - ); - } - - template - constexpr bool match(const char (&str)[N]) const - { - return match(buffers::cstring_buffer(str)); - } - - template - constexpr bool match(const Buffer& buf) const - { - detail::no_stream s; - return match(buf, s); - } - - template - constexpr bool match(const Buffer& buf, Stream& s) const - { - return match(match_options{}, buf, s); - } - - template - constexpr bool match(match_options opts, const Buffer& buf, Stream& s) const - { - auto res = dfa_match(sm, opts, source_point{}, buf.begin(), buf.end(), s); - if (res.term_idx == 0 && res.it == buf.end()) - return true; - else - { - if (res.term_idx == 0) - s << "Leftover text after recognition: " << buf.get_view(res.it, buf.end()) << "\n"; - else - s << "Unexpected char: " << utils::c_names.name(*res.it) << "\n"; - return false; - } - } - - template - constexpr void write_diag_str(Stream& stream) const - { - regex::write_dfa_diag_str(sm, stream); - } - - private: - dfa sm; - }; -} - -template -class regex_term : public term -{ -public: - using internal_value_type = std::string_view; - - static const size_t dfa_size = regex::analyze_dfa_size(Pattern); - static const bool is_trivial = false; - - static const size_t pattern_size = std::size(Pattern); - - constexpr regex_term(associativity a = associativity::no_assoc) : - regex_term(nullptr, 0, a) - {} - - constexpr regex_term(int precedence = 0, associativity a = associativity::no_assoc) : - regex_term(nullptr, precedence, a) - {} - - constexpr regex_term(const char *custom_name, int precedence = 0, associativity a = associativity::no_assoc) : - term(precedence, a), - custom_name(custom_name) - { - id[0] = 'r'; - id[1] = '_'; - utils::copy_array(&id[2], Pattern, std::make_index_sequence{}); - } - - constexpr const char* get_name() const { return custom_name ? custom_name : id; } - constexpr const char* get_id() const { return id; } - constexpr auto get_data() const { return regex::regex_pattern_data{ Pattern }; } - - constexpr const auto& get_ftor() const { return detail::pass_sv; } - -private: - char id[pattern_size + 2] = {}; - const char* custom_name = nullptr; -}; - -} // namespace exaudf_ctpg - -#endif diff --git a/exaudfclient/base/script_options_parser/ctpg/script_option_lines_ctpg.cc b/exaudfclient/base/script_options_parser/ctpg/script_option_lines_ctpg.cc deleted file mode 100644 index fa7c0ba..0000000 --- a/exaudfclient/base/script_options_parser/ctpg/script_option_lines_ctpg.cc +++ /dev/null @@ -1,283 +0,0 @@ -#include "script_option_lines_ctpg.h" -#include "ctpg.hpp" -#include -#include -#include -#include "script_options_parser/exception.h" - -using namespace exaudf_ctpg; -using namespace exaudf_ctpg::ftors; - - -namespace ExecutionGraph -{ - -namespace OptionsLineParser -{ - - -namespace CTPG { - - -struct Option { - std::string key; - std::string value; - source_point start; - source_point end; -}; - -using options_type = std::vector